Linux usb设备驱动(2)---> 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设备链表,一个为 USB驱动链表。设备链表包含各种系统中的 USB设备以及这些设备的所有接口,驱动链表包含 USB 设备驱动程序(usb device driver)和 USB驱动程序(usb driver)。

 

1. USB设备驱动程序(usb device driver)和 USB驱动程序(usb driver)的区别是什么?

USB 设备驱动程序包含 USB 设备的一些通用特性,将与所有 USB设备相匹配。在 USB core 定义了:struct usb_device_driver usb_generic_driver。usb_generic_driver是 USB 子系统中唯一的一个设备驱动程序对象。而 USB驱动程序则是与接口相匹配,接口是一个完成特定功能的端点的集合。

 

2.设备是如何添加到设备链表上去的?

在设备插入 USB控制器之后,USB core 即会将设备在系统中注册,添加到 USB设备链表上去。

 

3. USB设备驱动程序(usb device driver)是如何添加到驱动链表上去的?

在系统启动注册 USB core时,USB 设备驱动程序即将被注册,也就添加到驱动链表上去了。

 

4.接口是如何添加到设备链表上去的?

在 USB 设备驱动程序和 USB 设备的匹配之后,USB core会对设备进行配置,分析设备的结构之后会将设备所有接口都添加到设备链表上去。比如鼠标设备中有一个接口,USB core对鼠标设备配置后,会将这个接口添加到设备链表上去。

 

5. USB驱动程序(usb driver)是如何添加到驱动链表上去的?

在每个 USB驱动程序被注册时,USB 驱动程序即会添加到驱动链表上去。比如鼠标驱动程序,usb_mouse_init函数将通过 usb_register(&usb_mouse_driver)将鼠标驱动程序注册到 USB core 中,然后就添加到驱动链表中去了。其中 usb_mouse_driver是描述鼠标驱动程序的结构体。

 

-------------------------------------------------------------------------------------------------------

已配置状态(configured status)之后话

 

当鼠标的设备、接口都添加到设备链表,并且鼠标驱动程序也添加到驱动链表上去了,系统就进入一种叫做已配置(configured)的状态。要达到已配置状态,将经历复杂的过程,USB core 为 USB 设备奉献着无怨无悔。在这个过程中,系统将会建立起该设备的的设备、配置、接口、设置、端点的描述信息,它们分别被 usb_device、usb_configuration、usb_interface、usb_host_interface、usb_host_endpoint结构体描述。

设备达到已配置状态后,首先当然就要进行 USB驱动程序和相应接口的配对,对于鼠标设备来说则是鼠标驱动程序和鼠标中的接口的配对。USB core会调用 usb_device_match 函数,通过比较设备中的接口信息和 USB驱动程序中的 id_table,来初步决定该 USB驱动程序是不是跟相应接口相匹配。通过这一道关卡后,USB core会认为这个设备应该由这个驱动程序负责。

然而,仅仅这一步是不够的,接着,将会调用 USB驱动程序中的 probe 函数对相应接口进行进一步检查。如果该驱动程序确实适合设备接口,对设备做一些初始化工作,分配 urb准备数据传输。

当鼠标设备在用户空间打开时,将提交 probe函数构建的 urb请求块,urb将开始为传送数据而忙碌了。urb请求块就像一个装东西的“袋子”,USB驱动程序把“空袋子”提交给 USB core,然后再交给主控制器,主控制器把数据放入这个“袋子”后再将装满数据的“袋子”通过 USB core 交还给 USB驱动程序,这样一次数据传输就完成了。

 

 

以下是完全注释后的鼠标驱动程序代码 usbmouse.c

 

view plaincopy to clipboardprint?

 * $Id: usbmouse.c,v 1.15 2001/12/27 10:37:41 vojtech Exp $ 

 * Copyright (c) 1999-2001 Vojtech Pavlik 

 * USB HIDBP Mouse support 

 */ 

 

#include <linux/kernel.h>   

#include <linux/slab.h>   

#include <linux/module.h>   

#include <linux/init.h>   

#include <linux/usb/input.h>   

#include <linux/hid.h>   

 

/* 

 * Version Information 

 */ 

#define DRIVER_VERSION "v1.6"   

#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"   

