基於W5500的嵌入式SNMP代理端實現

WIZnet發表於2015-04-01



 實驗背景

最近一個做焊接裝置的朋友想在焊機上新增監控的新功能,實時獲取焊機的溫度、功耗等引數,還可簡單控制,實現對叢集焊接裝置的網路化管理。而這個朋友不想在開發管理系統上花太多精力,想找一個開源的管理軟體來實現他的需求。這讓我想到了簡單郵件管理協議SNMP,它生來就是為搞網路管理服務的。能廣泛相容各網路裝置,一經推出就得到了廣泛的應用和支援,幾乎所有的網路裝置生產廠家都實現了對SNMP的支援,大多數網路管理系統和平臺也都是基於SNMP的。事實上,目前SNMP已成為網路管理領域中的工業標準,我國國家廣電總局就要求通訊領域的標準網路裝置都必須支援SNMP協議。SNMP代理端實際佔用系統資源少,在微控制器上執行是沒有問題的。於是我想到用手頭的WIZnet-W5500評估板實現了SNMP代理端,給他提供一個參考。

 SNMP基礎普及

在實現SNMP代理端之前,我們先了解一下SNMP的基本知識。管理系統中就要有管理者和被管理者,網管協議定義它為管理站和代理端,它們通過管理資訊庫MIB進行介面統一,實現資料的通訊。

MIB可以認為是一個被管理物件的集合,每個物件規定了能夠被管理程式查詢和設定的資訊,同時都有自己的名字我們稱之為物件識別符號,簡稱OID,它的命名方法跟DNS樹形結構命名類似,通過OID就能知道這個裝置所屬的領域和廠家,如MIB中有一個節點{1.3.6.1.4.1},即enterprises,代表企業,它以下的節點都為企業型的。如IBM{1.3.6.1.4.1.2}Cisco{1.3.6.1.4.1.9}等。任何一個公司、學校只要用電子郵件發往iana-mib@isi.edu進行申請即可獲得一個結點名。這樣就可以定義自己的產品的OID,使它能用SNMP進行管理。

為了操作管理資料庫MIB,如圖1所示:SNMP規定了5種協議SNMP報文,用來在管理程式和代理之間的交換。1 get-request2 get-next-request3 set-request4 get-response5trap。前面的3種操作是由管理程式向代理程式發出的get/set操作,雙方都使用UDP161埠。第4個是對前三種操作的迴應,用UDP161埠,第5個代理程式主動發出的報文,通知管理程式有某些事情發生,使用UDP162埠。

  

1 SNMP5種報文操作

2是封裝成UDP資料包的5種操作的SNMP報文格式。可見一個SNMP報文共有三個部分組成,即公共SNMP首部、get/set首部或trap首部、變數繫結。

2 SNMP報文格式

 SNMP嵌入式系統實現方法

瞭解了SNMP協議之後,下面就讓我們通過WIZnet W5500EVB做一個嵌入式SNMP代理端的簡單實驗。

1.實驗目的:建立一個SNMP代理端

2.硬體環境

微控制器:STM32F103RC256K位元組Flash48K位元組SRAM

乙太網控制器:W5500SPI介面與微控制器相連

電源:USB供電

硬體外設:板載LED

3.開發工具: IAR V5.14(版本不一樣,需要稍加改動)

4.測試軟體:串列埠除錯助手,Net-SNMP(可從網路下載)

 

軟體部分是實現簡單網路管理協議SNMP的關鍵,下面就以程式流程圖的形式看看我們是如何實現的。

3為主程式流程圖,我們可以看出程式首先進行微控制器系統軟硬體初始化,然後初始化W5500,配置了IP地址、MAC地址、和閘道器。

3主程式流程圖

配置完畢後就是代理端主動傳送SNMP Trap報文了,傳送SNMP Trap報文的過程比較簡單,主要就是安裝Trap報文格式對傳送資料進行打包即可,需要注意的是資料包要根據ASN.1中的BER編碼方式(格式型別/長度/值)進行編碼。打包完畢後,開啟UDP Socket,本地埠為162,然後向管理的162埠傳送Trap包。接下來就進入一個迴圈,等待解析SNMP管理站發來Request資料包,邊解析,邊準備要回復的資料包,下圖為代理端解析管理站發來的GET/SET請求,並準備Response資料包的流程圖。

4代理端解析Request程式流程圖

