日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 嵌入式 > 嵌入式教程
[導讀]嵌入式Linux網絡驅動程序開發(fā)設計

引言
隨著人們對開放源代碼軟件熱情的日益增高,Linux作為一個功能強大而穩(wěn)定的開源操作系統(tǒng),越來越受到成千上萬的計算機專家和愛好者的青睞。在嵌入式領域,通過對Linux進行小型化裁剪后,使其能夠固化在容量只有幾十兆字節(jié)的存儲器芯片或單片機中,成為應用于特定場合的嵌入式Linux系統(tǒng)。Linux強大的網絡支持功能實現(xiàn)了對包括TCP/IP在內的多種協(xié)議的支持,滿足了面向21世紀的嵌入式系統(tǒng)應用聯(lián)網的需求。因此,在嵌入式系統(tǒng)開發(fā)調試時,網絡接口幾乎成為不可或缺的模塊。

1 嵌入式Linux網絡驅動程序介紹
Linux網絡驅動程序作為Linux網絡子系統(tǒng)的一部分,位于TCP/IP網絡體系結構的網絡接口層,主要實現(xiàn)上層協(xié)議棧與網絡設備的數據交換。Linux的網絡系統(tǒng)主要是基于BSD Unix的套接字(socket)機制,網絡設備與字符設備和塊設備不同,沒有對應地映射到文件系統(tǒng)中的設備節(jié)點。
通常,Linux驅動程序有兩種加載方式:一種是靜態(tài)地編譯進內核,內核啟動時自動加載;另一種是編寫為內核模塊,使用insmod命令將模塊動態(tài)加載到正在運行的內核,不需要時可用rmmod命令將模塊卸載。Linux 2.6內核引入了kbuild機制,將外部內核模塊的編譯同內核源碼樹的編譯統(tǒng)一起來,大大簡化了特定的參數和宏的設置。這樣將編寫好的驅動模塊加入內核源碼樹,只需要修改相應目錄的Kconfig文件,把新的驅動加入內核的配置菜單,然后需要修改相應子目錄中與模塊編譯相關的Kbuild Makefile,即可使新的驅動在內核源碼樹中被編譯。在嵌入式系統(tǒng)驅動開發(fā)時,常常將驅動程序編寫為內核模塊,方便開發(fā)調試。調試完畢后,就可以將驅動模塊編譯進內核,并重新編譯出支持特定物理設備的Linux內核。

2 嵌入式Linux網絡驅動程序的體系結構和實現(xiàn)原理
2.1 Linux網絡設備驅動的體系結構
如圖1所示,Linux網絡驅動程序的體系結構可劃分為4個層次。Linux內核源代碼中提供了網絡設備接口及以上層次的代碼,因此移植特定網絡硬件的驅動程序的主要工作就是完成設備驅動功能層的相應代碼,根據底層具體的硬件特性,定義網絡設備接口struct net_device類型的結構體變量,并實現(xiàn)其中相應的操作函數及中斷處理程序。
Linux中所有的網絡設備都抽象為一個統(tǒng)一的接口,即網絡設備接口,通過struct net_device類型的結構體變量表示網絡設備在內核中的運行情況,這里既包括回環(huán)(loopback)設備,也包括硬件網絡設備接口。內核通過以dev_base為頭指針的設備鏈表來管理所有的網絡設備。
 

2.2 net_device 數據結構
 struct net_device結構體是整個網絡驅動結構的核心,其中定義了很多供網絡協(xié)議接口層調用設備的標準方法,該結構在2.6內核源碼樹文件中定義,下面只列出其中主要的成員。

2.2.1全局信息及底層硬件信息
name:網絡設備名稱,默認是以太網;
*next:指向全局鏈表下一個設備的指針,驅動程序中不修改;
mem_,rmem_:發(fā)送和接收緩沖區(qū)的起始,結束位置;
base_addr,irq:網絡設備的I/O基地址,中斷號,ifconfig命令可顯示和修改;
hard_header_len:硬件頭的長度,以太網中值為14;
mtu:最大傳輸單元,以太網中值為1500B;
dev_addr[MAX_ADDR_LEN]:硬件(MAC)地址長度及設備硬件地址,以太網地址長度是48bit,ether_setup會對其進行正確的設置;

2.2.2 主要的操作方法
int (*init)(struct net_device *dev); 設備初始化和向系統(tǒng)注冊的函數,僅調用一次;
int (*open)(struct net_device *dev);設備打開接口函數,當用ifconfig激活網絡設備時被調用,注冊所用的系統(tǒng)資源(I/O端口,IRQ,DMA等)同時激活硬件并增加使用計數;
int (*stop)(struct net_device *dev);執(zhí)行open方法的反操作;
*hard_start_xmit;初始化數據包傳輸的函數;
*hard_header;該函數(在hard_start_xmit前被調用)根據先前檢索到的源和目標硬件地址建立硬件頭。    eth_header是以太網類型接口的默認函數;