#define DRIVER_DESC "USB HID Boot Protocol mouse driver"   

#define DRIVER_LICENSE "GPL"   

 

MODULE_AUTHOR(DRIVER_AUTHOR);  

MODULE_DESCRIPTION(DRIVER_DESC);  

MODULE_LICENSE(DRIVER_LICENSE);  

 

/* 

 * 鼠标结构体,用于描述鼠标设备。 

 */ 

struct usb_mouse   

{  

    /* 鼠标设备的名称,包括生产厂商、产品类别、产品等信息 */ 

    char name[128];   

    /* 设备节点名称 */ 

char phys[64];    

    //鼠标:鼠标设备结构体,输入设备结构体

    /* USB鼠标是一种 USB 设备,需要内嵌一个 USB设备结构体来描述其 USB属性 */ 

    struct usb_device  *usbdev;  

    /* USB鼠标同时又是一种输入设备,需要内嵌一个输入设备结构体来描述其输入设备的属性 */ 

    struct input_dev *dev;    

    /* URB请求包结构体,用于传送数据 */ 

    struct urb *irq;  

    /* 普通传输用的地址 */ 

    signed char *data;  

    /* dma传输用的地址 */ 

    dma_addr_t data_dma;          

};  

 

/* 

 * urb回调函数,在完成提交 urb后,urb回调函数将被调用。 

 * 此函数作为 usb_fill_int_urb 函数的形参,为构建的 urb制定的回调函数。 

 */ 

static void usb_mouse_irq(struct urb *urb)  

{  

/* urb 中的 context 指针用于为 USB驱动程序保存一些数据。比如在这个回调函数的形参没有传递在 probe中为 mouse结构体分配的那块内存的地址指针,而又需要用到那块内存区域中的数据,context指针则帮了大忙了!在填充 urb 时将 context指针指向 mouse 结构体数据区,在这又创建一个局部 mouse指针指向在 probe函数中为 mouse申请的那块内存,那块内存保存着非常重要数据。当 urb 通过 USB core 提交给 hc之后,如果结果正常,mouse->data 指向的内存区域将保存着鼠标的按键和移动坐标信息,系统则依靠这些信息对鼠标的行为作出反应。mouse中内嵌的 dev 指针,指向 input_dev所属于的内存区域*/ 

 

    struct usb_mouse *mouse = urb->context;  

    signed char *data = mouse->data;  

    struct input_dev *dev = mouse->dev;  

    int status;  

 

    /* 

     * status值为 0 表示 urb成功返回,直接跳出循环把鼠标事件报告给输入子系统。 

     * ECONNRESET出错信息表示 urb 被 usb_unlink_urb函数给 unlink 了,ENOENT出错信息表示 urb 被  

     * usb_kill_urb函数给 kill 了。usb_kill_urb表示彻底结束 urb 的生命周期,而 usb_unlink_urb则 

     * 是停止 urb,这个函数不等 urb完全终止就会返回给回调函数。这在运行中断处理程序时或者等待某自旋锁 

     * 时非常有用,在这两种情况下是不能睡眠的,而等待一个 urb 完全停止很可能会出现睡眠的情况。 

     * ESHUTDOWN这种错误表示 USB 主控制器驱动程序发生了严重的错误,或者提交完 urb的一瞬间设备被拔出。 

     * 遇见除了以上三种错误以外的错误,将申请重传 urb。 

     */ 

    switch (urb->status)  

    {  

    case 0:     /* success */ 

        break;  

    case -ECONNRESET:   /* unlink */ 

    case -ENOENT:  

    case -ESHUTDOWN:  

        return;  

    /* -EPIPE:  should clear the halt */ 

    default:        /* error */ 

        goto resubmit;  

    }  

    /* 

     * 向输入子系统汇报鼠标事件情况,以便作出反应。 

     * data数组的第0个字节:bit 0、1、2、3、4分别代表左、右、中、SIDE、EXTRA键的按下情况; 

     * data数组的第1个字节:表示鼠标的水平位移; 

     * data数组的第2个字节:表示鼠标的垂直位移; 

     * data数组的第3个字节:REL_WHEEL位移。 

     */ 

    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]);  

    input_report_rel(dev, REL_Y,     data[2]);  

    input_report_rel(dev, REL_WHEEL, data[3]);  

 

    / *这里是用于事件同步。上面几行是一次完整的鼠标事件,包括按键信息、绝对坐标信息和滚轮信息,输入子系统正是通过这个同步信号来在多个完整事件报告中区分每一次完整事件报告。示意如下: 

