1. 程式人生 > >STM32F103程式碼遠端升級(六)基於小米IoT開發者平臺遠端升級程式碼的實現

STM32F103程式碼遠端升級(六)基於小米IoT開發者平臺遠端升級程式碼的實現

目錄

一、準備工作

二、熟悉選用的WiFi模組

三、雲端升級韌體過程

第一步:進入後臺管理

第二步:上傳韌體

第三步:開始升級程式

四、程式的具體實現過程

情況一:只有Bootloader程式的板子實現升級過程

情況二:在韌體應用程式裡面實現升級過程

五、應用程式燒寫損壞的處理

最後的話


在實現且熟悉運用了前面幾種遠端升級的方法之後,最後專案選擇了在小米IoT平臺上開發,直接通過米家APP雲端升級韌體程式~~~

那麼本篇文章就主要記錄一下我在使用小米IoT平臺和米家APP直接實現STM32F103程式碼更新的過程(此次只更改了WiFi模組,主控不變)。


一、準備工作

註冊小米賬號——>成為平臺的開發者——>建立產品(即在小米平臺上新增相關硬體),具體可見小米IoT平臺簡介


二、熟悉選用的WiFi模組

此次採用的WiFi模組是——ESP-WROOM-02D 小米研發的智慧模組中的WiFi-Fi單模。(小米智慧模組是由小米研發的、為裝置提供Wi-Fi或藍芽連線能力的晶片模組。當前有Wi-Fi單模模組、Wi-Fi藍芽雙模模組、藍芽單模模組)

ESP-WROOM-02 模組是基於 ESP8266EX 晶片設計開發的物聯網無線模組。它集成了 TCP/IP 網路協議棧,32 位低功耗 MCU,10 位元精度 ADC,並帶有 HSPI、UART、PWM、I2C 和 I2S 等介面,並且可以在低功耗連線模式下工作。

小米智慧模組中的MIIO晶片提供一套可讀的串列埠文字命令,供外部晶片呼叫,一般適用於MIIO模組不是主控晶片的情況,即 MIIO晶片只負責網路通訊,而不關心業務邏輯

通過閱讀小米IoT 開發平臺的——>開發引導 可知傳送給WiFi模組的每一條串列埠命令都要以“\r”為結束標識,並且我們傳送的每一條命令WiFi模組都會給我們返回相應的結果或錯誤提示,具體的串列埠指令可以看小米IoT平臺的開發手冊WiFi模組的串列埠命令手冊


三、雲端升級韌體過程

第一步:進入後臺管理

在上述的準備工作做好了之後,進入小米 開發平臺 

我們能看見已經新增好的硬體,選擇 開發 進入小米開發的後臺管理,如圖一所示。

圖一

第二步:上傳韌體

通過 韌體管理 這裡就可以上傳我們的韌體同時配置相關功能函式(關聯功能到韌體),這裡的韌體指的是我們的主應用程式,注意和Bootloader區分開來。

這裡需要注意的是,上傳的韌體首先需要 尾部新增CRC 後再上傳,可以直接使用小米提供的工具自行新增(甚至可以整合到編譯腳本里面)。同時上傳的韌體版本,版本號要遵循小米平臺規定的保持在四位數,我們可以選擇從 0001 開始逐個遞增,上傳成功之後還需要將韌體版本設定為 白名單測試 顯示狀態為測試中,如圖二所示,這樣作為白名單上開發人員的你才能使用。

圖二

第三步:開始升級程式

在首次升級程式且擴充套件程式還未開發出來的時候(這裡所說的擴充套件程式是我們將我們的硬體新增到米家APP上之後需要上傳的屬於我們裝置的應用程式,從而來完成對我們的裝置功能控制)完成了第二步的上傳韌體之後,我們通過上圖一中的 功能除錯 進入線上除錯介面,前提是你已經在你的手機上的米家APP中添加了你的裝置,並且裝置已經連線上了網路,如圖三所示,只有連線上了網路的裝置才會出現除錯字樣,否則就會顯示為離線狀態。

圖三

進入除錯之後,我們需要測試OTA指令的可行性。即我們在下方的傳送指令部分,選擇 miio(公共功能) ,選擇 milO.ota測試方法,選擇相應指令,然後將第二步上傳的韌體的連結複製到指令中的 mcu_url 處,這裡的下載連結直接通過如圖二上傳好了的韌體中的 檢視詳情 處獲取。最後我們傳送指令,當收到返回結果為 ok 便表示傳送成功。

這時我們通過米家APP的 我的——>設定——>檢查更新 便可以看到我們剛上傳的相應的韌體,點選更新,當顯示更新完成即表示我們的韌體更新完畢。當完成了相應的軟體擴充套件程式之後我們也可以直接選擇在我們自己的擴充套件程式裡更新韌體。

