历史上的今天
返回首页

历史上的今天

今天是:2025年06月01日(星期日)

2018年06月01日 | 在STM8L上实现IAP(In Application Programming)

2018-06-01 来源:eefocus

1.实现将Boot和App下载到FLASH的不同地址上,我们需要对链接脚本进行配置
IAR默认的链接脚本在安装目录下
C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.0\stm8\config
找到对应芯片打开后可以看到的这样的字样:


  1. /////////////////////////////////////////////////////////////////  

  2. //      Example ILINK command file for  

  3. //      STM8 IAR C/C++ Compiler and Assembler.  

  4. //  

  5. //      Copyright 2014 IAR Systems AB.  

  6. //  

  7. /////////////////////////////////////////////////////////////////  

  8.   

  9.   

  10. define memory with size = 16M;  

  11.   

  12.   

  13. define region TinyData = [from 0x00 to 0xFF];  

  14.   

  15.   

  16. define region NearData = [from 0x0000 to 0x0FFF];  

  17.   

  18.   

  19. define region Eeprom = [from 0x1000 to 0x10FF];  

  20.   

  21.   

  22. define region BootROM = [from 0x6000 to 0x67FF];  

  23.   

  24.   

  25. define region NearFuncCode = [from 0x8000 to 0xFFFF];  

  26.   

  27.   

  28. define region FarFuncCode = [from 0x8000 to 0xFFFF]  

  29.                           | [from 0x10000 to 0x17FFF];  

  30.   

  31.   

  32. define region HugeFuncCode = [from 0x8000 to 0x17FFF];  


这里定义了不同区域对应的地址,先将该文件拷贝到工程目录下,我们要对其做相应的修改,
我规划Boot的大小为5k,所以将三个FuncCode的范围改为如下:


  1. define region NearFuncCode = [from 0x8000 to 0x93FF];  

  2. define region FarFuncCode = [from 0x8000 to 0x93FF];  

  3. define region HugeFuncCode = [from 0x8000 to 0x93FF];  

相应的app的链接脚本我们也做了如下的修改:


  1. define region NearFuncCode = [from 0x9400 to 0xFFFF];  

  2. define region FarFuncCode = [from 0x9400 to 0xFFFF]  

  3.                           | [from 0x10000 to 0x17FFF];  

  4. define region HugeFuncCode = [from 0x9400 to 0x17FFF];  

最后我们对配置进行修改,右击工程->Options->Linker->Config->Linker configuration file->选中Override define,
并将链接脚本路径改为工程目录下:$PROJ_DIR$\lnkstm8l052r8.icf
至此Boot和App地址空间划分完毕