按键信息坐标位移信息滚轮信息 EV_SYC |按键信息坐标位移信息滚轮信息 EV_SYC ... 

     */ 

    input_sync(dev);  

 

    /* 系统需要周期性不断地获取鼠标的事件信息,因此在 urb回调函数的末尾再次提交 urb请求块,这样又会调用新的回调函数,周而复始。 

    在回调函数中提交 urb一定只能是 GFP_ATOMIC 优先级的,因为 urb回调函数运行于中断上下文中,在提交 urb 过程中可能会需要申请内存、保持信号量,这些操作或许会导致 USB core睡眠,一切导致睡眠的行为都是不允许的。 

     */ 

resubmit:  

    status = usb_submit_urb (urb, GFP_ATOMIC);  

    if (status)  

        err ("can't resubmit intr, %s-%s/input0, status %d",  

                mouse->usbdev->bus->bus_name,  

                mouse->usbdev->devpath, status);  

}  

/* 

 * 打开鼠标设备时,开始提交在 probe函数中构建的 urb,进入 urb周期。 

 */ 

static int usb_mouse_open(struct input_dev *dev)  

{  

    struct usb_mouse *mouse = dev->private;  

    mouse->irq->dev = mouse->usbdev;  

    if (usb_submit_urb(mouse->irq, GFP_KERNEL))  

        return -EIO;  

    return 0;  

}  

 

/* 

 * 关闭鼠标设备时,结束 urb 生命周期。 

 */ 

static void usb_mouse_close(struct input_dev *dev)  

{  

    struct usb_mouse *mouse = dev->private;  

 

    usb_kill_urb(mouse->irq);  

}  

 

/* 

 * 驱动程序的探测函数 

 */ 

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

