我理解的網口:
協議,協議,協議,看的頭暈死了。。。
最近在做網口的工作,頭疼得要死,弄來弄去終於有點眉目了。
我的系統使用了ucos作業系統,所以用task(任務來處理)。
首先寫好驅動(這個任務已經有人完成,不再某某人的職責範圍,我也不會寫),然後開始工作。
1. 在硬體啟動時task_start(專門建立任務的任務)任務中,建立一個網口接受的任務和一個網口發送的任務。分別調用task_net_rx,task_net_tx。
2. 在初始化函數sys_init(專門進行上電初始化的函數)中調用net_init()函數,進行網口的IP地址、網關、子網路遮罩、MAC地址等資訊的設定,並啟動網關工作。
3. 首先,需要建立發送接受環形緩衝區,我這裡已經建立完成。先揀簡單的說:task_net_tx函數的實現:等待接受函數發送一個訊號量net_sem,接受到的話,按照發送資料的長度net_tx_num從環形緩衝區中取數並發送。
4. 然後重點是接受函數:接受函數需要解析發送來的內容用的是什麼協議,代表是什麼意思,接受到以後怎麼處理等資訊,所以比較複雜。想要通訊首先要實現ARP協議,保證通訊的基礎;然後要實現TCP、UDP協議這是通訊的主要通路;實現PING功能,保證測試通訊的基礎。由於不是實現完整的TCP/IP協議棧,為了減少代碼量,所以自己寫代碼來實現這一功能。作為載體TCP、UDP資料包包含了資料資訊,在資料資訊中也有協議的實現,比如modbus協議、104通訊規約、DNP協議和自訂協議等等任何使用者需要的協議。在每個具體的協議實現裡面,怎樣去解析和處理資料又是另外一層處理。在這裡主要體現一個分層的思想。
從分層的思想來看,我可以將這個處理過程分為幾個層次。
最低層:
task_net_rx
{
If(ARP) arp_ack();
Else if(UDP) udp_ack();
…
將返回資料儲存到環形緩衝區,設定訊號量。
}
再上一層是這些協議的實現,在這裡提供更上一層協議的介面:
Udp_ack()
{
…
If(modbus) n = modbus_ack();
Else if(dnp) n = dnp_ack();
…
…
}
在上面同樣的道理。
這樣一分層,整個網路處理的結構就出來了。
由於時間有限,我沒空去看lwip的詳細代碼,看了它的說明文檔,順便說一下我的理解:
1. lwip實現了比較詳細的分層。我這個代碼是按照自己的理解來分層,沒那麼嚴格。
2. lwip有專門的緩衝和資料管理機制。我這個沒有。
3. lwip沒有完全分層,為了減少層與層之間資料的拷貝而浪費資源。我這個代碼完全是全域變數,不進行資料拷貝。
4. lwip實現了定製,可以增減代碼,並實現了socket介面。My Code也可以刪除,但是比較簡單。
等有時間了好好看看這些高手的代碼,長點見識!
呵呵,記錄到此為止,over!