分析USB鼠标——usbmouse.c

USB驱动之常规usb鼠标驱动 常规usb鼠标驱动使用的是linux中常用的drivers/hid/usbhid/usbmouse.c驱动。 static const struct usb_device_id usb_mouse_id_table[] = { { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, USB_INTERFACE_PROTOCOL_MOUSE) }, { } /* Terminating e... 阅读详情

声明:本文章是看完韦东山老师的USB鼠标驱动的视频后,结合usb鼠标的驱动程序锁写的自己对usbmouse.c的分析,如果有与您重复的地方,敬请原谅。同时希望大家可以通过本文了解到usb驱动鼠标。而我认为我们不应该只是学习老师所教的课程,而自己独立的分析内核代码也是我们所要学习的内容。

下面就要讲到对内核中usbmouse.c的分析,而在我分析之前,我要几个要点是希望大家可以明白的,因为只有明白了这些知识点,你才可以更好的了解我对usbmouse.c的分析。

1.usb是主从结构的,而我们缩写的驱动程序是为匹配从设备所写的驱动程序

2.说到usb驱动就要讲到usb_bus_type,要了解USB总线类型,只有了解这些才可以对下面的分析充分了解。否则只能是雾里看花

3.对usb的插入拔出主设备的过程有所了解,

4.还有就是对usb的描述符有所了解,

以上这些如果有不明白的我建议你可以看一下我写的文章:

USB原理以及对照hub.c的代码分析

嵌入式Linux —— usb鼠标驱动

而在分析这代码之前我们要介绍一下usb驱动代码的大致格式:

1.分配设置:usb_driver

2.在入口函数中注册,在出口函数中注销

下面我们就进行代码分析,分析一个驱动程序就是要从他的入口程序开始分析:

 

static int __init usb_mouse_init(void)
{
	int retval = usb_register(&usb_mouse_driver);  //注册usb_driver结构体
	if (retval == 0)
		info(DRIVER_VERSION ":" DRIVER_DESC);
	return retval;
}

我们可以看出这个入口函数中注册了usb_driver 结构体,而这个结构体做了什么那?我们看一下他的设置:

 

 

static struct usb_driver usb_mouse_driver = {
	.name		= "usbmouse",
	.probe		= usb_mouse_probe,
	.disconnect	= usb_mouse_disconnect,
	.id_table	= usb_mouse_id_table,       
};


我们可以看到这个结构体中定义了name,probe函数,disconnect函数,以及id_table结构体,而后面的三项是并不可少的,而id_table就是用来与device匹配时进行比较的。只有匹配成功才可以调用probe函数。我们先来看一下这个id_table中定义了什么:

 

 

static struct usb_device_id usb_mouse_id_table [] = {
	{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
		USB_INTERFACE_PROTOCOL_MOUSE) },
	{ }	/* Terminating entry */
};

代码中的USB_INTERFACE_INFO是个结构体:

 

 

/**
 * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces 
 * @cl: bInterfaceClass value
 * @sc: bInterfaceSubClass value
 * @pr: bInterfaceProtocol value
 *
 * This macro is used to create a struct usb_device_id that matches a
 * specific class of interfaces.
 */
#define USB_INTERFACE_INFO(cl,sc,pr) \
	.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \
	.bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)


通过注解可以知道这个宏是用来比较特定接口的结构体,而结合上边的id_table我们就可以知道,这个是通过比较接口类,接口子类以及接口协议来与设备进行匹配的。如果匹配成功那就将调用probe函数了:

 

 

static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)


