现在能远程通信的产品一般都会要求有远程更新功能。最近用stm8s007c8t6做了一个产品,在远程更新实现过程中踩了好几个坑。主要记录一下写boot loader时关键问题。
stm8s的IAP关键是中断向量表的处理。
stm8s的默认中断向量表是从0x8000开始的128字节区域不能改变,也就是说,无论运行引导程序还是应用程序,产生中断时都会跳转到这个默认的中断向量表,然后根据这个中断向量表的指向跳转到中断服务函数。
boot loader的中断向量表在0x8000开始的128字节区域;APP的中断向量表在APP起始地址开始的128字节区域。一般boot loader都需要中断,所以需要在boot loader的中断向量表重定向之前备份到其他区域。当然也可以boot loader中不开启中断,这就不说了。
因此总的思路是:烧写好程序第一次运行boot loader的时候备份好中断向量表;之后每次在boot loader和跳转到APP运行之前把从0x8000开始的128字节区域重定向。
上代码:
/* Main Loop -----------------------------------------------------------------*/
void main(void)
{
uint32_t Buffer32 = 0;
sys_start();
while (1)
{
Buffer32 = EEPRom_ReadHalfWord(UPGRATE_STATE_ADDR);//读取Upgrade_Flag
if(UPGRADE_NEED_S == Buffer32)
{
//sys_boot_doenload_interface_init();
//固件下载流程
//Boot_Load_Firmware();
}
Buffer32 = EEPRom_ReadWord(JUMP_DESTINATION_ADDR);//读取跳转地址
if((Buffer32 == DESTINATION_ADDRESS1) || (Buffer32 == DESTINATION_ADDRESS2))//确认跳转地址
Jump_To(Buffer32);
else //跳转地址错误
Jump_To(DESTINATION_ADDRESS1);//跳转到出厂固件
sys_all_led_toggles();
delay_ticks