由于之前写个STM32的IAP晋级程序,所以我总结了做IAP晋级的三个首要的难点:
1、怎么设置中止向量,也便是说中止向量的重定向
2、怎么装备程序的开端地址
3、怎么从IAP跳转到APP程序
4、运用库函数要注意的当地(避免被坑)
说文章的时分我现已完成了一个最简略的IAP晋级程序,能够经过串口接纳bin文件写入到flash里边,然后再运行。
1、怎么设置中止向量,也便是说中止向量的重定向
STM8不像STM32那样有个一寄存器办理着中止向量的地址,所以STM32的中止能够恣意设置(符合要求的状况之下),可是STM8的中止向量表是固定的
在0X8000地址,不能修正,所以BOOT区不能开中止,否则会和APP区的中止打架,可是APP区的一但敞开中止后就会跳转到0x8000地址,这样就跳到了BOOT区,因而需求运用跳转指令将中止跳回到APP区,
经过下面的方法就能够重定向APP的中止向量,可是bootloader就不能够运用中止了,可是网上有人说能够把中止定向到arm里边,经过arm的特点在bootloader和APP别离重定向,就能够完成bootloader和APP都运用中止,可是我还不会 ,假如你们会能够留言告诉我 谢谢
__root const long reintvec[]@“.intvec”=
{
0x82008080,0x8200A804,0x8200A808,0x8200A80c,
0x8200A810,0x8200A814,0x8200A818,0x8200A81c,
0x8200A820,0x8200A824,0x8200A828,0x8200A82c,
0x8200A830,0x8200A834,0x8200A838,0x8200A83c,
0x8200A840,0x8200A844,0x8200A848,0x8200A84c,
0x8200A850,0x8200A854,0x8200A858,0x8200A85c,
0x8200A860,0x8200A864,0x8200A868,0x8200A86c,
0x8200A870,0x8200A874,0x8200A878,0x8200A87c,
}; 这便是我的重定向中止 ,由于STM8的flash从0x8000开端到0xA800 正好是0x2800字节 ,这个数正好是10K,也便是说我给bootloader预留了10K的空间,而我用的stm8s207R8t6是64k
2、怎么装备程序的开端地址
装备bootloader程序空间的巨细是在一个后缀为icf的文件里边设置,这个文件在iar的装置目录里边的有
我装置的目录如下C:Program Files (x86)IAR SystemsEmbedded Workbench 7.0stm8config
在这儿边能够看到很多.icf后缀的文件,然后挑选一个和芯片共同的,我就挑选lnkstm8s207r8.icf,复制到咱们的工程里边,再在IAR里边如下设置
r
然后翻开icf文件修正如下
define region NearFuncCode = [from 0x8000 to 0xA7FF];
define region FarFuncCode = [from 0x8000 to 0xA7FF];
// “ [from 0x10000 to 0x17FFF];
define region HugeFuncCode = [from 0x8000 to 0xA7FF];
这面都是说修正的是bootloader的程序
下面是修正app的icf文件
define region NearFuncCode = [from 0xA800 to 0x17FFF];
define region FarFuncCode = [from 0xA800 to 0xFFFF]
| [from 0x10000 to 0x17FFF];
define region HugeFuncCode = [from 0xA800 to 0x17FFF];
到这儿地址的修正也就完成了,下面开端说下跳转
3、怎么从IAP跳转到APP程序
STM8的跳转很简单,运用如下汇编就能够完成跳转
asm(”LDW X, SP “);
asm(”LD A, $FF“);
asm(”LD XL, A “);
asm(”LDW SP, X “);
asm(”JPF $A800“);
这个便是完成跳转到app的程序
4、运用库函数要注意的当地(避免被坑)
运用库函数读写flash的时分必定要注意,由于STM8的flash的库函数有点问题,他把地址都强制转换成16位的了,16位的寻址规模是0至0xFFFF的64K空间,可是STM8的flash运用0x8000开端,64kflash的巨细空间到了0x17FFF,所以假如不修正库函数的读写就会犯错。
这便是库函数的,咱们要把它改成uint32_t这样才能够读写超越0xFFFF的地址