内核中的probe函数喜欢先做初始化相关的工作:

 

 

	struct usb_device *dev = interface_to_usbdev(intf);    //定义一个usb_device的机构体
	struct usb_host_interface *interface;                  //定义一个usb主机接口
	struct usb_endpoint_descriptor *endpoint;              //定义一个端点描述符
	struct usb_mouse *mouse;                               //定义一个usb_mouse结构体
	struct input_dev *input_dev;                           //定义一个input_dev结构体 
	int pipe, maxp;                                        //定义源和最大包数量
	int error = -ENOMEM;

	interface = intf->cur_altsetting;                      //获得当前的接口

	if (interface->desc.bNumEndpoints != 1)                //对当前接口的端点的判断
		return -ENODEV;

	endpoint = &interface->endpoint[0].desc;              //获得端点,此处的endpoint[0]不是端点0,而是端点1
	if (!usb_endpoint_is_int_in(endpoint))                 //判断此端点是否为输入中断端点(鼠标是输入端点)
		return -ENODEV;

	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);  //获得源地址,这个宏还将端点的类型以及将端点的地址与设备地址绑定
	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));     //获得最大包的大小      

	mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);     //为usb_mouse分配空间
	input_dev = input_allocate_device();                     //分配input_dev结构体
	if (!mouse || !input_dev)
		goto fail1;

	mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);   //获得目的地址
	if (!mouse->data)
		goto fail1;

	mouse->irq = usb_alloc_urb(0, GFP_KERNEL);                    //分配urb(usb request block),用于传输数据
	if (!mouse->irq)
		goto fail2;

	mouse->usbdev = dev;                                        //将usb_device设备放入usb_mouse中
	mouse->dev = input_dev;                                   // 将input_dev放入usb_mouse中

 

从上面的代码可以看出,到这里probe主要做的就是定义各种将要用到的设备结构体,设备描述符结构体,并为其分配空间。同时还将通信时的源以及目标定义并获得相应的地址,并且定义了urb用于通信。

而下面这些则是通过usb_device和input_dev向usb_mouse这个结构体中添加数据:

 

	if (dev->manufacturer)                                                           
		strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));     //生产商

	if (dev->product) {
		if (dev->manufacturer)
			strlcat(mouse->name, " ", sizeof(mouse->name));
		strlcat(mouse->name, dev->product, sizeof(mouse->name));           //产品
	}

	if (!strlen(mouse->name))
		snprintf(mouse->name, sizeof(mouse->name),                  
			 "USB HIDBP Mouse %04x:%04x",
			 le16_to_cpu(dev->descriptor.idVendor),             //设备ID
			 le16_to_cpu(dev->descriptor.idProduct));           //产品ID

	usb_make_path(dev, mouse->phys, sizeof(mouse->phys));               //??
	strlcat(mouse->phys, "/input0", sizeof(mouse->phys)); 

	input_dev->name = mouse->name;                                      //设备名字
	input_dev->phys = mouse->phys;                                     //设备的物理地址
	usb_to_input_id(dev, &input_dev->id);                            //input_dev 的ID
	input_dev->dev.parent = &intf->dev;                                //设备的父类

而下面的代码就是要设置input_dev结构体了:

 

 

	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);            //定义产生按键类和相对位移类事件
	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); //按键类中的左键,右键,中键
	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);           //相对位移类的X和Y方向的位移
	input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);  //按键中的侧键以及附加键 
	input_dev->relbit[0] |= BIT(REL_WHEEL);               //相对位移中的滚轮位移

	input_set_drvdata(input_dev, mouse);                 //设置input_dev中的私有数据

	input_dev->open = usb_mouse_open;                    //定义开函数:应用层打开鼠标设备时此函数被调用
	input_dev->close = usb_mouse_close;                   //定义关函数:应用层关闭鼠标设备时此函数被调用	input_dev->close = usb_mouse_close;                   //定义关函数:应用层关闭鼠标设备时此函数被调用

 

 

而probe函数之后做的工作就是设置urb从而设置数据的传输:

 

 

 