2.中断向量表的配置
在stm32中,有一个寄存器保存着中断向量表的起始地址,所以在Boot和App中可以有两个中断向量表,
当从Boot跳转到App时只需要设置一下这个寄存器里的值就行了。
但是STM8l的中断向量位置是固定的,从0x8000处开始。
当中断发生时都是跳转到0x8000开始的中断向量表。那么问题就来了,如果App中发生中断,要是跳到Boot中去了,
那不就GG了,所以我们要对Boot的中断向量表进行修改:


  1. /**************************************************  

  2.  *  

  3.  * System initialization code for the STM8 IAR Compiler.  

  4.  *  

  5.  * Copyright 2010 IAR Systems AB.  

  6.  *  

  7.  * $Revision: 1413 $  

  8.  *  

  9.  ***************************************************  

  10.  *  

  11.  * To add your own interrupt handler to the table,  

  12.  * give it the label _interrupt_N, where N is the  

  13.  * offset from the RESET vector.  Your label will  

  14.  * override the corresponding weak label declaration  

  15.  * on the unhandled_exception function.  

  16.  *  

  17.  **************************************************/  

  18.   

  19.   

  20.         MODULE   ?interrupt  

  21.   

  22.   

  23.         SECTION __DEFAULT_CODE_SECTION__:CODE  

  24.   

  25.   

  26. /*  

  27.  * The interrupt vector table.  

  28.  */  

  29.   

  30.   

  31.   

  32.   

  33.         SECTION `.intvec`:CONST  

  34.   

  35.   

  36.   

  37.   

  38.         PUBLIC  __intvec  

  39.         EXTERN  __iar_program_start  

  40.           

  41.   

  42.   

  43.         //app start at 0x9000  

  44. __intvec:  

  45.         DC8     0x82  

  46.         DC24    __iar_program_start          ;; RESET    0x8000  

  47.         DC8     0x82  

  48.         DC24    0x9404  

  49.         DC8     0x82  

  50.         DC24    0x9408  

  51.         DC8     0x82  

  52.         DC24    0x940C  

  53.         DC8     0x82  

  54.         DC24    0x9410  

  55.         DC8     0x82  

  56.         DC24    0x9414  

  57.         DC8     0x82  

  58.         DC24    0x9418  

  59.         DC8     0x82  

  60.         DC24    0x941C  

  61.         DC8     0x82  

  62.         DC24    0x9420  

  63.         DC8     0x82  

  64.         DC24    0x9424  

  65.         DC8     0x82  

  66.         DC24    0x9428  

  67.         DC8     0x82  

  68.         DC24    0x942C  

  69.         DC8     0x82  

  70.         DC24    0x9430  

  71.         DC8     0x82  

  72.         DC24    0x9434  

  73.         DC8     0x82  

  74.         DC24    0x9438  

  75.         DC8     0x82  

  76.         DC24    0x943C  

  77.         DC8     0x82  

  78.         DC24    0x9440  

  79.         DC8     0x82  

  80.         DC24    0x9444  

  81.         DC8     0x82  

  82.         DC24    0x9448  

  83.         DC8     0x82  

  84.         DC24    0x944C  

  85.         DC8     0x82  

  86.         DC24    0x9450  

  87.         DC8     0x82  

  88.         DC24    0x9454  

  89.         DC8     0x82  

  90.         DC24    0x9458  

  91.         DC8     0x82  

  92.         DC24    0x945C  

  93.         DC8     0x82  

  94.         DC24    0x9460  

  95.         DC8     0x82  

  96.         DC24    0x9464  

  97.         DC8     0x82  

  98.         DC24    0x9468  

  99.         DC8     0x82  

  100.         DC24    0x946C  

  101.         DC8     0x82  

  102.         DC24    0x9470  

  103.         DC8     0x82  

  104.         DC24    0x9474  

  105.         DC8     0x82  

  106.         DC24    0x9478  

  107.         DC8     0x82  

  108.         DC24    0x947C  

  109.   

  110.   

  111.         END  


个人理解DCn是开辟一个n bit的汇编指令吧。0x82 为操作码,意思是跳转到后面的地址去执行。
0x94XX表示一个地址,我们会将这个地址里的数据赋值给PC指针。
那么这个中断向量表的意思就是,除了Reset,其他的中断发生时,都跳转到App的中断向量表去执行。
这么做的后果就是,Boot中不能使用中断了。不然就跳转到App中去执行了。
那有的同学头就很铁,我偏要两个地方都是用中断呢?
还真有办法,前面的流程都一样,但是用一个全局变量来表示当前程序是在在哪里运行的,
然后在中断函数里根据这个全局变量来选择执行哪段程序。大致思路就这样,具体没有去实现过。
这里还要说一句:既然写Boot就好好写一个功能专一点的Boot,干嘛非要用中断。这种花里胡哨的搞来搞去,没有用的!


3.执行Boot到App的跳转
比较常用的跳转方法有两种,在C语言里,我们一般使用函数指针的方式,还有一种就是使用汇编直接改变PC指针的值。
stm8l中用的是第二种:


  1. asm("LDW X,  SP ");  

  2. asm("LD  A,  $FF");  

  3. asm("LD  XL, A  ");  

  4. asm("LDW SP, X  ");  

  5. asm("JPF $9400");  


我只知道这些是C语言内嵌汇编的写法,对于stm8l的架构是一无所知,大概就是设置了堆栈,然后跳转吧$9400就是App的起始地址。


推荐阅读

史海拾趣

Greenray Industries Inc公司的发展小趣事

