白小姐六肖中特
STM32的基于串口的IAP固件升级与加密
发表日期 : 2019/03/11  131 收藏
川楠
向TA提问
701
总阅读量
6
作品

        大家好,我是川楠,最近,在问答频道上看到有人对IAP升级心存疑惑。恰好,我本人在这方面的做过功课,也实战使用到很多的项目上,所以我就来为大家做个抛砖引玉吧。

         本次例程,我用的是STM32F103VET6单片机开发板,这个是我2012年买的,有没有人和我用的一样的呢?

          01.jpg

         所谓的IAP In Application Programming)即在线应用编程。其主要的应用就是对程序的在线升级更新。比如,我们开发的产品,在已经大量出货的情况下,突然发现我们产品的程序有个BUG,在这种情况下,总不能把所有的产品都召回吧,这样成本太高了。IAP就可以很好避免这个问题。

         如果你的设?#24178;?#26377;IAP功能,你可以要求把你的产品接到网口、USB、插个有新程序的TF卡、或者串口等等,就能对产品设备进行固件升级。就像我们的手机刷机一样。

 

IAP升级原理

         STM32单片机,根据BOOT电平的设置,其上电启动的地址也是部一样的,常用的是从Flash启动。对应的BOOT电平设置如下:

         02.jpg

FLASH启动模式下,上电的启动地址是:0x0800 0000,也是FLASH的起始地址。

03.jpg

         比如,本?#38382;?#29992;的STM32F103VET6单片机,其FLASH大小为512K,RAM尺寸为64K。这里我将程序设计成两个BOOT程序和APP程序。

BOOT程序:位于FLASH的起始地址,及0x0800 0000.主要进行对后面APP程序的FLASH扇区经行编程,上电默?#29616;?#34892;。

APP程序:位于FLASH的后半段,为用户实现功能的程序。

         所以这里将512KFLASH分成了两部分从0x0800 000 -0x0800 FFFF BOOT程序区,合计64K;剩下的从0x0801 0000-0x0808 0000为用户APP程序区,合计448K

 

程序的启动流程是:

04.jpg

单片机上电之后,首先从0x08000000启动,运行BOOT程序,在BOOT程序中检测是否需要进行固件升级:

如果需要升级,则按照规定的方式,从串口接收数据对单片机的FLASH进行改写,改写完成之后,需要对改写的固件进行校验。校验通过后,则进行程序跳转。

如果不需要升级,则判断APP程序的起始地址是否正常,若正常,则进行程序跳转,运行APP即可。

 

说了这么多,下面开始实操。

 

BOOT程序设计

BOOT程序的核心功能有两个:

1、程序跳转

2、对APP程序的FLASH扇区内容进行改写

 

程序跳转很简单,也就几句话:

05.jpg

其中的 APP_START 就是我们APP程序的起始地址:0x0801 0000

 

FLASH的改写稍微麻烦些,需要将0x0801 0000 后面的FLASH扇区进行擦除和重写。重写的类容为我们新的APP程序类容。

         这里?#24471;?#19979;,新的APP程序数据,有多种来源方式:可以将新的APP程序的BIN文件放到TF卡中,BOOT程序根据TF卡的BIN文件,去改写APP扇区。?#37096;?#20197;用过CANRS485、串口、USB等串行接口接收新的APP程序数据包,并把数据包?#26469;?#20889;到APP扇区。本?#38382;?#29992;的是串口。

配置工程:默认的是ROM1的起始地址为0x0800 0000 SIZE 0x8 0000

而本次我们分配的BOOT程序为64K,所以需要修改SIZE0x1 0000

07.jpg

其他的地方编程和我们平时编程是一样的。

08.jpg

程序编写成功之后,点击“LOAD”下载就可以了。

这里需要主要的是:

1、每个单片机的FLASH大小和扇区是不一样的,两个程序的分割点,一定要选择某个扇区的起始地址。

2、本?#38382;?#20351;用的单片机有256个扇区,每个扇区为2K,但是并不是所有单片机的PAGE都是一样大小的,比如STM32F407的扇区就不是平均分配的。

3BOOT的功能建议设计为越简单越好,其主要功能就是为了下载程序。所以,越简单,其可能出问题的几率就越小。如果BOOT程序出了问题,那?#35805;?#21482;能进行产品召回了。

4、安全很重要。在BOOT程序里,一定要记得,要将其他的控制引脚保持在合适的电平。比如:做小车控制板,在BOOT程序升级的时候,忘记了把运动控制引脚的电平拉低,导致在升级的时候,小车乱跑,容易撞到东西。

 

========================示例:我设计的BOOT程序升级流程=====================

正常情况下,程序上电启动之后从MCU起始地址0x0800 0000直接启动,读取BKP_DR1寄存器,判断是否需要固件升级,如果不要升级,则进入固件跳转,运行APP程序。

 

当需要更新固件的时候,需要严格按照如下的步骤和通讯要求进行操作,具体操作如下:

l  目标设?#24178;?#30005;之后(程序已经完成了跳转),上位机发送“固件更新命令?#20445;?#30446;标设备重新?#27425;?#21551;动,在这个过程?#24515;?#26631;设备不能断电(此时固件更新命令将保存到BKP_DR1备份寄存器中)。

