<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/STM32W5500AIR202B/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
說明
這節測試一下STM32+W5500實現利用http遠程更新STM32程序
升級方式為:備份升級
STM32控制W5500使用http獲取雲端info.txt文件,從文件里面獲取遠端固件版本,固件下載地址等信息
如果和自身版本號不一致,固件下載地址寫入flash,設置更新標志,重啟,
BootLoader提取固件下載的地址升級程序!

注:當前程序只支持HTTP下載,HTTPS將放到優化章節里面
提示1
1.我已經把固件文件放在了自己的服務器上
默認使用本人提供的下載路徑測試
后面會說明如何應用到用戶的服務器.

2.記得修改控制生成bin文件的指令,否則編譯報錯

3.跳線帽短接單片機串口1 和 USB轉串口模塊

4.連接網線(網線另一端連接可以上網的路由器或者交換機)

下載BootLoader程序到開發板

1.下載以后打印如下

2.falsh分配情況

提示2
后面咱分為兩種情況:
人為下載進去用戶程序和讓單片機升級進去用戶程序
一,人為下載用戶程序到開發板(注意下載細節)
1.上面已經下載了BootLoader程序,為了再次下載用戶程序不覆蓋掉BootLoader程序
需要下載的時候做一下配置.
需要使用下載器 ST-Link / Jlink
2.打開用戶程序( STM32F10xTemplate )
調整用戶程序的下載設置
選擇只擦除使用的部分

3.注意檢查下其它配置是否正確

4.記得根據自己的軟件修改路徑,否則編譯會報錯

5.然后點擊下載

6.下載進去用戶程序以后,將會從BootLoader加載用戶程序運行
注:用戶程序是在基本控制篇MQTT通信程序的基礎上增加了升級處理程序

7.用戶程序運行10S左右發送get指令獲取雲端的info.txt文件
info.txt文件
version: 雲端固件的版本號
size: 雲端固件的大小
url: 雲端固件的下載地址
info:暫時用不到,后面的APP/上位機控制升級使用
如果和當前固件版本不一致,則提取size和url存入flash,設置更新標志,重啟

8.BootLoader檢測到升級標志,提取固件文件大小,解析url,執行備份

9.發送get指令獲取程序文件,寫入flash,打印每一幀數據校驗結果

10,寫入下載成功標志,重啟以后運行新程序

11,我放到雲端的程序就是當前的用戶程序,只不過版本設置的不一樣
也是每隔10S發送get指令獲取info.txt文件,檢測一下版本

二,只下載BootLoader的情況下測試
1.如果客戶不能按照上面的方式下載用戶程序
BootLoader程序里面也是可以測試升級
實際上該功能是為了預防程序徹底崩潰而做!
注意:程序本身就支持自動回滾,崩潰處理基本上用不到!
2.下載好BootLoader程序以后,需要用戶按照下面的步驟操作
① 按下PB5(不要松開)
② 復位STM32(或者斷電上電)
③ PB5按下大約10S,指示燈500ms閃耀,此時松開PB5,程序進入崩潰處理狀態

3.使用調試口發送以下指令
{"data":updata,"cmd":"start"}
程序重啟以后將自動執行更新操作

提示:
1.崩潰處理狀態下,也支持重新設置程序文件下載地址
{"url":"http://mnif.cn/ota/hardware/STM32W5500BK/user_crc.bin"}
當前是按照內部默認路徑.
應用到自己的服務器
1,在自己的網站根目錄建立幾個文件夾
關於本人服務器文件夾解釋:
html:網站根目錄
ota -> hardware : ota升級,用於升級硬件端程序
STM32W5500BK: 作為產品的型號,和程序里面設置的型號保持一致!!!后面的控制升級方式會用到這個型號

2.打開BootLoader程序的 IAP.c
修改一下 http://mnif.cn/ota/hardware/STM32W5500BK/user_crc.bin
mnif.cn/ota/hardware/STM32W5500BK 根據自己的服務器修改

