解决stm8L bootloader无法使用中断的问题

芯片:stm8L151K6T6
开发环境:iar for stm8

stm8L151K6T6的flash大小为32kb,这里我打算把bootloader放在前面的0-12kb(0x8000-0xAFFF),应用程序放在12-32kb(0xAFFF-0xFFFF),这里我打算尽量不用汇编的方式解决问题
bootloader的中断函数入口只需要跳转1次,pc->(0x8000+pos)->我们写的中断处理函数,为什么是0x8000请查看数据手册中的54页的向量表
应用程序的中断函数入口需要跳转2次,pc->(0x8000+pos)->(0x8000+pos+APPstartaddr)->我们写的中断处理函数,这里的APPstartaddr就是0xB000

#define APP_CODE_ADDR   (0xB000)//应用程序地址
typedef void (*FUN_point)(void);
void jump_app(void);
void jump_app(void)
{
  FUN_point app_start=(FUN_point)(APP_CODE_ADDR);
  disableInterrupts();//写向量表需要关闭中断
  write_app_ventor_tab(APP_CODE_ADDR);//写入APP向量表
  enableInterrupts();//执行应用程序之前需要开启中断
  app_start();//开始执行应用程序
}

现在需要解决向量表的切换问题
我的思路是利用stm8L的eeprom保存bootloader的中断入口表,因为当运行app时,bootloader的向量表肯定已经被修改,上电时假如需要升级,那么从eeprom恢复bootloader向量表,等升级完成后,向量表再次切换到主程序,然后正式执行主程序

/*
写入app的中断向量表
*/
void write_app_ventor_tab(u32 offet)
{
  u8 Index;
  if(*(u32 *)(0X8004)<(0x82000000+APP_CODE_ADDR))
  {
	  FLASH_Unlock(FLASH_MemType_Program);
	  while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET);
	  for(Index = 1; Index < 0X20;Index++)
	  {
	    value=*(u32 *)(0X8000+4*Index);
	    value1=(0X82000000+offet+Index*4);
	    if(value!=value1)
	    {
	      FLASH_ProgramWord(0X8000+4*Index,value1);
	    }
	  }
	  FLASH_Lock(FLASH_MemType_Program);
  }
}
/*
从eeprom里恢复bootloader的向量表
*/
void get_bootloader_ventor_tab(void)
{
  u8 Index;
  if(*(u32 *)(0X8004)<(0x82000000+APP_CODE_ADDR))
  {    
    FLASH_Unlock(FLASH_MemType_Data);
    for(Index = 1; Index < 0X20;Index++)
    {
      FLASH_ProgramWord(0x1020+Index*4,*(u32 *)(0X8000+4*Index));    
    }
    FLASH_Lock(FLASH_MemType_Data);    
  }
  else
  {
    FLASH_Unlock(FLASH_MemType_Program);
    while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET);
    for(Index = 1; Index < 0X20;Index++)
    {
      FLASH_ProgramWord(0X8000+4*Index,*(u32 *)(0x1020+4*Index)); 
    }
    FLASH_Lock(FLASH_MemType_Program);    
  }
}
void save_bootloader_ventor_tab(void)
{
  u8 Index;
  if(*(u32 *)(0X8004)<(0x82000000+APP_CODE_ADDR))
  {    
    //写eeprom
    FLASH_Unlock(FLASH_MemType_Data);
    for(Index = 1; Index < 0X20;Index++)//31*4=124字节
    {
      FLASH_ProgramWord(0x1020+Index*4,*(u32 *)(0X8000+4*Index)); //把bootloader的向量表保存起来到eeprom-0x1020    
    }
    FLASH_Lock(FLASH_MemType_Data);    
  }
}
int main()
{
  disableInterrupts();
  init();
  save_bootloader_ventor_tab();
  if(key_update_check()!=0)//是否需要升级的判断
  {
    jump_app();//不需要升级直接进入主程序
  }
  
  get_bootloader_ventor_tab();//恢复bootloader向量表
  enableInterrupts();
  //这里开始就可以使用中断了
  bootloader_init(); //bootloader的一些初始化 
  
  while(1)
  {
  	//升级的一些操作,把app的bin文件写入到app代码区......
  }
  
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值