http://blog.chinaunix.net/uid-25445243-id-3971724.html
Linux中__init、__devinit等初始化宏解析和入口函数
参考内核驱动
drivers\hid\usbhid\usbmouse.c
1. USB是主从结构的
所有的USB传输,都是从USB主机这方发起;USB设备没有"主动"通知USB主机的能力。
例子:USB鼠标滑动一下立刻产生数据,但是它没有能力通知PC机来读数据,只能被动地等得PC机来读。
2. USB的传输类型:
a. 控制传输:可靠,时间有保证,比如:USB设备的识别过程
b. 批量传输: 可靠, 时间没有保证, 比如:U盘
c. 中断传输:可靠,实时,比如:USB鼠标
d. 实时传输:不可靠,实时,比如:USB摄像头
3. USB传输的对象:端点(endpoint)
我们说"读U盘"、"写U盘",可以细化为:把数据写到U盘的端点1,从U盘的端点2里读出数据
除了端点0外,每一个端点只支持一个方向的数据传输
端点0用于控制传输,既能输出也能输入
分配/设置usb_driver
static struct usb_driver usbmouse_as_key_driver = {
.name = "usbmouse_as_key_",
.probe = usbmouse_as_key_probe,
.disconnect = usbmouse_as_key_disconnect,
.id_table = usbmouse_as_key_id_table,
};
注册
入口函数: usb_register(&usbmouse_as_key_driver);
usbmouse.c
int retval = usb_register(&usb_driver);
if (retval == 0)
info(DRIVER_VERSION ":" DRIVER_DESC);
return retval;
出口函数: usb_deregister(&usbmouse_as_key_driver);
探测函数:usb_probe
插入usb设备时,若匹配 usb_device_id,则调用usb_probe,拔出则调用disconnect
//数据传输三要素:源,目的,长
//源:usb设备端点
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
//长度
len = endpoint->wMaxPacketSize;
//目的
usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &data_dma);
//使用三要素
//分配usb request block urb
my_urb = usb_alloc_urb(0, GFP_KERNEL);
usb_fill_int_urb(my_urb, dev, pipe, usb_buf,len,usbdrv_irq,NULL, endpoint->bInterval);
my_urb->transfer_dma = data_dma;
my_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_submit_urb(my_urb, GFP_KERNEL);
static void usbdrv_irq(struct urb *urb)
{
int i;
static int cnt = 0;
printk("data cnt %d: ", ++cnt);
for (i = 0; i < len; i++)
{
printk("%02x ", usb_buf[i]);
}
printk("\n");
/* 重新提交urb */
usb_submit_urb(my_urb, GFP_KERNEL);
}