3.打開用戶程序的 IAP.c
修改 http://mnif.cn/ota/hardware/STM32ESP8266BK/info.txt
mnif.cn/ota/hardware/STM32W5500BK 根據自己的服務器修改
char DeviceModel[50] = "STM32ESP8266BK";//型號和上面保持一致
char FirmwareVersion[FirmwareVersionLen] = "0.0.1";//提示一個版本好測試

編譯用戶程序
1.默認會生成 user.bin文件

2.打開OTA Tools上位機軟件

提示:該軟件是修改bin文件加入校驗(使得升級穩定可靠)
3.按照紅框選擇配置
固件版本和程序里面設置的一致
固件下載地址(文件路徑) http://mnif.cn/ota/hardware/STM32W5500BK/ 和上面設置的一致

4.選擇用戶程序生成的 bin文件

5.點擊 生成固件

6.將在user.bin目錄生成info.txt 和 user_crc.bin文件

info.txt文件(utf8編碼)
{"version":"0.0.1","size":42380,"url":"http://mnif.cn/ota/hardware/STM32W5500BK/user_crc.bin","info":"1.解決了部分BUG
2.優化了部分程序"}
"version":"0.0.1" :程序版本號,升級前先訪問這個文件,用於對比版本號
"size":42380 :程序文件的大小,用於接收判斷接收完成
url :固件的下載地址,單片機獲取此地址,通過訪問此地址獲取固件程序
info: 當前用不到,APP/微信小程序,點擊檢查硬件版本,更新時,提示的信息.
user_crc.bin文件
此文件是在user.bin的基礎上每隔128字節增加了CRC校驗位
如果最后不滿128字節則用0xff補全

7.把info.txt 和 user_crc.bin 放到雲端服務器

8.然后按照一開始的測試步驟測試即可
注意:如果客戶事先下載用戶程序然后測試,需要保證和雲端寫的版本不一致!
否則會顯示版本一致,不需要升級.

用戶程序執行詳細說明
1.用戶程序對於更新就做三件事情
一是解析info.txt文件的地址


上面的程序是解析 char IAPUrlUserInfoPath[IAPUrlPathLen]="http://mnif.cn/ota/hardware/STM32W5500BK/info.txt";
IAPStructValue.SSLEN :0-http 1-https
IAPStructValue.IP :IP地址或者域名 解析上面的為:mnif.cn
IAPStructValue.Port :端口號 如果用戶不指定,http默認80端口,https默認443端口
IAPStructValue.Path :路徑 /ota/hardware/STM32W5500BK/info.txt
二是處理更新


從上面的流程圖可知:寫完程序以后BootLoader寫入更新狀態為 0x01
重啟以后,BootLoader判斷是0x01 寫入 0xFF
用戶程序需要清除這個狀態,如果不清除0xFF
那么再次重啟以后,BootLoader判斷是0xFF便會執行回滾操作!
提示:用戶應該在認為程序執行沒有錯誤的地方調用
IAPUpdateDispose();
三是http獲取處理info文件




上面的程序便是解析info.txt文件里面的內容
對比版本號,提取文件大小,提取url,設置更新標志,重啟
BootLoader程序執行詳細說明
1.BootLoader所有的初始化程序都在 IAPInit();

2.提取升級文件信息

3.如果有更新標志則備份程序文件,擦除程序運行地址,准備接收程序


4.如果沒有更新標志,檢查更新狀態變量
如果是更新有錯誤,則回滾程序

如果更新標志是 0x01 則修改更新標志為 0xff

5.如果有更新標志,控制W5500連接服務器

6.連接上服務器以后,置位連接標志

7.發送get指令獲取程序文件


8.如果判斷接收到了 Web服務器返回的數據,寫入緩存

9.從環形隊列里面提取數據寫入falsh,提取寫入的數據,校驗



提示:為了保證校驗無誤,是先寫入,然后再提取之后做校驗
而不是先校驗數據,再寫入!
10,接收完數據,如果有錯誤則設置對於的更新狀態,否則寫入0x01(重啟)

11.如果有錯誤則執行嘗試升級

默認嘗試3次,超過次數執行回滾操作!
其它細節說明
1.再過一遍流程
用戶程序get指令獲取info.txt文件的內容
從內容里面提取版本號
如果版本號和本地的不一致
則接着提取size(程序文件大小),url(固件下載的地址) 存儲到flash,置位升級標志,重啟
BootLoader執行以后從Flash里面提取size,url.然后根據url獲取程序文件
2.BootLoader從Flash里面提取size,url解析部分

以上程序會把用戶存儲的url解析處理
假設url是 http://mnif.cn/ota/hardware/STM32W5500BK/user_crc.bin
IAPStructValue.SSLEN = 0;(如果開頭是http則為0,如果是https則為1)
IAPStructValue.IP = "mnif.cn"
IAPStructValue.Port = 80 (如果開頭是http則為80,如果是https則為443,如果指定了端口則按照指定的)
IAPStructValue.Path = "/ota/hardware/STM32W5500BK/user_crc.bin"
3.再次解析IAPStructValue.IP
w5500連接服務器之前,如果地址是域名,則需要先執行DNS解析域名,獲取IP地址
如果地址是字符串型IP地址,則需要轉成十進制.
實際上最終的IP地址存儲在 IAPStructValue.IPValue 數組里面

4.在前面的文章中說過一個事情:凡是在BootLoader里面使用中斷,
用戶程序必須重寫,可以不做任何處理,但是必須重寫!!!
BootLoader里面使用了,
定時器2; 串口1,2,3接收/發送/空閑中斷; 看門狗.
為了便於用戶移植使用,在加載用戶程序之前清除了除了看門狗以外的所有中斷.
用戶只需在用戶程序里面打開開門狗.具體看后面的移植使用部分

5.關於flash區域分配
客戶可以在 stmflash.h里面設置flash分配

調整以后,可以查看日志查看具體地址信息

然后根據上面打印的信息調整用戶程序參數

6.BootLoader把程序文件寫入Flash詳細流程
1.連接Web服務器


2.連接上服務器以后發送獲取文件指令


3.如果服務器正確返回應答,則把接收的數據寫入環形隊列

4.讀取環形隊列數據,並寫入Flash
注:程序沒有直接接收以后寫入flash,因為W5500平均接收的數據為1452,最大不超過2K
直接對1452字節數據做校驗然后寫入Flash,有可能耽擱W5500接收數據.加入緩存以后
我每次處理130字節,然后整體輪訓.

提取數據以一個校驗幀進行提取,當前程序是提取130字節(128字節數據+2字節CRC校驗)
然后把128字節寫入Flash(為了加快寫的速度,一次寫四字節)

寫完以后再從Flash讀取寫入的數據,計算CRC

5.環形隊列里面沒有了數據,如果接收的數據等於文件大小,則認為接收完了數據

6.如果超過了一定時間環形隊列沒有數據可以讀取,也認為接收完了數據


7.接收數據以后檢查數據,沒有問題寫入0x01標記,重啟
有問題就執行重試!默認3次,3次都不成功則重啟

8.重啟以后,有問題則執行回滾,沒有問題執行0xFF

9.加載運行程序

7.程序里面有下載超時和整體運行超時檢測
下載超時:只有在確認開始寫入程序文件的時候才運行,每次寫入程序文件會清零.
整體運行超時:該超時只要執行BootLoader程序便一直運行

客戶可以在IAP.h修改默認的超時時間

結語
其實此套升級方案經過了大量用戶的測試,應用和反饋,然后經過好幾次的迭代
才形成了當前的方案.客戶當前只需要拿去先使用即可.
后面會有專門的移植使用教程,可以讓用戶輕松的移植到自己的項目中使用!
