作為支援遠端連接互聯網的物聯網設備,本地或遠端OTA升級也是腳本編程控制器的重要功能,因為不能保證繼電器完全沒有Bug,在利用bug,如果沒有OTA升級接口,很難讓客戶透過串口升級固件,控制器只能回廠升級,成本高,影響大。
此外,客戶可能有一些個人化功能無法透過中文程式設計實現,需要升級控制器韌體才能實現。
這兩種情況需要透過本地或遠端OTA功能來解決。
這幾天花了一點時間完成這個功能,現總結如下:
(1) ESP8266 的 FLASH 可以儲存兩個韌體,名稱分別為 user1.bin 到 user2.bin,兩個韌體的位址由位址 0x0000 處儲存的引導程式 boot.bin 決定,且儲存位址不同不同的閃光燈容量。
例如,Flash 容量為 1Mbyte 的 ESP8266-01S,儲存位址分別為 0x01000 和 0x81000,FLASH 容量為 4Mbyte 的 ESP8266-07S,儲存位址分別為 0x01000 和 0x10100000。
(2)透過函數system_upgrade_userbin_check的回傳值取得目前程式正在執行的user1.bin或user2.bin,進行韌體升級,到另一個韌體儲存區寫入完整的韌體,例如如果目前執行的是儲存的在user1.bin的0x1000處,然後到位址0x81000(ESP8266-01S)或0x101000(EPS8266-07S)寫入韌體user2.bin,寫入完畢後,再透過函數system_upgrade_flag_set(0x02)通知SDK 設定係統參數,以便ESP8266 啟動時引導到另一個韌體。
3)官方推薦的做法是透過http協定將韌體下載到雲端伺服器到記憶體中,我沒有使用這個方案,主要是出於兩個考慮,一是這個方案是否經過嚴格驗證,以及是否有充分考慮數據驗證以避免升級到磚塊,我對此表示懷疑。其次,這個程式要求控制器能夠連接到外部網絡,從伺服器下載固件,這並不容易做到。
我目前正在使用delphi開發一套韌體升級軟體,該軟體作為TCP客戶端直接連接到控制器,或連接到雲端伺服器的TCP網關然後傳輸到控制器,然後根據一幀資料512 位元組,用於將韌體推送到控制器。
接下來可以將這套邏輯移植到伺服器上,客戶可以透過瀏覽器開啟網頁將韌體推送到控制器。
4)資料的完整性得到充分驗證,第一幀資料做crc32校驗,韌體寫入flash然後讀出與寫入的值進行比較,同時計算出值的crc32,與上位機發送的crc32的值相比,讀寫資料是相同的,crc的值也相同,則認為該幀資料寫入成功;
同時對每一幀資料的crc32值再進一步做crc32值,得到總的crc32值,與上位機發送的總crc32值進行比較,該值與呼叫函數system_upgrade_flag_set之前的值相同( 0x02) 以允許SDK 切換到啟動韌體。
(5)寫入兩個不同韌體區的韌體user1.bin、user2.bin不一樣,對於RTOS sdk開發,需要修改Makefile變數APP的值產生user1.bin、user2 .bin,分別是上位機根據控制器傳回的目前運作的韌體儲存區域,選擇另一個儲存區域的韌體傳送給控制器。上位機根據控制器所傳回的目前運作韌體的儲存區域,選擇另一個儲存區域的韌體。
如果兩個儲存區域使用相同的韌體,ESP8266 將無法正常啟動。
以上是如何實現ESPith SDK x(腳本可編程控制器)的OTA功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!