/**
 * usb_fill_int_urb - macro to help initialize a interrupt urb
 * @urb: pointer to the urb to initialize.
 * @dev: pointer to the struct usb_device for this urb.
 * @pipe: the endpoint pipe
 * @transfer_buffer: pointer to the transfer buffer
 * @buffer_length: length of the transfer buffer
 * @complete_fn: pointer to the usb_complete_t function
 * @context: what to set the urb context to.
 * @interval: what to set the urb interval to, encoded like
 *	the endpoint descriptor's bInterval value.
 *
 * Initializes a interrupt urb with the proper information needed to submit
 * it to a device.
 * Note that high speed interrupt endpoints use a logarithmic encoding of
 * the endpoint interval, and express polling intervals in microframes
 * (eight per millisecond) rather than in frames (one per millisecond).
 */                                                                                                                      	usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
			 (maxp > 8 ? 8 : maxp),
			 usb_mouse_irq, mouse, endpoint->bInterval);
	mouse->irq->transfer_dma = mouse->data_dma;        //告诉urb物理地址
	mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;  //告诉urbMAP标记位
	the endpoint descriptor's bInterval value.
 *
 * Initializes a interrupt urb with the proper information needed to submit
 * it to a device.
 * Note that high speed interrupt endpoints use a logarithmic encoding of
 * the endpoint interval, and express polling intervals in microframes
 * (eight per millisecond) rather than in frames (one per millisecond).
 */                                                                                                                      	usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
			 (maxp > 8 ? 8 : maxp),
			 usb_mouse_irq, mouse, endpoint->bInterval);
	mouse->irq->transfer_dma = mouse->data_dma;        //告诉urb物理地址
	mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;  //告诉urbMAP标记位

usb_fill_int_urb函数的参数分别为:urb结构体,usb_device结构体,pipe源,目的地址(此处为虚拟地址),数据长度,中断函数(或完成函数),上下文,以访问时间间隔。
 

 

最后probe会注册input_dev,并将usb_mouse这个结构体放入usb_interface中:

 

error = input_register_device(mouse->dev);
usb_set_intfdata(intf, mouse);


虽然probe函数讲完了,但是他里面的usb_mouse_irq,usb_mouse_open函数还没有完善。下面我们一边讲解一边完善。我们知道主机控制器会不断的查询usb设备,当获得数据后就会将数存储到buffer中并产生中断函数从而导致usb_mouse_irq函数被调用,下面我就将这个函数:

 

 

static void usb_mouse_irq(struct urb *urb)
{
	struct usb_mouse *mouse = urb->context;  //定义usb_mouse
	signed char *data = mouse->data;         //定义目的
	struct input_dev *dev = mouse->dev;    //定义input_dev
	int status;

	input_report_key(dev, BTN_LEFT,   data[0] & 0x01); //上报左键状态
	input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);  //上报右键状态
	input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);  //上报中键状态
	input_report_key(dev, BTN_SIDE,   data[0] & 0x08);    //上报侧键状态
	input_report_key(dev, BTN_EXTRA,  data[0] & 0x10);  //上报附加建状态

	input_report_rel(dev, REL_X,     data[1]);           //上报相对位移中X方向位移
	input_report_rel(dev, REL_Y,     data[2]);          //上报相对位移中Y方向位移
	input_report_rel(dev, REL_WHEEL, data[3]);          //上报相对位移中滚轮方向位移

	input_sync(dev);                               //上报同步事件
resubmit:
	status = usb_submit_urb (urb, GFP_ATOMIC);        //提交urb
	if (status)
		err ("can't resubmit intr, %s-%s/input0, status %d",
				mouse->usbdev->bus->bus_name,
				mouse->usbdev->devpath, status);
}

我们可以看出,usb_mouse_irq函数主要的工作就是上报数据。我们说过在usb驱动中我们没有直接直接对硬件的读写函数,而是通过usb总线驱动程序获得读写的函数,但是驱动知道数据的含义,所以他会对数据进行处理。并将这些数据通过urb传输。

 

而接下来我们要介绍的就是usb_mouse_open函数。当应用层打开鼠标设备时,usb_mouse_open将被调用,这句话告诉我们这个函数什么时候被调用。 代码为:

 

static int usb_mouse_open(struct input_dev *dev)
{
	struct usb_mouse *mouse = input_get_drvdata(dev);

	mouse->irq->dev = mouse->usbdev;
	if (usb_submit_urb(mouse->irq, GFP_KERNEL))        //上报urb
		return -EIO;

	return 0;
}


从上面的代码中我们知道,usb_mouse_open函数的主要工作就是上报urb,当应用层打开鼠标设备时,就上报urb,然后就回到上面中断函数中的不断将按键和位移上报。

 

