1-CH32V307+ESP8266程序升级篇(自建物联网平台)-CH32V307通过ESP8266使用http或https下载程序文件升级程序(单片机程序轮训检查更新)
<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ZLIOTE_CH32V307/ESP8266/myota.html" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
这节测试一下CH32V307通过ESP8266使用http或https远程下载升级单片机程序
我已经把固件文件放在了自己的服务器上
默认使用本人提供的下载路径测试
文件路径: 网站根目录->ota->hardware->CH32V307ESP8266BK
user_crc.bin: 是固件程序文件.
该固件程序文件并不是直接可以运行的文件
里面的数据每隔128字节后面增加2位CRC校验位
单片机下载以后每隔130字节校验一下数据,然后把前128字节写入Flash.
加入CRC校验让升级变的稳定可靠.
info.txt文件内容:
version:0.0.1 云端固件程序版本
url:http://mnif.cn/ota/hardware/CH32V307ESP8266BK/user_crc.bin 固件程序下载地址
"info":"1.解决了部分BUG 2.优化了部分程序" 使用APP控制升级时,APP的提示信息.
升级过程:
用户程序里面每隔一定时间控制网络模块使用http的GET指令获取云端info.txt文件
然后从文件里面获取服务器里面的固件程序版本和固件程序下载地址等信息
如果与自身版本号对比不一致,就把固件程序下载地址写入flash,然后设置更新标志,重启,
重启执行BootLoader以后,BootLoader程序检测到更新标志,则提取固件下载的地址,
然后使用http下载程序文件,把程序文件写入flash,完成升级.
备份升级流程图
测试
1,使用单片机串口1打印串口日志(115200)
2,打开下面的工程
3,为快速测试, 可直接在用户程序里面设置模组连接的路由器
4,重新编译用户程序, 先使用下载器下载用户程序
5,再使用下载器下载BootLoader程序
BootLoader下载的时候不要选择全部擦除
可能出现的问题
如果出现下面的情况,就按一下开发板上的复位按键,复位下芯片
3.观察日志,说明执行流程
开始运行用户程序,默认提供的用户程序设置的程序版本是0.0.0
用户程序控制模组连接服务器,使用get指令获取获取服务器上的固件信息文件 info.txt
检测到版本不一致以后,把获取的url存储到flash,设置更新标志,重启.
重启之后BootLoader提取url
BootLoader发送get指令获取程序固件
升级完成以后,运行新下载的程序.
用户程序每隔一段时间控制模组连接服务器,使用get指令获取获取服务器上的固件信息文件 info.txt
现在程序版本和上面的是一致的,所以不需要更新
应用到自己的服务器(如果使用SSL, 则把单片机程序下载路径的http改为https即可)
1,首先确定好程序文件在服务器的路径
关于本人服务器文件夹解释:(自己随意就好,最后的文件夹命名建议使用产品的型号)
html:网站根目录
ota: ota升级
hardware : 硬件程序
CH32V307ESP8266BK: 作为产品的型号(根据自己的产品型号修改)
我把固件放到了里面那么固件程序下载地址为:
http://服务器IP地址/ota/hardware/CH32V307ESP8266BK/user_crc.bin
那么固件信息的下载地址为:
http://服务器IP地址/ota/hardware/CH32V307ESP8266BK/info.txt
2.修改 用户程序(mcu_project) 的IAP.C文件
1.产品型号(我设置的为CH32V307ESP8266BK)
2.修改固件程序版本(可随意指定,我设置的为0.0.1)
3.修改记录云端固件信息文件下载地址(我的为:http://mnif.cn/ota/hardware/CH32V307ESP8266BK/info.txt)
提示:
为了BootLoader下载的时候提取这些数据,下面两个数据我存储在程序bin文件的1024字节倍数的位置, ;
由于编译器不支持at命令,所以我直接在ld文件里面写了点程序,定义的位置
一个存储在偏移20KB的地方, 一个存储在偏移21KB的地方(了解就可以,用户实际上也不需要改啥)
5.修改BootLoader程序 的 IAP.c (设置下产品型号和默认的固件程序下载地址)
注意:BootLoader里面的产品型号要和用户里面的一样!!!!
BootLoader程序下载的时候会判断这个型号一不一致
6.编译用户程序(mcu_project)
会在工程目录的obj文件夹生成 user.bin文件
7.打开OTA Tools上位机软件
8.按照红框选择配置
9.选择用户程序生成的 bin文件
10.点击 生成固件
11.将在user.bin目录生成user_crc.bin文件
两个bin文件的区别:
1.user_crc.bin文件是在user.bin的基础上增加了CRC校验位
2.改写size,把真实的文件大小填写到bin文件
12.把生成的user_crc.bin文件拷贝到服务器
13.还差一个info.txt文件
我准备了一个模板
14.修改版本号(和用户程序里面设置的一样)
16.修改固件程序下载地址(和服务器上面的保持一致)
17.最后的提示信息不需要更改,当前用不到
18.把info.txt文件也拷贝到服务器,然后按照一开始的步骤测试即可
小总结
远程升级单片机程序其实就是使用模组以TCP方式连接Web服务器,
然后给TCP服务器发数据,数据格式是GET指令.
服务器接收到指令以后会下发文件给模组,模组通过串口把数据发给单片机,
单片机接收到数据以后写到flash,最后加载运行.
关于Flash分配调整
1.打开BootLoader 或者 用户程序(mcu_project)里面的iap_interface.h 文件
flash的最一开始存储的BootLoader程序, 结尾存储更新相关数据, 预留一些空间让用户存储其它数据
最后剩下的平半分, 一部分存储用户程序, 另一部分用来备份用户程序
用户可以根据自己的需求调整Flash分配大小, 注意:BootLoader程序和用户程序的Flash分配要保证一样.
用户可以根据自己的需求调整Flash分配大小, 注意:BootLoader程序和用户程序的Flash分配要保证一样.
用户可以根据自己的需求调整Flash分配大小, 注意:BootLoader程序和用户程序的Flash分配要保证一样.
我设置了BootLoader占用50KB(用户可以根据自己的BootLoader程序的bin文件大小进行更改)
存储更新相关数据至少用1K(一般占用一页), 这个用户不要改动.
如果用户在项目中也需要使用flash存储数据, 可以根据自己存储的数据量调整
数据存储的起始地址是: FLASH_USERDATE_ADDR
2.调整完成以后,下载BootLoader程序, 串口会打印flash具体分配
用户需要根据上面打印的设置下用户程序(mcu_project)运行地址和占用空间
注意运行地址是0x800c800, 但是写的时候只需要写偏移地址(相对于flash基地址)
flash的基地址是0x08000000, 运行地址是0x0800c800, 所以只需要写 0x0000c800
0x19400换算一下就是101KB
关于升级底层包
1.升级底层包分为iap文件 和 iap_interface文件
2. iap文件主要是控制着升级流程的文件
可以在BootLoader程序里面设置升级过程中需要如何去下载,设置多大的缓存区
3. iap_interface是接口文件
根据移植的单片机实现内部的接口,只要完成里面的接口就完成了升级程序框架
用户程序说明
1.解析下info.txt下载路径(服务器上记录固件信息的文件)
做这个程序是为省去用户解析的繁琐.
执行解析之后:
IAPStructValue.SSLEN = 0;
IAPStructValue.IP = mnif.cn;
IAPStructValue.Port = 80;
IAPStructValue.Path = /ota/hardware/CH32V307ESP8266BK/info.txt
如果路径写的是https
IAPStructValue.SSLEN = 1;
IAPStructValue.Port = 443;
如果指定了端口号 http://mnif.cn:8080/xxxxxx
IAPStructValue.Port = 8080;
4.处理更新(这个程序需要在认为用户程序没有问题的时候在用户程序里面执行一下)
解释:
BootLoader更新程序的时候会设置一些更新状态;用户程序需要调用一下这个函数清除更新状态.
如果用户程序不清除更新状态,那么一旦程序重启以后BootLoader检查到更新状态以后会自行回滚程序.
5.控制模组发送get指令获取服务器上记录固件信息的文件
6.解析info.txt文件内容
如果版本号不一样,提取和存储url然后设置升级标志,重启.
BootLoader程序详细说明
1.查看IAPInit函数
2.获取存储的固件下载的url,并解析下url
3.如果有更新标志,则备份下用户程序
4.如果没有更新标志,则查看下更新状态
如果状态是更新有错误,则执行回滚,如果检测到没有备份的程序,就重新执行升级
5.如果更新状态是0x01,就设置更新状态为0xFE
7.控制模组连接TCP服务器(Web服务器),
8.发送get指令获取程序文件
8.在TCP接收数据函数里面把固件数据写入缓存
单片机是通过串口和模组通信,所以在串口中断里面接收
9.从缓存取数据,并写入flash
11,如果接收到相应的文件个数
设置 IAPStructValue.ReadDataEndFlag = 1;认为接收完成
12,判断接收完成之后做各种判断
如果确实接收完了,则写入0x01状态,重启.
如果有错误,则尝试重新下载.
13,如果是程序文件下载完成以后重启,重启以后检查到更新状态是0x01会设置更新状态为0XFE
14,然后加载运行用户程序
15,超过一段时间没有接收到数据了也设置为接收完了数据
16,客户可以在IAP.h修改默认的超时时间
整体运行超时是BootLoader程序一运行就一直累加的的定时, 超过时间就会控制程序重启