对于MSP430,STM8L,cortex-M0内核远程固件升级总结。

小愚在一家仪表公司工作3年有余,由于产品种类多,所以接触了一些不同厂家的单片机。做过的项目有基于COSEM通信结构的DLMS协议,645通信规约,188通信协议等。在做DLMS协议的仪表时,由于老外要求具有远程固件升级功能,由于第一次做,所以寻求过厂家的帮助,不过流程过于复杂,做产品要考虑可靠。有过这次经验后,所以在其他产品上增加了远程固件升级功能。虽然MSP430自带BSLSTM8L自带BOOTLOAD,但是过于限制,需要预留接口,并且协议固定,如果使用自己的固件,那么我们可以使用很多介质去传输,比如RS485MBUS,红外,CPU卡等。结合论坛上各个大神的经验,及自己开发中的经验,在此和大家分享学习。在实际测试过程中,成功率99%以上。不管是MSP430,还是STM8L或者CM0内核,万变不离其宗,只要知道原理和方法,流程都是一样的。

第一篇

在项目开发中,至关重要的是保证产品运行的可靠,如果遇到异常,能否恢复很重要,而不是像砖头一样,程序死在某个地方。固件升级的原理就是重写向量表,在引导区更新app区的flash,然后跳转app区。实际开发中就会有以下问题:

1.如果MCU复位,比如PORPDRWDT等复位,都会使sp指针指向复位地址。那么MCU从引导区执行,如果APP区程序有效,应该如何控制程序跳转到APP区。

2.如果APP区或者引导区接受新固件,在更新APPflash时,如果此时MCU发生掉电,当再次上电后,MCU该如何执行。或许有人说,我们有外部的EEP或者外部的FLASH,会使用状态和标志去记录当时MCU操作flash的状态,当然这些状态和标志有校验,并且存储到外部EEPFLASH。上电后我们会判断校验,然后读出来作为依据。在理想情况下,这样做非常完美,但是MCU在运行中,什么情况都可能发生。比如电源掉的很快,那么算出来的校验有什么意义,还怎么保证写到EEPFLASH的可靠性,特别是有外部FLASH,几ma

电流MCU瞬时根本扛不住。即使是EEP,就算将引导区配置成最低功耗,这种意外也是不可避免的,此时的标志和状态只是徒劳。那么会造成一种MCU假死状态,滞留在引导区,然后死循环。如果要解除,只能通过仿真器进入仿真模式,更改变量值去解除。而这样的后果就违背了升级的初衷和产品的可靠。

3.对于新固件的更新,是接收全部数据再更新还是接收部分数据更新FLASH,这个具体依据自己使用的硬件资源,不过重点还是在于第二点的处理。

4.如果升级过程中,传输数据或读取数据突然中断,或者新的固件验证失败,那么这些操作该如何恢复,而不至于MCU假死。

自己实践中的处理,总结了如下几条:

1.首先我们要明白MCU复位后是要从复位执行,并且MCU中断后,会跳转到实际中断向量地址,也就是向量区重写。在应用区如果有中断发生,MCU会跳转到中断原始地址,通过跳转指令执行位于应用区实际的中断处理函数。例如我使用的是MSP430FR6972,它的FRAM分配是0x4400-0x13FFF,它的向量区地址在0xFF80-0xFFFF。假如分成两个区,引导区0xF000-0xFFFFAPP0x7C00-0xEFFF。现在程序执行在0x7C00-0xEFFF的应用区,此时MCU响应了一个中断,假设这个中断函数的入口地址是0xEFF2,按照常理,MCU也应该执行这个地址的内容,实际上,MCU会跳转到这个中断的原始中断向量地址0xFFF2,因为0xEF80-0xEFFF只是我们虚拟的中断向量地址,0xFF80-0xFFFF才是真正的中断向量区。这也是为什么要在引导区重写中断向量,如

#pragma vector=WDT_VECTOR

__interrupt void WDT_ISR(void)                         //0xFFF2

{

 asm(" br &0xEFF2;");

}

执行中断,栈会保存sp等寄存器的内容,执行完后会恢复,继续执行APP区程序。

2.不管是引导区和APP区,MCU的寄存器地址都是固定的,ram的地址也是一样的,但是FLASH是各自独立的,不能重叠。特别注意的是,在引导区和APP区处理全局变量或静态变量时,一定要初始化,或者依据校验从存储器恢复,因为跳转(非中断跳转)会导致这些变量是乱的。

3.要明白编译出的文件格式,知道数据要写到MCUFLASH的地址。例如MSP430编译出的文件:

@F000

01 02 03 04 05 06 07

@F008

31 40 00 24 8C 00 08 1C 3E 40 17 02 3F 4000 00

B0 13 B4 FE 8C 00 00 1C 8D 00 00 F0 3E 4007 00

……

@FFC6

38 F0 3E F0 44 F0 4A F0 50 F0 56 F0 5C F062 F0

68 F0 6E F0 74 F0 7A F0 80 F0 86 F0 8C F092 F0

98 F0 9E F0 A4 F0 AA F0 B0 F0

@FFF2

B6 F0 BC F0 C2 F0 C8 F0 CE F0 D4 F0 08 F0

q

@后的内容是代码段的地址,是说明段数据要写入的地址,这些地址不需要写入到FLASH中。地址的分配与link文件分配有关。

-Z(CONST)DATA16_C,DATA16_ID,TLS16_ID,DIFUNCT,CHECKSUM=F000-FF7F

-Z(CONST)DATA20_C,DATA20_ID,CODE_ID=F000-FF7F

-Z(CODE)CSTART,ISR_CODE,CODE16=F000-FF7F

-P(CODE)CODE=F000-FF7F

-Z(CONST)SIGNATURE=FF80-FF8F

-Z(CONST)JTAGSIGNATURE=FF80-FF83

-Z(CONST)BSLSIGNATURE=FF84-FF87

-Z(CONST)IPESIGNATURE=FF88-FF8F

-Z(CODE)INTVEC=FF90-FFFF

-Z(CODE)RESET=FFFE-FFFF

-z-p这些都是编译指令,(data)(const)(code)都是说明修饰,DATA16_C,DATA16_ID等都是数据段类型描述。

q就是结束标志。

例如stm8l编译出的我文件格式:

:108000008200FBA0820166548200FE8D82016655CB    //起始地址是0x8000

:108010008200FEA78200FEA8820126B18200F1C77D     //起始地址是0x8010

:108020008200FEA98200FEAA820113AA8200F38ABE    //起始地址是0x8020

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值