<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_B/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
說明
這節測試一下STM32+Air302(NB-IOT)實現利用http遠程更新STM32程序
我已經把固件文件放在了自己的服務器上
默認使用本人提供的下載路徑測試
文件路徑: 網站根目錄->ota->hardware->STM32Air302BK
user_crc.bin:
是固件程序文件.
該固件程序文件並不是直接可以運行的文件
里面的數據每隔128字節后面增加2位CRC校驗位
單片機下載以后每隔130字節校驗一下數據,然后把前128字節寫入Flash.
加入CRC校驗讓升級變的穩定可靠.
info.txt文件內容:
{"version":"0.0.1","size":16900,"url":"http://mnif.cn/ota/hardware/STM32Air302BK/user_crc.bin","info":"1.解決了部分BUG
2.優化了部分程序"}
version:0.0.1 雲端固件程序版本
size:16900 固件程序大小(字節)
url:http://mnif.cn/ota/hardware/STM32Air302BK/user_crc.bin 固件程序下載地址
"info":"1.解決了部分BUG 2.優化了部分程序" 使用APP控制升級時,APP的提示信息.
升級過程:
注:使用TCP連接Web服務器,然后發送相應的GET指令獲取文件!
用戶程序里面每隔一定時間控制網絡模塊使用http的GET指令獲取雲端info.txt文件
然后從文件里面獲取服務器里面的固件程序版本,固件程序大小和固件程序下載地址等信息
如果與自身版本號對比不一致,就把固件程序大小和固件程序下載地址寫入flash,然后設置更新標志,重啟,
重啟執行BootLoader以后,BootLoader程序檢測到更新標志,則提取固件下載的地址,
然后使用http下載程序文件,把程序文件寫入flash,完成升級.
備份升級流程圖
測試
1.插上手機卡和天線,使用杜邦線或者跳線帽短接單片機串口2和模組串口
以前版本連接如下:
3.0版本以后連接如下
2.下載BootLoader程序到開發板
3.下載以后打印如下
4.下載用戶程序到開發板
上面已經下載了BootLoader程序,為了下載用戶程序時不覆蓋掉BootLoader程序
需要下載的時候做一下配置. 需要使用下載器 ST-Link / Jlink
提示:如果使用的串口下載,可以按照第一節把BootLoader和用戶程序的hex文件合成一個hex文件下載到開發板
提示:如果使用的串口下載,可以按照第一節把BootLoader和用戶程序的hex文件合成一個hex文件下載到開發板
提示:如果使用的串口下載,可以按照第一節把BootLoader和用戶程序的hex文件合成一個hex文件下載到開發板
下面演示使用下載器下載
打開用戶程序
調整用戶程序的下載設置,只擦除使用的部分
注意檢查下其它配置是否正確
然后點擊下載
5.下載以后會看到程序先執行BootLoader 然后運行用戶程序
6.用戶程序里面發送get指令獲取服務器上的固件信息文件 info.txt
如果固件版本不一致,存儲固件下載地址和固件大小,設置升級標志,重啟
7.重啟后BootLoader檢測到有升級標志,則備份源程序,然后發送http指令獲取程序文件
8.升級完成以后,運行新程序.
9.雲端的程序就是當前的用戶程序,只不過版本設置的不一樣
用戶程序是每隔一段時間發送get指令獲取info.txt文件,檢測一下版本
應用到自己的服務器
1,首先確定好程序文件在服務器的路徑
關於本人服務器文件夾解釋:(自己隨意就好,最后的文件夾命名建議使用產品的型號)
html:網站根目錄
ota: ota升級
hardware : 硬件程序
STM32Air302BK: 作為產品的型號(根據自己的產品型號修改)
2.假設固件程序的名字為 user_crc.bin
把該固件文件放到上面的目錄中
固件程序下載地址為:
http://服務器IP地址/ota/hardware/STM32Air302BK/user_crc.bin
3.假設記錄固件程序信息文件的名字為 info.txt
把該文件放到上面的目錄中
則文件下載地址為:
http://服務器IP地址/ota/hardware/STM32Air302BK/info.txt
4.修改 用戶程序 的 IAP.C 文件
1.修改固件程序版本(可隨意指定,我設置的為0.0.2)
2.修改產品型號(我設置的為STM32Air302BK)
3.修改記錄雲端固件信息文件下載地址(我的為:http://mnif.cn/ota/hardware/STM32Air302BK/info.txt)
5.修改BootLoader程序 的 IAP.c,設置下產品型號和默認的固件程序下載地址
6.編譯用戶程序
會在工程目錄的bin文件夾生成 user.bin文件
7.打開OTA Tools上位機軟件
提示:該軟件是修改bin文件加入校驗(使得升級穩定可靠)
8.按照紅框選擇配置
9.選擇用戶程序生成的 bin文件
10.點擊 生成固件
11.將在user.bin目錄生成user_crc.bin文件
12.把生成的user_crc.bin文件拷貝到服務器
13.還差一個info.txt文件
我准備了一個模板
14.修改版本號(和用戶程序里面設置的一樣)
15.修改固件程序大小(OTA Tools提示信息里面有這個大小)
16.修改固件程序下載地址(和服務器上面的保持一致)
17.最后的提示信息不需要更改,當前用不到
18.把info.txt文件也拷貝到服務器
然后按照一開始的測試步驟測試即可
程序通用說明
1.小總結
遠程升級單片機程序其實就是使用模組以TCP方式連接Web服務器,
然后給TCP服務器發數據,數據格式是GET指令.
服務器接收到指令以后會下發文件給模組,模組通過串口把數據發給單片機,
單片機接收到數據以后寫到flash,最后加載運行.
2.Flash分配
用戶可以根據自己的需求調整stmflash.h文件Flash分配大小
注意:BootLoader程序和用戶程序的stmflash.h文件要保證一樣.
注意:如果使用的芯片的Flash容量是 256及其以上的型號
假設使用的是 256的
因為容量是256的,所以flash是以2K為一頁.
首先FLASH_IAP_SIZE, FLASH_UPDATE_SIZE, FLASH_USERDATA_SIZE 保證是2的倍數
為保證程序運行區和程序備份區的地址是某一頁的開始地址
所以 LASH_IAP_SIZE + FLASH_UPDATE_SIZE + FLASH_USERDATA_SIZE 的和需要是4的倍數
3.user.bin 和 user_crc_bin的區別
每隔128字節增加CRC校驗位
改寫size,把真實的文件大小填寫到bin文件
用戶程序詳細說明
1.設置中斷向量偏移
地址其實就是用戶程序運行地址
2.軟件設置程序運行位置和占用flash大小
注:在下載完BootLoader程序以后,串口日志會打印這些信息,根據日志打印的設置即可
3.解析下info.txt下載地址(服務器上記錄固件信息的文件)
做這個程序是為省去用戶解析的繁瑣.
執行解析之后:
IAPStructValue.IP = mnif.cn;
IAPStructValue.Port = 80;
IAPStructValue.Path = /ota/hardware/STM32Air302BK/info.txt
4.處理更新(這個程序需要在認為用戶程序沒有問題的時候在用戶程序里面執行一下)
如果更新成功,BootLoader里面會把更新狀態置為 0xFF;用戶程序需要調用一下這個函數清零這個狀態.
如果用戶程序不清零這個狀態,重啟以后BootLoader檢查到0xFF會認為執行用戶程序失敗了.然后執行回滾.
5.控制模組獲取服務器上記錄固件信息的文件
6.解析info.txt文件內容
如果版本號不一樣,提取和存儲url和文件大小,然后設置升級標志,重啟.
BootLoader程序詳細說明
1.查看IAPInit函數
2.獲取存儲的固件文件大小,固件下載的url,並解析下url
3.如果有更新標志,則備份下用戶程序
4.如果沒有更新標志,則查看下更新狀態
如果狀態是更新有錯誤,則執行回滾,如果檢測到沒有備份的程序,就重新執行升級
5.如果更新狀態是0x01,就設置更新狀態為0xFF
7.控制模組連接TCP服務器(Web服務器)
8.發送get指令獲取程序文件
8.在串口中斷函數里面把固件數據寫入緩存
提示:模組返回網絡數據格式 +SKTRECV: {空格}{socked id},{數據個數}{冒號}{16進制表示的數據}{冒號}
假設返回"12"這個數據: +SKTRECV: {socked id},1"3132"
下面的NETRECV xxxxx 是為了做轉換
注: IAPHttpHead是為了去掉http 頭,找到數據的開始位置
9.主循環從緩存取數據,並寫入flash
10.校驗數據是把先前寫入的提取出來校驗,主要是為了保證更新的時候萬無一失
11.判斷接收完成
接收到相應的文件個數設置 IAPStructValue.ReadDataEndFlag = 1;//接收完成
則寫入0x01狀態,重啟.
如果有錯誤,則嘗試重新下載.
注:超過一段時間沒有接收到數據,也會設置IAPStructValue.ReadDataEndFlag = 1;//接收完成
12,程序里面有下載超時和整體運行超時檢測
下載超時:只有在確認開始寫入程序文件的時候才運行,每次寫入程序文件會清零.
主要解決接收一半程序便不再接收的問題
整體運行超時:該超時只要執行BootLoader程序便一直運行
客戶可以在IAP.h修改默認的超時時間
12.重啟以后如果檢測到狀態是0x01則寫入0xFF,執行用戶程序
如果檢測狀態是更新錯誤,則回滾程序,執行用戶程序.
細節說明
1.如果編譯用戶程序出現下面的警告
其實是這個地方導致的
為了便於BootLoader程序提取用戶程序bin文件里面的型號,把型號存儲在了偏移1024字節的位置.
為了便於上位機把bin文件大小寫到bin文件里面,還有便於BootLoader提取這個大小,也設置存儲在了偏移1024字節的位置.
設置的這個字符串存儲的位置影響到了芯片本身分配一些數組的位置.就會報上面的錯誤
用戶可以把偏移個數增加,便可沒有該警告
2.在前面的文章中說過一個事情:
凡是在BootLoader里面使用中斷,跳轉到用戶程序以后同樣有效
BootLoader里面使用了,滴答定時器中斷; 串口1,2接收中斷,空閑中斷; 看門狗.
在加載用戶程序之前清除了除了看門狗以外的所有中斷.
如果用戶在BootLoader里面使用了其它中斷,也需要在此處清除!!
如果用戶在BootLoader里面使用了其它中斷,也需要在此處清除!!
如果用戶在BootLoader里面使用了其它中斷,也需要在此處清除!!
3.恢復出廠設置
為了預防超級意外的情況導致程序完全崩潰,在上電之前按下一個按鈕,然后給板子上電.
用戶按下時間超過5S,用戶松開按鈕以后
設置更新標志,清空flash里面記錄的url地址,重啟設備.
設備重啟以后便會按照默認的地址下載程序
4.用戶按照自己的項目修改BootLoader程序注意事項
1.在發送完獲取程序文件指令以后,主循環不能帶有執行超過5ms的延時函數
延時函數的存在會影響提取緩存數據寫入flash的時間,從而導致緩存溢出,數據接收不完整.
2.如果用戶想在BootLoader運行的時候顯示更新狀態或者進度
可以在IAPInit() ;IAPGetProgramFile(); IAPWriteData();函數里面相應的位置增加提示
注意:IAPWriteData()函數里面不能加延時!!!!
3.如果要展示更新進度
文件大小(字節): IAPStructValue.FileSizeSave
當前接收(字節): IAPStructValue.FileSizeNow
3.如果用戶想只下載BootLoader之后讓BootLoader自己立即升級程序