首先,stm8的中断向量的跳转地址是固定的。也就是说发生中断时,芯片会跳转到0x8000对应中断的偏移地址。而大部分bootloader都是在该区域实现。也就是说中断向量会被bootloader所占用。当用户程序执行中断时会跳转到bootloader程序的中断向量。也就会执行bootloader对应的中断。如果要执行用户代码区的中断函数则需要在bootloader的向量表区存放跳转置用户软件中断向量表。如下图跳转:
以上是带有bootloader的用户软件的运行步骤,这样在bootloader区按道理是无法实现中断的。因为向量表是跳转到用户软件向量表。实质上是可以同时在boot和app区实现中断的,但为了boot区越简单越好的原则这样做就足够了。
其次,如何实现boot区中断向量的改写将其跳转至用户中断向量表区?实现代码如下:
__root const long reintvec[]@".intvec"=
{
0x82008080,0x82009004,0x82009008,0x8200900c, 0x82009010,0x82009014,0x82009018,0x8200901c,
0x82009020,0x82009024,0x82009028,0x8200902c,
0x82009030,0x82009034,0x82009038,0x8200903c,
0x82009040,0x82009044,0x82009048,0x8200904c,
0x82009050,0x82009054,0x82009058,0x8200905c,
0x82009060,0x82009064,0x82009068,0x8200906c,
0x82009070,0x82009074,0x82009078,0x8200907c,
};
这是将该数组的值固定存储在intvec区域。
在icf文件中我们可以找到以下语句:
define region NearFuncCode = [from 0x8000 to 0xFFFF];
define block INTVEC with size = 0x80 { ro section .intvec };
place at start of NearFuncCode { block INTVEC };
以上三条是系统默认的,只要在bootloader代码中加入以上数组,那么向量表就会被改变。在使用IAR仿真时可以看到以下内容:
0x82008080是上电复位跳转指令,后面0x82009004是用户中断向量表区对应中断。如果用户代码并非存放在0x9000区,则该数组值也要相应改变。
在地址0x9000用户代码区数据如下:
该区域才是真正的中断入口地址。
最后就是写bootloader代码了。可以通过串口、I2C、SPI或者CAN来接收用户代码并写入到FLASH中。写入成功后执行跳转指令进入用户APP。升级步骤如下:
最终,使用的是st官方的跳转指令如下:
asm("LDW X, SP ");
asm("LD A, $FF");
asm("LD XL, A ");
asm("LDW SP, X ");
asm("JPF $9000");
上一篇:单片机功能测试:PCA功能
下一篇:单片机C语言模块化编程方法
推荐阅读最新更新时间:2024-03-16 15:45