{  

    /*  

     * 接口结构体包含于设备结构体中,interface_to_usbdev 是通过接口结构体获得它的设备结构体。 

     * usb_host_interface是用于描述接口设置的结构体,内嵌在接口结构体 usb_interface中。 

     * usb_endpoint_descriptor是端点描述符结构体,内嵌在端点结构体 usb_host_endpoint中,而端点 

     * 结构体内嵌在接口设置结构体中。 

     */ 

    struct usb_device *dev = interface_to_usbdev(intf);  

    struct usb_host_interface *interface;  

    struct usb_endpoint_descriptor *endpoint;  

    struct usb_mouse *mouse;  

    struct input_dev *input_dev;  

    int pipe, maxp;  

 

    interface = intf->cur_altsetting;  

 

    /* 鼠标仅有一个 interrupt 类型的 in端点,不满足此要求的设备均报错 */ 

    if (interface->desc.bNumEndpoints != 1)  

        return -ENODEV;  

 

    endpoint = &interface->endpoint[0].desc;  

    if (!usb_endpoint_is_int_in(endpoint))  

        return -ENODEV;  

 

    /* 

     * 返回对应端点能够传输的最大的数据包,鼠标的返回的最大数据包为4个字节,数据包具体内容在 urb 

     * 回调函数中有详细说明。 

     */ 

    pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);  

    maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));  

 

    /* 为 mouse 设备结构体分配内存 */ 

    mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);  

    /* input_dev */ 

    input_dev = input_allocate_device();  

    if (!mouse || !input_dev)  

        goto fail1;  

 

    /* 申请内存空间用于数据传输,data 为指向该空间的地址,data_dma则是这块内存空间的 dma 映射,即这块内存空间对应的 dma地址。在使用 dma 传输的情况下,则使用 data_dma指向的 dma 区域,否则使用 data指向的普通内存区域进行传输。 

     * GFP_ATOMIC表示不等待,GFP_KERNEL是普通的优先级,可以睡眠等待,由于鼠标使用中断传输方式,不允许睡眠状态,data又是周期性获取鼠标事件的存储区,因此使用 GFP_ATOMIC优先级,如果不能分配到内存则立即返回 0。 

     */ 

    mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);  

    if (!mouse->data)  

        goto fail1;  

 

    /* 为 urb 结构体申请内存空间,第一个参数表示等时传输时需要传送包的数量,其它传输方式则为0。申请的内存将通过下面即将见到的 usb_fill_int_urb函数进行填充。  

     */ 

    mouse->irq = usb_alloc_urb(0, GFP_KERNEL);  

    if (!mouse->irq)  

        goto fail2;  

 

    /* 填充 usb 设备结构体和输入设备结构体 */ 

    mouse->usbdev = dev;  

    mouse->dev = input_dev;  

 

    /* 获取鼠标设备的名称 */ 

    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),  

             le16_to_cpu(dev->descriptor.idProduct));  

 

    /* 

     * 填充鼠标设备结构体中的节点名。usb_make_path 用来获取 USB设备在 Sysfs 中的路径,格式 

     * 为:usb-usb 总线号-路径名。 

     */ 

    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;  

   

     /* input_dev中的 input_id 结构体,用来存储厂商、设备类型和设备的编号,这个函数是将设备描述符中的编号赋给内嵌的输入子系统结构体 

     */ 

    usb_to_input_id(dev, &input_dev->id);  

    /* cdev是设备所属类别(class device) */ 

    input_dev->cdev.dev = &intf->dev;  

 

    /* evbit 用来描述事件,EV_KEY是按键事件,EV_REL是相对坐标事件 */ 

    input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);  

    /* keybit表示键值,包括左键、右键和中键 */ 

    input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);  

    /* relbit用于表示相对坐标值 */ 

    input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);  

    /* 有的鼠标还有其它按键 */ 

    input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);  

    /* 中键滚轮的滚动值 */ 

    input_dev->relbit[0] |= BIT(REL_WHEEL);  

 

   /* input_dev 的 private数据项用于表示当前输入设备的种类,这里将鼠标结构体对象赋给它 */ 

    input_dev->private = mouse;  

    /*填充输入设备打开函数指针 */  ---- >>>> 参照输入子系统

    input_dev->open = usb_mouse_open;  

    /* 填充输入设备关闭函数指针 */ 

    input_dev->close = usb_mouse_close;  

 

    /* 填充构建 urb,将刚才填充好的 mouse结构体的数据填充进 urb结构体中,在 open中递交 urb。当 urb包含一个即将传输的 DMA 缓冲区时应该设置 URB_NO_TRANSFER_DMA_MAP。USB核心使用transfer_dma变量所指向的缓冲区,而不是transfer_buffer变量所指向的。URB_NO_SETUP_DMA_MAP用于 Setup 包,URB_NO_TRANSFER_DMA_MAP用于所有 Data 包。 

     */ 

    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;  

    mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;  

 

    /* 向系统注册输入设备 */ 

    input_register_device(mouse->dev);  

 

    /*  一般在 probe函数中,都需要将设备相关信息保存在一个 usb_interface结构体中,以便以后通过usb_get_intfdata 获取使用。这里鼠标设备结构体信息将保存在 intf 接口结构体内嵌的设备结构体中的 driver_data数据成员中,即 intf->dev->dirver_data = mouse。 

     */ 

    usb_set_intfdata(intf, mouse);  

    return 0;  

 

fail2:  usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);  

fail1:  input_free_device(input_dev);  

    kfree(mouse);  

    return -ENOMEM;  

}  

 

/* 

 * 鼠标设备拔出时的处理函数 

 */ 

static void usb_mouse_disconnect(struct usb_interface *intf)  

{  

    /* 获取鼠标设备结构体 */ 

struct usb_mouse *mouse = usb_get_intfdata (intf);  

 

    /* intf->dev->dirver_data = NULL,将接口结构体中的鼠标设备指针置空。*/ 

    usb_set_intfdata(intf, NULL);   

    if (mouse)  

    {  

        /*结束 urb 生命周期 */ 

        usb_kill_urb(mouse->irq);  

        /*将鼠标设备从输入子系统中注销 */ 

        input_unregister_device(mouse->dev);  

        /*释放 urb 存储空间 */ 

        usb_free_urb(mouse->irq);  

        /* 释放存放鼠标事件的 data存储空间 */ 

        usb_buffer_free (interface_to_usbdev(intf),

8, mouse->data, mouse->data_dma);  

        /*释放存放鼠标结构体的存储空间 */ 

        kfree(mouse);  

    }  

}  

 