2.3網絡驅動程序的編寫及實現(xiàn)原理
Linux網絡系統(tǒng)各個層次之間的數據傳送都是通過套接字緩沖區(qū)sk_buff完成的,sk_buff數據結構是各層協(xié)議數據處理的對象。sk_buff是驅動程序與網絡之間交換數據的媒介,驅動程序向網絡發(fā)送數據時,必須從其中獲取數據源和數據長度;驅動程序從網絡上接收到數據后也要將數據保存到sk_buff中才能交給上層協(xié)議處理。
對于實際開發(fā)以太網驅動程序,可以參照內核源碼樹中的相應模板程序,重點理解網絡驅動的實現(xiàn)原理和程序的結構框架,然后針對開發(fā)的特定硬件改寫代碼,實現(xiàn)相應的操作函數。下面結合作者利用Linux2.6.18內核在深圳優(yōu)龍公司的FS2410開發(fā)板(SAMSUNG S3C2410處理器)上移植編寫嵌入式CS8900A網卡驅動程序的實例,說明網絡驅動程序的實現(xiàn)原理。

2.3.1網絡設備初始化
網絡設備的初始化是由net_device結構中的init函數實現(xiàn)的,內核加載網絡驅動模塊后,就會調用初始化過程。實例中初始化函數_init cs8900_probe中主要完成的工作:
a.調用內核中通用的設置以太網接口的函數ether_setup();
b.填充net_device結構體變量dev中其它大部分成員;
c.調用check_mem_region()檢測I/O地址空間,然后調用request_mem_region()申請以dev->base_addr為起始地址的16個連續(xù)的 I/O地址空間;
d.通過cs8900_read()探測網卡CS8900A,讀取ID信息;
e.設置CS8900A的INTRQ0作為中斷信號輸出引腳;
f.將MAC地址寫入CS8900A的IA寄存器中;
g.通過register_netdev()將CS8900A注冊到Linux全局網絡設備鏈表中;[!--empirenews.page--]

2.3.2打開(或關閉)網絡設備
系統(tǒng)響應ifconfig命令時,打開(關閉)一個網絡接口。ifconfig命令開始會調用ioctl(SIOCSIFADDR)來將地址賦予接口。響應SIOCSIFADDR由內核來完成,與設備無關。接著,ifconfig命令會調用ioctl(SIOCSIFFLAGS)設置dev->flag的IFF_UP位來打開設備,這個調用會使設備的open方法得到調用。(當ifconfig調用ioctl(SIOCSIFFLAGS)清除dev->flag的IFF_UP位時,設備的stop方法將被調用)

實例中利用cs8900_start()函數打開網絡設備,主要完成的工作:
a.通過set_irq_type()向內核注冊網絡設備的中斷處理程序;
b.通過cs8900_set()設置CS8900A網卡中各控制寄存器和配置寄存器;
c.通過內核中netif_start_queue()函數開啟網絡接口的數據傳輸隊列;

2.3.3網絡數據包的發(fā)送
數據包的發(fā)送和接收是網絡驅動程序中實現(xiàn)的兩個最重要的任務。當網絡設備被激活時,net_device結構中的open方法被調用,它負責打開設備并調用net_device結構中的hard_header函數指針建立硬件幀頭信息。最后通過函數dev_queue_xmit()來調用net_device結構中的hard_start_xmit方法把存放在sk_buff中的數據發(fā)送到網絡物理設備。如果發(fā)送成功,則在hard_start_xmit中釋放sk_buff并返回0;如果硬件設備忙暫時無法處理,則返回1。網絡硬件在發(fā)送完數據包后會產生中斷,把dev->tbusy置0,通知系統(tǒng)可以再次發(fā)送。
實例中,hard_start_xmit方法即為網絡設備數據發(fā)送函數cs8900_send_start(),該函數實現(xiàn)把數據發(fā)送到以太網上,由網絡協(xié)議接口層函數dev_queue_xmit()對其調用。

cs8900_send_start()中主要完成的工作:
a.發(fā)送數據前關閉中斷,中止網絡設備的數據傳輸隊列;
b.向CS8900A寄存器TxCMD中寫入傳送數據命令控制字,向寄存器TxLength中寫入待發(fā)送數據幀長度;
c.通過cs8900_read()反復讀取CS8900A總線狀態(tài)寄存器BusST信息,直到其已經準備好接收來自主機的數據;
d.調用cs8900_frame_write()將待發(fā)數據送入CS8900A的sk_buff中,硬件設備會將數據幀發(fā)送到以太網上;
e.記錄數據幀的發(fā)送時刻,打開中斷,釋放sk_buff緩存,函數返回0;

