嵌入式 > 技术百科 > 详情

stm8 bootloader IAP升级

发布时间:2024-10-31 发布时间:
|

首先,stm8的中断向量的跳转地址是固定的。也就是说发生中断时,芯片会跳转到0x8000对应中断的偏移地址。而大部分bootloader都是在该区域实现。也就是说中断向量会被bootloader所占用。当用户程序执行中断时会跳转到bootloader程序的中断向量。也就会执行bootloader对应的中断。如果要执行用户代码区的中断函数则需要在bootloader的向量表区存放跳转置用户软件中断向量表。如下图跳转:

【原创】stm8 <wbr><wbr>bootloader自制bootloader(IAP远程升级)填写图片摘要(选填)

以上是带有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仿真时可以看到以下内容:

【原创】stm8 <wbr><wbr>bootloader自制bootloader(IAP远程升级)填写图片摘要(选填)

0x82008080是上电复位跳转指令,后面0x82009004是用户中断向量表区对应中断。如果用户代码并非存放在0x9000区,则该数组值也要相应改变。

在地址0x9000用户代码区数据如下:

【原创】stm8 <wbr><wbr>bootloader自制bootloader(IAP远程升级)填写图片摘要(选填)

该区域才是真正的中断入口地址。

最后就是写bootloader代码了。可以通过串口、I2C、SPI或者CAN来接收用户代码并写入到FLASH中。写入成功后执行跳转指令进入用户APP。升级步骤如下:

【原创】stm8 <wbr><wbr>bootloader自制bootloader(IAP远程升级)填写图片摘要(选填)

最终,使用的是st官方的跳转指令如下:

        asm("LDW X,  SP ");

        asm("LD  A,  $FF");

        asm("LD  XL, A  ");

        asm("LDW SP, X  ");

        asm("JPF $9000");



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Tensilica宣布推出可支持最新的嵌入式Linux版本