/* 

 * usb_device_id 结构体用于表示该驱动程序所支持的设备,USB_INTERFACE_INFO可以用来匹配特定类型的接口,这个宏的参数意思为 (类别,子类别, 协议)。USB_INTERFACE_CLASS_HID表示是一种 HID (Human Interface Device),即人机交互设备类别;

 USB_INTERFACE_SUBCLASS_BOOT是子类别,表示是一种 boot 阶段使用的 HID; USB_INTERFACE_PROTOCOL_MOUSE表示是鼠标设备,遵循鼠标的协议。 

 */ 

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驱动程序来说,第一个参数必须是usb。 

 */ 

MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);  

 

/* 

 *鼠标驱动程序结构体 

 */ 

static struct usb_driver usb_mouse_driver = {  

    .name       = "usbmouse",  

    .probe      = usb_mouse_probe,  

    .disconnect = usb_mouse_disconnect,  

    .id_table   = usb_mouse_id_table,  

};  

 

/* 

 *驱动程序生命周期的开始点,向 USB core注册这个鼠标驱动程序。 

 */ 

static int __init usb_mouse_init(void)  

{  

    int retval = usb_register(&usb_mouse_driver);  

    if (retval == 0)  

        info(DRIVER_VERSION ":" DRIVER_DESC);  

    return retval;  

}  

 

/* 

 *驱动程序生命周期的结束点,向 USB core注销这个鼠标驱动程序。 

 */ 

static void __exit usb_mouse_exit(void)  

{  

    usb_deregister(&usb_mouse_driver);  

}  

 

module_init(usb_mouse_init);  

module_exit(usb_mouse_exit); 

 


VC6.0 USB HID通信源代码详解与应用 本文还有配套的精品资源,点击获取 简介:本源代码旨在VC6.0环境下,实现与USB HID设备的通信功能。开发者可以利用此代码与键盘、鼠标等HID类设备直接交互,无需额外驱动程序。源代码中包含关键组件如HID类库、设备枚举、设备描述符解析、IO控制、事件处理和错误处理等,旨在帮助开发者深入理解USB HID通信机制,并实现应用层的逻辑。同时,考虑到与不同Windows系统的... 阅读详情

相关推荐

cyusb_linux_1.0.5.tar.gz

cyusb的linux应用库,基于libusb,可以直接操作usb2.0、3.0设备,避免了在linux上开发驱动的麻烦。

分析USB鼠标——usbmouse.c

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

静祥阁 2525

CY7C68013A签名的驱动

自己从CY3684-FX2LP DVK安装包里提取出来的(cy3684kit_revSA), 这个是3.4.5签名的驱动,能在64位的windows7下使用。

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

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

飞天鱼 953

从零构建OpenBMC风扇控制:基于phosphor-pid-control的实战配置指南

本文详细介绍了如何从零开始构建OpenBMC风扇控制系统,基于phosphor-pid-control框架实现风扇自动调速。通过解析PID算法配置、传感器定义及控制区域设置,提供工业级散热解决方案,帮助开发者优化服务器能效与可靠性。

weixin_29263201的博客 747

OpenClaw 接入智谱 GLM-5-Turbo 龙虾套餐:完整避坑指南与 SOP

OpenClaw 接入智谱 GLM-5-Turbo 的核心在于“端点匹配”和“多渠道验证”。端点匹配:龙虾套餐必须用标准端点。多渠道验证:遇到 TUI 不显示时,用curl或飞书机器人验证,不要被 Bug 误导。希望这份 SOP 能帮你顺利跑通 OpenClaw + GLM-5-Turbo,享受强大的 AI 编程助手!

Aaron_liu20的博客 1702

系统自带 usbmouse.c usbkbd.c

D:\source_code\linux-2.6.22.6\drivers\hid\usbhid\usbmouse.c #include &lt;linux/kernel.h&gt; #include &lt;linux/slab.h&gt; #include &lt;linux/module.h&gt; #include &lt;linux/init.h&gt; #include &lt;l...

