Настройка сборки и прошивки MIMXRT1052 bootable image с помощью SPSDK на хосте
This commit is contained in:
Dmitry Akimov 2026-03-10 13:35:25 +03:00
parent 5ac85b90f5
commit 853eda2d08
40 changed files with 221765 additions and 247 deletions

View file

@ -5,18 +5,11 @@ Checks: >
clang-analyzer-*,
cppcoreguidelines-avoid-magic-numbers,
cppcoreguidelines-macro-usage,
cppcoreguidelines-owning-references,
cppcoreguidelines-pro-bounds-constant-array-index,
cppcoreguidelines-pro-bounds-pointer-arithmetic,
cppcoreguidelines-pro-type-const-cast,
cppcoreguidelines-pro-type-reinterpret-cast,
cppcoreguidelines-pro-type-static-cast-downcast,
hicpp-no-array-decay,
hicpp-signed-bitwise,
modernize-avoid-c-arrays,
performance-*,
portability-*,
readability-avoid-const-params-in-declarations,
readability-braces-around-statements,
readability-container-size-empty,
readability-function-size,
@ -26,7 +19,7 @@ Checks: >
readability-named-parameter,
readability-unified-declaration
WarningsAsErrors: 'bugprone-*,clang-analyzer-*'
HeaderFilterRegex: "^((?!Drivers|CMSIS|Core|Middlewares).)*$"
HeaderFilterRegex: "^((?!sdk/|lib/|bsp/board/).)*\\.h$"
CheckOptions:
# ===== ТИПЫ =====
- key: readability-identifier-naming.TypedefCase

View file

@ -2,7 +2,7 @@
If:
PathMatch: "tests/host/.*\\.c"
CompileFlags:
CompilationDatabase: build-host-debug
CompilationDatabase: build/host-debug
---
# Для всего кроме тестов, подхватываем compile_commands для target

View file