2.3.4網絡數據包的接收和中斷處理
網絡設備是異步地接收外來的數據包并且主動的“請求”將硬件獲得的數據包壓入內核。網絡設備接收數據包是通過中斷實現(xiàn)的。對于網絡接口,接收到新數據包,發(fā)送完成或者報告錯誤信息及連接狀態(tài)等都會觸發(fā)中斷,通常中斷處理程序通過檢測硬件狀態(tài)寄存器判斷是哪種情況。
當設備收到數據后會產生一個中斷,由硬件通知驅動程序有數據包到達。在中斷處理程序中驅動程序申請一塊sk_buff(一般定義為skb)緩沖區(qū),然后從硬件讀出數據放到申請好的緩沖區(qū)里,接下來填充sk_buff中的部分信息:包括接收到數據的設備結構體指針填入skb->dev;收到數據幀的類型填入skb->protocol;把指針skb->mac.raw指向硬件數據并丟棄硬件針頭(skb_pull);設置skb->pkt_type,標明鏈路層數據類型。最后調用協(xié)議接口層函數netif_rx() 把接收到的數據包傳輸到網絡上層協(xié)議處理。這里,netif_rx()只是負責把數據放入工作隊列就返回,真正的處理是在中斷返回以后,這樣可減少中斷處理的時間。幾乎每個中斷處理程序的編寫都要涉及底半部機制,這樣可以保證中斷的高效處理。

實例中數據接收函數cs8900_receive()由網絡驅動的中斷處理函數調用,主要完成如下工作:
a.通過從I/O口讀取RxStatus和RxLength的值,確定接收數據幀的狀態(tài)信息和長度;
b.判斷接收數據幀的狀態(tài)是否正常,若異常則記錄相關錯誤信息,然后函數返回;
c.正常情況下,在內存中申請一塊sk_buff緩存,并將數據從CS8900A的片內存儲器傳送到sk_buff緩存中;d.從數據幀中獲取協(xié)議頭并賦給skb->protocol;
e.通過調用netif_rx()函數將接收到的數據送往上層協(xié)議棧進行處理;
f.記錄接收數據的時間并更新統(tǒng)計信息;

3 將設備驅動模塊編譯進內核
設計好模塊化的網絡驅動程序后,我們就可以編譯這個內核模塊,并將這個自定義的內核模塊作為Linux系統(tǒng)源碼的一部分編譯出新的系統(tǒng)。下面介紹的內容均在Linux2.6.18內核上編譯通過,可以在2.6.x版本內核中通用。如前所述,由于Linux2.6內核引入了kbuild的新機制,使得編譯新的內核模塊或者將自己編寫的內核模塊集成到內核源碼中都變得非常簡單了。
Linux2.6內核中,編譯內核模塊首先要在/usr/src下正確配置和構造內核源碼樹,即把需要版本的內核源碼解壓在/usr/src/,并在內核源碼的主目錄下(這里為/usr/src/linux-2.6.18.3),使用make menuconfig或者make gconfig命令配置內核,然后使用make all完整編譯內核。

下面以作者開發(fā)的CS8900A網卡驅動為實例,介紹如何將網絡設備驅動模塊編譯進內核。
a.在系統(tǒng)源碼樹drivers目錄下創(chuàng)建新目錄Cs8900;
b.將編寫好的文件cs8900.c和cs8900.h拷貝到drivers/Cs8900目錄下;
c.在drivers/Cs8900目錄下,編寫Makefile文件:
#Makefile for CS8900A Network Driver
obj -$(CONFIG_DRIVER_CS8900A)  +=cs8900.o
d.在drivers/Cs8900目錄下,編寫Kconfig文件:
#Just for CS8900A Network Interface
menu "CS8900A Network Interface support"
config DRIVER_CS8900A
tristate "CS8900A support"
--------help--------
This is a network driver module for CS8900A.
endmenu

e.在driver目錄下的Kconfig文件endmenu語句前,加入一行:
source "drivers/Cs8900/Kconfig"
這樣在內核源碼樹的主目錄下,通過make menuconfig或者make gconfig命令就可以在Device Drivers選項的下面找到CS8900A Network Interface support選項,并找到CS8900A support的選擇菜單,它有三種狀態(tài):未選中(不編譯)、選中(M)一編譯為模塊、選中(*)一編譯為新系統(tǒng)一部分。
重新編譯內核即可得到支持CS8900A網卡的內核,然后將內核下載到FS2410的開發(fā)板上,通過配置網絡參數,就可以測試網卡驅動程序的行為了。