l  上位机可以使用相关的命令获取设备的MCU型号、内存、ID、版本、固件起始地址(主要是固件起始地址?#38382;?#22914;果知道可以跳过此步骤)等相关信息。

l  上位机发送“开始更新固件”命令,该命令包含固件的起始地址,目标设备收到后需要应答。

l  上位机开始分包发送固件数据帧,目标设?#24863;?#39564;并保存固件数据,同时需要应答上位机;如果数据校验失败,可以要求上位机重传。

l  上位机收到应答数据帧之后,才能继续发送固件数据帧。当上位机发送完整个固件数据帧之后,上位机需要发送固件数据更新完毕命令,目标设备应答,开始重启,此刻目标设备固件更新完成。

 

具体流程如下图所示:

09.jpg

    在BootLoader程序中,固件的起始地址、BootLoader版本都在程序的代码中固化好了;CPUID、内存尺寸直接读取MCU相关的寄存器即可。

   a1.jpg

=========================================================================

 

 

APP程序设计

         APP程序与我们平时编写的程序稍微有点差别了,因为其程序的起始地址发生了变化,所以需要修改两个地方:程序的起始地址和中断向量偏?#39057;?#22336;。

 

 

1、程序起始地址修改.

         划分的APP程序起始地址为0x0801 0000APP?#21152;每占?#22823;小为448KSIZE=0x70000

a2.jpg

2、修改中断向量偏?#39057;?#22336;

         system_stm32f10x.c文件中,修改VECT_TAB_OFFSET的值为0x10000

         默认程序定义的值为0

        a3.jpg

         需要修改为:

a4.jpg

         完成上面的修改之后,按照正常的程序设计编程即可。

 

========================示例:我设计的APP程序===========================

我的APP程序很简单,就是点灯。

a5.jpg

=========================================================================

 

     经过上面的程序设计,我们拿到两个HEX文件,分别是BOOTAPPHEX文件。BOOT程序需要通过下载器下载到单片机中,这里使用的是JLINK

         APP程序则需要按照我们?#32423;?#30340;固件升级协议,通过串口下载下去。

 

         为了更好的验证和提高?#32422;海?#36825;里使用C#?#32422;?#32534;写了一个上机软件。这个上位机软件的主要功能,就是将我的APPHEX文件,解析出来,把升级数据,按照BOOT程序的协议和流程,分包把固件数据?#26469;?#21457;到单片机?#23567;?

a6.jpga7.jpg

         也是这个实验,让我一只脚又跨入了C#的桌面窗口程序编程?#23567;?#25972;个例程前前后后花了我两个多月的下班休息时间,也熬了太多个白天和黑夜。单片机程序也就1-2周就搞定了,但是C#上位机软件设计花了2个月。主要是我C#都是从零开始的,不论窗口程序控件还是定期、串口控件等,我都是现学现用,看视频和别人的代码,慢慢的搞定的。

a8.jpg

界面写的有点LOW,大家将就看下就可以,毕竟不是专业的美术UI设计。

 

最后实?#22987;?#39564;一下

1、先将BOOT程序使用下载器下载到开发板。

b1.jpg

2、程序运行起来之后,使用我写的上位机软件,将开发板与PC通过串口连接起来。

b2.jpg 

3、这个我?#32422;?#20570;的读取信息。

b3.jpg

读信息:这个是我?#32422;?#35774;计的一个功能,通过读信息:可以读出单片机型号(?#22336;?#20018;信息,BOOT程序固化好的);内存尺寸MCU内部有寄存器表示?#35805;?#26412;信息是程序固化好的,包含硬件版本和软件版本;APP起始地址和CPUID

 

APP起始地址,我在上位机软件里面,并没有设计成为固定的偏移量。主要是希望这个上位机软件能够?#35270;?#26356;多的MCU。比如我用STM32F103C8T6,这个单片机的内存本来小,BOOT?#21152;?#30340;?#21344;?#21487;能就不能按照现在的分配方式,所以使用可以灵活配置的方?#20132;?#26356;好。

 

CPUID这个很重要,我可以读出MCU的唯一序列号,传给上位机软件,上位机利用这个序列号计算出加密结果,写到特定的位置,或者更改APP特定位置的代码,保证每台设备的APP代码的唯一性;这样即使别人读出MCU的代码,复制抄板出硬件,也不能拿到另外的单片机中使用。

 

4、下载程序。

b4.jpg

固件更新的时候,加载文件是HEX文件,同样我的这个上位机也支持BIN文件的加载;如果是HEX文件,则需要按照特定的方式去除地址信息,只要固件数据,然后将固件数据发到单片机。详情可以自行查阅HEX文件格式方面的资料。

 

更新完成之后程序重启一?#24405;?#21487;,?#27604;灰部?#20197;不用重启,一切都看你BOOT程序是怎么设计的。


原创作品,未经权利人授权禁止转载。详情见转载须知

单片机 IAP 固件升级
【你的赞赏是对原创作者最大的认可】
打赏
2人已打赏
川楠
向TA提问
701
总阅读量
6
作品
相关文章推荐
换一批
相关回答
换一批
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
白小姐六肖中特 福彩快三群主怎么赚钱 陕西快乐十分奖金对照表 重庆时时走势图 安徽时时彩中奖规则 258彩票开户 二码二码中特 新时时彩保号法 新加坡快乐8开奖时间 体育票福建时时 香港白小特马资料