NXP i.MX7D и ядро Cortex-M4 в его составе
Если вы знакомы с младшенькими кортексами, то считайте себя знатоком дела.
Камушек оснащён полноценным M4F, как например в
F407.
Вся эта инфраструктура довольно хорошо документирована. Поэтому я рассмотрю лишь главное
- высокоуровневый старт ядра с нуля, во время инициализации камня.
При холодном старте, ядро M4 затактировано частотой 240 МГц
и висит в состоянии сброса.
Смотрите файл
Стартовать M4.asm.
@ Оживим M4
MOV32 R10, SRC_BASE
@ Отключить собачку и снять с ядра жёсткий сброс
MOV R11, 5 << MASK_WDOG3_RST + 1 << ENABLE_M4
STR R11, [R10, M4RCR] @ WDOG3 замаскирован
@ Дождаться завершения сброса
1:
LDR R11, [R10, M4RCR]
TST R11, 1 << SW_M4P_RST
BNE 1b
TST R11, 1 << SW_M4C_RST
BNE 1b
Прошивку будем загружать в быструю память программ TCML.
Со стороны М4 она видна по адресу 0x1FFF8000.
Со стороны A7 - 0x007F8000.
Где будет размещаться исполняемый код М4, под тот адрес его и компилируйте.
Хотя при грамотном подходе, код можно сделать полностью переносимым,
в ARM есть все необходимые средства для этого.
@ Загрузить прошивку вовнутрь M4
MOV32 R6, Код_для_Cortex_M4 @ Базовый адрес файла прошивки
MOV32 R7, 0x007F8000 @ Базовый адрес памяти программ TCML
MOV32 R8, Длинна_кода_Cortex_M4 @ Размер прошивки в байтах
1:
PLD [R6, 192] @ Быстрая загрузка
VLDM R6!,{D0-D7} @ Блоками
VSTM R7!,{D0-D7} @ По 64 байта
DEC R8, 64
BGE 1b
Прошивку мы загрузили в TCML. Но после сброса, ядро M4 её не увидит,
потому что всегда стартует по адресу OCRAM_S.
Со стороны М4, эта память видна по адресу 0x20180000 или по алиасу 0x00000000.
А со стороны A7 она находится по адресу 0x00180000. Именно там
мы и разместим стандартный заголовок, который состоит из двух слов:
адрес стека и вектор сброса - адрес начала исполняемого кода.
Вектор сброса имеет стандартный для режима Thumb формат - младший бит адреса
должен быть == 1.
Если забыть об этом, ядро повиснет и не стартанёт.
Предполагается, что вектора уже настроены в прошивке.
Именно оттуда мы их и возьмём.
Будьте внимательны.
@ Вставить указатели по адресу OCRAM_S
MOV32 R11, 0x00180000 @ M4 всегда стартует по этому адресу
@ Установить стек
MOV32 R6, Код_для_Cortex_M4 @ Данные берутся из заголовка прошивки
LDR R10, [R6], 4 @ Прочитать указатель стека
STR R10, [R11], 4 @ Положить в OCRAM_S
@ Установить вектор сброса
LDR R10, [R6] @ Прочитать вектор сброса
STR R10, [R11] @ Положить в OCRAM_S + 4
Всё готово, стартуем код на выполнение!
@ Выполнить мягкий сброс M4
@ И программа начнёт выполняться
MOV32 R10, SRC_BASE
LDR R11, [R10, M4RCR]
BIS R11, 1 << SW_M4C_RST
STR R11, [R10, M4RCR]
@ Дождаться завершения сброса
1: @ Хотя можно и не ждать
LDR R11, [R10, M4RCR]
TST R11, 1 << SW_M4C_RST
BNE 1b
Если вы ожидаете каких-то непосредственных действий от М4, то помните,
что он выходит из сброса и запускается
не сразу.
На его раскачку может потребоваться несколько микросекунд.
@ Немного подождите
Пауза 10 @ Время на раскачку ядра M4
Бинарный файл прошивки для М4 размещается в общем теле бинарника A7.
Инкапсулируется просто:
.text 2
.align 6, 0
Код_для_Cortex_M4:
.incbin "Файлы для вложений/Cortex-M4/exe/M4.bin"
Длинна_кода_Cortex_M4 = . - Код_для_Cortex_M4
.text 0
Всё готово! Ядрышко молотит, программа выполняется. Если хотите перестроить частоту ядра,
то измените содержимое регистра TARGET_ROOT1. С частотами слишком увлекаться не стоит,
это может привести к деградации кристалла и его разрушению..
MOV32 R10, CCM_BASE + TARGET_ROOT1 @ ARM_M4_CLK_ROOT
MOV32 R9, 1<<28 + 0<<24
@ 0<<24 = 24 МГц
@ 1<<24 = 240 МГц (по умолчанию)
@ 3<<24 = 270 МГц предел (ядрышко сгорит)
STR R9, [R10]
Итак, мы с вами рассмотрели наиболее сложный вариант - размещение проекта М4 в отдельной папке.
Со своим набором файлов, которые лежат в папке
Cortex-M4.
Хотя для небольших проектов, можно инкапсулировать исполняемый код М4 непосредственно
в листингах ассемблера A7. Для этого нужно только перестроить режим компилятора
и все последующие ассемблерные строки будут компилироваться под М4.
Внутри кода A7, вставьте волшебные слова:
.align 2, 0
Встроенный_код_для_M4:
.syntax unified
.arch armv7-m
.cpu cortex-m4
.fpu fpv4-sp-d16
.thumb
.thumb_func
@ В этой точке начинается исполняемый код М4
nop
nop
nop
Длинна_кода_Cortex_M4 = . - Встроенный_код_для_M4
Прелесть встроенного ядра в том, что он имеет доступ ко всем ресурсам процессора.
Реализовано кеширование!
Вы можете в полной мере воспользоваться MPU.
В папке Cortex-M4 находится небольшой проект, который раскачивает ядро и настраивает
М4 MPU.
Здесь я только лишь коснулся большого мира маленького Cortex-М4.
А дальше - разбирайтесь самостоятельно!