讲到这里,这个驱动程序就讲完了,而我还是想说前面的那句话,作为要学习驱动的同学,有时候多看看内核自己的驱动代码还是有好处的,虽然有时候你会觉得很难看懂,这时候你可以去网上找一下,也许有很好的解释。

这里我贴一篇对我有帮助的文章:

嵌入式linux下如何使用usb键盘和鼠标

 


 

 

 

Android 14.0 通过驱动实现禁用usb鼠标和usb键盘功能 在14.0的系统产品定制化开发中,在进行定制中有关于usb键盘和usb鼠标的需求中,产品要求禁止usb口挂载usb鼠标和usb键盘,所以需要要求在usb挂载类型的时候 判断如果是usb鼠标和usb键盘就不让挂载,这就需要从驱动方面入手来解决这个问题,接下来看下驱动的某些挂载usb的相关文件来解决这个功能的禁用问题 阅读详情

相关推荐

Android 12.0 通过驱动实现禁用usb鼠标和usb键盘功能

在12.0的系统产品定制化开发中,在进行定制中有关于usb键盘和usb鼠标的需求中,产品要求禁止usb口挂载usb鼠标和usb键盘,所以需要要求在usb挂载类型的时候 判断如果是usb鼠标和usb键盘就不让挂载,这就需要从驱动方面入手来解决这个问题,接下来看下驱动的某些挂载usb的相关文件来解决这个功能的禁用问题

安卓兼职framework和app工程师的博客 2217

Linux+USB+鼠标驱动程序详解