zmjames2000 Just record 476

微带天线理论学习笔记(1)

微带天线的概念是由Deschamps于1953年提出来的,它是在一块厚度远小于工作波长的介质基片的一面敷以金属辐射片、一面全部敷以金属薄层作接地板而成。辐射片可以根据不同的要求设计成各种形状。微带天线具有质量轻、体积小和易于制造等优点,广泛应用于个人无线通信中。

qq_36521926的博客 6227

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

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

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

深入解析XTEA加密算法的核心机制与优化策略

本文深入解析XTEA加密算法的核心机制与优化策略,详细介绍了XTEA在嵌入式系统和资源受限环境中的优势,包括其高效的加解密速度和低资源消耗。文章还探讨了XTEA的轮函数设计、关键参数优化策略以及实战应用中的性能对比,为开发者提供了安全增强方案和优化技巧。

k8l9m0n的博客 242

YOLOv11改进缝合FasterBlock | 一种新型轻量化卷积结构C3k2的设计与实证:兼顾精度与速度的改进方法(附代码)

YOLO系列一直是目标检测领域的明星算法,凭借其实时性和准确性在众多应用中占据一席之地。随着YOLO版本的不断迭代,网络架构逐渐变得更为复杂,尤其是在卷积模块的设计上。本文将介绍如何利用FasterNet的FasterBlock创新,并通过二次创新C3k2提出一种全新的卷积结构。该结构旨在提高YOLOv11的计算效率和准确性,特别是在视觉任务中的表现。我们的创新在保证高精度的前提下,有效降低了计算量和内存需求,特别适合在资源受限的设备上运行。

一键难忘的博客 906

串行协议——USB驱动[基础]

串行协议——USB驱动[基础知识],Linux内核驱动源码分析,pl2303和mouse驱动源码分析

啥也不懂的研究生也淦SLAM的博客 768

如何使用DPABI 进行核磁共振数据结果统计分析?

下面总结使用DPABI 的统计模块对MRI 图像进行统计分析的基本方法,并与SPM 的统计结果进行简单的对比。DPABI 的统计模块包含了常用的统计模型和多重比较校正方法、在控制协变量上也非常方便。 DPABI 进行结果统计分析一、下载和安装 DPABI二、下载样例数据三、统计模型和多重比较校正四、DPABI 的统计主界面五、DPABI 的可视化主界面六、查看统计结果 一、下载和安装 DPABI 下载 DPABI 包,解压后将文件夹和子文件夹加入MATLAB 的搜索路径即可。 具体安装方法详见 dpabi

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 1万+

Linux USB驱动阅读笔记(1)

本文是对相关 USB 驱动技术文章的补充与拓展。内容围绕 Linux USB 体系结构展开,深入补充了四个核心板块:USB 总线的设备查询与 Hub 传输机制;usb-skeleton 框架中的 DMA 机制与读写逻辑;USB 子系统核心的事件队列(usb_hub_wq)与主控初始化流程;以及 USB 鼠标驱动中 usb_mouse 与 input_dev 的结构体绑定和 URB 中断处理细节,旨在补全原文章的底层技术实现。

kdxiaojie的博客 526

【无人机项目实战】第三章:fast_planner工程解读(附C++代码)

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、规划系统运行逻辑【业务部分】1.Fast_planner_node.cpp【程序入口】功能代码实现2.kino_replan_fsm.cpp【状态机转移】功能代码实现KinoReplanFSM::init()函数订阅目标点回调函数订阅里程计回调函数检查路径规划是否成功【重要】执行状态机FSM定时器回调函数【重要】判断目标点是否有障碍物或者是轨迹执行过程中是否有障碍物的回调函数3

qq_35635374的博客 1万+

【AI技术赋能有限元分析应用实践】Abaqus有限元分析与深度学习结合20个案例与有限元分析数据来源方法说明

结合 Abaqus 和深度学习,数据的获取和处理是关键的一步。通过从仿真、实验、公开数据库或合成数据中获取数据,经过预处理后,可以将其用于训练深度学习模型。最终,将训练好的深度学习模型与 Abaqus 集成,用于材料行为预测、结构优化、非线性分析、损伤预测等任务,从而提升仿真效率和精度。

