基於 HTTP的遠程配置和固件更新

(已在《無線電》雜誌第10期刊登)

對於HTTP的思考

你也許會問,既然通過一個上位機程序可以完成這個任務,為什麼還要通過瀏覽器實現呢?其實這兩個方法各有優缺點,用上位機程序,用戶可以自己定製協議,但是用戶不僅需要安裝該上位機程序,而且還要考慮面對不同的操作系統下的兼容情況。然而通過網頁更新的話,只需要設備內嵌一個HTTP服務器,便省去了編寫上位機程序的負擔,並無須考慮去兼容不同的操作系統。當然,上位機程序可以實現UDP廣播尋址終端,無需知道終端IP地址即可找到同一網段下的多個終端。而使用網頁的話就只能是預先知道終端IP地址並逐一配置。

其實,對於通過網頁配置相信大家並不陌生,家裡有無線路由器的朋友估計都有實踐經驗。通過瀏覽器鍵入路由器的默認IP,然後根據網頁提示就可以一步步地實現設備信息配置,諸如WiFi密碼、SSID等。今天,我們就是來探究一下這個應用的原理,在單片機里實現一個HTTP服務器,通過這個HTTP服務器來配置設備信息,並實現了設備固件更新。

當然,我這裡的這個HTTP服務器沒有家裡的路由器那樣的功能強大,在這裡也只是拋磚引玉,希望大家能夠從中獲取啟發,設計出更出色的產品。方便起見,我們仍舊延續上一篇文章的平台——基於Cortex-M3的W5200評估板(STM32F108C8 + W5200)。

 http1

圖1 W5200評估板

該評估板單片機的系統資源:64KB的閃存和20KB的SRAM。

(W5200可以和任何單片機配合使用,如果用戶想使用其他單片機+W5200來實現的話,需要您自行修改代碼,這裡暫不提供其他庫。)

 

功能演示

在我們展開談論基於HTTP的遠程配置和固件更新的原理之前,先給大家看一下我們這個程序小樣的功能演示。感興趣的朋友可以在接下來的文章中,了解到具體該功能是如何實現的。

步驟1

用ISP工具燒錄Boot(評估板SW2 調至PROP),不了解的話,可以參考我們上一個主題內容。

 http2

圖2用FlashLoader燒錄boot.bin

步驟2

將評估板上SW2 調到RUN模式,打開ConfigTool。點擊按鈕http3,可查找到當前設備,並可通過按鈕http4,將app.bin程序上傳至評估板中,右側可看到當前設備的IP地址及版本號等信息,此時版本號為1.0,如圖:

http5

圖3配置工具燒錄app.bin成功

ConfigTool這裡的工作也很簡單,就是在第一次Boot啟動時,把App傳給單片機。當App運行時,ConfigTool就無用武之地了,因為用瀏覽器就可以完成ConfigTool的工作了。

(註:以上途徑並不是必須的,僅為了方便演示,保證boot和app程序已經燒錄好即可。)

步驟3

在瀏覽器中輸入W5200評估板的IP地址,回車後出現Web界面。

如圖可看到,界面分為Device Settings和Firmware Updating兩部分,其中Device Settings中依次列出W5200評估板的硬件版本號、MAC地址、IP地址、子網掩碼以及默認網關基本配置。

用戶可以配置其他IP地址,子網掩碼及網關,並點擊’Save settings and Reboot’,設置並重啟生效;

http6

圖4 Web配置界面

如:

在WEB界面上,將IP地址192.168.1.2改為192.168.1.20。更改後保存,等待後更改成功:

http7

圖5更改IP成功

步驟4

下面針對固件更新,點擊“瀏覽”按鈕,選擇好要更新文件。http8;選好後開始上傳,出現以下界面,更新過程需要6s.http9

圖6等待升級完成

更新完成,可以看到新成功,版本號更改為5.0,IP地址以及界面顏色都進行了更新,如下圖:

 http10

圖7升級成功

是不是很簡單?馬上動手,也給你的設備加入一個HTTP服務器,實現遠程配置升級功能吧。當然,配置和升級只是應用的一小部分,你也完全可以通過模擬/數字輸入接入幾個傳感器,比如溫度、濕度和PM2.5,這樣打開瀏覽器就可以監視這些傳感器數據了。

這個小樣只是一個簡單的功能及原理演示,下面就讓我們來看一下這個基於 HTTP的遠程配置和固件更新實現的思路及原理。

應用原理

1.        方框圖

http11

圖8 HTTP遠程更新固件框圖

每次重啟,均從首地址開始執行程序:

1啟動進入BOOT區,若BOOT檢測APP區的不為空,則跳轉到APP區的首地址執行主程序;

2瀏覽器訪問APP區的網頁服務器

  • 配置網絡參數:即將瀏覽器中鍵入的參數通過APP更新到Configure Information區
  • 遠程更新固件:即進入到以下步驟3

3瀏覽器訪問APP主程序的網頁服務器,並通過瀏覽器將即將更新的APP寫入到Backup區;

4當APP檢測到Backup區域已經有新的APP程序後,跳轉到BOOT區,執行更新操作;

5BOOT將APP區擦除,並將新APP從Backup區寫入到APP區;

重啟,重新執行程序。

2.        內存圖

http12

圖9 W5200評估板內存空間分配

 

