固件在運行過程中通過外部方式將新的固件傳送給W800並寫入到flash中,在下次上電重啟時運行新的固件。外部方式可以是wifi的socket或者http,也可以是uart、spi、ble等,這些只是傳輸方式不同,最終都是調用驅動裡相同的接口來實現功能。
固件分兩個區域,一個是運行區,一個是OTA區域,升級時新的固件是寫入到OTA區域,在上電過程中,啟動程序會自動判斷是否有新的固件並搬運到運行區域執行新的固件,這個過程用戶不需要參與。用戶需要做的是通過某種方式接收固件並調用OTA驅動接口寫入到FLASH中。
升級的驅動是在sdk裡的wm_fwup.c和wm_fwup.h裡,主要是如下幾個接口。
u32 tls_fwup_enter(enum tls_fwup_image_src image_src);
初始化接口,參數image_src直接寫0就可以,實際並沒有用到該參數。裡面會做一些初始化的操作。返回值為session id,後續接口會用到該值,也是判斷是否是同一次升級的標志,後續接口裡會判斷該值,如果該值變了,就認為不是同一次升級了,會返回錯誤。
int tls_fwup_request_sync(u32 session_id, u8 *data, u32 data_len);
通過不同的方式收到的新的固件內容寫到flash裡,session_id就是初始化返回的值。data和data_len是收到的固件內容和長度,這裡是固件的內容,不包括自定義的傳輸協議的額外內容。長度沒有限制,驅動裡會自動判斷並寫入flash中。flash的地址也不需要關心,在生成固件時已經設置好了,所以接收到的固件內容裡已經包含了這些信息,並且驅動裡會自動解析。
u16 tls_fwup_current_state(u32 session_id);
判斷當前的操作狀態,每次調用寫入接口後可以再調用該接口判斷下狀態是否出錯。
int tls_fwup_exit(u32 session_id);
如果判斷到狀態錯誤,可以調用該接口退出升級。下次再重新初始化開始。
驅動裡會判斷接收到的數據長度是否達到了固件的總長度,如果達到了,就會做固件的整體CRC校驗來判斷是否接收或寫入出錯。判斷正確後會自動重啟。如果用戶不希望升級成功後自動重啟,可以在驅動裡把tls_sys_reset();這行注釋掉,在應用層選擇合適的時機來重啟使新固件生效。
根據《WM_W800_QFLASH布局說明》裡,OTA區域的起始地址默認是0x08010000,這裡不需要改動。
如果使用的是http方式升級,可以直接使用int t_http_fwup(char *url)接口來自動完成整個升級,如果是其他方式,則直接調用上面提到的接口來實現,不需要參照t_http_fwup的實現方式,因為裡面做了一些較複雜的操作,對其他接口不適用,反而複雜化了問題。