源代码杀手的博客 3213

linux usb urb,usb中urb接口函数

一. 简介usb总线是一种轮询式总线,协议规定所有的数据传输都必须由主机发起,usb主机与设备之间是通过管道(pipe)传输的,管道两边分别对应主机中的数据缓冲区和设备侧的端点(endpoint),端点是通信的发送和接收点,要发送数据,只要把数据发到对应的端点就可以,而这个数据发送的动作由usb主机实现,驱动中只需确定接收端点,然后把数据提交给主机控制器,主机会把数据发送给接收端点,原理同i2c,...

weixin_42122306的博客 838

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

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

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

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

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

LInux usb mouse(鼠标)驱动分析

linux 下usb 鼠标的驱动基本上属于USB 协议中HID 设备的中断通信的应用。代码vendor\mstar\kernel\linaro\drivers\hid\usbhid\usbmouse.c,下面一起学习usb 鼠标驱动。 USB mouse 设备结构 struct usb_mouse { char name[128]; // 名称,一般存储制造商名称 char phys[6...

Tony的专栏 4851

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

usb鼠标驱动注解及测试

参考2.6.14版本中的driver/usb/input/usbmouse.c。鼠标驱动可分为几个部分:驱动加载部分、probe部分、open部分、urb回调函数处理部分。 下文阴影部分为注解。 一、驱动加载部分 static int __init usb_mouse_init(void){ int retval = usb_register(&amp;usb_mouse_driver);...

编程开发资料库 233

linux鼠标脚本,使用Linux虚拟鼠标驱动程序

我正在尝试根据Essential Linux设备驱动程序手册实现虚拟鼠标驱动程序.有一个用户空间应用程序,它生成坐标和内核模块.1.)我编译了用户空间应用程序和驱动程序的代码.2.)接下来我检查了dmesg输出并且,input: Unspecified device as /class/input/input32Virtual Mouse Driver Initialized3.)sysfs节点在...

weixin_39652154的博客 476

(转)Linux设备驱动之HID驱动 源码分析

//Linux设备驱动之HID驱动 源码分析 http://blog.chinaunix.net/uid-20543183-id-1930836.html HID是Human Interface Devices的缩写.翻译成中文即为人机交互设备.这里的人机交互设备是一个宏观上面的概念,任何设备,只要符合HID spec,都可以称之为HID设备.常见的HID设备有鼠标键盘,游戏操纵杆等等.在...

weixin_33898233的博客 703

LInux找不到动态链接库,./cyusb_linux: error while loading shared libraries: libcyusb.so: cannot open shared

1.安装cyusb给lime SDR刷固件的时候,cyusb安装好了但是打不开,提示如下找不到动态链接库 ./cyusb_linux: error while loading shared libraries: libcyusb.so: cannot open shared object file:No such file or directory 解决方法就是在当前目录下执行idconfig,...

weixin_43478836的博客 2008

浅谈Linux USB设备驱动

1、USB基础介绍 1-1、USB硬件接口介绍 USB接口在硬件上总共有四根线组成VCC、D+、D-、GND,通过计算D+和D-的差值来确定数据。USB设备在传输速率上可以分为低速(1.5Mbps)、全速(12Mbps),高速(480Mbps)。在USB主机控制器端D+和D-都皆有一个下拉电阻,在USB设备端的D+或D-接了一个上拉电阻,USB设备插入后USB主机控制器的D+或D-会被拉高,这样USB主机控制器就能发现有设备接入。USB设备是主从式的设备,主机是在host端的主机控制器,从机就是如鼠标、

JJ1116的博客 6059

2024年Linux设备驱动之usb设备驱动详解_usb数据什么驱动设备类型,看这里

unsigned int pipe usb_sndintpipe和usb_rcvintpipe分别是usb发送端点管道和接收端点管道。struct usb_host _interface *cur_altsetting是usb interface的当前可选设置。struct usb_host_interface *altsetting包含了usb interface的所有可选设置。以上三个结构体分别是usb_driver,usb_bus,usb_device设备结构体。

2401_85012446的博客 1445
上一篇: Linux usb 设备驱动 (1)
下一篇: USB芯片
shareCode
博客等级 码龄15年 125粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值