通過圖4流程圖我們可以看到,整個過程是嚴格按照SNMP協議一步步進行解析判斷的。需要說明的是,也是先根據SNMP編碼方式進行解碼,再進行比較和判斷。我們知道SNMPMIB聯絡管理站和代理端的關鍵,解析程式到最後查詢的便是MIB中的物件,在此我們給出定義MIB物件的結構體:

typedef struct {

   uint8 oidlen;

   uint8 oid[MAX_OID];

   uint8 dataType;

   uint8 dataLen;

   union {

      uint8octetstring[MAX_STRING];

      uint32 intval;

   } u;

   void(*getfunction)(void *, uint8 *);

   void(*setfunction)(int32);

} dataEntryType;

通過該結構體的定義我們可以知道MIB物件的幾個部分:OID ,資料型別,資料長度,資料,get函式,set函式,本方案MIB中定義的一個控制LED動作的一個物件:{8, {0x2b, 6, 1, 4, 1, 0, 2, 0},SNMPDTYPE_INTEGER, 4,{""},  NULL, setWIZnetLed}

其中8OID長度,0x2bASN.1中“1.3”的縮寫,即:1*40+3=0x2b。整個OID其實為1.3.6.1.4.1.0.2.0。該物件的set函式為setWIZnetLed

void setWIZnetLed(int32 val){

   wiznetLedStatus =val;// W5500-EVB

   if (wiznetLedStatus==0 )GPIO_SetBits(GPIOA, LED3); // STM32

   elseGPIO_ResetBits(GPIOA, LED3);

}

此為函式名,同樣也為函式的指標,在解析SET函式過程中有一句程式碼:snmpData[id].setfunction(snmpData[id].u.intval);就是執行了該函式,其中snmpData[id].u.intval為從set Request當中解析到的繫結變數值。

整個MIB就是由上述格式的物件組成,讓可以自己定義物件的OID變數及物件的函式,當管理站向該物件傳送請求時,就可以執行相應函式,從而完成你所需要讓SNMP完成的管理和控制。

完整源程式下載:http://pan.baidu.com/s/1qWmHpTE

測試SNMP代理端

下面以PC機為SNMP管理站,講述如何測試我們實現的SNMP代理端。

1.在電腦中安裝Net-SNMP軟體。Net-SNMP是一個免費的、開放原始碼的SNMP實現方式。按預設選型安裝軟體後,點選Windows開始——>執行 輸入“ CMD ,點選確認,進入DC命令環境,輸入“ cd \usr\bin,此路徑即安裝的NetSNMP預設路徑,在此路徑下可執行SNMP命令。

2.修改PC本地連線IP地址。控制皮膚——>網路和Internet——>網路連線,點選本地連線選擇屬性,設定PC為靜態IP(與W5500在同一網段),設定完成後點選確定,本例中我們設定PCip192.168.1.110SNMP代理端IP192.168.1.111,預設閘道器都為192.168.1.1

3.接著用網線把PCW5500EVB連線,開啟串列埠軟體,選擇正確的COM口並開啟串列埠,以獲取除錯資訊。

4.下載編譯好的程式碼並復位W5500EVB,我們發現板子上有一排LED,最右邊這個LED就是我們要查詢並且控制的。如圖5所示,現在這個LED是亮的。

5最右邊LED

5.在剛才開啟的NetSNMP預設路徑下可以輸入指令,如圖所示輸入“snmpget -v 1 -cpublic 192.168.1.111 .1.3.6.1.4.1.0.1.0 ”回車,查詢到“LED On”,符合板子現在亮的情況。

6.再輸入“snmpset -v 1 -cpublic 192.168.1.111 .1.3.6.1.4.1.0.2.0 i 0”回車,結合這個OID物件的set函式分析可知,該條命令是置STM32LED3對應引腳為高,即關閉LED。如圖6觀察板子上的LED3,可見已滅。

6最右邊LED

7.如圖7再次輸入第5步的snmpget指令,可以查詢到狀態為“LED Off”。

7 Net-SNMP工具測試SNMP協議

通過以上步驟可以看出SNMP Agent已經執行,當然要實現一個複雜的網路管理功能還需要NetSNMP中很多其他指令在此不一一列舉。

總結

本文給出了基於W5500的嵌入式系統SNMP的設計與實現方案,並展示瞭如何用Net-SNMP除錯工具進行簡單控制的方法。隨著物聯網事業的發展,越來越多的嵌入式裝置都將擁有聯網功能,相信SNMP協議的作用將越來越重要。除了智慧家居,在當下物聯網時代,想必還有其他應用也會遇到類似問題,希望本文能對做網路裝置開發的朋友有所幫助。

相關文章