ESA2GJK1DH1K升級篇: STM32遠程乒乓升級,基於Wi-Fi模組AT指令TCP透傳方式,MQTT通訊控制升級(含有數據校驗)-APP用戶程式製作過程
- 2019 年 12 月 24 日
- 筆記
前言
這一節和上一節是搭配的
給大家魚,也必須給魚竿!
我期望自己封裝的程式碼,無論過了多少年都有應用的價值!
這節說明一下製作APP用戶程式的過程
咱是用MQTT通訊控制模組實現升級,所以首先自己的程式先實現MQTT哈.
協議
注:所有的實現MQTT的軟體,統稱為MQTT上位機 一,MQTT上位機通過MQTT發送獲取設備資訊指令 {"data":"updata","cmd":"DeviceInfo"} //設備接收到回復 {"data":"updata","model":"STM32_MQTT_AT8266_SUM","version":"1.0.2"}//假設現在的型號是 STM32_MQTT_AT8266_SUM,當前設備硬體版本是1.0.2 二,MQTT上位機根據型號使用http訪問雲端存放的記錄更新資訊的文件 "型號" 列如:上位機使用http訪問 http://47.92.31.46/hardware/STM32_MQTT_AT8266_SUM/updatainfo.txt 假設updatainfo.txt文件資訊是: {"version":"1.0.45611","SumBin1":219,"SumBin2":103,"details":"1,優化了部分BUG;2,測試升級;3,支援升級STM32程式;4,修改XXXBUG"} 注:版本號最大設置為20位元組 後面的 "details":"1,優化了部分BUG;2,測試升級;3,支援升級STM32程式;4,修改XXXBUG" MQTT上位機可作為升級提示資訊,提示給用戶 三,MQTT上位機對比版本號,如果不一致,則發送以下指令 {"data":"updata","cmd":"start"} 注:測試時可直接發送此指令 //設備接收到回復 {"data":"updata","status":"start"} 然後進入BootLoader程式執行升級去了 四,設備連接上MQTT發送的第一條消息為 "{"data":"status","status":"online","UpdataStatus":"UpdataSuccess","version":"1.0.45611"}" UpdateStatus_None //沒有更新 UpdateStatus_DataAddressError //Flash的高位地址不是0x08 或者 RAM的高位地址不是0x20 UpdateStatus_DataOverflow //數據接收溢出 UpdateStatus_DownloadTimeout //程式下載超時 UpdateStatus_MainTimeout //整個程式運行的時間 UpdateStatus_FlashWriteErr //Flash 寫錯誤 UpdateStatus_VersionLenErr //版本號長度錯誤 UpdateStatus_VersionAlike //版本號和伺服器上面的一致 UpdateStatus_FlashEraseErr //Flash 擦除失敗 UpdateStatus_MissingData //數據接收不完整 UpdateStatus_SumBinRangeErr //校驗和範圍錯誤(獲取的雲端的校驗和,不在0-255之間) UpdateStatus_SumCheckErr //校驗和不一致 UpdateStatus_RunAppError //上次更新的程式沒有運行起來 ---------------------------------------------------------------- 控制指令,查詢繼電器狀態 {"data":"switch","bit":"1","status":"-1"} 設備回復 {"data":"switch","bit":"1","status":"1"} 或者 {"data":"switch","bit":"1","status":"0"} 六,控制指令,控制繼電器吸合 {"data":"switch","bit":"1","status":"1"} 設備回復 {"data":"switch","bit":"1","status":"1"} 七,控制指令,控制繼電器斷開 {"data":"switch","bit":"1","status":"0"} 設備回復 {"data":"switch","bit":"1","status":"0"}把以下文件放到自己的工程
stmflash文件直接拷貝的上一節的
IAP和上一節的不一樣,做了很多裁剪.

主函數配置
1.包含下頭文件

2.調用一個函數 IAPGetUpdateInfo();//獲取更新的資訊

