要实现基于EZUSB-CX3的双阶段引导加载程序,需要遵循以下步骤和关键设计考虑:
1. 存储空间划分
将SPI闪存划分为两个区域:
- Bootloader区:存放第二阶段引导程序(地址:
0x0000 - 0x7FFF)
- Main Firmware区:存放主CX3固件(地址:
0x8000 - 0xFFFF)
注:实际地址需根据SPI闪存容量调整。
2. 双阶段引导流程
阶段1:内部ROM Bootloader
- 芯片上电后,内部ROM Bootloader从SPI Flash的
0x0000地址加载用户Bootloader。
阶段2:用户Bootloader
初始化硬件(时钟、GPIO、SPI等)。
检查更新标志:
- 如果检测到更新标志(如特定GPIO电平或寄存器值),进入固件更新模式。
- 否则跳转到Main Firmware(
0x8000)。
固件更新流程:
- 通过USB/UART接收新固件数据。
- 擦除Main Firmware区。
- 写入新固件并计算CRC校验。
- 验证通过后清除更新标志,复位系统。
阶段3:Main Firmware
- 主程序运行时,若检测到新固件(如USB指令),设置更新标志并触发软复位。
3. 关键代码实现
Bootloader跳转主程序
void JumpToMainFirmware(void) {
typedef void (*MainAppEntry)(void);
MainAppEntry AppStart = (MainAppEntry)(0x8000); // Main固件入口地址
// 关闭中断
__disable_irq();
// 重置堆栈指针
__set_MSP(*(volatile uint32_t *)0x8000);
// 跳转到主程序
AppStart();
}
主程序设置更新标志
void TriggerFirmwareUpdate(void) {
// 写入非易失性存储(如EEPROM或Flash特定位置)
NV_WriteUpdateFlag(1);
// 触发软复位
SCB->AIRCR = 0x05FA0004;
}
4. 映像文件合并
使用hexmerge或objcopy工具将Bootloader和Main固件合并为单一文件:
srec_cat bootloader.hex -Intel main_firmware.hex -Intel -o combined_image.hex -Intel
5. 可靠性设计
- CRC校验:在写入新固件后计算CRC,确保数据完整性。
- 回滚机制:保留旧固件备份,若新固件启动失败则自动回滚。
- 看门狗:在Bootloader中启用看门狗,防止更新过程卡死。
6. 开发工具配置
链接脚本:确保Bootloader和Main固件的代码地址不重叠。
/* Bootloader链接脚本 */
MEMORY { FLASH (rx) : ORIGIN = 0x0000, LENGTH = 32K }
/* Main Firmware链接脚本 */
MEMORY { FLASH (rx) : ORIGIN = 0x8000, LENGTH = 32K }
烧录工具:使用CyConsole或Cypress Programmer烧录合并后的映像。
文档重点参考
- AN92584:EZ-USB CX3 Boot Process and Firmware Loading
- CX3 TRM:Technical Reference Manual中的SPI Flash接口章节
- FX3 SDK:
CyBootloader示例代码(路径:CypressEZ-USB FX3 SDK1.3firmwarebootloader)
通过以上步骤,可实现从主固件触发Bootloader、安全更新SPI Flash并返回主程序的完整流程。建议先调试Bootloader的单独功能,再逐步集成双阶段跳转逻辑。
要实现基于EZUSB-CX3的双阶段引导加载程序,需要遵循以下步骤和关键设计考虑:
1. 存储空间划分
将SPI闪存划分为两个区域:
- Bootloader区:存放第二阶段引导程序(地址:
0x0000 - 0x7FFF)
- Main Firmware区:存放主CX3固件(地址:
0x8000 - 0xFFFF)
注:实际地址需根据SPI闪存容量调整。
2. 双阶段引导流程
阶段1:内部ROM Bootloader
- 芯片上电后,内部ROM Bootloader从SPI Flash的
0x0000地址加载用户Bootloader。
阶段2:用户Bootloader
初始化硬件(时钟、GPIO、SPI等)。
检查更新标志:
- 如果检测到更新标志(如特定GPIO电平或寄存器值),进入固件更新模式。
- 否则跳转到Main Firmware(
0x8000)。
固件更新流程:
- 通过USB/UART接收新固件数据。
- 擦除Main Firmware区。
- 写入新固件并计算CRC校验。
- 验证通过后清除更新标志,复位系统。
阶段3:Main Firmware
- 主程序运行时,若检测到新固件(如USB指令),设置更新标志并触发软复位。
3. 关键代码实现
Bootloader跳转主程序
void JumpToMainFirmware(void) {
typedef void (*MainAppEntry)(void);
MainAppEntry AppStart = (MainAppEntry)(0x8000); // Main固件入口地址
// 关闭中断
__disable_irq();
// 重置堆栈指针
__set_MSP(*(volatile uint32_t *)0x8000);
// 跳转到主程序
AppStart();
}
主程序设置更新标志
void TriggerFirmwareUpdate(void) {
// 写入非易失性存储(如EEPROM或Flash特定位置)
NV_WriteUpdateFlag(1);
// 触发软复位
SCB->AIRCR = 0x05FA0004;
}
4. 映像文件合并
使用hexmerge或objcopy工具将Bootloader和Main固件合并为单一文件:
srec_cat bootloader.hex -Intel main_firmware.hex -Intel -o combined_image.hex -Intel
5. 可靠性设计
- CRC校验:在写入新固件后计算CRC,确保数据完整性。
- 回滚机制:保留旧固件备份,若新固件启动失败则自动回滚。
- 看门狗:在Bootloader中启用看门狗,防止更新过程卡死。
6. 开发工具配置
链接脚本:确保Bootloader和Main固件的代码地址不重叠。
/* Bootloader链接脚本 */
MEMORY { FLASH (rx) : ORIGIN = 0x0000, LENGTH = 32K }
/* Main Firmware链接脚本 */
MEMORY { FLASH (rx) : ORIGIN = 0x8000, LENGTH = 32K }
烧录工具:使用CyConsole或Cypress Programmer烧录合并后的映像。
文档重点参考
- AN92584:EZ-USB CX3 Boot Process and Firmware Loading
- CX3 TRM:Technical Reference Manual中的SPI Flash接口章节
- FX3 SDK:
CyBootloader示例代码(路径:CypressEZ-USB FX3 SDK1.3firmwarebootloader)
通过以上步骤,可实现从主固件触发Bootloader、安全更新SPI Flash并返回主程序的完整流程。建议先调试Bootloader的单独功能,再逐步集成双阶段跳转逻辑。
举报