USB 总线引出两个重要的链表! 一个 USB 总线引出两个重要的链表,一个为 USB 设备链表,一个为 USB 驱动链表。设备链表包含各种系统中的 USB 设备以及这些设备的所有接口,驱动链表包含 USB 设备驱动程序(usb device driver)和 USB 驱动程序(usb driver)。 USB 设备驱动程序(usb device driver)和 USB 驱动程序(usb d

飞天鱼 953

学习LINUX下的USBMOUSE.C鼠标驱动模块

学习LINUX下的USBMOUSE.C鼠标驱动模块,加载到内核中使用~ 主要是带了详细的中文解释,可以方便新人学代码或者过课设

系统自带 usbmouse.c usbkbd.c

D:\source_code\linux-2.6.22.6\drivers\hid\usbhid\usbmouse.c #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include <l...

zmjames2000 Just record 476

usbmouse.c(usbmouse.c剖析系列文章分析的usbmouse.c源码)

[干货][linux][usb][usbmouse]:usbmouse.c剖析系列文章分析的usbmouse.c源码

Cocos Creator3.5.2使用Spine切换皮肤

3、然后获取当前spine中是否有皮肤数据,如果spine连皮肤数据都没有,接着写可能会error,这里的 skins[skin],是判断皮肤列表中是否有需要更换的皮肤。2、因为spine往往意味着异步加载,换肤时也经常出现频繁异步的情况,所以下一步我们要可以判断当前spine组件里是否已经加载好了spine文件。换肤前隐藏好需要换肤的节点,避免穿帮;官网文档的换肤流程太简化,对于实际使用来说会有各种各样的问题。1、首先获取对应的spine组件。这里的skin自然是外部传入的需要换肤的皮肤名。

tc654321的博客 1818

[干货][linux][usb][usbmouse]:usbmouse.c剖析(第二话)

USB 背景知识介绍: 目录 USB 背景知识介绍: #1 USB的各个版本/传输速率/英文别名/输出电流 #2 USB驱动框架 其中usbmouse.c就属于USB设备驱动,USB Core 和 USB 主机控制器内核已经帮我们实现。 内核是伟大的,为了减缓程序搬砖民工脱发的速度,默默的奉献了自己的靓丽青春。 # USB 电器特性 # USB的四种传输方式 那么,usbmouse.c会用到其中的控制传输和中断传输。 这里的中断并非物理意义上的IRQ, .

天天搬砖的秃头程序员的博客 392

安卓无障碍服务保活实战:如何用AccessibilityService实现后台常驻(附完整代码)

本文深入解析如何利用Android无障碍服务(AccessibilityService)实现后台服务保活,涵盖多版本系统适配、前台服务集成、开机自启机制等关键技术。通过详细的Kotlin代码示例和合规性指导,帮助开发者构建稳定可靠的后台服务解决方案,同时避免因滥用无障碍服务导致的应用下架风险。

milk5的博客 1073

[干货][linux][usb][usbmouse]:usbmouse.c剖析(第一话)

# 问题:想学习一下usb 模块驱动,哪个driver比较适合入门。 推荐:Usbmouse.c (drivers\hid\usbhid) 6857 2015/3/24 原因嘛,第一它的代码量真的少,第二它麻雀虽小五脏俱全,废话少说,开始解剖吧。 思维导图登场先: 图中标号1 ~ 10 就是插入mouse后,该c文件的执行过程。 同时牵涉到input框架和usb框架, 后续我们一个一个分析。 欲知详情如何,且待下回分解。 ...

天天搬砖的秃头程序员的博客 254

告别手动发日报!用n8n+钉钉打造智能报告机器人(含模板下载)

本文详细介绍了如何利用n8n开源工作流自动化平台与钉钉机器人搭建智能日报系统,实现数据自动采集、处理和发送。通过实战步骤和模板下载,帮助用户告别手动处理日报的繁琐,提升工作效率和数据准确性。

h3i4j的博客 857

堆一呼一吸之间:动态扩缩容引发JVM堆内存震荡的伸缩算法、代际传导与容器定容解析

Kubernetes扩容后,新Java实例的GC频率常比老实例高出数倍,堆容量反复伸缩。本文从一次支付系统的GC陡增出发,结合HotSpot源码与JDK 8实测,拆解堆伸缩的记账规则:期望容量以GC后已用量为基数、以Xms为下限,按空闲比例判断扩缩,收缩只在老年代回收后按0%、10%、40%、100%步进;再剖析年轻代随老年代联动、晋升风暴与元空间触发线,对比Parallel、G1、ZGC等收集器及JDK 26的变化,讨论容器分账、HPA共振与原地扩缩容,最后给出分级定容、预热与监控的方案。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 15万+

USB驱动——鼠标驱动程序(中断传输)

本文以 usbmouse.c 为例,简单分析usb鼠标驱动程序。 static int __init usb_mouse_init(void) { int retval = usb_register(&usb_mouse_driver); if (retval == 0) printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"

漫不经心 4011

使用libVLC进行视频截图的C/C++实现

通过这些代码,你可以在C/C++应用程序中实现视频截图功能,并将视频帧保存为图像文件。请注意,本文只提供了基本的示例代码,你可以根据自己的需求进行扩展和修改。libVLC是一个强大的开源多媒体框架,可以用于在C/C++应用程序中处理和播放音频和视频文件。我们将展示如何初始化libVLC,打开视频文件,捕获视频帧并保存为图像文件。在开始编写代码之前,你需要包含libVLC的头文件,并链接相应的库文件。在链接阶段,你需要添加libVLC库的链接选项。在使用libVLC之前,你需要初始化libVLC的实例。

学习使你进步。 471

Linux下的USB驱动资料收集

USB驱动资料收集 Linux下的USB总线驱动(01)——USB理论  Linux下的USB总线驱动(02)——USB框架usb-skeleton.c  Linux下的USB总线驱动(03)——USB鼠标驱动 usbmouse.c  Linux下的USB总线驱动(04)——USB键盘驱动 usbkbd.c

Android开发 694

YOLOv11改进,YOLOv11结合DynamicConv(动态卷积),CVPR2024,二次创新C3k2结构

DynamicConv(动态卷积)是一个用于提高卷积神经网络(CNN)性能的技术,核心思想是动态地生成卷积核(filter),而不是使用固定的卷积核。通过引入更多的计算灵活性和适应性来增强卷积操作的表达能力,进而提升模型的性能。专家选择:DynamicConv 通过引入多个“专家”(experts),每个专家学习特定的卷积模式。输入图像的不同部分会选择不同的专家进行卷积。动态卷积核生成:根据输入的不同特征,专家网络动态地生成卷积核,而不是使用固定的卷积核。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 2263

Ollama系列---【ollama使用gpu运行大模型】

一、安装CudaToolkit 使用控制台命令查看当前显卡驱动中的cuda版本 nvidia-smi 二、下载CudaToolkit 注意:CudaToolkit版本要低于上面的显卡Cuda版本。 Cuda各版本下载地址:https://developer.nvidia.com/cuda-toolkit-archive 下载好之后,一路下一步,一直默认即可。 如果安装到了自定义的位置,记得加环...

-少年-的博客 7982

arm 驱动进阶:usb驱动程序设计过程与实现

usb驱动程序设计实现步骤: usb总线驱动内核代码分析过程: analysis code hub_irq kick_khubd hub_thread hub_events hub_port_connect_change ...

372

【深度学习新浪潮】OpenClaw技术架构详解:从核心组件到生产级优化

OpenClaw 以三层解耦架构 + 四大核心模块为基础,实现了本地优先、易部署、易扩展、易优化的 AI 智能体平台。开发者可通过极简部署快速落地,再通过量化、缓存、并发、分布式等手段持续优化性能,适合从个人助理到企业级自动化的全场景应用。

专注:太空算力、AI infra、异构调度、大模型成本工程 2921

USB驱动程序(三)——鼠标驱动程序(中断传输)

本文以 usbmouse.c 为例,简单分析usb鼠标驱动程序。 [cpp] view plain copy  print? static int __init usb_mouse_init(void)   {       int retval = usb_register(&usb_mouse_driver);       if (retv

yangguoyu8023的博客 915

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

usb驱动(1)

usbmouse_as_key.c /*  * drivers\hid\usbhid\usbmouse.c  */ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include...

qq_35270493的博客 113

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Linux下的USB总线驱动(二)

版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127   2.USB鼠标驱动 usbmouse.c 下面我们分析下USB鼠标驱动,鼠标输入HID类型,其数据传输采用中断URB,鼠标端点类型为IN。好了,我们先看看这个驱动的模块加载部分。 static int __init usb_mouse_init(void) {     

jianghuan555的专栏 418

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Linux usb设备驱动(2)---> usbmouse.c 源码分析

一个 USB 总线引出两个重要的链表,一个为 USB设备链表,一个为 USB驱动链表。设备链表包含各种系统中的 USB设备以及这些设备的所有接口,驱动链表包含 USB 设备驱动程序(usb device driver)和 USB驱动程序(usb driver)。   1. USB设备驱动程序(usb device driver)和 USB驱动程序(usb driver)的区别是什

1405

Linux下的USB总线驱动(03)——USB鼠标驱动 usbmouse.c

USB鼠标驱动 usbmouse.c 原文链接:http://www.linuxidc.com/Linux/2012-12/76197p7.htm drivers/hid/usbhid/usbmouse.c 下面我们分析下USB鼠标驱动,鼠标输入HID类型,其数据传输采用中断URB,鼠标端点类型为IN。我们先看看这个驱动的模块加载部分。 [cpp]view ...

FLY_THINK2012的博客 188

【北京迅为】iTOP-4412精英版使用手册-第六十七章 USB鼠标驱动详解

其中的参数 name,则是驱动名称“usbmouse”,既然有驱动名称,那一定有设备名称,请注意前面介绍过的 USB 描述符,USB 描述符的具体内容是在USB 设备中的,相当于设备注册是在实体的“USB 设备”中!可以这样类比,当我们要到大学报到的时候,我们要填写学籍档案,假设学籍档案中信息都在户口簿上,例如:姓名、籍贯以及身份证号等等,这些信息从户口簿传递到学籍档案中,信息其实是一样的,只是在户口簿和学籍档案中组织形式不一样,名称不一样,实际包含的信息是一样的。主机只能和 USB 设备的“端点”通信;

BeiJingXunWei的博客 1086

Linux 驱动开发之USB设备分析7

Linux 驱动开发之USB设备分析7(基于Linux6.6)---USB鼠标驱动介绍

ListQ的博客 1211
上一篇: 嵌入式Linux —— usb鼠标驱动
下一篇: 嵌入式Linux——块设备驱动
moxue10
博客等级 码龄19年 388粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值