<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_B/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
1.这节测试下STM32F407VET6+串口网络模组(ESP8266/Air202/Air302)使用http或者https远程升级单片机程序.
当前已经了做好:
STM32F407VET6+ESP8266(http/https)
STM32F407VET6+Air202(http/https)
因为程序基本都是一样的,以STM32F407VET6+ESP8266为例.
2.整个的升级流程和前面的文章一样
先测试下升级
先使用我提供的程序下载地址测试.
注意:ESP8266的程序当前不能测试使用https访问mnif.cn这个服务器下载程序文件
如果要测试,需要把地址改为: https://mnifdv.cn/ota/hardware/STM32F4xxESP8266BK/user_crc.bin
我把文件也放在mnifdv.cn这个服务器上了一份.
1.打开这节的程序
2.连接引脚说明
使用串口1作为了日志打印,串口2连接模组.
(单片机)PA2 -- RX(模组)
(单片机)PA3 -- TX(模组)
(单片机)PA8 -- RST(模组复位引脚)
另外:
PA6作为了指示灯
PE4作为了按键
指示灯和按键不是必须的!
可以按照自己的板子在各个头文件里面修改引脚定义
3.下载BootLoader到自己的开发板
4.打开用户程序,修改成连接自己的路由器名称和密码
5.如果测试https方式.把地址改为:
https://mnifdv.cn/ota/hardware/STM32F4xxESP8266BK/info.txt
6.接着再下载用户程序(选择只擦除程序使用的部分)
观察串口1打印的日志
1.烧录完BootLoader然后再烧录用户程序打印如下:
2.在用户程序中控制模组连接路哟器
3.获取服务器固件信息,如果有新版本,重启
4.更新完成
应用到自己的项目
1.在自己的Web服务器上建一个目录,作为存放固件文件
我的地址为: 网站根目录/ota/hardware/STM32F4xxESP8266BK
2.修改BootLoader的IAP.c文件里面的产品型号和默认固件的下载地址
3.打开用户程序的IAP.c文件,修改里面的产品型号和记录固件信息文件的地址
注:如果需要使用https下载,则可以写成: https://{用户的IP地址或者域名}/下载路径
4.分别编译下BootLoader程序和用户程序
先下载BootLoader程序到板子
再下载用户程序到板子
5.把用户程序的版本改为其它版本,然后编译下用户程序
6.编程以后会在其工程目录生成Bin文件夹,并在里面生成user.bin文件
7. 如果用户程序编译出现下面的警告
其实是这个地方导致的
为了便于BootLoader程序提取用户程序bin文件里面的型号,把型号存储在了偏移1024字节的位置.
就是我设置的这个字符串存储的位置影响到了芯片本身分配一些数组的位置.
用户可以把后面的20改为21或者其他大些的数值,直至不出现警告即可.
这个数值目前是不能超过0x70000 /1024 = 447;
不用设置为最大哈,这样的话编译出来的文件就会很大,其中大部分空间都是每用的!
8.打开OTA Tools上位机软件
提示:该软件是修改bin文件加入校验(使得升级稳定可靠)
9.按照红框选择配置
10.选择用户程序生成的 bin文件
11.点击 生成固件
12.将在user.bin目录生成user_crc.bin文件
user_crc.bin文件只是在user.bin的基础上增加了CRC校验位
13.把生成的user_crc.bin文件拷贝到服务器
14.打开info.txt文件
15.修改版本号(和用户程序里面设置的一样)
16.修改固件程序大小(OTA Tools提示信息里面有这个大小)
17.修改固件程序下载地址(和服务器路径保持一致)
18.最后的提示信息不需要更改,当前用不到
19.把info.txt文件也拷贝到服务器
20.然后观察日志,查看升级情况
正常情况下会和一开始的日志流程一样完成升级.
程序详细说明
1.远程升级其实就是使用模组以TCP方式连接Web服务器,
然后给TCP服务器发数据,数据格式是GET指令.
服务器接收到指令以后会下发文件给模组,模组通过串口把数据发给单片机,
单片机接收到数据以后写到flash,最后加载运行.
2.流程图
3.flash分配
4.用户可以根据自己的需求调整BootLoader ,用户程序, 备份用户程序的flash分配扇区
注意:BootLoader程序和用户程序要保持一致.
5.用户可以根据自己的需求调整存储其它数据使用的扇区
注意:BootLoader程序和用户程序要保持一致.
用户程序详细说明
1.设置中断向量偏移
地址其实就是用户程序运行地址,0x08010000
2.软件设置程序运行位置和占用flash大小
64+128+128+128=448KB = 448*1024= 458752字节 = 0x70000
3.解析下info.txt(服务器上记录固件信息的文件)
做这个程序是为省去用户解析的繁琐.
执行解析之后:
IAPStructValue.IP = mnif.cn;
IAPStructValue.Port = 80;
IAPStructValue.Path = /ota/hardware/STM32F4xxESP8266BK/info.txt
4.处理更新(这个程序需要在认为用户程序没有问题的时候在用户程序里面执行一下.)
为什么要执行一下:
如果更新成功,BootLoader里面会把更新状态置为 0xFF;用户程序需要调用一下这个函数清零这个状态.
如果用户程序不清零这个状态,重启以后BootLoader检查到0xFF会认为执行用户程序失败了.然后执行回滚.
如果本身BootLoader下载程序过程中就检查到下载的程序文件有问题,BootLoader把更新状态设置为对应的错误
然后执行回滚.用户程序需要调用一下这个函数清零状态,如果用户程序不清零这个状态,
重启以后BootLoader检查状态是错误,就会再次执行回滚(擦除flash会缩短flash寿命).
5.控制模组获取服务器上记录固件信息的文件
6.解析info.txt文件内容
如果版本号不一样,提取和存储url和文件大小,然后设置升级标志,重启.
BootLoader程序详细说明
1.查看IAPInit函数
2.获取存储的固件文件大小,固件下载的url,并解析下url
3.如果有更新标志,则备份下用户程序
4.如果没有更新标志,则查看下更新状态,如果状态是更新有错误,则执行回滚
如果检测到没有备份的程序,就重新执行升级
5.如果更新状态是0x01,就设置更新状态为0xFF
6.控制模组连接TCP服务器(Web服务器),并配置为串口透传
7.发送get指令获取程序文件
8.把数据写入缓存
IAPHttpHead是为了去掉http 头
检测到http头过去,把真实的数据写入缓存.
注:+IPD,XXXX:是模块在非透传模式下,模块会在每一条数据前面增加的内容.
如果自己使用的模块会有类似的添加的内容,用户可参考修改.
咱的主要目的是把真实的程序文件数据写到缓存里面.
9.主循环从缓存取数据,并写入flash
10.校验数据的时候是把先前写入的提取出来校验
11.如果缓存里面没有数据,如果接收到相应的文件个数或者超过一段时间没有接收到数据
会设置 IAPStructValue.ReadDataEndFlag = 1;则认为接收完成
然后做各种判断,
如果确实接收完了,则写入0x01状态,重启.
如果有错误,则尝试重新下载.
接收空闲是在这地方做的判断
空闲时间默认3S
12.重启以后如果检测到状态是0x01则写入0xFF,执行用户程序
如果检测状态是更新错误,则回滚程序,执行用户程序.
细节说明
1.首先整体思路就是把程序文件写入缓存,然后主循环从缓存里面提取数据写入flash.
其它各种程序只是为了使升级更加稳定可靠而做.
2.BootLoader跳转到用户程序之前需要关闭使用的中断
3.恢复出厂设置
为了预防超级意外的情况导致程序完全崩溃,在上电之前按下一个按钮,然后给板子上电.
如果检测到用户按下时间超过5S,控制指示灯快闪,用户松开按钮以后
设置更新标志,清空flash里面记录的url地址,重启设备.
设备重启以后便会按照默认的地址下载程序
4.程序里面有下载超时和整体运行超时检测
下载超时:只有在确认开始写入程序文件的时候才运行,每次写入程序文件会清零.
主要解决接收一半程序便不再接收的问题
整体运行超时:该超时只要执行BootLoader程序便一直运行
客户可以在IAP.h修改默认的超时时间
移植使用说明
1.建议用户直接在提供的工程上进行增加额外的功能
警告:用户不能在BootLoader程序主循环加硬延时
警告:用户不能在BootLoader程序主循环加硬延时
警告:用户不能在BootLoader程序主循环加硬延时
加了延时会影响提取缓存数据的速度,从而导致缓存溢出,接收数据错误.
底层串口1日志打印printf为了不过多占用主循环时间,使用的是环形队列+中断发送.
如果用户更改了日志打印口,也必须如此!否则就会造成上面说的情况.
2.BootLoader程序主要是修改对应的模组连接TCP服务器的命令.
如果模组是串口透传模式,那么修改完命令就可以了.其它的底层就自动完成了.
3.如果模组不是串口透传模式,用户需要处理下数据,然后把正常的数据丢给缓存
.其它的底层就自动完成了.
4.如果用户想在BootLoader运行的时候显示更新状态或者进度
1.可以在IAPInit() ;IAPGetProgramFile(); IAPWriteData();函数里面相应的位置增加提示
注意:IAPWriteData()函数
2.如果要展示更新进度
文件大小(字节): IAPStructValue.FileSizeSave
当前接收(字节): IAPStructValue.FileSizeNow
5.对于WiFi模块而言可以在BootLoader程序里面加上配网程序
加上这个程序以后,可以出厂的时候只烧录BootLoader.配网结束以后让设备自己去更新程序.
配网程序直接从提供的用户程序里把文件复制过来即可
6.关于使用APP控制升级
1.使用APP的话流程就是APP使用http或者mqtt或者mqtt获取下和设备通信获取下设备的版本,
然后APP也获取下服务器上的info.txt文件,APP对比下版本,如果版本不一致,就把info.txt文件发给单片机就可以.
2.更新完了以后,用户程序里面可以在IAPUpdateDispose函数里面获取到这次的升级是不是成功.
然后上报给APP即可.
STM32F407VET6+Air202(GPRS)简要说明
前要:默认固件不支持SSL,如果要测试https方式下载数据
用户参考硬件使用说明刷下支持SSL的固件.
1.程序和上面的是一样的.
只是控制模组的指令不一样,我只简要说下不一样的地方
2.打开程序
3.用户程序不一样的地方只是配置模组连接TCP服务器(Web服务器),获取服务器固件信息.
4.BootLoader 程序中控制模组连接服务器
5.发送获取文件GET 指令
6.https是非透传模式才可以,模组返回数据是 +SSL RECEIVE,0,数据个数: 真实数据,所以需要剔除
7.因为GSM通信延迟高些,所以修改为了5S.
8.然后就是这些.