在我們要演示的程序中,將MCU閃存劃分成了四個區:

http133.        各分區的主要功能

了解了空間分配之後,我們再來看一下我們這個演示中各部分的主要功能:

  1. BOOT區:
  • 清空APP區,為新APP寫入做準備;
  • 把暫存在Backup區的新版本程序拷貝到APP區;
  • 與上位機程序通信,獲取App;

備註:其實,這裡Boot不必具備這個功能,只是我們編譯完兩個固件後,不想合併兩個二進制文件,然後再通過ISP工具燒錄,所以偷個懶,沿用了上次的上位機程序。

  1. APP區

APP區是應用程序運行區域,實現了HTTP服務器,並集成了一個簡單的網頁。

  • 配置網絡參數;
  • 在線固件升級;

上電啟動後,進入Boot區,若判斷上層APP區的狀態量成功,則直接從Boot區跳轉到APP區,運行主程序。

備註:想修改網頁的話,可以參考webpage.h,所有的HTML代碼都在這個頭文件裡面。

  1. Backup區
  • 接收並備份需要更新的新App

備註:由於Backup區的大小為23K,所以意味着APP的大小最大為23KAPP區為24K,其實有1K是無數據存放的;

  1. Configure Information區
  • 存放IP地址,MAC地址,子網掩碼等網絡參數,以供App調用;
  • App可以再寫入,更新該區域存放的網絡配置參數;

程序開發

我們將App程序主要分為5個文件:

main.c實現HTTP固件更新的主流程;

httputil.c文件用於實現HTTP協議響應報文的發送;

httpd.c文件用於實現對HTTP請求報文的解析;

device.c文件用於實現W5200的初始化及單片機的基本配置;

webpage.h文件定義web界面的html語言。

這裡我們重點介紹一下http()函數:

http()函數實現了Web服務器接受請求和回復響應的全過程,由於Web服務器在和瀏覽器通信時使用TCP協議工作,根據SOCK_HTTP之間狀態的不同,執行不同的操作。

http14

圖10 HTTP服務器通信過程示意圖

HTTP服務器的通信過程大致分為三步:

  1. 連接:W5200分配socket到HTTP服務器,打開socket並監聽。
  2. 通信:連接建立了。W5200在接收到來自客戶端的HTTP請求後發送HTTP應答。
  3. 關閉:HTTP 請求/應答完成後關閉連接。

 

voiddo_http(void)

{

uint8 ch=SOCK_HTTP;                      //定義HTTP通信的socket端口變量

uint16len;

st_http_request *http_request;

memset(rx_buf,0x00,MAX_URI_SIZE);

http_request = (st_http_request*)rx_buf;       // 定義HTTP請求報文的結構指針

/* HTTP Server 狀態之間的轉換 */

switch(getSn_SR(ch))

{

case SOCK_INIT:                         //socket 初始化狀態

listen(ch);                            //Web服務器監聽

break;

case SOCK_LISTEN:                      //socket監聽狀態

break;

case SOCK_ESTABLISHED:                //socket建立連接成功

if(getSn_IR(ch) &Sn_IR_CON)

{

setSn_IR(ch, Sn_IR_CON);           //Sn_IR的第0位置1

}

if ((len = getSn_RX_RSR(ch)) > 0)

{

len = recv(ch, (uint8*)http_request, len);   //接收客戶端的請求並存入http_request中

*(((uint8*)http_request)+len) = 0;

proc_http(ch, (uint8*)http_request);     //解析HTTP請求,並發送HTTP Response

disconnect(ch);                      //斷開TCP連接

}

break;

case SOCK_CLOSE_WAIT:                  //socket等待關閉狀態

if ((len = getSn_RX_RSR(ch)) > 0)

{

//printf(“close wait: %d\r\n”,len);

len = recv(ch, (uint8*)http_request, len);

*(((uint8*)http_request)+len) = 0;

proc_http(ch, (uint8*)http_request);   // 解析HTTP請求,並發送HTTP Response

}

disconnect(ch);                      // 斷開TCP連接

break;

case SOCK_CLOSED:                    // socket 關閉狀態

socket(ch, Sn_MR_TCP, 80, 0x00);       //初始化socket端口

break;

default:

break;

}

}

完整的程序代碼請於以下地址下載:

http://pan.baidu.com/share/link?shareid=1808179627&uk=1930353891

 

後記

以上我們介紹了基於 HTTP的遠程配置和固件更新的相關原理及思路。細心的朋友可能會發現,我們這裡的網頁是和APP程序放在一起的,均在APP區。也就是意味着,我們通過網頁更新APP程序,其實也同時把網頁本身更新了(參見更新前後網頁背景顏色變化)。我們這樣做的目的是方便以後用戶對於網頁架構等內容重新編輯時使用的,這樣用戶不僅可以更新APP,也可更新網頁。當然,如果我們的網頁已經是確定不變的話,可以將MCU的內存再單獨分離出一塊作為網頁存貯區(形如‘Configure Information區’一般),這樣用戶就無需每次更新大量數據,只需針對性的更新APP即可。這個也是我們為讀者留下的一個課題,供感興趣的讀者業餘動手實踐一下。

作者:Katrina,Jerry,Cillian 

 

感謝閱讀!

更多信息請關注WIZnet官方微博:

http://weibo.com/wiznet2012