为了加速绿色技术的推广和应用,GreenTech积极寻求与全球知名企业的战略合作。例如,公司与一家国际领先的电动汽车制造商达成合作协议,共同研发用于电动汽车的高效电池管理系统。通过这一合作,GreenTech不仅提升了自身在电池技术领域的竞争力,还成功将绿色技术应用于实际产品中,推动了电动汽车行业的绿色发展。

Global Connector Technology公司的发展小趣事
按照厂家提供的安装说明,检查继电器的安装位置和连接线路是否正确。
思瑞浦微电子科技(3PEAK INCORPORATED)公司的发展小趣事
电源系统中的电磁干扰或电压波动可能影响继电器的正常工作。
AUSTIN公司的发展小趣事

然而,好景不长。奥斯汀公司在全力投入研发的WW1车系上遭遇了挫折,销售不佳导致公司濒临破产。在这个关键时刻,奥斯汀汽车公司通过研发新的车型来寻求突破。1922年,Seven车系成功上市,凭借其卓越的性能和合理的价格,使得奥斯汀汽车转危为安,重新获得了市场的认可。

Arcolectric公司的发展小趣事

Arcolectric深知合作伙伴的重要性,因此一直致力于与全球各地的优质企业建立紧密的合作关系。通过与这些合作伙伴的深入合作,Arcolectric不仅获得了更多的市场机会和资源支持,还不断吸收和借鉴先进的经验和技术,推动公司的持续发展和创新。

COILCRAFT公司的发展小趣事

为了更好地服务全球客户,COILCRAFT公司在北美、亚洲和欧洲等地建立了制造、分销和工程设施。这一全球布局使得公司能够快速地响应客户需求,提供高效的服务和运输。同时,COILCRAFT还拥有丰富的网络工具库和免费评估样品政策,这些措施简化了部件选择过程,提高了客户的满意度。

问答坊 | AI 解惑

双面板孔金属化的制作方法详解

在印制板加工厂采用的是自动化的连续作业设备,设备成本昂贵,这在业余条件下是根本不可能做到的。我们在这里推出的是一种接近工厂正规生产工艺流程,但生产工艺相对简单,设备极其低廉,业余条件下比较容易完成操作的方法。郑州东明电子研究所为此 ...…

查看全部问答>

正激式变压器开关电源 开关电源原理与设计(连载13)

1-6.正激式变压器开关电源 正激式变压器开关电源输出电压的瞬态控制特性和输出电压负载特性,相对来说比较好,因此,工作比较稳定,输出电压不容易产生抖动,在一些对输出电压参数要求比较高的场合,经常使用。 1-6-1.正激式变压器开关电源工作 ...…

查看全部问答>

ADOCE3.1+SQLCE2.0出现内存泄漏现象

我想问一下专家们.是ADOCE3.1提供的接口有问题还是?...搞得一个星期了头痛.希望高手指点下或介绍点其他方法.已尝试结果未出现内存泄漏现象 QQ9737964 E-MAIL:lmj1912@163.com msn:lmj1912@hotmail.com…

查看全部问答>

windowsCE SDK开发

请问各位 windowsCE SDK开发是什么意思??? SDK不是在PB中导出的的吗…

查看全部问答>

232口电压控制

各位大侠,谁有汇编控制232的开关…

查看全部问答>

RT-Thread 1.0.0正式版发布

RT-Thread从2006年诞生到现在已经5年了,历经多次版本更迭(0.2.x,0.3.0,0.3.3,0.4.0 beta1,0.4.0 beta2,0.4.0 RC1)内核更稳定:增强上下文检查的功能,更多的错误检查组件更丰富:有文件系统,有RTGUI,支持TCP/IP协议栈,支持动态模块加载 ...…

查看全部问答>

如何理解PWM的发生器

LM3S811的PWM有3个发生器,如何理解呢?我现在是用发生器1,在PWM0,PWM1产生2路波形。3个发生器之间的关系是什么,与PWMx接口有什么关系呢…

查看全部问答>

新手求助,求解答~

#include \"iom16v.h\" void io_init(void)   {        DDRA=0x00;          PORTA=0xFF;         DDRD = 0xFF;   PORTD = ...…

查看全部问答>