1. gzyueqian
      13352868059
      首頁 > 新聞中心 > > 正文

      源碼公開的TCP/IP協議棧在遠程監測中的應用

      更新時間: 2005-12-01 00:00:00來源: 粵嵌教育瀏覽量:3929

      目前,隨著互聯網的發展,越來越多的工業測控設備已經將網絡接入功能作為其默認配置,以實現設備的遠程監控和信息分布式處理。筆者曾參與某發電機射頻監測儀的開發,該設備主要用于診斷和預警發電機早期故障,并通過RS232接口定時輸出電平和狀態數據,現場專門設一臺PC作接收、顯示及存儲。每年都要有專家到各發電廠對以往數據作檢查和診斷,不勝其煩。因此有必要設計一個RS232到Internet的數據傳輸模塊,以便對發電機的運行狀況作遠程監測。設計該模塊的關鍵在于如何實現一個嵌入式TCP/IP協議棧,根據以往的經驗,自己設計一個協議棧的難度很可能超過應用本身,而采用商業的協議棧似乎又無必要(功能過于復雜),筆者選用一種功能簡易的免費TCP/IP協議棧uIP 0.9作為設計核心。

      1 嵌入式TCP/IP協議棧

      目前,市場上幾乎所有的嵌入式TCP/IP協議棧都是根據BSD版的TCP/IP協議棧改寫的。在商業嵌入式TCP/IP協議棧大都相當昂貴的情況下,很多人轉而使用一些源代碼公開的免費協議棧,并加以改造應用。目前較為的免費協議棧有:

      lwIP(Light weight TCP/IP Stack)——支持的協議比較完整,一般需要多任務環境支持,代碼占用ROM>40KB,不適合8位機系統,沒有完整的應用文檔;

      uC/IP(TCP/IP stack for uC/OS)—基于uC/OS的任務管理,接口較復雜,沒有說明文檔。

      筆者采用的協議棧系瑞典計算機科學研究所Adam Dunkels開發的uIP0.9。其功能特性總結如下:

      *完整的說明文檔和公開的源代碼(全部用C語言編寫,并附有詳細注釋);

      *極少的代碼占用量和RAM資源要求,尤其適用于8/16位單片機(見表1);

      *高度可配置性,以適應不同資源條件和應用場合;

      *支持ARP、IP、ICMP、TCP、UDP(可選)等必要的功能特性;

      *支持多個主動連接和被動連接并發,支持連接的動態分配和釋放;

      *簡易的應用層接口和設備驅動層接口;

      *完善的示例程序和應用協議實現范例。

      表1 uIP在ATMEL AVR上代碼和RAM占用情況

      協議模塊 代碼大小/B 使用的RAM/B 
      ARP 1324 118 
      IP/ICMP/TCP 3304 360 
      HTTP 994 110 
      校驗和函數 636 0 
      數據包緩存 0 400 
      總和 6258 988 

      注:配置為1個TCP聽端口,10個連接,10個ARP表項,400字節數據包緩存。

      正是由于uIP所具有的顯著特點,自從0.6版本以來就被移植到多種處理器上,包括MSP430、AVR和Z80等。筆者使用的uIP0.9是2003年11月發布的版本。目前,筆者已將它成功移植到MCS-51上了。

      2 uIP0.9的體系結構

      uIP0.9是一個適用于8/16位機上的小型嵌入式TCP/IP協議棧,簡單易用,資源占用少是它的設計特點。它去掉了許多全功能協議棧中不常用的功能,而保留網絡通信所必要的協議機制。其設計重點放在IP、ICMP和TCP協議的實現上,將這三個模塊合為一個有機的整體,而將UDP和ARP協議實現作為可選模塊。UIP0.9的體系結構如圖1所示。

      UIP0.9處于網絡通信的中間層,其上層協議在這里被稱之為應用程序,而下層硬件或固件被稱之為網絡設備驅動。顯然,uIP0.9并不是僅僅針對以太網設計的,以具有媒體無關性。

      為了節省資源占用,簡化應用接口,uIP0.9在內部實現上作了特殊的處理。

      ①注意各模塊的融合,減少處理函數的個數和調用次數,提高代碼復用率,以減少ROM占用。

      ②基于單一全局數組的收發數據緩沖區,不支持內存動態分配,由應用負責處理收發的數據。

      ③基于事件驅動的應用程序接口,各并發連接采用輪循處理,僅當網絡事件發生時,由uIP內核喚起應用程序處理。這樣,uIP用戶只須關注特定應用就可以了。傳統的TCP/IP實現一般要基于多任務處理環境,而大多數8位機系統不具備這個條件。

      ④應用程序主動參與部分協議棧功能的實現(如TCP的重發機制,數據包分段和流量控制),由uIP內核設置重發事件,應用程序重新生成數據提交發送,免去了大量內部緩存的占用。基于事件驅動的應用接口使得這些實現較為簡單。

      3 uIP的設備驅動程序接口

      uIP內核中有兩個函數直接需要底層設備驅動程序的支持。

      一是uip_input()。當設置驅動程序從網絡層收到的一個數據包時要調用這個函數,設備驅動程序必須事先將數據包存入到uip_buf[]中,包長放到uip_len,然后交由uip_input()處理。當函數返回時,如果uip_len不為0,則表明有帶外數據(如SYN,ACK等)要發送。當需要ARP支持時,還需要考慮更新ARP表示或發出ARP請求和回應,示例如下:

      #define BUF((struct uip_eth_hdr*)&uip_buf[0])

      uip_len=ethernet_devicedriver_poll(); //接收以太網數據包(設備驅動程序)

      if(uip_len>0){ //收到數據

      if(BUF->type= =HTONS(UIP_ETHTYPE_IP)){//是IP包嗎?

      uip_arp_ipin(); //去除以太網頭結結,更新ARP表

      uip_input(); //IP包處理

      if(uip_len>0){ //有帶外回應數據

      uip_arp_out(); //加以太網頭結構,在主動連接時可能要構造ARP請求

      ethernet_devicedriver_send(); //發送數據到以太網(設備驅動程序)

      }

      }else if(BUF->type==HTONS(UIP_ETHTYPE_ARP)){

      //是ARP請求包

      uip_arp_arpin(); //如是是ARP回應,更新ARP表;如果是請求,構造回應數據包

      if(uip_len>0){ //是ARP請求,要發送回應

      ethernet_devicedriver_send(); //發ARP回應到以太網上

      }

      }

      另一個需要驅動程序支持的函數是uip_periodie(conn)。這個函數用于uIP內核對各連接的定時輪循,因此需要一個硬件支持的定時程序周期性地用它輪循各連接,一般用于檢查主機是否有數據要發送,如有,則構造IP包。使用示例如下:

      for(i=0;i
      uip_periodic(i);

      if(uip_len>0){

      uip_arp_out();

      ethernet_devicedriver_send();

      }

      }

      從本質上來說,uip_input()和uip_periodic()在內部是一個函數,即uip_process(u8t flag),UIP的設計者將uip_process(UIP_DATA)定義成uip_input(),而將uip_process(UIP_TIMER)定義成uip_periodic(),因此從代碼實現上來說是完全復用的。

      4 uIP的應用程序接口

      為了將用戶的應用程序掛接到uIP中,必須將宏UIP_APPCALL()定義成實際的應用程序函數名,這樣每當某個uIP事件發生時,內核就會調用該應用程序進行處理。如果要加入應用程序狀態的話,必須將宏UIP_APPSTATE_SIZE定義成應用程序狀態結構體的長度。在應用程序函數中,依靠uIP事件檢測函數來決定處理的方法,另外可以通過判斷當前連接的端口號來區分處理不同的連接。下面的示例程序是筆者實現的一個Web服務器應用的框架。

      #define UIP_APPCALL uip51_appcall

      #define UIP_APPSTATE_SIZE sizeof(struct uip51app_state)

      struct uip51app_state{

      unsigned char * dataptr;

      unsigned int dataleft;

      };

      void uip51_initapp{ //設置主機地址

      u16_t ipaddr[2];

      uip_ipaddr(ipaddr,202,120,127,192);

      uip_sethostaddr(ipaddr);

      uip_listen(HTTP_PORT); //HTTP WEB PORT(80);

      }

      void uip51_appcall(void){

      struct uip51app_state *s;

      s=(struct uip51lapp_state *)uip_conn->appstate; //獲取當前連接狀態指針

      if(uip_connected()){

      … //有一個客戶機連上

      }

      if(uip_newdat()||uip_rexmit()){ //收到新數據或需要重發

      if(uip_datalen()>0){

      if(uip_conn->lport==80){ //收到GET HTTP請求

      update_table_data();//根據電平狀態數據表動態生成網頁

      s->dataptr=newpage;

      s->dataleft=2653;

      uip_send(s->dataptr,s->dataleft); //發送長度為2653B的網頁

      }

      }

      }

      if(uip_acked()){ //收到客戶機的ACK

      if(s->dataleft>uip_mss()&&uip_conn->lport==80){ //發送長度>段長時

      s->dataptr+=uip_conn->len; //繼續發送剩下的數據

      s->dataleft-=uip-conn->len;

      uip_send(s->dataptr,s->dataleft);

      }

      return;

      }

      if(uip_poll())

      {… //將串口緩存的數據復制到電平狀態數據表

      return;

      }

      if(uip_timedout()|| //重發確認超時

      uip_closed()|| //客戶機關閉了連接

      uip_aborted()){ //客戶機中斷連接

      return;}

      }

      5 uIP0.9在電機遠程監測系統中的應用

      筆者設計了一個嵌入式Web模塊UIPWEB51,用于將發電機射頻監測儀串口輸出的數據上網,以實現對發電機工作狀態的遠程監測,目前已獲得初步成功。該模塊的硬件框圖如圖2所示。

      單片機采用的是Atmel的AT89C55WD,它內置20KB程序Flash,512字節RAM,3個這時器/計數器,工作在22.1184MHz時具有約2MIPS的處理速度。網卡芯片同樣采用的是低成本的RTL8019AS,是一款NE2000兼容的網卡芯片,系統外擴了32KB的SRAM,用于串口數據和網絡數據的緩沖,另外還存放了uIP的許多全局變量。

      UIPWEB51的主程序采用中斷加輪循的方式,用中斷觸發的方式接收發電機射頻監測儀發出的數據,開設置了一個接收隊列暫存這些數據。在程序中輪循有無網絡數據包輸入,如有則調用uIP的相關處理函數(如上uip_input()使用示例);如無則檢測定時輪循中斷是否發生。這里將T2設為uIP的定時輪循計數器,在T2中斷中設置輪循標志,一旦主程序檢測到這一標志就調用uip_periodic()輪循各連接(如上uip_periodic()使用示例)。

      UIPWeb51的應用程序(如uIP的應用程序接口示例),這個Web服務器首先打開80端口的監聽,一旦有客戶機要求連上,uIP內部會給它分配一個連接項,接著等收到客戶機IE瀏覽器發出的“GET HTTP……”請求后,將發電機電平與狀態數據隊列中的數據填入網頁模板,生成一幅新的網頁發給客戶機。因為這幅網頁的大小已經超過uIP的段長(MSS),因此在uIP內核次實際只發出了MSS個字節,在連接處于空閑的時候(uip_poll()),應用程序可以從串口隊列中讀出原始數據,經格式處理后再存到電機電平與狀態數據隊列中,而在這個隊列中保存著當前1min的設備工作數據,以便下次更新網頁時使用。在網頁中添加了更新按鈕,一旦瀏覽器用戶占擊了按鈕,瀏覽器會自動發出CGI請求,UIPWEB51收到后,立即發送包含數據的網頁。如果uIP接收ACK超時,它會自動設置重發標志,應用程序中可以用uip_rexmit()來檢測這個標志,重新生成網頁并發送。一旦用戶關閉了瀏覽器,uIP也會自動檢測到這一事件(應用程序中可以用uip_closed()來檢測),并且釋放掉這個連接項。

      6 測試結果

      將uIP0.9配置成允許4個并發連接,1個監聽端,10端個ARP表項,去掉UDP支持,UIP_ZBUFSIZE=1500和其它優化選項。用KEIL C編譯,整個uIP0.9內核模式代碼量小于8KB(含Web應用程序),內核對RAM的占用小于2KB(不含網頁)。整個系統程序的代碼量小于12KB,占用的RAM小于10KB。另外,在公網上測試了該模式的傳輸速度,大于20Kbps,對于此項應用已達到要求。目前,該模塊正準備應用于新一代的發電機射頻監測系統中。 

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 欧美国产日韩久久mv | 亚洲一区二区在线 | 日本一区二区三区精品道不卡 | 五月激情婷婷丁香综合基地 | 中文字幕激情欧美 | 日韩视频中文字幕在线一区 |