OpenBLT 移植指南

OpenBLT 移植指南 OpenBLT 移植指南从 Demo 到 STM32F407 BCU以源码 Demo 工程为起点步步详解移植过程一、起点与终点起点Demo 工程 终点BCU 工程 Target/Demo/ BootLoader/ ARMCM4_STM32F4_Olimex_STM32P405_ STM32F407VETx CubeIDE/Boot/ 自定义板卡 MCU: STM32F405RGTx → 改为 → STM32F407VETx 晶振: 8MHz → 改为 → 25MHz 主频: 168MHz → 改为 → 160MHz 通信: RS232 CAN → 改为 → Modbus RTU (RS485) Flash: 1024KB → 改为 → 512KB APP起始: 0x0800C000 → 改为 → 0x08008000二、第一步改 CubeMX 硬件配置打开 Demo 的Boot.ioc逐项修改。2.1 换 MCU 型号CubeMX → Project Manager → 把 STM32F405RGTx 换成 STM32F407VETx2.2 改时钟Demo: HSE 8MHz → PLL → 168MHz BCU: HSE 25MHz → PLL → 160MHz CubeMX → Clock Configuration: HSE: 25 MHz PLL Source: HSE PLLM: 25 (/25 1MHz 给 PLL) PLLN: 320 (×320 320MHz VCO) PLLP: 2 (÷2 160MHz SYSCLK) APB1: ÷4 (40MHz) APB2: ÷2 (80MHz)2.3 改 USARTDemo: USART2 (RS232, 57600bps) BCU: USART3 (RS485 Modbus RTU, 9600bps) USART1 (调试, 115200bps, 可选) CubeMX → Pinout: USART3: TXPB10, RXPB11, 9600bps, 8N1 USART1: TXPA9, RXPA10, 115200bps, 8N12.4 改 GPIO需要新增的 GPIO: PB15 → UART3_DE (RS485 方向控制推挽输出) PC5 → LED3 (状态指示推挽输出) PB1 → LED7 (状态指示推挽输出)2.5 重新生成代码CubeMX → GENERATE CODE → main.c, stm32f4xx_hal_msp.c, main.h 自动更新 → 系统时钟初始化代码自动生成 → 外设初始化函数自动生成CubeMX 不需要配置 TIM1。OpenBLT 的timer.c会在TimerInit()中自主初始化 TIM1CubeMX 不要去动它否则可能冲突。三、第二步改链接脚本STM32F407VETX_FLASH.ld——限定 BootLoader 占 32KB。MEMORY { FLASH (rx) : ORIGIN 0x8000000, LENGTH 32K // ← 从 Demo 的 32K 不变 RAM (xrw) : ORIGIN 0x20000000, LENGTH 128K }Demo 原本就是 32KBCU 保持 32K不用改。BootLoader 实际编译出来约 20~24KB留 32K 有足够余量。四、第三步改 blt_conf.h核心工作对比 Demo 和 BCU每一个改动的原因4.1 时钟// Demo:#defineBOOT_CPU_XTAL_SPEED_KHZ8000#defineBOOT_CPU_SYSTEM_SPEED_KHZ168000// BCU:#defineBOOT_CPU_XTAL_SPEED_KHZ25000// 板子焊的 25MHz 晶振#defineBOOT_CPU_SYSTEM_SPEED_KHZ160000// 25MHz → PLL → 160MHz4.2 通信接口// Demo: RS232 CAN#defineBOOT_COM_RS232_ENABLE1#defineBOOT_COM_CAN_ENABLE1// BCU: 关掉 RS232 和 CAN只开 Modbus RTU#defineBOOT_COM_RS232_ENABLE0#defineBOOT_COM_CAN_ENABLE0#defineBOOT_COM_NET_ENABLE0#defineBOOT_COM_USB_ENABLE0#defineBOOT_COM_MBRTU_ENABLE1// ← 新增Demo 没有这个宏4.3 Flash 参数// Demo:#defineBOOT_NVM_SIZE_KB1024// BCU:#defineBOOT_NVM_SIZE_KB512// STM32F407VE 512KB Flash#defineBOOT_FLASH_VECTOR_TABLE_CS_OFFSET0x1AC// F4 系列统一值4.4 功能钩子// 看门狗、跳转前回调 保持与 Demo 一致#defineBOOT_COP_HOOKS_ENABLE1#defineBOOT_CPU_USER_PROGRAM_START_HOOK1// 后门——BCU 关掉钩子用内置超时模式#defineBOOT_BACKDOOR_HOOKS_ENABLE0// Demo 是 0BCU 保持 0#defineBOOT_BACKDOOR_ENTRY_TIMEOUT_MS1500// 校验和——BCU 开钩子暂时不做校验开发阶段#defineBOOT_NVM_CHECKSUM_HOOKS_ENABLE1// 外部 Flash 操作——BCU 用了 W25Q128#defineBOOT_NVM_HOOKS_ENABLE1五、第四步添加 Modbus RTU 传输层这是 Demo 没有的移植中最关键的新增工作。5.1 在 blt_conf.h或 plausibility.h中补充宏定义// 宏定义被放在 plausibility.h 中作为默认值#defineBOOT_COM_MBRTU_BAUDRATE9600#defineBOOT_COM_MBRTU_CHANNEL_INDEX2// USART3#defineBOOT_COM_MBRTU_PARITY0// 无校验#defineBOOT_COM_MBRTU_STOPBITS1#defineBOOT_COM_MBRTU_NODE_ID1// Modbus 从站地址 1#defineBOOT_COM_MBRTU_TX_MAX_DATA250#defineBOOT_COM_MBRTU_RX_MAX_DATA250#defineBOOT_COM_MBRTU_DRIVER_OUTPUT_ENABLE_DELAY_US500#defineBOOT_COM_MBRTU_DRIVER_OUTPUT_DISABLE_DELAY_US5005.2 创建 mbrtu.c核心文件Loader/ARMCM4_STM32F4/mbrtu.c。功能是把 XCP 包嵌入 Modbus RTU 帧通过 USARTRS485 收发。包含函数作用MbRtuInit()初始化 USART计算 T3_5 时间等待总线空闲MbRtuTransmitPacket()拼 Modbus 帧地址功能码109XCP数据CRC拉 DE 发送MbRtuReceivePacket()收字节→ T3_5 超时判定帧结束→ CRC 校验→ 提取 XCP 数据MbRtuFreeRunningCounterGet()读 TIM1-CNT100kHz用于 T3_5 计时MbRtuDriverOutputControlHook()RS485 DE 引脚控制USART3→PB155.3 在 main.c 中调用intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();// 调试用可删MX_USART3_UART_Init();// Modbus RTU 用AppInit();// OpenBLT 入口while(1){AppTask();// OpenBLT 主循环}}六、第五步改 hooks.c6.1 LED 和看门狗// CopInitHook() —— 看门狗初始化时顺便初始化 LEDvoidCopInitHook(void){LedBlinkInit(200);// 200ms 闪烁周期}// CopServiceHook() —— 喂狗 LED 闪烁擦除 Flash 期间也会被调voidCopServiceHook(void){LedBlinkTask();// 在定时器中断中跑 LED 任务// HAL_IWDG_Refresh() 等喂狗操作}LedBlinkInit/LedBlinkTask/LedBlinkExit 实现在App/led.c中控制 PC5 和 PB1 两个 LED。6.2 跳转前清理blt_boolCpuUserProgramStartHook(void){LedBlinkExit();// 关 LEDreturnBLT_TRUE;// 允许跳转}6.3 后门——BCU 不用钩子// BOOT_BACKDOOR_HOOKS_ENABLE 0// 走内置超时模式上电 1.5 秒内收到 CONNECT → 进升级6.4 校验和——BCU 暂时跳过// BOOT_NVM_CHECKSUM_HOOKS_ENABLE 1blt_boolNvmVerifyChecksumHook(void){returnBLT_TRUE;}// 永远有效blt_boolNvmWriteChecksumHook(void){returnBLT_TRUE;}// 不写七、第六步编译验证CubeIDE → Project → Build All 预期输出: text data bss dec hex filename 22xxx xxx xxx 24xxx xxxx openblt_bcu.elf FLASH 占用 32KB → 链接通过 ✓ 下载到板子: ST-Link 烧录 BootLoader 固件到 0x08000000 上位机 MicroBoot 选 XCP on Modbus RTU → 配 COM 口 → 连接 → 刷 APP八、移植对照总表改动项Demo 值BCU 值理由MCUSTM32F405RGSTM32F407VE硬件不同HSE 晶振8MHz25MHz板子晶振SYSCLK168MHz160MHz25MHz PLL 配法通信接口RS232 CANModbus RTUBMS 行业用 RS485USARTUSART2USART3硬件引脚分配波特率576009600Modbus RTU 标准Flash 大小1024KB512KBF407VE 512KBAPP 起始地址0x0800C0000x08008000BootLoader 占 32KB后门方式超时模式超时模式相同校验和标准校验钩子跳过开发阶段简化RS485 DE 引脚无PB15Modbus RTU 必须链接脚本32K32K相同九、常见踩坑链接脚本忘记改→ APP 起始地址跟着 Demo 走 0x0800C000实际应该是 0x08008000flashLayout 没注释 sector 0~1→ 升级时会擦掉 BootLoader 自身T3_5 计时不准→ TIM1 没配成 100kHz 或没初始化RS485 DE 引脚时序→ DE 拉高后没有等够时间就开始发数据导致前几个字节丢失校验和位置对不上→ BOOT_FLASH_VECTOR_TABLE_CS_OFFSET 设错永远判定 APP 无效上位机连不上→ 忘了在上电 1.5 秒内发起连接超时后 BootLoader 已跳到 APP移植的本质换个 MCU → 换引脚 → 加 Modbus RTU 传输层 → 改几个宏。其他地方 OpenBLT 都替你写好了。