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.

А дальше - разбирайтесь самостоятельно!