# Boot-дефайны IMXRT1052 [Manufacturing User's Guide](../docs/manufacturing_user's_guide.pdf) ## Процесс загрузки При старте BootROM читает QSPI Flash через FlexSPI и ищет специальные структуры по фиксированным смещениям от начала Flash (`0x60000000`): ```bash 0x60000000 FDCB — FlexSPI NOR Configuration Block (512 bytes) 0x60000400 IVT — Image Vector Table 0x60000420 Boot Data 0x60000430 DCD — Device Configuration Data (опционально) ``` После разбора структур BootROM передаёт управление на точку входа прошивки. --- ### `XIP_EXTERNAL_FLASH=1` Код исполняется напрямую из QSPI Flash через XIP (Execute-In-Place) без копирования в RAM. FlexSPI отображает Flash в адресное пространство начиная с `0x60000000`. Стартап и SDK знают что копирование кода из Flash в RAM не требуется. Код в стартапе, который отвечает за инициализацию частоты FlexSPI **не выполняется** ### `XIP_BOOT_HEADER_ENABLE=1` Включает генерацию FDCB и IVT в начале Flash-образа. ### `XIP_BOOT_HEADER_DCD_ENABLE=1` Включает DCD внутри boot header. DCD — список команд для BootROM (запись регистров, ожидание флагов), которые выполняются **до** передачи управления прошивке. Используется для ранней инициализации SDRAM, чтобы линкер мог размещать данные в SDRAM с самого старта. > Если SDRAM инициализируется вручную в `main()` — DCD можно отключить, > убрав этот дефайн. ### `SKIP_SYSCLK_INIT` Запрещает `SystemInit()` (вызывается из стартапа до `main()`) настраивать системные часы. Конфигурация тактирования полностью делегируется `BOARD_BootClockRUN()` из `clock_config.c`. Без этого флага часы инициализировались бы дважды, что может привести к нестабильной работе на этапе старта. --- ## Сценарии размещения кода ### Справка: внутренняя RAM IMXRT1052 IMXRT1052 имеет три региона внутренней RAM: | Регион | Адрес | Размер | Назначение | |--------|--------------|--------|------------------------------------------------------| | ITCM | `0x00000000` | 512 KB | Tightly Coupled Instruction Memory — код, ISR | | DTCM | `0x20000000` | 512 KB | Tightly Coupled Data Memory — стек, критичные данные | | OCRAM | `0x20200000` | 512 KB | On-Chip RAM — общего назначения, доступна DMA | **ITCM** — лучший выбор для исполнения кода из RAM. Подключена напрямую к ядру по выделенной шине, работает без wait states и без кэша. Даёт максимальную детерминированность — критично для ISR и time-critical кода. OCRAM подключена через системную шину и кэш — выше латентность, но доступна периферии и DMA. --- ### Сценарий 1: хранение и исполнение из Flash (XIP) Код хранится в QSPI Flash и исполняется напрямую оттуда через FlexSPI. Копирования не происходит. Простейший вариант — минимум настроек. **Применение:** большинство приложений где производительность не критична, быстрый старт разработки. ```cmake target_compile_definitions(bsp_board PUBLIC XIP_EXTERNAL_FLASH=1 # исполнение прямо из Flash XIP_BOOT_HEADER_ENABLE=1 # FDCB + IVT в начале образа XIP_BOOT_HEADER_DCD_ENABLE=1 # DCD для инициализации SDRAM если нужна SKIP_SYSCLK_INIT ) ``` Линкерный скрипт: `MIMXRT1052xxxxx_flexspi_nor.ld` ```bash Flash (XIP): 0x60000000 — код и константы DTCM: 0x20000000 — стек, .data, .bss ``` **Ограничения:** FlexSPI шина делится между исполнением кода и доступом к данным Flash. При интенсивной работе с Flash (запись, чтение данных) производительность кода падает. --- ### Сценарий 2: хранение во Flash, исполнение из внутренней RAM (ITCM) Код хранится в QSPI Flash, при старте стартап копирует секцию `.text` в ITCM. BootROM загружает стартап из Flash, стартап копирует остальной код и передаёт управление. **Применение:** ISR с жёсткими временными требованиями, алгоритмы управления, участки кода где нужна детерминированная латентность. ```cmake target_compile_definitions(bsp_board PUBLIC # XIP_EXTERNAL_FLASH не определяем — код копируется в ITCM XIP_BOOT_HEADER_ENABLE=1 # FDCB + IVT нужны — BootROM всё равно грузит из Flash XIP_BOOT_HEADER_DCD_ENABLE=1 # DCD нужен если SDRAM используется под данные SKIP_SYSCLK_INIT ) ``` Линкерный скрипт: `MIMXRT1052xxxxx_flexspi_nor_txt_itcm.ld` (или кастомный) ```bash Flash: 0x60000000 — хранение образа ITCM (LMA→VMA): 0x00000000 — исполнение кода DTCM: 0x20000000 — стек, .data, .bss ``` **Ограничения:** ITCM всего 512 KB — весь исполняемый код должен в него поместиться. Время старта увеличивается на время копирования из Flash. --- ### Сценарий 3: хранение во Flash, исполнение из SDRAM Код хранится в QSPI Flash, при старте копируется в SDRAM (32 MB, `0x80000000`). SDRAM **должна быть инициализирована до копирования** — через DCD BootROM. **Применение:** большие приложения которые не помещаются во внутреннюю RAM и слишком медленно работают из Flash — например, UI с графикой, обработка изображений. ```cmake target_compile_definitions(bsp_board PUBLIC # XIP_EXTERNAL_FLASH не определяем — код копируется в SDRAM XIP_BOOT_HEADER_ENABLE=1 XIP_BOOT_HEADER_DCD_ENABLE=1 # обязательно — DCD инициализирует SDRAM до старта SKIP_SYSCLK_INIT ) ``` Линкерный скрипт: кастомный с регионом SDRAM ```bash Flash: 0x60000000 — хранение образа SDRAM (LMA→VMA): 0x80000000 — исполнение кода (32 MB) DTCM: 0x20000000 — стек, критичные данные ITCM: 0x00000000 — ISR и time-critical функции ``` Для ISR и критичного кода используй атрибут `__attribute__((section(".itcm")))` чтобы разместить их в ITCM отдельно от основного кода в SDRAM. **Ограничения:** SDRAM работает через SEMC с несколькими wait states — медленнее ITCM. DCD усложняет конфигурацию — при смене частоты тактирования SEMC параметры DCD нужно пересчитывать. --- ### Сводная таблица | Сценарий | `XIP_EXTERNAL_FLASH` | `XIP_BOOT_HEADER_ENABLE` | `XIP_BOOT_HEADER_DCD_ENABLE` | `SKIP_SYSCLK_INIT` | |---------------------|----------------------|--------------------------|------------------------------|--------------------| | XIP из Flash | `1` | `1` | `1` (если SDRAM нужна) | да | | Копирование в ITCM | не определять | `1` | `1` (если SDRAM нужна) | да | | Копирование в SDRAM | не определять | `1` | `1` (обязательно) | да |