@ -39,9 +39,6 @@ LABEL maintainer="von.akimov@gmail.com" \
ENV DEBIAN_FRONTEND=noninteractive
# Копируем тулчейн из Stage 1
COPY --from=toolchain /opt /opt
ENV PATH="/opt/arm-toolchain/bin:${PATH}"
# Устанавливаем LLVM GPG ключ и репозиторий (llvm >= 16 для поддержки If в .clangd), затем все dev-инструменты
@ -61,7 +58,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 100 \
&& update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-17 100 \
&& update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 100 \
&& pip3 install --no-cache-dir cmake-format==0.6.13 \
&& pip3 install --no-cache-dir spsdk cmake-format==0.6.13 \
&& ln -s /usr/bin/clangd /usr/local/bin/clangd \
&& ln -s /usr/bin/clang /usr/local/bin/clang \
&& rm -rf /var/lib/apt/lists/*

View file

@ -1,5 +1,6 @@
{
"name": "MIMXRT1052 TFT Project",
"remoteUser": "devuser",
"build": {
"dockerfile": "Dockerfile"
},

3
.gitignore vendored
View file

@ -63,4 +63,7 @@ Testing/
compile_commands.json
.cache/
.DS_Store
.venv/
__pycache__/
*.pyc

View file

@ -43,8 +43,8 @@
│ ├── bootloader/ # [Проект 2] Загрузчик с поддержкой A/B обновления
│ └── app/ # [Проект 3] Основная боевая прошивка (FreeRTOS)
├── tests/ # Host-тесты (unit + integration)
│ ├── unit/
│ └── integration/
│ ├── host/
│ └── target/
└── tools/ # Скрипты для прошивки, провизии, HIL-тестов
├── flash_usb.py # Прошивка через USB ROM (blhost / nxp-spsdk)
├── flash_remote.sh # Прошивка на удалённый сервер через SSH
@ -94,10 +94,8 @@ Bare-metal прошивка для входного контроля на про
| `clangd` | Language server для VSCode |
| `clang-format` | Форматирование кода |
| `clang-tidy` | Статический анализ |
| `cppcheck` | Дополнительный статический анализ |
| `lcov / gcovr` | Покрытие host-тестов |
| `Python 3 + nxp-spsdk` | Прошивка (blhost, nxpimage), производственная провизия |
| `srec_cat` | Манипуляции с бинарными образами |
---

View file

@ -14,10 +14,29 @@ target_include_directories(bsp_board PUBLIC board)
# Подавляем предупреждения о macro redefined
set_source_files_properties(board/board.c board/pin_mux.c
PROPERTIES COMPILE_OPTIONS "-w")
# Дефайны PUBLIC — транзитивно подтянутся во все firmware таргеты
# Дефайны PUBLIC — транзитивно подтянутся во все firmware таргеты TODO: для
# каждого приложения свои дефайны
target_compile_definitions(bsp_board PUBLIC CPU_MIMXRT1052CVJ5B
SKIP_SYSCLK_INIT)
# Сценарий A: XIP — код исполняется прямо из Flash
add_library(bsp_boot_xip INTERFACE)
target_compile_definitions(
bsp_board PUBLIC CPU_MIMXRT1052CVJ5B XIP_EXTERNAL_FLASH=1
XIP_BOOT_HEADER_DCD_ENABLE=1 SKIP_SYSCLK_INIT)
bsp_boot_xip INTERFACE XIP_EXTERNAL_FLASH=1 XIP_BOOT_HEADER_ENABLE=1
XIP_BOOT_HEADER_DCD_ENABLE=1)
# Сценарий B: копирование в ITCM (для bootloader или критичного кода)
add_library(bsp_boot_itcm INTERFACE)
target_compile_definitions(
bsp_boot_itcm INTERFACE XIP_BOOT_HEADER_ENABLE=1 XIP_BOOT_HEADER_DCD_ENABLE=1
# XIP_EXTERNAL_FLASH намеренно отсутствует
)
# Сценарий C: копирование в SDRAM (для app с графикой)
add_library(bsp_boot_sdram INTERFACE)
target_compile_definitions(
bsp_boot_sdram INTERFACE XIP_BOOT_HEADER_ENABLE=1
XIP_BOOT_HEADER_DCD_ENABLE=1)
# sdk_device PUBLIC — транзитивно подтянется во все firmware таргеты
target_link_libraries(bsp_board PUBLIC sdk_device sdk_clock sdk_common)

4
bsp/board/.clang-tidy Normal file
View file

@ -0,0 +1,4 @@
---
# Vendored / сгенерированный код — не анализируем вообще
InheritParentConfig: false
Checks: "-*"

219123
bsp/board/MIMXRT1052.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -5,5 +5,4 @@
void BOARD_Init(void) {
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitRS_GPIO();
}

View file

@ -6,8 +6,9 @@
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
* This file was generated by the MCUXpresso Config Tools. Any manual edits made
*to this file will be overwritten if the respective MCUXpresso Config Tools is
*used to update this file.
**********************************************************************************************************************/
#ifndef _PIN_MUX_H_
@ -18,8 +19,7 @@
**********************************************************************************************************************/
/*! @brief Direction type */
typedef enum _pin_mux_direction
{
typedef enum _pin_mux_direction {
kPIN_MUX_DirectionInput = 0U, /* Input direction */
kPIN_MUX_DirectionOutput = 1U, /* Output direction */
kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */
@ -51,11 +51,16 @@ void BOARD_InitBootPins(void);
#define BOARD_INITPINS_UserLed1_CHANNEL 3U /*!< Signal channel */
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_UserLed1_GPIO GPIO3 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_UserLed1_INIT_GPIO_VALUE 1U /*!< GPIO output initial state */
#define BOARD_INITPINS_UserLed1_GPIO \
GPIO3 /*!< GPIO peripheral base pointer \
*/
#define BOARD_INITPINS_UserLed1_INIT_GPIO_VALUE \
1U /*!< GPIO output initial state */
#define BOARD_INITPINS_UserLed1_GPIO_PIN 3U /*!< GPIO pin number */
#define BOARD_INITPINS_UserLed1_GPIO_PIN_MASK (1U << 3U) /*!< GPIO pin mask */
#define BOARD_INITPINS_UserLed1_PORT GPIO3 /*!< PORT peripheral base pointer */
#define BOARD_INITPINS_UserLed1_PORT \
GPIO3 /*!< PORT peripheral base pointer \
*/
#define BOARD_INITPINS_UserLed1_PIN 3U /*!< PORT pin number */
#define BOARD_INITPINS_UserLed1_PIN_MASK (1U << 3U) /*!< PORT pin mask */
@ -66,11 +71,16 @@ void BOARD_InitBootPins(void);
#define BOARD_INITPINS_UserLed2_CHANNEL 4U /*!< Signal channel */
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_UserLed2_GPIO GPIO3 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_UserLed2_INIT_GPIO_VALUE 1U /*!< GPIO output initial state */
#define BOARD_INITPINS_UserLed2_GPIO \
GPIO3 /*!< GPIO peripheral base pointer \
*/
#define BOARD_INITPINS_UserLed2_INIT_GPIO_VALUE \
1U /*!< GPIO output initial state */
#define BOARD_INITPINS_UserLed2_GPIO_PIN 4U /*!< GPIO pin number */
#define BOARD_INITPINS_UserLed2_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */
#define BOARD_INITPINS_UserLed2_PORT GPIO3 /*!< PORT peripheral base pointer */
#define BOARD_INITPINS_UserLed2_PORT \
GPIO3 /*!< PORT peripheral base pointer \
*/
#define BOARD_INITPINS_UserLed2_PIN 4U /*!< PORT pin number */
#define BOARD_INITPINS_UserLed2_PIN_MASK (1U << 4U) /*!< PORT pin mask */
@ -82,7 +92,8 @@ void BOARD_InitBootPins(void);
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_SdPwr_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_SdPwr_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */
#define BOARD_INITPINS_SdPwr_INIT_GPIO_VALUE \
0U /*!< GPIO output initial state */
#define BOARD_INITPINS_SdPwr_GPIO_PIN 19U /*!< GPIO pin number */
#define BOARD_INITPINS_SdPwr_GPIO_PIN_MASK (1U << 19U) /*!< GPIO pin mask */
#define BOARD_INITPINS_SdPwr_PORT GPIO1 /*!< PORT peripheral base pointer */
@ -97,7 +108,8 @@ void BOARD_InitBootPins(void);
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_LcdLed_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_LcdLed_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdLed_INIT_GPIO_VALUE \
0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdLed_GPIO_PIN 20U /*!< GPIO pin number */
#define BOARD_INITPINS_LcdLed_GPIO_PIN_MASK (1U << 20U) /*!< GPIO pin mask */
#define BOARD_INITPINS_LcdLed_PORT GPIO1 /*!< PORT peripheral base pointer */
@ -111,10 +123,16 @@ void BOARD_InitBootPins(void);
#define BOARD_INITPINS_TactBut1_CHANNEL 30U /*!< Signal channel */
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_TactBut1_GPIO GPIO2 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_TactBut1_GPIO \
GPIO2 /*!< GPIO peripheral base pointer \
*/
#define BOARD_INITPINS_TactBut1_GPIO_PIN 30U /*!< GPIO pin number */
#define BOARD_INITPINS_TactBut1_GPIO_PIN_MASK (1U << 30U) /*!< GPIO pin mask */
#define BOARD_INITPINS_TactBut1_PORT GPIO2 /*!< PORT peripheral base pointer */
#define BOARD_INITPINS_TactBut1_GPIO_PIN_MASK \
(1U << 30U) /*!< GPIO pin mask \
*/
#define BOARD_INITPINS_TactBut1_PORT \
GPIO2 /*!< PORT peripheral base pointer \
*/
#define BOARD_INITPINS_TactBut1_PIN 30U /*!< PORT pin number */
#define BOARD_INITPINS_TactBut1_PIN_MASK (1U << 30U) /*!< PORT pin mask */
@ -160,7 +178,8 @@ void BOARD_InitBootPins(void);
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_LcdLr_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_LcdLr_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdLr_INIT_GPIO_VALUE \
0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdLr_GPIO_PIN 28U /*!< GPIO pin number */
#define BOARD_INITPINS_LcdLr_GPIO_PIN_MASK (1U << 28U) /*!< GPIO pin mask */
#define BOARD_INITPINS_LcdLr_PORT GPIO1 /*!< PORT peripheral base pointer */
@ -175,7 +194,8 @@ void BOARD_InitBootPins(void);
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_LcdMode_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_LcdMode_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdMode_INIT_GPIO_VALUE \
0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdMode_GPIO_PIN 29U /*!< GPIO pin number */
#define BOARD_INITPINS_LcdMode_GPIO_PIN_MASK (1U << 29U) /*!< GPIO pin mask */
#define BOARD_INITPINS_LcdMode_PORT GPIO1 /*!< PORT peripheral base pointer */
@ -190,7 +210,8 @@ void BOARD_InitBootPins(void);
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_LcdUd_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_LcdUd_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdUd_INIT_GPIO_VALUE \
0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdUd_GPIO_PIN 30U /*!< GPIO pin number */
#define BOARD_INITPINS_LcdUd_GPIO_PIN_MASK (1U << 30U) /*!< GPIO pin mask */
#define BOARD_INITPINS_LcdUd_PORT GPIO1 /*!< PORT peripheral base pointer */
@ -204,11 +225,18 @@ void BOARD_InitBootPins(void);
#define BOARD_INITPINS_LcdDithb_CHANNEL 31U /*!< Signal channel */
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_LcdDithb_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_LcdDithb_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdDithb_GPIO \
GPIO1 /*!< GPIO peripheral base pointer \
*/
#define BOARD_INITPINS_LcdDithb_INIT_GPIO_VALUE \
0U /*!< GPIO output initial state */
#define BOARD_INITPINS_LcdDithb_GPIO_PIN 31U /*!< GPIO pin number */
#define BOARD_INITPINS_LcdDithb_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */
#define BOARD_INITPINS_LcdDithb_PORT GPIO1 /*!< PORT peripheral base pointer */
#define BOARD_INITPINS_LcdDithb_GPIO_PIN_MASK \
(1U << 31U) /*!< GPIO pin mask \
*/
#define BOARD_INITPINS_LcdDithb_PORT \
GPIO1 /*!< PORT peripheral base pointer \
*/
#define BOARD_INITPINS_LcdDithb_PIN 31U /*!< PORT pin number */
#define BOARD_INITPINS_LcdDithb_PIN_MASK (1U << 31U) /*!< PORT pin mask */
@ -219,14 +247,19 @@ void BOARD_InitBootPins(void);
#define BOARD_INITPINS_TactBut2_CHANNEL 31U /*!< Signal channel */
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_TactBut2_GPIO GPIO2 /*!< GPIO peripheral base pointer */
#define BOARD_INITPINS_TactBut2_GPIO \
GPIO2 /*!< GPIO peripheral base pointer \
*/
#define BOARD_INITPINS_TactBut2_GPIO_PIN 31U /*!< GPIO pin number */
#define BOARD_INITPINS_TactBut2_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */
#define BOARD_INITPINS_TactBut2_PORT GPIO2 /*!< PORT peripheral base pointer */
#define BOARD_INITPINS_TactBut2_GPIO_PIN_MASK \
(1U << 31U) /*!< GPIO pin mask \
*/
#define BOARD_INITPINS_TactBut2_PORT \
GPIO2 /*!< PORT peripheral base pointer \
*/
#define BOARD_INITPINS_TactBut2_PIN 31U /*!< PORT pin number */
#define BOARD_INITPINS_TactBut2_PIN_MASK (1U << 31U) /*!< PORT pin mask */
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
@ -238,7 +271,6 @@ void BOARD_InitPins(void);
#define BOARD_INITRS_UART_RsRx_PERIPHERAL LPUART3 /*!< Peripheral name */
#define BOARD_INITRS_UART_RsRx_SIGNAL RX /*!< Signal name */
/*!
* @brief RS_RX pin is used as LPUART3_RX
*
@ -252,12 +284,17 @@ void BOARD_InitRS_UART(void);
#define BOARD_INITRS_UART_DEINIT_RsRx_CHANNEL 23U /*!< Signal channel */
/* Symbols to be used with GPIO driver */
#define BOARD_INITRS_UART_DEINIT_RsRx_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITRS_UART_DEINIT_RsRx_GPIO \
GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITRS_UART_DEINIT_RsRx_GPIO_PIN 23U /*!< GPIO pin number */
#define BOARD_INITRS_UART_DEINIT_RsRx_GPIO_PIN_MASK (1U << 23U) /*!< GPIO pin mask */
#define BOARD_INITRS_UART_DEINIT_RsRx_PORT GPIO1 /*!< PORT peripheral base pointer */
#define BOARD_INITRS_UART_DEINIT_RsRx_GPIO_PIN_MASK \
(1U << 23U) /*!< GPIO pin mask */
#define BOARD_INITRS_UART_DEINIT_RsRx_PORT \
GPIO1 /*!< PORT peripheral base pointer */
#define BOARD_INITRS_UART_DEINIT_RsRx_PIN 23U /*!< PORT pin number */
#define BOARD_INITRS_UART_DEINIT_RsRx_PIN_MASK (1U << 23U) /*!< PORT pin mask */
#define BOARD_INITRS_UART_DEINIT_RsRx_PIN_MASK \
(1U << 23U) /*!< PORT pin mask \
*/
/* GPIO_AD_B1_07 (coord K10), RsRx */
/* Routed pin properties */
@ -277,11 +314,11 @@ void BOARD_InitRS_UART(void);
#define BOARD_INITRS_UART_DEINIT_RsRx_SIGNAL IN /*!< Signal name */
#define BOARD_INITRS_UART_DEINIT_RsRx_CHANNEL 12U /*!< Signal channel */
/*!
* @brief This is a de-initialization function for 'BOARD_InitRS_UART' function.
* It sets all pins features (routing, direction and electrical) to their after-reset state.
* It also tries to route the previous peripheral signals to their default pins.
* It sets all pins features (routing, direction and electrical) to their
* after-reset state. It also tries to route the previous peripheral signals to
* their default pins.
*
*/
void BOARD_InitRS_UART_deinit(void);
@ -300,7 +337,6 @@ void BOARD_InitRS_UART_deinit(void);
#define BOARD_INITRS_GPIO_RsRx_PIN 23U /*!< PORT pin number */
#define BOARD_INITRS_GPIO_RsRx_PIN_MASK (1U << 23U) /*!< PORT pin mask */
/*!
* @brief RS_RX pin is used as GPIO_INPUT
*
@ -314,12 +350,17 @@ void BOARD_InitRS_GPIO(void);
#define BOARD_INITRS_GPIO_DEINIT_RsRx_CHANNEL 23U /*!< Signal channel */
/* Symbols to be used with GPIO driver */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_GPIO GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_GPIO \
GPIO1 /*!< GPIO peripheral base pointer */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_GPIO_PIN 23U /*!< GPIO pin number */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_GPIO_PIN_MASK (1U << 23U) /*!< GPIO pin mask */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_PORT GPIO1 /*!< PORT peripheral base pointer */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_GPIO_PIN_MASK \
(1U << 23U) /*!< GPIO pin mask */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_PORT \
GPIO1 /*!< PORT peripheral base pointer */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_PIN 23U /*!< PORT pin number */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_PIN_MASK (1U << 23U) /*!< PORT pin mask */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_PIN_MASK \
(1U << 23U) /*!< PORT pin mask \
*/
/* GPIO_AD_B1_07 (coord K10), RsRx */
/* Routed pin properties */
@ -339,11 +380,11 @@ void BOARD_InitRS_GPIO(void);
#define BOARD_INITRS_GPIO_DEINIT_RsRx_SIGNAL IN /*!< Signal name */
#define BOARD_INITRS_GPIO_DEINIT_RsRx_CHANNEL 12U /*!< Signal channel */
/*!
* @brief This is a de-initialization function for 'BOARD_InitRS_GPIO' function.
* It sets all pins features (routing, direction and electrical) to their after-reset state.
* It also tries to route the previous peripheral signals to their default pins.
* It sets all pins features (routing, direction and electrical) to their
* after-reset state. It also tries to route the previous peripheral signals to
* their default pins.
*
*/
void BOARD_InitRS_GPIO_deinit(void);

View file

@ -36,10 +36,10 @@ MEMORY
m_flash_config (RX) : ORIGIN = 0x60000000, LENGTH = 0x00001000
m_ivt (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00
m_qacode (RX) : ORIGIN = 0x00000000, LENGTH = 0x00020000
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00040000
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x007FDC00 /* External QSPI FLASH 8 MB */
m_qacode (RX) : ORIGIN = 0x00000000, LENGTH = 0x00020000 /* SRAM_ITC 128KB */
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* SRAM_DTC 128KB */
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00040000 /* SRAM_OC 256KB */
}
/* Define output sections */

View file

@ -1,5 +1,7 @@
# Boot-дефайны IMXRT1052
[Manufacturing User's Guide](../docs/manufacturing_user's_guide.pdf)
## Процесс загрузки
При старте BootROM читает QSPI Flash через FlexSPI и ищет специальные структуры
@ -21,12 +23,11 @@
Код исполняется напрямую из QSPI Flash через XIP (Execute-In-Place) без
копирования в RAM. FlexSPI отображает Flash в адресное пространство начиная с
`0x60000000`. Стартап и SDK знают что копирование кода из Flash в RAM не
требуется.
требуется. Код в стартапе, который отвечает за инициализацию частоты FlexSPI **не выполняется**
### `XIP_BOOT_HEADER_ENABLE=1`
Включает генерацию FDCB и IVT в начале Flash-образа. Без этих структур BootROM
не сможет найти прошивку и передать ей управление — устройство не загрузится.
Включает генерацию FDCB и IVT в начале Flash-образа.
### `XIP_BOOT_HEADER_DCD_ENABLE=1`

BIN
docs/MT48LCxxM4,8,16A2.pdf Normal file

Binary file not shown.

Binary file not shown.

BIN
docs/mcu_rm.pdf Normal file

Binary file not shown.

View file

@ -13,6 +13,7 @@ target_sources(firmware_test PRIVATE main.c
target_link_libraries(
firmware_test
PRIVATE bsp_board
bsp_boot_xip
# SDK драйверы периферии — добавляй по мере написания тестов
sdk_lpuart # UART тест
sdk_flexcan # CAN тест
@ -44,5 +45,7 @@ add_custom_command(
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:firmware_test>
${CMAKE_BINARY_DIR}/firmware_test.bin
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:firmware_test>
${CMAKE_BINARY_DIR}/firmware_test.hex
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:firmware_test>
COMMENT "Generating firmware_test.bin")

View file

@ -6,8 +6,12 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "SEGGER_RTT.h"
#include "board.h"
#include "fsl_gpio.h"
#include "pin_mux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
@ -23,13 +27,12 @@
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Main function
*/
int main(void) {
const uint32_t USER_DELAY_US = 1000000;
BOARD_Init();
GPIO_PinWrite(BOARD_INITPINS_UserLed1_PORT, BOARD_INITPINS_UserLed1_PIN, 0);
GPIO_PinWrite(BOARD_INITPINS_UserLed2_PORT, BOARD_INITPINS_UserLed2_PIN, 0);
while (1) {
}
}

4
sdk/.clang-tidy Normal file
View file

@ -0,0 +1,4 @@
---
# Vendored / сгенерированный код — не анализируем вообще
InheritParentConfig: false
Checks: "-*"

6
tests/.clang-tidy Normal file
View file

@ -0,0 +1,6 @@
---
InheritParentConfig: true # наследуем корневой конфиг...
Checks: >
-*,
bugprone-*,
clang-analyzer-* # ...но оставляем только это

164
tools/README.md Normal file
View file

@ -0,0 +1,164 @@
# Host Tools — окружение для прошивки
Изолированное Python-окружение на базе [uv](https://docs.astral.sh/uv/).
Устанавливается на хост-машине разработчика — **не внутри devcontainer**.
## Структура
```bash
tools/host/
├── dcd/
│ ├── dcd_mt48lc16m16a2.cfg ← источник истины для DCD (коммитить)
│ ├── dcd_compiler.py ← скрипт: .cfg → .bin
│ └── dcd.bin ← артефакт (пересобирается из .cfg)
├── fdcb/
│ ├── fcb_w25q64_quad.yaml ← конфиг FCB: W25Q64, Quad I/O, 133 MHz
│ └── fcb.bin ← артефакт (пересобирается из .yaml)
├── hab/
│ ├── hab_firmware_test.yaml ← HAB: Debug + DCD (входной контроль)
│ ├── hab_bootloader.yaml ← HAB: Release, без DCD
│ └── hab_app.yaml ← HAB: Release + DCD (боевая прошивка)
├── image/
│ ├── bootimg_firmware_test.yaml
│ ├── bootimg_bootloader.yaml
│ └── bootimg_app.yaml
├── pyproject.toml ← зависимости (spsdk, версия зафиксирована)
├── uv.lock ← lockfile (коммитить)
├── .python-version
└── README.md
```
## Установка uv (один раз на машину)
```bash
# Linux/macOS
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```
## Первый запуск (один раз на репозиторий)
```bash
cd tools/host
uv sync
```
### udev правило для USB SDP — только Linux, один раз на машину
Без этого правила `blhost` требует `sudo`:
```bash
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1fc9", ATTR{idProduct}=="0135", MODE="0666", GROUP="plugdev"' \
| sudo tee /etc/udev/rules.d/99-nxp-sdp.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
sudo usermod -a -G plugdev $USER
# Перелогиниться после usermod!
```
## Пайплайн сборки загрузочного образа
### Шаг 1 — DCD (пересобирать при изменении dcd_mt48lc16m16a2.cfg)
```bash
cd tools/host/dcd
uv run python3 dcd_compiler.py dcd_mt48lc16m16a2.cfg dcd.bin
```
### Шаг 2 — FCB (пересобирать при изменении fcb_w25q64_quad.yaml)
```bash
cd tools/host/fdcb
uv run nxpimage bootable-image fcb export -c fcb_w25q64_quad.yaml -o fcb.bin
```
### Шаг 3 — Загрузочный образ
```bash
cd tools/host/image
# firmware_test (Debug, входной контроль)
uv run nxpimage bootable-image export -c bootimg_firmware_test.yaml
# bootloader (Release)
uv run nxpimage bootable-image export -c bootimg_bootloader.yaml
# app (Release, боевая прошивка)
uv run nxpimage bootable-image export -c bootimg_app.yaml
```
Артефакты попадают в `build/Debug/` и `build/Release/` соответственно.
### Проверка образа
```bash
cd tools/host/image
uv run nxpimage bootable-image parse \
-b ../../../../build/Debug/firmware_test_bootable.bin \
-f mimxrt1050
```
В выводе должны присутствовать секции `FCB`, `IVT`, `BDT`, `DCD`, `App`.
## Прошивка через USB (BootROM SDP режим)
Перевести плату в SDP режим: `BOOT_MOD_1 = 1` (подтянуть к 3V3), затем подать питание или нажать Reset.
```bash
cd tools/host
# Проверить что устройство определилось (VID:PID 1FC9:0135)
export VID_PID=0x1fc9:0x0130
uv run nxpdevscan
# Версия BootROM на таргете
uv run blhost -u $VID_PID get-property 1
# Доступные BootROM области памяти
uv run blhost -u $VID_PID list-memory
# Прошить firmware_test
uv run blhost -u $VID_PID flash-erase-all
uv run blhost -u $VID_PID write-memory 0x60000000 \
../../build/Debug/firmware_test_bootable.bin
uv run blhost -u $VID_PID reset
# Загрузить в RAM без записи во Flash (для быстрой отладки)
uv run blhost -u $VID_PID load-image ../../build/Debug/firmware_test_bootable.bin
```
После прошивки вернуть `BOOT_MOD_1 = 0` (подтянуть к GND) для нормального старта из Flash.
## Удалённая прошивка (сервер)
```bash
# Из devcontainer или локально — копируем образ на сервер и прошиваем
./tools/host/flash_remote.sh firmware_test Debug
```
## Диагностика
```bash
# Список поддерживаемых семейств (проверка установки)
uv run nxpimage bootable-image get-families
# Список доступных шаблонов для mimxrt1050
uv run nxpimage bootable-image list-templates -f mimxrt1050
# Версия SPSDK
uv run nxpimage --version
uv run blhost --version
```
## Обновление зависимостей
```bash
cd tools/host
uv add "spsdk==X.Y.Z"
uv sync
git add uv.lock
```

Binary file not shown.

View file

@ -0,0 +1 @@
3.10

BIN
tools/host/dcd/dcd.bin Normal file

Binary file not shown.

View file

@ -0,0 +1,216 @@
#!/usr/bin/env python3
"""
dcd_cfg_to_bin.py конвертация DCD .cfg (NXP Config Tools) в .bin (BootROM формат)
Формат DCD бинарника (IMX RT RM, Chapter 9.7):
[Header]
0xD2 DCD tag
length[1:0] общая длина в байтах (big-endian, 2 байта)
0x41 version
[Commands] последовательно:
Write Data (0xCC):
0xCC tag, length BE16, parameter (ширина: 4=word)
[addr BE32, value BE32] × N группируются подряд идущие записи
Check Bits Set (0xCF) wait_until (expr & mask) != 0:
0xCF tag, 0x000C length, parameter (4=word)
addr BE32, mask BE32, count BE32 (0 = бесконечно)
Использование:
python3 dcd_cfg_to_bin.py dcd.cfg dcd.bin
python3 dcd_cfg_to_bin.py dcd.cfg # выведет dcd.bin рядом с cfg
"""
import re
import struct
import sys
from pathlib import Path
from dataclasses import dataclass, field
from typing import Union
# ─── Константы DCD ────────────────────────────────────────────────────────────
DCD_TAG = 0xD2
DCD_VERSION = 0x41
CMD_WRITE = 0xCC
CMD_CHECK_SET = 0xCF # wait_until (reg & mask) != 0
CMD_CHECK_CLEAR = 0xD0 # wait_until (reg & mask) == 0
WIDTH_WORD = 0x04 # 32-bit
# ─── Типы команд ──────────────────────────────────────────────────────────────
@dataclass
class WriteEntry:
addr: int
value: int
@dataclass
class WriteCmd:
entries: list[WriteEntry] = field(default_factory=list)
def to_bytes(self) -> bytes:
length = 4 + len(self.entries) * 8
# NXP RM format: Tag(1) | Length(2 BE) | Parameter(1)
hdr = struct.pack(">BHB", CMD_WRITE, length, WIDTH_WORD)
data = b"".join(
struct.pack(">II", e.addr, e.value) for e in self.entries
)
return hdr + data
@dataclass
class CheckCmd:
addr: int
mask: int
check_set: bool = True # True = wait != 0, False = wait == 0
def to_bytes(self) -> bytes:
tag = CMD_CHECK_SET if self.check_set else CMD_CHECK_CLEAR
# NXP RM format: Tag(1) | Length(2 BE=12) | Parameter(1) | Addr(4) | Mask(4)
# Parameter: bits[2:0]=width(4=32bit), bit[3]=check_set → 0x1C / check_clear → 0x14
# No count field — poll indefinitely is the default (length=12, not 16)
param = 0x1C if self.check_set else 0x14
length = 12 # 4 header + 4 addr + 4 mask
return struct.pack(">BHBII", tag, length, param, self.addr, self.mask)
# ─── Парсер .cfg ─────────────────────────────────────────────────────────────
def parse_hex(s: str) -> int:
return int(s, 16) if s.startswith("0x") or s.startswith("0X") else int(s)
def parse_cfg(text: str) -> list[Union[WriteCmd, CheckCmd]]:
"""
Парсит .cfg и возвращает список команд DCD.
Соседние write-записи группируются в одну WriteCmd.
"""
# Убираем блочные комментарии /* ... */
text = re.sub(r"/\*.*?\*/", "", text, flags=re.DOTALL)
# Убираем строчные комментарии // ...
text = re.sub(r"//[^\n]*", "", text)
commands: list[Union[WriteCmd, CheckCmd]] = []
current_write: WriteCmd | None = None
# Паттерн: *(uint32_t*)0xADDR = 0xVALUE;
re_write = re.compile(
r"\*\s*\(\s*uint32_t\s*\*\s*\)\s*(0x[0-9A-Fa-f]+)\s*=\s*(0x[0-9A-Fa-f]+)\s*;"
)
# Паттерн: (*(uint32_t*)0xADDR & 0xMASK) != 0;
re_check_set = re.compile(
r"\(\s*\*\s*\(\s*uint32_t\s*\*\s*\)\s*(0x[0-9A-Fa-f]+)\s*&\s*(0x[0-9A-Fa-f]+)\s*\)\s*!=\s*0\s*;"
)
# Паттерн: (*(uint32_t*)0xADDR & 0xMASK) == 0;
re_check_clear = re.compile(
r"\(\s*\*\s*\(\s*uint32_t\s*\*\s*\)\s*(0x[0-9A-Fa-f]+)\s*&\s*(0x[0-9A-Fa-f]+)\s*\)\s*==\s*0\s*;"
)
for line in text.splitlines():
line = line.strip()
if not line:
continue
m = re_write.search(line)
if m:
addr = parse_hex(m.group(1))
value = parse_hex(m.group(2))
if current_write is None:
current_write = WriteCmd()
commands.append(current_write)
current_write.entries.append(WriteEntry(addr, value))
continue
m = re_check_set.search(line)
if m:
if current_write is not None:
current_write = None # разрываем группу write
addr = parse_hex(m.group(1))
mask = parse_hex(m.group(2))
commands.append(CheckCmd(addr, mask, check_set=True))
continue
m = re_check_clear.search(line)
if m:
if current_write is not None:
current_write = None
addr = parse_hex(m.group(1))
mask = parse_hex(m.group(2))
commands.append(CheckCmd(addr, mask, check_set=False))
continue
# Не write и не check — разрываем текущую write-группу
# (на случай если между записями есть другой синтаксис)
if current_write is not None:
current_write = None
return commands
# ─── Сборка бинарника ─────────────────────────────────────────────────────────
def build_dcd_binary(commands: list[Union[WriteCmd, CheckCmd]]) -> bytes:
body = b"".join(cmd.to_bytes() for cmd in commands)
total_length = 4 + len(body) # 4 байта header
# NXP RM format: Tag(1) | Length(2 BE) | Version(1)
header = struct.pack(">BHB", DCD_TAG, total_length, DCD_VERSION)
return header + body
# ─── Отчёт ────────────────────────────────────────────────────────────────────
def print_report(commands: list[Union[WriteCmd, CheckCmd]], out_size: int) -> None:
writes = sum(1 for c in commands if isinstance(c, WriteCmd))
checks = sum(1 for c in commands if isinstance(c, CheckCmd))
entries = sum(len(c.entries) for c in commands if isinstance(c, WriteCmd))
print(f"\n{''*52}")
print(f" DCD конвертация завершена")
print(f"{''*52}")
print(f" Write команд (групп) : {writes}")
print(f" Write записей всего : {entries}")
print(f" Check команд : {checks}")
print(f" Размер бинарника : {out_size} байт (0x{out_size:04X})")
print(f"{''*52}")
print("\n Команды:")
for i, cmd in enumerate(commands):
if isinstance(cmd, WriteCmd):
print(f" [{i:02d}] WRITE × {len(cmd.entries):3d} entries"
f" (0x{cmd.entries[0].addr:08X} … 0x{cmd.entries[-1].addr:08X})")
else:
kind = "CHECK_SET (!= 0)" if cmd.check_set else "CHECK_CLR (== 0)"
print(f" [{i:02d}] {kind} addr=0x{cmd.addr:08X} mask=0x{cmd.mask:08X}")
print()
# ─── main ─────────────────────────────────────────────────────────────────────
def main():
if len(sys.argv) < 2:
print(__doc__)
sys.exit(1)
cfg_path = Path(sys.argv[1])
if not cfg_path.exists():
print(f"[ERROR] Файл не найден: {cfg_path}")
sys.exit(1)
out_path = Path(sys.argv[2]) if len(sys.argv) >= 3 else cfg_path.with_suffix(".bin")
text = cfg_path.read_text(encoding="utf-8", errors="replace")
commands = parse_cfg(text)
if not commands:
print("[ERROR] Ни одной команды не найдено. Проверь формат .cfg файла.")
sys.exit(1)
binary = build_dcd_binary(commands)
out_path.write_bytes(binary)
print(f"[OK] Входной файл : {cfg_path}")
print(f"[OK] Выходной файл: {out_path}")
print_report(commands, len(binary))
if __name__ == "__main__":
main()

View file

@ -0,0 +1,232 @@
[DCD Descriptor]
// =============================================================================
// Clock Init
// MT48LC16M16A2 SDRAM on MIMXRT1052CVJ5B
//
// Включаем только необходимые тактовые домены (fix 6):
// CCM_CCGR0: биты [1:0]=11 (aips_tz1), биты [3:2]=11 (aips_tz2) — доступ к периферии
// CCM_CCGR2: биты [29:28]=11 (iomuxc) — конфигурация пинов
// CCM_CCGR3: биты [5:4]=11 (semc) — контроллер SDRAM
// CCM_CCGR4: биты [3:2]=11 (iomuxc_gpr) — GPR регистры
// CCM_CCGR5: биты [1:0]=11 (rom) — BootROM
//
// ВАЖНО: если после изменения плата не стартует — проверь по RM Table 18-5
// (CCM Clock Gating Register) и вернись к 0xFFFFFFFF для отладки.
// =============================================================================
*(uint32_t*)0x400FC068 = 0x0000000F; // CCM_CCGR0: aips_tz1 + aips_tz2
*(uint32_t*)0x400FC06C = 0x00000000; // CCM_CCGR1: не нужен для DCD
*(uint32_t*)0x400FC070 = 0x30000000; // CCM_CCGR2: iomuxc (CG14, bits[29:28])
*(uint32_t*)0x400FC074 = 0x00000030; // CCM_CCGR3: semc (CG2, bits[5:4])
*(uint32_t*)0x400FC078 = 0x0000000C; // CCM_CCGR4: iomuxc_gpr (CG1, bits[3:2])
*(uint32_t*)0x400FC07C = 0x00000003; // CCM_CCGR5: rom (CG0, bits[1:0])
*(uint32_t*)0x400FC080 = 0x00000000; // CCM_CCGR6: не нужен для DCD
// PLL_SYS: 528 MHz (24 MHz * 22), DIV_SELECT=1 → Fvco=528MHz
*(uint32_t*)0x400D8030 = 0x00002001;
// Ждём lock PLL_SYS (bit 31 = LOCK) перед переключением источника тактирования (fix 3)
(*(uint32_t*)0x400D8030 & 0x80000000) != 0;
// PFD2 = 528 * 18 / 0x23(35) = ~271 MHz... нет.
// PFD528[PFD2_FRAC] = 0x23 = 35 → Fout = 528 * 18 / 35 = ~271?
// Фактически 0x00230000 → PFD2_FRAC = 0x23 = 35 → F = 528*18/35 ≈ 271 МГц
// Но для SEMC @ 133 МГц нужен делитель CCM_CBCDR[SEMC_PODF].
// Проверь соответствие с clock_config.c!
*(uint32_t*)0x400D8100 = 0x00230000; // CCM_ANALOG_PFD_528: PFD2 = 133 MHz
// CCM_CBCDR: SEMC_CLK_SEL=1 (PLL2_PFD2), SEMC_ALT_CLK_SEL=0, SEMC_PODF=1 (делитель /2)
// → SEMC clock = 133 / 2 = 66.5 МГц
// Если нужно 133 МГц — SEMC_PODF=0 (делитель /1), но убедись что SDRAM выдержит
*(uint32_t*)0x400FC014 = 0x00010D40; // CCM_CBCDR
// =============================================================================
// SDRAM Init — Configure IOMUXC for SEMC pins
// MT48LC16M16A2: 16Mx16bit, 4 Banks, LVTTL
// =============================================================================
// IOMUXC — MUX mode: все пины SEMC в режиме ALT0 (SEMC функция)
*(uint32_t*)0x401F8014 = 0x00000000;
*(uint32_t*)0x401F8018 = 0x00000000;
*(uint32_t*)0x401F801C = 0x00000000;
*(uint32_t*)0x401F8020 = 0x00000000;
*(uint32_t*)0x401F8024 = 0x00000000;
*(uint32_t*)0x401F8028 = 0x00000000;
*(uint32_t*)0x401F802C = 0x00000000;
*(uint32_t*)0x401F8030 = 0x00000000;
*(uint32_t*)0x401F8034 = 0x00000000;
*(uint32_t*)0x401F8038 = 0x00000000;
*(uint32_t*)0x401F803C = 0x00000000;
*(uint32_t*)0x401F8040 = 0x00000000;
*(uint32_t*)0x401F8044 = 0x00000000;
*(uint32_t*)0x401F8048 = 0x00000000;
*(uint32_t*)0x401F804C = 0x00000000;
*(uint32_t*)0x401F8050 = 0x00000000;
*(uint32_t*)0x401F8054 = 0x00000000;
*(uint32_t*)0x401F8058 = 0x00000000;
*(uint32_t*)0x401F805C = 0x00000000;
*(uint32_t*)0x401F8060 = 0x00000000;
*(uint32_t*)0x401F8064 = 0x00000000;
*(uint32_t*)0x401F8068 = 0x00000000;
*(uint32_t*)0x401F806C = 0x00000000;
*(uint32_t*)0x401F8070 = 0x00000000;
*(uint32_t*)0x401F8074 = 0x00000000;
*(uint32_t*)0x401F8078 = 0x00000000;
*(uint32_t*)0x401F807C = 0x00000000;
*(uint32_t*)0x401F8080 = 0x00000000;
*(uint32_t*)0x401F8084 = 0x00000000;
*(uint32_t*)0x401F8088 = 0x00000000;
*(uint32_t*)0x401F808C = 0x00000000;
*(uint32_t*)0x401F8090 = 0x00000000;
*(uint32_t*)0x401F8094 = 0x00000000;
*(uint32_t*)0x401F8098 = 0x00000000;
*(uint32_t*)0x401F809C = 0x00000000;
*(uint32_t*)0x401F80A0 = 0x00000000;
*(uint32_t*)0x401F80A4 = 0x00000000;
*(uint32_t*)0x401F80A8 = 0x00000000;
*(uint32_t*)0x401F80AC = 0x00000000;
*(uint32_t*)0x401F80B0 = 0x00000010; // SEMC_DATA15: SION=1 (software input on)
*(uint32_t*)0x401F80B4 = 0x00000000;
*(uint32_t*)0x401F80B8 = 0x00000000;
// IOMUXC — PAD ctrl: 0x000110F9
// SRE=1 (Fast Slew Rate)
// DSE=7 (Drive Strength: R0/7 — максимальный)
// SPEED=3 (200 MHz)
// ODE=0 (Open Drain disabled)
// PKE=1 (Pull/Keeper enabled)
// PUE=1 (Pull — не Keeper)
// PUS=0 (100K pull-down)
// HYS=0 (Hysteresis disabled)
*(uint32_t*)0x401F8204 = 0x000110F9;
*(uint32_t*)0x401F8208 = 0x000110F9;
*(uint32_t*)0x401F820C = 0x000110F9;
*(uint32_t*)0x401F8210 = 0x000110F9;
*(uint32_t*)0x401F8214 = 0x000110F9;
*(uint32_t*)0x401F8218 = 0x000110F9;
*(uint32_t*)0x401F821C = 0x000110F9;
*(uint32_t*)0x401F8220 = 0x000110F9;
*(uint32_t*)0x401F8224 = 0x000110F9;
*(uint32_t*)0x401F8228 = 0x000110F9;
*(uint32_t*)0x401F822C = 0x000110F9;
*(uint32_t*)0x401F8230 = 0x000110F9;
*(uint32_t*)0x401F8234 = 0x000110F9;
*(uint32_t*)0x401F8238 = 0x000110F9;
*(uint32_t*)0x401F823C = 0x000110F9;
*(uint32_t*)0x401F8240 = 0x000110F9;
*(uint32_t*)0x401F8244 = 0x000110F9;
*(uint32_t*)0x401F8248 = 0x000110F9;
*(uint32_t*)0x401F824C = 0x000110F9;
*(uint32_t*)0x401F8250 = 0x000110F9;
*(uint32_t*)0x401F8254 = 0x000110F9;
*(uint32_t*)0x401F8258 = 0x000110F9;
*(uint32_t*)0x401F825C = 0x000110F9;
*(uint32_t*)0x401F8260 = 0x000110F9;
*(uint32_t*)0x401F8264 = 0x000110F9;
*(uint32_t*)0x401F8268 = 0x000110F9;
*(uint32_t*)0x401F826C = 0x000110F9;
*(uint32_t*)0x401F8270 = 0x000110F9;
*(uint32_t*)0x401F8274 = 0x000110F9;
*(uint32_t*)0x401F8278 = 0x000110F9;
*(uint32_t*)0x401F827C = 0x000110F9;
*(uint32_t*)0x401F8280 = 0x000110F9;
*(uint32_t*)0x401F8284 = 0x000110F9;
*(uint32_t*)0x401F8288 = 0x000110F9;
*(uint32_t*)0x401F828C = 0x000110F9;
*(uint32_t*)0x401F8290 = 0x000110F9;
*(uint32_t*)0x401F8294 = 0x000110F9;
*(uint32_t*)0x401F8298 = 0x000110F9;
*(uint32_t*)0x401F829C = 0x000110F9;
*(uint32_t*)0x401F82A0 = 0x000110F9;
*(uint32_t*)0x401F82A4 = 0x000110F9;
*(uint32_t*)0x401F82A8 = 0x000110F9;
// =============================================================================
// SEMC Controller — конфигурация для MT48LC16M16A2
// Базовый адрес SDRAM: 0x80000000
// Размер: 32 MB (MT48LC16M16A2: 16M × 16bit = 32 MB)
// =============================================================================
// SEMC_MCR: MDIS=0, BTO=0x1F (timeout), DQSMD=1 (DQS internal loop)
*(uint32_t*)0x402F0000 = 0x10000004;
// SEMC_BMCR0 & BMCR1: burst весовые коэффициенты
// 0x00000081: WQOS=1, RQOS=0, AGE=0, BSTLEN=0x10 (16 burst)
*(uint32_t*)0x402F0008 = 0x00000081; // SEMC_BMCR0
*(uint32_t*)0x402F000C = 0x00000081; // SEMC_BMCR1
// SEMC_BR0..BR7 — Base Register для каждого region
// BR0: SDRAM @ 0x80000000, размер 32MB (MR=0x1B → 32MB), VLD=1
*(uint32_t*)0x402F0010 = 0x8000001B; // BR0: SDRAM CS0, 0x80000000, 32MB
*(uint32_t*)0x402F0014 = 0x82000000; // BR1: SDRAM CS1 (если есть)
*(uint32_t*)0x402F0018 = 0x84000000; // BR2
*(uint32_t*)0x402F001C = 0x86000000; // BR3
*(uint32_t*)0x402F0020 = 0x90000021; // BR4: NAND
*(uint32_t*)0x402F0024 = 0xA0000019; // BR5: NOR/SRAM
*(uint32_t*)0x402F0028 = 0xA8000017; // BR6
*(uint32_t*)0x402F002C = 0xA900001B; // BR7
*(uint32_t*)0x402F0030 = 0x00000021; // BR8
// SEMC_INTEN: прерывания отключены
*(uint32_t*)0x402F0004 = 0x000079A8;
// SEMC_SDRAMCR0: тайминги MT48LC16M16A2 @ 133MHz
// PS=1 (16-bit data bus), BL=3 (Burst Length 8), COL=2 (9-bit col addr),
// CL=3 (CAS Latency 3)
*(uint32_t*)0x402F0040 = 0x00000F31;
// SEMC_SDRAMCR1
// PRE2ACT=2, ACT2RW=2, RFRC=9 (tRFC), WRC=2, CKEOFF=2, ACT2PRE=6
*(uint32_t*)0x402F0044 = 0x00652922;
// SEMC_SDRAMCR2: Refresh rate
// MT48LC16M16A2: 4096 refresh cycles / 64ms → ~15.6 мкс @ 133MHz
// SRRC=0x02 (самообновление), REF2REF=0x02, ACT2ACT=0x01
*(uint32_t*)0x402F0048 = 0x00020201;
// SEMC_SDRAMCR3
// REBL=1, PRESCALE=0x21, RT=0x3D, UT=0x0F
*(uint32_t*)0x402F004C = 0x08193D0F;
// SEMC_IOCR
*(uint32_t*)0x402F0080 = 0x00000021;
*(uint32_t*)0x402F0084 = 0x00888888;
// SEMC_IPTXDAT / IPRXDAT placeholder
*(uint32_t*)0x402F0094 = 0x00000002;
*(uint32_t*)0x402F0098 = 0x00000000;
// =============================================================================
// SDRAM Init Sequence (JEDEC: Precharge All → Auto-Refresh × 2 → Mode Register Set)
// =============================================================================
// SEMC_IPCR0: IP command target адрес = начало SDRAM
*(uint32_t*)0x402F0090 = 0x80000000;
// IPCMD: Precharge All (команда 0xF)
*(uint32_t*)0x402F009C = 0xA55A000F;
// Ждём завершения: SEMC_INTR[IPCMDDONE] (bit 0)
(*(uint32_t*)0x402F003C & 0x01) != 0;
// IPCMD: Auto-Refresh #1 (команда 0xC)
*(uint32_t*)0x402F0090 = 0x80000000;
*(uint32_t*)0x402F009C = 0xA55A000C;
(*(uint32_t*)0x402F003C & 0x01) != 0;
// IPCMD: Auto-Refresh #2
*(uint32_t*)0x402F0090 = 0x80000000;
*(uint32_t*)0x402F009C = 0xA55A000C;
(*(uint32_t*)0x402F003C & 0x01) != 0;
// Mode Register Set:
// MRS = 0x33: Burst Length=8 (BL=3), Burst Type=Sequential, CAS Latency=3
*(uint32_t*)0x402F00A0 = 0x00000033;
*(uint32_t*)0x402F0090 = 0x80000000;
// IPCMD: Mode Register Set (команда 0xA)
*(uint32_t*)0x402F009C = 0xA55A000A;
(*(uint32_t*)0x402F003C & 0x01) != 0;
// SEMC_SDRAMCR3: финальное значение Refresh Rate после инит-последовательности
// Переключаемся с медленного (init) refresh на рабочий
*(uint32_t*)0x402F004C = 0x50210A09;

BIN
tools/host/fdcb/fcb.bin Normal file

Binary file not shown.

View file

@ -0,0 +1,152 @@
# =============================================================================
# FCB — Flash Configuration Block
# Чип: Winbond W25Q128FVSSIG (64 Mbit = 8 MB), Quad SPI
# Режим: Fast Read Quad I/O (0xEB), 133 MHz, 4-line
# Цель: MIMXRT1052CVJ5B (family: mimxrt1050 в SPSDK 3.7)
#
# LUT-последовательности:
# Seq 0: Fast Read Quad I/O (0xEB) — основное XIP-чтение
# Seq 1: Read Status Reg 1 (0x05) — опрос WIP бита
# Seq 2: Write Enable (0x06) — перед любой записью/стиранием
# Seq 3: Erase Sector 4KB (0x20) — стирание сектора
# Seq 4: Write SR2 (0x31) — установка QE бита (вызов при старте)
# Seq 5: Page Program Quad (0x32) — запись страницы в Quad режиме
# Seq 11: Chip Erase (0x60) — полное стирание чипа
# Seq 12: Read Status Reg 1 (0x05) — дублирует seq1, для blhost
# =============================================================================
family: mimxrt1050
revision: latest
type: flexspi_nor
fcb_settings:
tag: '0x42464346' # 'FCFB' — magic, фиксировано
version: '0x56010400' # Version 1.4 (актуально для SPSDK 3.7)
readSampleClkSrc: '0x01' # loopback from DQS pad
csHoldTime: '0x03'
csSetupTime: '0x03'
columnAddressWidth: '0x03'
# ---------------------------------------------------------------------------
# QE bit enable — W25Q128 Status Register 2, bit 1
# BootROM выполнит Write Enable (seq 2) + Write SR2 (seq 4) при старте.
# deviceModeArg = 0x02 → SR2 = 0b00000010 (QE=1)
# waitTimeCfgCommands = 30 × 100us = 3ms (достаточно для записи SR)
# ---------------------------------------------------------------------------
deviceModeCfgEnable: '0x01'
deviceModeType: '0x01'
waitTimeCfgCommands: '0x001E'
deviceModeSeq:
seqNum: 1
seqId: 4 # → Seq 4: Write SR2 (0x31)
deviceModeArg: '0x00000002' # SR2 = 0x02 → QE=1
deviceType: '0x01' # Serial NOR
sflashPadType: '0x04' # Quad — 4 линии данных (IO0..IO3)
serialClkFreq: '0x07' # 133 MHz
sflashA1Size: '0x01000000' # 16 MB — W25Q128FVSSIG (128 Mbit / 8)
pageSize: '0x00000100' # 256 байт — стандарт для W25Q128
sectorSize: '0x00001000' # 4 KB — минимальная единица стирания
# ---------------------------------------------------------------------------
# LUT — Look-Up Table
# Каждая последовательность: 8 инструкций (instr0..instr7)
# Неиспользуемые инструкции = STOP (значение по умолчанию, можно не писать)
# ---------------------------------------------------------------------------
# ── Seq 0: Fast Read Quad I/O (0xEB) ───────────────────────────────────────
# CMD(×1) 0xEB → RADDR(×4) 24bit → DUMMY(×4) 6cycles → READ(×4)
lookupTable_seq0_instr0:
OPERAND: 0xEB
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq0_instr1:
OPERAND: 0x18 # 24-bit address
NUM_PADS: 4PAD
OPERATION_CODE: RADDR_SDR
lookupTable_seq0_instr2:
OPERAND: 0x06 # 6 dummy cycles @ 133MHz (4 mode + 2 dummy)
NUM_PADS: 4PAD
OPERATION_CODE: DUMMY_SDR
lookupTable_seq0_instr3:
OPERAND: 0x04
NUM_PADS: 4PAD
OPERATION_CODE: READ_SDR
# ── Seq 1: Read Status Register 1 (0x05) ───────────────────────────────────
# CMD(×1) 0x05 → READ(×1) 1byte
lookupTable_seq1_instr0:
OPERAND: 0x05
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq1_instr1:
OPERAND: 0x04
NUM_PADS: 1PAD
OPERATION_CODE: READ_SDR
# ── Seq 2: Write Enable (0x06) ──────────────────────────────────────────────
# CMD(×1) 0x06
lookupTable_seq2_instr0:
OPERAND: 0x06
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
# ── Seq 3: Erase Sector 4KB (0x20) ─────────────────────────────────────────
# CMD(×1) 0x20 → RADDR(×4) 24bit
lookupTable_seq3_instr0:
OPERAND: 0x20
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq3_instr1:
OPERAND: 0x18
NUM_PADS: 4PAD
OPERATION_CODE: RADDR_SDR
# ── Seq 4: Write Status Register 2 (0x31) — установка QE бита ──────────────
# CMD(×1) 0x31 → WRITE(×1) 1byte
# Вызывается через deviceModeSeq при инициализации BootROM.
# deviceModeArg (0x02) записывается как аргумент.
lookupTable_seq4_instr0:
OPERAND: 0x31
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq4_instr1:
OPERAND: 0x01 # записать 1 байт
NUM_PADS: 1PAD
OPERATION_CODE: WRITE_SDR
# ── Seq 5: Page Program Quad Input (0x32) ──────────────────────────────────
# CMD(×1) 0x32 → RADDR(×1) 24bit → WRITE(×4)
lookupTable_seq5_instr0:
OPERAND: 0x32
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq5_instr1:
OPERAND: 0x18
NUM_PADS: 1PAD
OPERATION_CODE: RADDR_SDR
lookupTable_seq5_instr2:
OPERAND: 0x04
NUM_PADS: 4PAD
OPERATION_CODE: WRITE_SDR
# Seq 6..10: не используются (STOP по умолчанию)
# ── Seq 11: Chip Erase (0x60) ───────────────────────────────────────────────
# CMD(×1) 0x60
lookupTable_seq11_instr0:
OPERAND: 0x60
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
# ── Seq 12: Read Status Register 1 (дубль для blhost) ──────────────────────
lookupTable_seq12_instr0:
OPERAND: 0x05
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq12_instr1:
OPERAND: 0x04
NUM_PADS: 1PAD
OPERATION_CODE: READ_SDR

View file

@ -0,0 +1,152 @@
# =============================================================================
# FCB — Flash Configuration Block
# Чип: Winbond W25Q64FVSSIG (64 Mbit = 8 MB), Quad SPI
# Режим: Fast Read Quad I/O (0xEB), 133 MHz, 4-line
# Цель: MIMXRT1052CVJ5B (family: mimxrt1050 в SPSDK 3.7)
#
# LUT-последовательности:
# Seq 0: Fast Read Quad I/O (0xEB) — основное XIP-чтение
# Seq 1: Read Status Reg 1 (0x05) — опрос WIP бита
# Seq 2: Write Enable (0x06) — перед любой записью/стиранием
# Seq 3: Erase Sector 4KB (0x20) — стирание сектора
# Seq 4: Write SR2 (0x31) — установка QE бита (вызов при старте)
# Seq 5: Page Program Quad (0x32) — запись страницы в Quad режиме
# Seq 11: Chip Erase (0x60) — полное стирание чипа
# Seq 12: Read Status Reg 1 (0x05) — дублирует seq1, для blhost
# =============================================================================
family: mimxrt1050
revision: latest
type: flexspi_nor
fcb_settings:
tag: '0x42464346' # 'FCFB' — magic, фиксировано
version: '0x56010400' # Version 1.4 (актуально для SPSDK 3.7)
readSampleClkSrc: '0x01' # loopback from DQS pad
csHoldTime: '0x03'
csSetupTime: '0x03'
columnAddressWidth: '0x03'
# ---------------------------------------------------------------------------
# QE bit enable — W25Q64 Status Register 2, bit 1
# BootROM выполнит Write Enable (seq 2) + Write SR2 (seq 4) при старте.
# deviceModeArg = 0x02 → SR2 = 0b00000010 (QE=1)
# waitTimeCfgCommands = 30 × 100us = 3ms (достаточно для записи SR)
# ---------------------------------------------------------------------------
deviceModeCfgEnable: '0x01'
deviceModeType: '0x01'
waitTimeCfgCommands: '0x001E'
deviceModeSeq:
seqNum: 1
seqId: 4 # → Seq 4: Write SR2 (0x31)
deviceModeArg: '0x00000002' # SR2 = 0x02 → QE=1
deviceType: '0x01' # Serial NOR
sflashPadType: '0x04' # Quad — 4 линии данных (IO0..IO3)
serialClkFreq: '0x07' # 133 MHz
sflashA1Size: '0x00800000' # 8 MB — W25Q64FVSSIG (64 Mbit / 8)
pageSize: '0x00000100' # 256 байт — стандарт для W25Q64
sectorSize: '0x00001000' # 4 KB — минимальная единица стирания
# ---------------------------------------------------------------------------
# LUT — Look-Up Table
# Каждая последовательность: 8 инструкций (instr0..instr7)
# Неиспользуемые инструкции = STOP (значение по умолчанию, можно не писать)
# ---------------------------------------------------------------------------
# ── Seq 0: Fast Read Quad I/O (0xEB) ───────────────────────────────────────
# CMD(×1) 0xEB → RADDR(×4) 24bit → DUMMY(×4) 6cycles → READ(×4)
lookupTable_seq0_instr0:
OPERAND: 0xEB
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq0_instr1:
OPERAND: 0x18 # 24-bit address
NUM_PADS: 4PAD
OPERATION_CODE: RADDR_SDR
lookupTable_seq0_instr2:
OPERAND: 0x06 # 6 dummy cycles @ 133MHz (4 mode + 2 dummy)
NUM_PADS: 4PAD
OPERATION_CODE: DUMMY_SDR
lookupTable_seq0_instr3:
OPERAND: 0x04
NUM_PADS: 4PAD
OPERATION_CODE: READ_SDR
# ── Seq 1: Read Status Register 1 (0x05) ───────────────────────────────────
# CMD(×1) 0x05 → READ(×1) 1byte
lookupTable_seq1_instr0:
OPERAND: 0x05
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq1_instr1:
OPERAND: 0x04
NUM_PADS: 1PAD
OPERATION_CODE: READ_SDR
# ── Seq 2: Write Enable (0x06) ──────────────────────────────────────────────
# CMD(×1) 0x06
lookupTable_seq2_instr0:
OPERAND: 0x06
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
# ── Seq 3: Erase Sector 4KB (0x20) ─────────────────────────────────────────
# CMD(×1) 0x20 → RADDR(×4) 24bit
lookupTable_seq3_instr0:
OPERAND: 0x20
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq3_instr1:
OPERAND: 0x18
NUM_PADS: 4PAD
OPERATION_CODE: RADDR_SDR
# ── Seq 4: Write Status Register 2 (0x31) — установка QE бита ──────────────
# CMD(×1) 0x31 → WRITE(×1) 1byte
# Вызывается через deviceModeSeq при инициализации BootROM.
# deviceModeArg (0x02) записывается как аргумент.
lookupTable_seq4_instr0:
OPERAND: 0x31
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq4_instr1:
OPERAND: 0x01 # записать 1 байт
NUM_PADS: 1PAD
OPERATION_CODE: WRITE_SDR
# ── Seq 5: Page Program Quad Input (0x32) ──────────────────────────────────
# CMD(×1) 0x32 → RADDR(×1) 24bit → WRITE(×4)
lookupTable_seq5_instr0:
OPERAND: 0x32
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq5_instr1:
OPERAND: 0x18
NUM_PADS: 1PAD
OPERATION_CODE: RADDR_SDR
lookupTable_seq5_instr2:
OPERAND: 0x04
NUM_PADS: 4PAD
OPERATION_CODE: WRITE_SDR
# Seq 6..10: не используются (STOP по умолчанию)
# ── Seq 11: Chip Erase (0x60) ───────────────────────────────────────────────
# CMD(×1) 0x60
lookupTable_seq11_instr0:
OPERAND: 0x60
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
# ── Seq 12: Read Status Register 1 (дубль для blhost) ──────────────────────
lookupTable_seq12_instr0:
OPERAND: 0x05
NUM_PADS: 1PAD
OPERATION_CODE: CMD_SDR
lookupTable_seq12_instr1:
OPERAND: 0x04
NUM_PADS: 1PAD
OPERATION_CODE: READ_SDR

View file

@ -0,0 +1,19 @@
# =============================================================================
# HAB Container — firmware/app (боевая прошивка)
#
# flags: 0x0 — образ НЕ подписан
# DCD: обязателен — линкер размещает FreeRTOS heap и буферы LCDIF
# в SDRAM (0x80000000), которая должна быть инициализирована
# до первой инструкции прошивки.
# =============================================================================
options:
flags: 0x0
family: mimxrt1050
bootDevice: flexspi_nor
startAddress: 0x60000000 # FlexSPI NOR base address (XIP)
DCDFilePath: ../dcd/dcd.bin
inputImageFile: "../../../build/Release/app.bin"
sections: []

View file

@ -0,0 +1,18 @@
# =============================================================================
# HAB Container — firmware/bootloader
#
# flags: 0x0 — образ НЕ подписан
# DCD: отсутствует намеренно — загрузчик не использует SDRAM,
# минимальная зависимость от железа = максимальная надёжность.
# SDRAM инициализируется позже, уже внутри app через её DCD.
# =============================================================================
options:
flags: 0x0
family: mimxrt1050
bootDevice: flexspi_nor
startAddress: 0x60000000 # FlexSPI NOR base address (XIP)
inputImageFile: "../../../build/Release/bootloader.bin"
sections: []

View file

@ -0,0 +1,23 @@
# =============================================================================
# HAB Container — firmware/test (входной контроль производства)
#
# flags: 0x0 — образ НЕ подписан (HAB в open/unsigned режиме)
# DCD: присутствует — инициализация SDRAM обязательна для тестов
#
# Важно: sections пустой — для unsigned образа CSF не нужен.
# BootROM примет образ без проверки подписи пока HAB не залочен (fuses).
# =============================================================================
options:
flags: 0x0 # unsigned — без подписи
family: mimxrt1050
bootDevice: flexspi_nor # ivtOffset=0x1000, initialLoadSize=0x2000 — автоматически
startAddress: 0x60000000 # FlexSPI NOR base address (XIP)
# DCD — инициализация SDRAM до передачи управления прошивке.
# Сгенерирован из dcd.cfg скриптом tools/dcd_cfg_to_bin.py
DCDFilePath: ../dcd/dcd.bin
inputImageFile: "../../../build/Debug/firmware_test.bin"
sections: []

View file

@ -0,0 +1,26 @@
# =============================================================================
# Bootable Image — firmware/app (боевая прошивка)
# Расположение: tools/host/image/bootimg_app.yaml
#
# Пайплайн сборки:
#
# 1. FCB (один раз, из tools/host/fdcb/):
# nxpimage bootable-image fcb export -c fcb_w25q64_quad.yaml -o fcb.bin
#
# 2. Образ (из tools/host/image/):
# nxpimage bootable-image export -c bootimg_app.yaml
#
# 3. Проверка:
# nxpimage bootable-image parse -b ../../../../build/Release/app_bootable.bin -f mimxrt1050
# =============================================================================
family: mimxrt1050
revision: latest
memory_type: flexspi_nor
output: "../../../build/Release/app_bootable.bin"
output_format: bin
fcb: ../fdcb/fcb.bin
hab_container: ../hab/hab_app.yaml

View file

@ -0,0 +1,26 @@
# =============================================================================
# Bootable Image — firmware/bootloader
# Расположение: tools/host/image/bootimg_bootloader.yaml
#
# Пайплайн сборки:
#
# 1. FCB (один раз, из tools/host/fdcb/):
# nxpimage bootable-image fcb export -c fcb_w25q64_quad.yaml -o fcb.bin
#
# 2. Образ (из tools/host/image/):
# nxpimage bootable-image export -c bootimg_bootloader.yaml
#
# 3. Проверка:
# nxpimage bootable-image parse -b ../../../../build/Release/bootloader_bootable.bin -f mimxrt1050
# =============================================================================
family: mimxrt1050
revision: latest
memory_type: flexspi_nor
output: "../../../build/Release/bootloader_bootable.bin"
output_format: bin
fcb: ../fdcb/fcb.bin
hab_container: ../hab/hab_bootloader.yaml

View file

@ -0,0 +1,36 @@
# =============================================================================
# Bootable Image — firmware/test (входной контроль производства)
# Расположение: tools/host/image/bootimg_firmware_test.yaml
#
# Пайплайн сборки:
#
# 1. FCB (один раз, из tools/host/fdcb/):
# nxpimage bootable-image fcb export -c fcb_w25q64_quad.yaml -o fcb.bin
#
# 2. Образ (из tools/host/image/):
# nxpimage bootable-image export -c bootimg_firmware_test.yaml
#
# 3. Проверка:
# nxpimage bootable-image parse -b ../../../../build/Debug/firmware_test_bootable.bin -f mimxrt1050
#
# Структура образа во Flash (0x60000000):
# 0x000 FCB (512 байт)
# 0x400 зарезервировано
# 0x1000 IVT ]
# 0x1020 BDT ] HAB container
# 0x1030 DCD ]
# 0x3000 код ]
# =============================================================================
family: mimxrt1050
revision: latest
memory_type: flexspi_nor
output: "../../../build/Debug/firmware_test_bootable.bin"
output_format: bin
# FCB — собран из tools/host/fdcb/fcb_w25q64_quad.yaml
fcb: ../fdcb/fcb.bin
# HAB container — YAML напрямую, export соберёт его сам
hab_container: ../hab/hab_firmware_test.yaml

View file

@ -0,0 +1,9 @@
[project]
name = "host"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"spsdk==3.7.0",
]

1279
tools/host/uv.lock Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,15 +0,0 @@
options {
flags = 0x00;
startAddress = 0x60000000;
ivtOffset = 0x1000;
initialLoadSize = 0x2000;
DCDFilePath = "dcd.bin";
entryPointAddress = 0x60002305;
}
sources {
elfFile = extern(0);
}
section (0) {
}

View file

@ -1,15 +0,0 @@
options {
flags = 0x00;
startAddress = 0x80000000;
ivtOffset = 0x1000;
initialLoadSize = 0x2000;
DCDFilePath = "dcd.bin";
entryPointAddress = 0x80002305;
}
sources {
elfFile = extern(0);
}
section (0) {
}