在後續的使用中,上傳了韌體之後一般不用再通過傳送 milO.ota 指令來手動向米家APP上傳我們的韌體,一般在上傳完成之後的5~10分鐘進入米家APP就能檢查出剛上傳的新版本。

另外,小米平臺提供的這個線上除錯功能還可以在我們的擴充套件程式未開發完成時,下位機直接通過線上除錯模擬上位機給我們傳送指令,例如我們可以定義好一個開機的自定義功能,然後通過平臺除錯這裡向WiFi模組傳送開機指令,WiFi模組收到指令之後再傳回給MCU,從而MCU進行相關操作。

當然要完成上述的雲端更新韌體最重要的還是在於我們的Bootloader的實現上。


四、程式的具體實現過程

小米IoT開發者平臺上的MCU OTA協議有將升級的流程和相關注意事項一一列出,從它的使用手冊上我們可以知道它用的檔案傳輸協議是Xmodem,所以要實現符合小米平臺的Bootloader程式只需要將之前已經實現過的基於Xmodem遠端升級的Bootloader程式通訊部分改為小米智慧WiFi模組通訊的操作命令即可。這裡我考慮了兩種情況。

情況一:只有Bootloader程式的板子實現升級過程

對於還未有應用程式的板子來說,我採用的方法是,在bootloader中上傳WiFi部分的模板號和韌體版本號,即相當於初始化WiFi模組(注意:小米WiFi模組在使用前必須通過這兩步進行相關初始化)。

串列埠傳送:model xxxxxx\r            收到ok  表示模板號初始化成功

串列埠傳送:mcu_version 0000\r    收到ok  表示韌體版本號初始化成功

注意:傳送給WiFi模組的每一條串列埠命令都要以\r為結束標識

在WiFi模組初始化完成之後,我通過不停的使用“get_down”命令獲取從雲端下發的指令(小米平臺推薦 get_down 指令迴圈週期為200ms),在bootloader裡面我只對接受到的 update_fw 指令進行了相關應答,即當串列埠收到 down update_fw,立即向串列埠回覆 result "ready" 。注意雲端傳送下發的指令只給了我們下位機1S的處理時間,所以在下位機已經做好升級的準備的時候需要立即回覆。在上傳了result "ready" 之後串列埠正常情況下會收到返回的ok,收到ok之後我們就可以直接呼叫之前實現的Xmodem接收函式進行檔案接收即可。

在這裡實現的Bootloader中,我採取了先將收到的韌體程式片段寫入Flash的備份區,待檔案接收完畢之後再寫入預定的應用區,這樣可以避免升級過程中,出現中途斷電或斷網而直接導致應用區程式寫入失敗。

情況二:在韌體應用程式裡面實現升級過程

首先我選用了兩個不同的地址作為儲存新舊韌體版本的地址,在應用程式開始執行時,就將Flash區的新舊韌體版本號統一寫成當前韌體版本號,並且初始化WiFi模組(即向雲端傳送當前WiF的模板號以及韌體版本號)。

然後以200ms為週期迴圈向雲端傳送get_down指令,獲取到down update_fw指令之後,立即向雲端回覆result "ready",然後將Flash中的新版本號+1,再重啟進入Bootloader程式中。

在Bootloader程式中實現了執行開始就檢查Flash中新舊韌體版本號是否一致,若不一致,則開啟Xmodem接收進行韌體升級。


五、應用程式燒寫損壞的處理

在實際使用的過程中,有可能會出現升級燒寫應用程式燒寫到部分的情況下就斷電,從而導致應用程式燒寫損壞。而採用先寫入備份區的方法只能解決在斷網的情況下燒寫應用區程式能夠正常進行。

這裡我通過仔細反覆閱讀小米開發者平臺上的開發引導中的串列埠OTA MCU協議找到了小米平臺提供的一種,當應用程式燒寫失敗之後可以通過下位機向雲端發起指令update_me來主動請求升級。

但是目前通過我的測試,向雲端發起了update_me之後,雲端返回的結果是todo,並不是ok/error。同時,雲端也並沒有在接收到這句指令之後向我發起update_fw指令。

所以,目前我採用的方法是,當應用程式燒寫損壞,程式將會跳轉到硬故障異常函式中執行(即HardFault_Handler函式),在這個函式裡我將Flash中寫入的新舊韌體版本號都歸0且將應用程式區域程式碼擦除,恢復到沒有應用程式的情況,再重新更新韌體即可。

最後的話

本篇部落格都是我在實際專案開發中的過程,若是文章中有寫錯的地方,歡迎各位指出,收到訊息核查之後便會及時更改。最後關於update_me這條指令的使用之處可能存在錯誤的理解,歡迎廣大網友指點。