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   設置的可以滿足

配置生成第一份程式文件

配置生成第二份程式文件

打開計算校驗和軟體

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

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

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

測試放到下一節

…

Tags: