欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
USB 3G網(wǎng)卡驅動(dòng)流程
  USB 3G網(wǎng)卡驅動(dòng)流程
簡(jiǎn)介
首先介紹一下linux下的整體驅動(dòng)模式:
本文基于的linux kernel版本為2.6.36 (并且華為EM770W驅動(dòng),是由FriendlyARM公司定制的。
所以該部分驅動(dòng)可以在友善的官方網(wǎng)站上下載。其宏定義為CONFIG_MACH_MINI6410)
總線(xiàn),設備,驅動(dòng):三者是互相關(guān)聯(lián)的,在總線(xiàn)上有設備列表,和驅動(dòng)列表。當一個(gè)設備接入時(shí),會(huì )在
總線(xiàn)上遍歷所有的驅動(dòng),知道找到支持他的驅動(dòng)。然后就會(huì )將設備結構體下的driver指針指向該驅動(dòng)。
同樣,驅動(dòng)也會(huì )將該設備加入自己的設備指針列表。
3G網(wǎng)卡是一個(gè)USB設備,那么就介紹一下USB驅動(dòng)。
總線(xiàn)
Usb總線(xiàn)結構體 struct bus_type usb_bus_type ={}; //那我們就來(lái)看看總線(xiàn)的結構體

[include/linux/device.h]文件中

struct bus_type {
const char *name;
…...
struct bus_type_private *p;
};
[drivers/base/base.h]文件中
struct bus_type_private {
struct kset subsys;

struct kset *drivers_kset;
struct kset *devices_kset;
struct klist klist_devices;
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:1;
struct bus_type *bus;
};
其中的klist_devices, klist_drivers分別為總線(xiàn)上的設備和驅動(dòng)列表。當有新的設備接入,或加載新的
驅動(dòng)時(shí)。就會(huì )在這兩個(gè)列表中遍歷。
設備
這里就以usb_device為例
[include/linux/usb.h]文件中
struct usb_device {
…...
struct usb_bus *bus; //指向該設備的總線(xiàn)
…...
struce device dev; //linux下通用設備的屬性
};
[include/linux/device.h]文件中
struct device {
…...
struct device_driver *driver; /* which driver has allocated this device */
…...
};
這里就有設備指向的總線(xiàn)和驅動(dòng)指針了。一個(gè)設備之用一個(gè)驅動(dòng)。下面的驅動(dòng),所支持的設備就是個(gè)列
表了。驅動(dòng)可以支持一系列的設備。
驅動(dòng)
以opton_driver為例[drivers/usb/serial/option.c]
static struct usb_driver option_driver = {
.name = "option",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
#ifdef CONFIG_PM
.suspend = usb_serial_suspend,
.resume = usb_serial_resume,
.supports_autosuspend = 1,
#endif
.id_table = option_ids,
.no_dynamic_id = 1,
};
[include/linux/usb.h]文件中
struct usb_driver {
const char *name;
…...
struct usbdrv_wrap drvwrap;
…...
};
struct usbdrv_wrap {
struct device_driver driver;
int for_devices;
};
[include/linux/device.h]文件中
struct device_driver {
…...
struct bus_type *bus; //驅動(dòng)所屬的總線(xiàn)
…...
struct driver_private *p;
…...
};
[drivers/base/base.h]文件中
struct driver_private {
struct kobject kobj;
struct klist klist_devices; //正在使用此驅動(dòng)的設備列表
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};
option驅動(dòng)總線(xiàn)賦值
[drivers/usb/serial/option.c]中option初始化時(shí),注冊過(guò)程會(huì )將驅動(dòng)所屬總線(xiàn)賦值
static int __init option_init(void)
{
retval = usb_register(&option_driver);
}
[include/linux/usb.h]中
static inline int usb_register(struct usb_driver *driver)
{
return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
}
[drivers/usb/core/driver.c]文件中
int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
const char *mod_name)
{
new_driver->drvwrap.driver.bus = &usb_bus_type;
new_driver->drvwrap.driver.probe = usb_probe_interface;
}
圖例
以華為EM770W為例
以HUAWEI EM770W WCDMA 3G網(wǎng)卡為例。
在內核文件linux/drivers/usb/serial/option.c中。
static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
}
有此行定義,在設備EM770W中讀取出的.idProduct與 HUAWEI_PRODUCT_E600定義的值相同。
當一個(gè)USB設備插入時(shí),會(huì )觸發(fā)hub_event時(shí)間調用函數
一: 添加usb設備
hub_events(); -->hub_port_connect_change();
--> udev = usb_alloc_dev(hdev, hdev->bus, port1); //將&usb_bus_type分配給設備
usb_new_device(udev);
-->device_add(&udev->dev);(drivers/base/core.c)
-->bus_add_device(dev); //將設備加入總線(xiàn)設備列表
//klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
bus_probe_device(dev);
-->device_attach(dev);[drivers/base/dd.c]
-->bus_for_each_drv(dev->bus, NULL, dev, __device_attach); // 遍歷驅動(dòng),找到支持此設備的
驅動(dòng)
-->__device_attach(drv, dev); // 找的驅動(dòng)usb 支持此設備
-->driver_probe_device(drv, dev);
-->really_probe(dev, drv); [drivers/base/dd.c]
-->drv->probe(dev); // 實(shí)際調用 usb_probe_device(dev);[drivers/usb/core/driver.c]
-->udriver->probe(udev); //實(shí)際上調用的 generic_probe(udev); [drivers/usb/core/generic.c]
-->usb_set_configuration(udev, c); [drivers/usb/core/message.c]
-->nintf = cp->desc.bNumInterfaces; // 這里首先得到設備的Interface數量,下面循環(huán)添加每個(gè)
Interface
for (i = 0; i < nintf; ++i) {
ret = device_add(&intf->dev);
}
二: 添加interface
下面進(jìn)入每個(gè)interface的添加設備過(guò)程,在這里單獨列出
device_add(&intf->dev);
-->bus_probe_device(dev); -->device_attach(dev); [drivers/base/dd.c]
-->bus_for_each_drv(dev->bus, NULL, dev, __device_attach); // 遍歷驅動(dòng),找到支持此設備的
驅動(dòng)
-->__device_attach(drv, dev); // 遍歷到option驅動(dòng)時(shí),在option_ids[]結構體中,找到該驅動(dòng)支
持此設備
-->driver_probe_device(drv, dev);
-->really_probe(dev, drv); [drivers/base/dd.c]
-->drv->probe(dev); //這里實(shí)際調用的函數為 usb_probe_interface(dev);
-->driver->probe(inif, id); //這里實(shí)際調用的函數為 usb_serial_probe(interface, id);
[drivers/usb/serial/usb-serial.c]
//這里檢測到使用pl2303 convertor, 并執行pl2303的attach函數
/*****************
*下面這部分做了許多事情。
* 創(chuàng )建一個(gè)usb_serial數據結構,增加一個(gè)interface接口設備,找到該接口的驅動(dòng)(如pl2303),設置
interface的endpoint等
******************/
-->type = search_serial_device(interface); //這里找到匹配的pl2303驅動(dòng) 參看下一節【USB 檢
測pl2303驅動(dòng)】
serial = create_serial(dev, interface, type); //創(chuàng )建serial, 將type驅動(dòng)賦值給新創(chuàng )建的serial-
>type,即驅動(dòng)指向為pl2303
port = serial->port[i];
dev_set_name(&port->dev, "ttyUSB%d", port->number);
device_add(&port->dev); //調用增加設備 ttyUSB0
-->bus_probe_device(dev);
-->...如上...
-->really_probe(dev, drv); [drivers/base/dd.c]
-->dev->bus->probe(dev); // ***** 這里實(shí)際上調用的就是usb_serial_device_probe(dev);
-->tty_register_device(usb_serial_tty_driver, minor, dev); //這里會(huì )再次調用 device_add(dev);
函數
USB 檢測pl2303驅動(dòng)
USB的串行設備也分為很多種類(lèi)。如pl2303,ViVOpay
usb_serial_probe(interface, id);[drivers/usb/serial/usb-serial.c]
-->type = search_serial_device(interface); //根據提供的interface接口,
//獲得了 static struct usb_serial_driver pl2303_device ={} [drivers/usb/serial/pl2303.c]
-->list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
id = get_iface_id(drv, iface);
if (id)
return drv;
}
pl2303驅動(dòng)的注冊過(guò)程
static int __init pl2303_init(void)
{
retval = usb_serial_register(&pl2303_device);
}
[drivers/usb/serial/usb-serial.c] 在注冊函數中,將pl2303驅動(dòng)加入usb serial驅動(dòng)列表
int usb_serial_register(struct usb_serial_driver *driver)
{
list_add(&driver->driver_list, &usb_serial_driver_list);
}
三: 添加endpoint
// 至此,整個(gè)調用逐步返回!
最后在usb_set_configuration(udev, c); [drivers/usb/core/message.c] 函數返回時(shí)調用
-->create_intf_ep_devs(intf); //增加endpoint設備
-->for (i = 0; i < alt->desc.bNumEndpoints; ++i)
(void) usb_create_ep_devs(&intf->dev, &alt->endpoint[i], udev);
-->retval = device_register(&ep_dev->dev);
3G網(wǎng)卡如何讀寫(xiě)呢
在pl2303驅動(dòng)加載完成后,生成的設備ttyUSB0, ttyUSB1, ttyUSB2后,即可以對這些設備進(jìn)行操
作。如open,close,read,write,ioctl等命令
pl2303.c中有如下函數,即當打開(kāi)網(wǎng)卡設備時(shí),就會(huì )調用此函數。
static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
{
}
在板子的可使用3G WCDMA網(wǎng)卡上,因為開(kāi)發(fā)板為3G網(wǎng)卡建立3個(gè)USB設備
ttyUSB0,ttyUSB1,ttyUSB2 所以在打開(kāi)時(shí),會(huì )調用3次該函數。
大概流程為
static int serial_open(struct tty_struct *tty, struct file *filp)
-->tty_port_open(&port->port, tty, filp);
-->port->ops->activate(port, tty); //此處調用的為static int serial_activate(struct tty_port
*tport, struct tty_struct *tty)
-->port->serial->type->open(tty, port); //這里即是調用static int pl2303_open(struct
tty_struct *tty, struct usb_serial_port *port)
從而對將設備打開(kāi),可以對設備進(jìn)行讀寫(xiě),控制等操作。
設備識別
在設備插入后,以HUAWEI ET127 3G網(wǎng)卡為例。插入設備后會(huì )有如下的log
scsi 0:0:0:0: CD-ROM HUAWEI Mobile CMCC CD 1.25 PQ: 0 ANSI: 0
大唐的AirCard 901插入后,同樣會(huì )有log如下:
csi 1:0:0:0: CD-ROM AirCard SetupDisk 1.00 PQ: 0 ANSI: 2
這時(shí),友善開(kāi)發(fā)板將此設備識別成為一個(gè)光盤(pán),即儲存設備。這時(shí),如果在ubuntu下,可以使用
usb_modeswitch將usb設備進(jìn)行模式轉換。然后驅動(dòng)3G網(wǎng)卡。我在網(wǎng)上搜索到一篇文章。說(shuō)可以驅
動(dòng)大部分3G網(wǎng)卡,就此我問(wèn)過(guò)胡菲菲。此前驅動(dòng)大唐的AirCard 901用的就是此種方法。
http://linuxidc.com:81/Linux/2011-03/33430.htm
我昨天嘗試按照這些步驟進(jìn)行實(shí)現。但是遇到兩個(gè)問(wèn)題
1:arm 卡發(fā)板上使用的是busybox, 和一些應用程序(如:dhcpcd)在A(yíng)ndroid系統下編譯。我編譯的
usb_modeswitch無(wú)法運行
2:插入usb 3G設備后,arm開(kāi)發(fā)板識別為sr0, sr1設備。不知道該如何將此設備退出?;蛟S
usb_modeswitch轉換完成后,即可以進(jìn)行AT命令通信。還需要進(jìn)行試驗才能知道。
usb_modeswitch作用
USB_ModeSwitch 是控制"flip flop"(多重設備)USB裝置的模式轉換工具。作用有如下的幾種:
1. Usb 閃存模式:提取和安裝驅動(dòng)
2. 轉換模式:儲存設備模式轉換為所需(如3G)設備模式
3. 所需設備模式:使用設備新的功能
詳細的可以參看usb_modeswitch的README文檔。
一些術(shù)語(yǔ)
USB 端點(diǎn)(endpoint)
端點(diǎn)是由廠(chǎng)商在USB設備內部建立的,因此是永久存在的。端點(diǎn)(endpoint)和主控制器(host
controller)基于管道(pipe)連接。
一個(gè)端點(diǎn)只能單向的(in/out)傳輸數據。
端點(diǎn)是以interface來(lái)分組的。每一個(gè)interface對應著(zhù)一個(gè)設備功能。
USB Interface
endpoint(端點(diǎn))是以interface來(lái)分組的。比如華為的WCDMA是以每三個(gè)ep為一組,隸屬于一個(gè)
interface。而且每一個(gè)interface對應著(zhù)一個(gè)單獨的設備功能。如華為ET127 TD-CDMA 3G網(wǎng)卡其
中一個(gè)interface設備命名為ttyUSB_utps_mms,對應的功能應該即為短信發(fā)送/接收。
USB設備號
//WCDMA 華為EM770W在ubuntu 10.04下查看
crw-rw---- 1 root dialout 188, 1 2011-05-04 16:19 ttyUSB_utps_diag
crw-rw---- 1 root dialout 188, 0 2011-05-04 16:19 ttyUSB_utps_modem
crw-rw---- 1 root dialout 188, 2 2011-05-04 16:21 ttyUSB_utps_pcui
//TD-SCDMA 華為ET127在ubuntu 10.04下查看
crw-rw---- 1 root dialout 166, 1 2011-05-04 16:23 ttyUSB_utps_mms
crw-rw---- 1 root dialout 166, 0 2011-05-04 16:23 ttyUSB_utps_modem
crw-rw---- 1 root dialout 166, 2 2011-05-04 16:23 ttyUSB_utps_pcui
idVendor=12d1, idProduct=1da1
大唐TD-SCDMA設備參數
idVendor=1ab7, idProduct=0301
主設備號含義
ACM調制解調器:主設備號 166
USB打印機: 主設備號 180(次設備號0~15)
USB串口: 主設備號 188  
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Linux驅動(dòng)開(kāi)發(fā)方法論
Linux關(guān)于總線(xiàn)、設備、驅動(dòng)的注冊順序
Linux設備模型(6)_Bus
rk系列之PCIE設備枚舉
Linux下USB core的工作原理及設備驅動(dòng)技術(shù)|Linux
Linux下的硬件驅動(dòng)——USB設備(下)(驅動(dòng)開(kāi)發(fā)部分)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久