RT_thread 使用4G模塊Air720H對STM32進行OTA遠程無線升級

    接上一篇博文,使用了在線升級的STM32程序的方法。此篇博文將利用4G模塊Air720H,使用AT指令集,通過HTTP協議從雲端服務器下載新版固件,從而實現對STM32的遠程無線程序升級。

   前面關於前期準備工作,在此不再累述 具體可以參考上一篇博文https://blog.csdn.net/ylzmm/article/details/104234099,關於簡易的HTTP服務器的搭建參考這篇博文https://blog.csdn.net/ylzmm/article/details/104311190

   本文在 RT_thread給出的HTTP升級的案例(具體參考https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/中的源碼實現部分),進行了部分修改。修改了爲AT指令的方式獲取固件。以下是整體的升級思路和在使用AT指令獲取固件時需要注意的事項。

  1.AT指令獲取固件 (未提供完整AT指令步驟,重點步驟提出)

發送:AT+HTTPACTION=0
應答:

OK

+HTTPACTION: 0,200,92240    /*200爲正常的服務器返回狀態 92240爲固件大小*/



發送:AT+HTTPREAD=0,100    /*0表示獲取固件從固件頭開始,100表示獲取前100個字節*/
應答:                     /*100,100 表示獲取從固件的100字節開始,後面100個字節*/

+HTTPREAD: 100            /*本次獲取的固件大小100*/
RBLk??^app2.0.000010203040506070809`?荱{qa苧餲噗?%2?  /*實際固件數據*/
OK

   通過AT指令依次循環獲取固件數據,獲取一批固件數據,寫入FLASH,以此循環。   

  2.固件數據的接收與寫入處理

   但是我在調試的過程中遇到了一個很奇特的問題。在升級固件時偶爾會出現升級失敗的現象,提示固件的CRC校驗錯誤,明顯是固件數據出現了遺漏。開始的時候我一直覺得是HTTP通信的問題,通信上下載固件數據偶爾出現了掉數據,後面實際中測試發現某次固件升級不成功,他會一直不成功,無論你重複下載多少次。由此排除了通信遺漏數據問題。之前我遇到的問題可以參考論壇中這一篇https://www.rt-thread.org/qa/thread-423550-1-1.html

  採用論壇中網友的答覆的方法,從而解決了這個問題。

  確實。我進行AT指令的應答處理中,我遺漏了一個很嚴重的問題。固件數據是一堆16進制的數據,如果我以讀取到OK,或者\r\n

這樣的判斷方式來進行判斷本次接收固件數據完畢,很容易出現誤判,固件數據可能存在干擾。

   最後採用了以下方式成功做到了100%升級:

 /*僅僅發送 應答數據在URC函數中處理*/
 if (at_exec_cmd(NULL,"AT+HTTPREAD=%d,4096",len_fir) != RT_EOK)
 {
     LOG_E("AT+HTTPACTION=%d,4096, send commands failed , response error or timeout 
             !",len_fir);
     goto __exit;
 }
 /*發送郵件 下載的字節數*/
 rt_mb_send(&http_mb, (rt_uint32_t)4096);   
		 
 /* 等待http數據傳回 信號量 */
 result = rt_sem_take(http_dysem, HTTP_OTA_OUTTIME);

AT指令只是發生下載的固件的指令,不進行返回值的判斷處理。一直等待一個信號量。

/*HTTP固件信息數據處理*/
static void urc_http_func(struct at_client *client ,const char *data, rt_size_t size)
{
	  char *recv_buf = RT_NULL;
	  int  number = 0;
	  recv_buf = (char *)rt_calloc(1, 4096);
	  
	  if (rt_mb_recv(&http_mb, (rt_ubase_t *)&number, RT_WAITING_FOREVER) == RT_EOK)
	  {
	      at_client_obj_recv(client,recv_buf,number,number);  
//	      /*打印接收部分數據*/
//		  ulog_hexdump(LOG_TAG, 16, (rt_uint8_t *)recv_buf, number);
	      rt_memset(firmware_http,0,sizeof(firmware_http));
	      rt_memcpy(firmware_http,recv_buf,number);
          rt_sem_release(http_dysem);
      }
	  rt_free(recv_buf);
}


static struct at_urc urc_firmware[]= {
		{"+HTTPREAD:",   "\r\n",     urc_http_func},
};

通過註冊URC回調函數,當接收到“+HTTPREAD:”數據時,表明了正在進入了固件下載時。於是在URC回調函數中進行接收指定的固件數的大小的數據字節即可。

更加具體的代碼實現,可以去參考RT的底層上關於TCP接收服務器下發的數據的處理方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章