USB網絡卡驅動分析(rt8152)

2021-09-29 00:24:55 字數 3415 閱讀 9387

網路裝置驅動程式分析

最近一直在搞zynq的pl部分,為了保持對驅動程式的敏感度,看著原始碼分析一下rt8152的驅動程式。之前學微控制器一直想著給微控制器裝乙個usb網絡卡,但是一直沒有思路。今天突然想到之前的想法,就帶著這個想法加上對核心驅動的懷念,寫一下,寫點東西有時候能讓人的心平靜點。

usb裝置的匹配不需要在裝置樹中進行定義,而是通過vid和pid。這是usb控制器在在完成熱插拔以後做的一項檢測工作,會從usb的端點0中讀取usb的vid和pid,然後在和已經裝在的usb驅動程式進行匹配。

static struct usb_device_id rtl8152_table = ,

, ,, ,

, {}

};

這是usb網絡卡的裝置id匹配表。當usb裝置接到usb匯流排上,如果正確匹配,probe函式就會被執行。

usb裝置驅動的pid和vid能不能動態配置?

usb裝置驅動程式中的vid和pid萬一重複怎麼辦?

之前寫過一篇 linux網絡卡裝置驅動(任意傳輸介質傳輸(與fpga互動)) 大致說了下網絡卡驅動程式的結構以及怎麼實現乙個網路驅動程式。

這裡在贅述一下,網絡卡驅動程式在probe函式中:

struct net_device *netdev;定義網路裝置結構體;

netdev = alloc_etherdev(sizeof(struct r8152));分配空間

填充該結構體;

ret = register_netdev(netdev);註冊該裝置;

實現傳輸函式以及中斷接收網路資料。(也可以是輪詢,取決於併發量,目前有一種自動檢測的驅動程式,第一次是中斷形式,之後是輪詢);

標題其實已經說明了,usb網絡卡驅動程式就是usb驅動程式加上網絡卡驅動程式。說說題外話吧,如何用帶usb控制器的微控制器來和usb網絡卡進行資料互動呢?之前做過stm32上的usb自定義裝置程式,是從機的(上位機用的是libusb+qt)。所以對微控制器的usb程式有一些記憶,基本都是對端點的操作。接下來去分析linux中的usb網絡卡驅動程式,以此來構想下微控制器如何驅動乙個usb網絡卡。

原始碼在drivers\net\usb\r8152.c下

先看下入口函式:

static int rtl8152_probe(struct usb_inte***ce *intf,const struct usb_device_id *id)

把結構性的**留下了,可以看出在probe函式中,完成了usb操作介面的獲取、網路裝置的註冊、pyh相關設定。

static int rtl_ops_init(struct r8152 *tp)

return ret;

}

這段**完成了所有網絡卡的操作函式的註冊。

static const struct net_device_ops rtl8152_netdev_ops = ;
rtl8152_start_xmit()函式很重要,完成了網路資料報的傳送。實現如下:

static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,

struct net_device *netdev)

else

} else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen)

return netdev_tx_ok;

}

再到usb中斷服務函式中找到接收大**:

static void tx_bottom(struct r8152 *tp)

else

} } while (res == 0);

}

這裡使用了中斷的下半部,說一下這個知識,在linux核心中,中斷處理一般分為以下幾種方式:

直接處理;

軟中斷tasklet;

中斷執行緒化;

工作佇列;

直接處理就是在中斷服務函式中直接處理相應的邏輯,這種情況對應於十分簡短的中斷處理邏輯;

軟中斷和tasklet都是發生在中斷上下文的,因此在處理函式中不能有休眠。工作佇列和中斷執行緒化可以用休眠,但是處理的實時性會差一些。

大體結構已經出來了,還有乙個urb的知識沒有說;在linux驅動中,通過驅動程式通過urb和裝置進行通訊。urb相當於網路裝置驅動程式中的skb。是傳輸資料的載體。

static void write_bulk_callback(struct urb *urb)

else

spin_lock(&tp->tx_lock);

list_add_tail(&agg->list, &tp->tx_free);

spin_unlock(&tp->tx_lock);

usb_autopm_put_inte***ce_async(tp->intf);

if (!netif_carrier_ok(netdev))

return;

if (!test_bit(work_enable, &tp->flags))

return;

if (test_bit(rtl8152_unplug, &tp->flags))

return;

if (!skb_queue_empty(&tp->tx_queue))

napi_schedule(&tp->napi);

}static void intr_callback(struct urb *urb)

d = urb->transfer_buffer;

if (intr_link & __le16_to_cpu(d[0]))

} else

}resubmit:

res = usb_submit_urb(urb, gfp_atomic);

if (res == -enodev) else if (res)

}

這是在usb網絡卡驅動中操作urb的例項,看起來很像i2c驅動中的i2c_msg;

usb驅動驅動具體操作下次會具體的說明。這次重點是usb網絡卡的結構分析;

回到最初的願望,用微控制器去控制usb網絡卡,實現微控制器上網可行嗎?

答案是可行的,首先要讓微控制器上有乙個簡單的作業系統,這樣方便網路協議棧的移植,然後就是把微控制器的usb host 調好,通過讀取usb裝置的端點來實現usb網絡卡和微控制器的資料互動。之後有時間做一下這個,實現下最初的理想。人有時候在不具備條件時,總是幻想著自己的夢想,當具備條件時,最初的夢想早已忘得一乾二淨。

在linux中,對usb抽象做的比較好,記得當時調微控制器的usb調了乙個週才實現了基本的資料互動,linux下只要你插上usb就會識別到匯流排驅動,前提是控制器正常工作,不然可比微控制器難搞。

sdio網絡卡有時間研究下,據說安卓好多用的是sdio的網絡卡晶元。

RT5370 USB無線網絡卡驅動移植

在天嵌公司買了乙個usb無線網絡卡,本以為就是移植手冊上用到的那種網絡卡,可是當我收到網絡卡的時候就懵了,網絡卡背面就寫了802.11n,也沒說是哪種晶元的。問了天嵌的售後,說是和移植手冊上的步驟是一樣的。於是我就照著手冊按部就班地做,但就是驅動不起來,開機的時候還提示手冊上的驅動載入不上。再去問問...

ARMLINUX網絡卡驅動分析

armlinux網絡卡驅動分析 一 網路裝置驅動結構 1網路協議介面層 2網路裝置介面層 3裝置驅動功能層 4網路裝置與媒介層 二 網路協議介面層 1功能 給上層協議提供透明的資料報傳送和接收介面 2定義在 include linux netdevice.h中 3函式原型 int dev queue...

USB驅動程式分析

1.對於每個pc來說,都有乙個或者多個稱為主機 host 控制器的裝置,該主機控制器和乙個根集線器 hub 作為乙個整體。2.每個host控制器其實就是乙個pci裝置,掛載在pci匯流排上。驅動開發人員應該給host控制器提供驅動程式,用usb hcd結構體表示。3.usb host控制器都會自帶乙...