這個函數做的工作
獲取雲端版本: 這個是在BootLoader裡面升級的時候存進去的
獲取設備版本: 當前這個版本還是以前的程式版本,還沒切換呢,後面會說在哪裡切換的
獲取更新狀態: BootLoader裡面設置的那些更新狀態


大家可以在用戶程式裡面 通過 IAPStructValue.UpdateStatusValue的值來知道上次更新的狀態
為了更直觀,大家直接可以調用 printf("%s",IAPStructValue.UpdateStatusStr); 列印對應的字元串
也可以在認為程式沒有問題的時候,把這些狀態發給上位機,這樣就直觀的知道更新的狀態
處理更新(為什麼會有處理更新)
先說一下哈,處理更新是這個函數
IAPUpdateDispose();
這個函數主要就是清零更新狀態,然後如果判斷運行的是新程式,則切換程式版本.

然後說一下上面函數的妙處
如果在BootLoader裡面程式文件下載成功

BootLoader下載好程式以後呢,寫入狀態為:0x01 然後重啟了
重啟以後當然還是先運行 BootLoader
然後 BootLoader 判斷是0x01以後 寫入 0xFF
然後運行新的用戶程式
假設用戶程式有問題 沒有執行函數 IAPUpdateDispose();
那麼就沒有把升級狀態清零
那麼單片機重啟以後又運行 BootLoader,此時BootLoader裡面一判斷還是0xFF
便會認為沒有正確執行用戶程式,就會切換上一份用戶程式執行
然後總的來說就一句話:
你認為APP用戶程式運行沒有問題了以後再調用 IAPUpdateDispose();
這節建議這樣處理
在連接上MQTT以後,咱調用下 IAPUpdateDispose();
然後把升級狀態通過MQTT發出去

/** * @brief 連接上MQTT以後發送一條上線指令 * @param * @param * @retval * @example **/ void FunctionSendOnline(void) { IAPUpdateDispose(); //如果不使用自定義的配置 #ifndef UserCustomConfig //device/Wi-Fi的MAC memset(MQTTPublishTopic,NULL,sizeof(MQTTPublishTopic)); sprintf(MQTTPublishTopic,"%s%s","device/",&MQTTid[0]);//組合發布的主題 #endif MqttPublishTopicStruct.topicName.cstring = MQTTPublishTopic;//設置發布的主題 MqttPublishTopicStruct.qos = 1; //消息等級 MqttPublishTopicStruct.retained = 1; //需要伺服器保留消息 //連接上MQTT以後發送一條上線資訊,攜帶著更新狀態,當前設備版本 MainLen= sprintf(MainBuffer,"{"data":"status","status":"online","UpdataStatus":"%s","version":"%s"}", IAPStructValue.UpdateStatusStr,//更新的狀態 IAPStructValue.VersionDevice //當前設備版本 );//組合發送的數據 MainLen = MqttPublish(MqttPublishTopicStruct,MainBuffer,MainLen);//打包MQTT數據 UsartOutStr(MqttSendData,MainLen);//發送MQTT協議數據 MqttPublishTopicStruct.retained = 0; //後期的數據不需要伺服器保留消息 }加上處理更新協議

如果通過MQTT接收到獲取設備資訊指令
就返回設備資訊(型號,和當前版本號)
MQTT上位機根據型號,http訪問對應的 updatainfo.txt
然後對比下版本號,如果不一致,就提示給用戶有新版本
然後用戶點擊升級的時候 再發給模組 開始更新的指令
模組收到以後設置更新標誌
返回給MQTT 我要升級了 "{"data":"updata","status":"start"}" 嘻嘻嘻
然後呢 重啟就好了
因為有了升級標誌,BootLoader裡面就去執行升級去了
先查看一下用戶程式的bin文件大小

咱上一節BootLoader裡面設置的
0x5C00 = 23KB 設置的可以滿足

配置生成第一份程式文件



配置生成第二份程式文件



打開計算校驗和軟體


計算第一份程式文件的校驗和

計算第二份程式文件的校驗和

把相應的文件放到雲伺服器



測試放到下一節
…