4 結束語
    在這個信息爆炸的時代,人們對于網絡的需求愈發(fā)強烈,越來越多的嵌入式設備都需要具有以太網的接入功能,因此開發(fā)網絡驅動程序對于很多嵌入式產品的研發(fā)至關重要。具體開發(fā)嵌入式Linux網絡驅動程序時,可以參照內核中已經支持的網絡驅動源代碼,在重點理解Linux網絡驅動實現(xiàn)原理的基礎上,按照模塊設計較為固定的開發(fā)模式,結合具體物理設備的硬件手冊,移植編寫需要的模塊化的網絡驅動程序。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

摘 要:從硬件與軟件方面介紹了基于PXI技術的1553B總線通訊模塊的設計,并對PXI總線接口設計、驅動程序的開發(fā)、 SDRAM存儲器的控制和1553B總線通信協(xié)議實現(xiàn)等關鍵技術進行了詳細的闡述,為航空領域測控系統(tǒng)開發(fā)P...

關鍵字: PXI技術 驅動程序 SDRAM存儲器 1553B總線

PnP全稱Plug-and-Play,譯文為即插即用。PnP的作用是自動配置低層計算機中的板卡和其他設備,然后告訴對應設備都做了什么。PnP的任務是把物理設備和軟件設備驅動程序相配合,并操作設備,在每個設備和它的驅動程序...

關鍵字: PnP 驅動程序 操作設備

作?者:道哥,10年嵌入式開發(fā)老兵,專注于:C/C、嵌入式、Linux。關注下方公眾號,回復【書籍】,獲取Linux、嵌入式領域經典書籍;回復【PDF】,獲取所有原創(chuàng)文章(PDF格式)。目錄kill命令和信號使用kill...

關鍵字: 信號 應用程序 驅動程序

驅動程序本質上是軟件代碼,主要作用是計算機系統(tǒng)與硬件設備之間完成數據傳送的功能,只有借助驅動程序,兩者才能通信并完成特定的功能。

關鍵字: 驅動程序 硬件設備 UNIX

驅動程序(Device Driver)全稱為“設備驅動程序”,是一種可以使計算機和設備通信的特殊程序,可以說相當于硬件的接口,操作系統(tǒng)只能通過這個接口,才能控制硬件設備的工作,假如某設備的驅動程序未能正確安裝,便不能正常...

關鍵字: 驅動程序 聲卡 設備

作?者:道哥,10年嵌入式開發(fā)老兵,專注于:C/C、嵌入式、Linux。關注下方公眾號,回復【書籍】,獲取Linux、嵌入式領域經典書籍;回復【PDF】,獲取所有原創(chuàng)文章(PDF格式)。目錄API函數編寫驅動程序編寫應用...

關鍵字: 編寫 驅動程序 字符設備驅動

作?者:道哥,10年嵌入式開發(fā)老兵,專注于:C/C、嵌入式、Linux。關注下方公眾號,回復【書籍】,獲取Linux、嵌入式領域經典書籍;回復【PDF】,獲取所有原創(chuàng)文章(PDF格式)。目錄示例程序目標編寫驅動程序編寫應...

關鍵字: GPIO 編寫 驅動程序

打印機 在我們的辦公區(qū)域實用性是非常強的,不僅可以提高辦公的效率,而且還能節(jié)省用戶時間,是一款非常不錯的辦公小助手。長時間使用, 打印機驅動程序無法使用 ,怎么回事呢?用戶一定要做出詳細了解,是否需要重新安裝,下面我們一...

關鍵字: 驅動程序 打印機驅動

作?者:道哥,10年嵌入式開發(fā)老兵,專注于:C/C、嵌入式、Linux。關注下方公眾號,回復【書籍】,獲取Linux、嵌入式領域經典書籍;回復【PDF】,獲取所有原創(chuàng)文章(PDF格式)。目錄混亂的API函數舊的API函數...

關鍵字: 驅動程序 字符設備驅動

作?者:道哥,10年嵌入式開發(fā)老兵,專注于:C/C、嵌入式、Linux。關注下方公眾號,回復【書籍】,獲取Linux、嵌入式領域經典書籍;回復【PDF】,獲取所有原創(chuàng)文章(PDF格式)。目錄學習的困惑實踐環(huán)境編譯進內核編...

關鍵字: 內核 編譯 驅動程序

嵌入式教程

6897 篇文章

關注

發(fā)布文章

編輯精選

技術子站

關閉