在ModusToolbox环境下,PSoC C3系列MCU支持通过双启动区(Dual-Bank)机制实现设备固件升级(DFU)。该机制利用Flash存储器的两个独立分区(Bank A和Bank B)分别存放运行固件和新固件,配合启动加载程序(Bootloader)在复位时选择有效分区启动,实现了固件更新过程中的数据完整性和系统可靠性。
PSoC C3系列的Flash存储器通常被划分为两个等大小的Bank,每个Bank可独立擦除和编程。在双Bank DFU方案中,系统运行于其中一个Bank(活动区),同时通过串行接口(如UART或USB)接收新固件数据,并将其写入另一个Bank(备用区)。固件接收完成后,系统对备用区固件进行完整性校验(如CRC32),校验通过则设置启动标志并触发系统复位。复位后Bootloader根据启动标志选择更新后的Bank启动,完成一次完整的DFU流程。
在ModusToolbox中实现此功能需要创建一个包含Bootloader和Bootloadable两个组件的项目。Bootloader项目负责启动时的分区选择和跳转逻辑,Bootloadable项目则包含实际应用程序固件。以UART为传输介质的DFU实现为例,Bootloader中通过Cy_Bootloader_Start()函数启动Bootloader组件,并在循环中监听来自串口的DFU命令帧。当接收到擦除指令时,Bootloader调用Cy_Flash_EraseRow()擦除备用Bank的Flash区域;接收到编程数据帧时,调用Cy_Flash_WriteRow()将数据写入Flash。写入完成后,Bootloader通过Cy_Bootloader_VerifyApplication()验证固件校验和,验证通过后设置下一次启动的Bank并复位进入应用程序。
以下是一个简化的DFU流程示例,展示Bootloader判断启动分区并跳转的过程:
c
#include "cy_pdl.h"
#include "cy_bootloader.h"
int main(void)
{
/* 初始化系统 */
SystemInit();
/* 检查启动标志,决定从哪个Bank启动 */
uint32_t boot_flag = Cy_Bootloader_GetBootFlag();
if (boot_flag == BOOT_FROM_BANK_B)
{
/* 设置栈顶指针和中断向量表为Bank B的地址 */
__set_MSP(*(uint32_t*)BANK_B_START_ADDR);
SCB->VTOR = BANK_B_START_ADDR;
/* 跳转到Bank B的复位处理函数 */
void (*app_entry)(void) = (void(*)(void))(*(uint32_t*)(BANK_B_START_ADDR + 4));
app_entry();
}
else
{
/* 默认从Bank A启动 */
__set_MSP(*(uint32_t*)BANK_A_START_ADDR);
SCB->VTOR = BANK_A_START_ADDR;
void (*app_entry)(void) = (void(*)(void))(*(uint32_t*)(BANK_A_START_ADDR + 4));
app_entry();
}
}
在应用程序(Bootloadable)侧,需实现固件接收逻辑以响应来自主机的升级命令。当应用程序收到DFU启动指令后,设置DFU标志并执行系统复位,使系统进入Bootloader模式。
双Bank DFU方案依赖有效的固件校验机制。ModusToolbox的Bootloader组件默认支持CRC校验,在配置界面中勾选“Enable application verification”即可启用该功能。Bootloader在每次启动时对备用Bank的固件进行CRC32校验,校验失败则自动回退至原有Bank,确保系统在任何情况下都能正常启动。
通过合理配置ModusToolbox中的Bootloader和Bootloadable组件,开发者可以在不依赖外部存储芯片的前提下实现可靠的固件升级功能,降低系统成本的同时提升了维护便利性。该方案适用于工业控制、物联网边缘设备等需要远程固件更新的应用场景。 |
|