linux 鼠标驱动

Linux内核:USB设备驱动——USB鼠标的加载、初始化和通信过程 经过probe过程,注册了输入设备则会在/dev/input/目录下会产生对应的鼠标设备节点,应用程序可以打开该节点来控制usb鼠标设备。input_report_key\input_report_rel\input_sync ///提交鼠标数据给input 子系统。usb鼠标既包含usb设备(usb_device)的属性也包含input输入设备(input_dev)的属性。////---->调用usbmouse_open() 阅读详情

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

 

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

 

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

 

USB 设备驱动程序(usb device driver)是如何添加到驱动链表上去的?
在系统启动注册 USB core 时,USB 设备驱动程序即将被注册,也就添加到驱动链表上去了。

 

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

 

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 驱动程序,这样一次数据传输就完成了。

/*
 * $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);



 

Linux USB 驱动开发实例(二)—— USB 鼠标驱动注解及测试 参考2.6.14版本中的driver/usb/input/usbmouse.c。鼠标驱动可分为几个部分:驱动加载部分、probe部分、open部分、urb回调函数处理部分。  一、驱动加载部分static int __init usb_mouse_init(void) { int retval = usb_register(&usb_mouse_driver);//注册鼠标驱动 阅读详情

相关推荐

Linux下USB模拟ps2鼠标驱动

在linu-kernel/drivers/input/mouse/psmouse-base.c是ps2鼠标驱动的主体,如psmouse_reset、psmouse_connect等函数具体实现在此文件之中。简单地,拿psmouse_reset为例,调用ps2_command()->ps2_sendbyte()->serio_write()来完成对硬件的操作。而serio_write()在已经指

hitxiaotao的专栏 2884

Linux USB驱动-鼠标驱动

1.概述 通用串行总线(USB)用于连接主机和外围设备。USB总线采用拓扑结构,USB主机和USB设备的连接构成了一颗树,树的结点为USB节点或USB集线器(HUB),USB集线器(HUB)用于扩展设备接口,一个集线器(HUB)可接多个USB设备或多个集线器。主机侧的USB节点为根节点,所有子节点都连接在根节点集线器(ROOT HUB)上,根节点由USB主机控制器(USB Host Controller)控制,设备侧的节点为子节点,由USB设备控制器(USB Device Controller)控制。在US

非专业业余程序员 2225

linux系统中USB模块鼠标驱动实现

参考网址:* libusb GIT仓库:https://github.com/libusb/libusb.git* libusb 官网:https://libusb.info/* libusb API接口:https://libusb.sourceforge.io/api-1.0/* libusb 示例:https://github.com/libusb/libusb/tree/master/exampleslibusb是一个使用C编写的库,它提供USB设备的通用的访问方法。

嵌入式技术开发 2167

20.Linux-USB鼠标驱动

在上一章分析完USB总线驱动程序后, 接下来开始写一个USB驱动: 本节目的: 将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键 参考/drivers/hid/usbhid/usbmouse.c(内核自带的USB鼠标驱动) 1.本节需要用到的宏如下: struct usb_device_id usbmouse_id_table []=USB_INT...

weixin_30432007的博客 228

动手实现Linux内核USB鼠标驱动开发实战

USB(Universal Serial Bus)设备作为一种常见的外设,其与主机的通信遵循一定的协议和机制。在Linux操作系统中,USB设备的通信主要通过USB驱动程序来实现。USB驱动程序作为内核的一部分,负责管理USB总线上的所有设备。Linux内核通过USB核心(usbcore)提供了一组标准的API来访问USB设备,使得USB设备的通信和控制变得简单而统一。USB设备与主机之间的通信主要涉及到数据的发送和接收,这包括设备的发现、配置以及数据传输等多个阶段。

weixin_35761094的博客 864

Linux USB鼠标驱动注解及测试

Linux USB鼠标驱动注解及测试Linux USB鼠标驱动注解及测试Linux USB鼠标驱动注解及测试

Linux驱动开发之USB鼠标驱动学习思路

a. 在入口函数init注册usb_driver驱动,出口函数exit卸载usb_driver驱动;①输入子系统,上报事件,把数据编程具体的含义,让人所知道的,如:按下鼠标左键,显示L;c和d点代码:中断是fill-urb中的:usbmouse_as_key_irq函数。d. 当USB主机控制器收到USB设备的数据,会在urb的一个函数irq产生中断;①输入子系统,完成①分配input_dev结构体,②设置产生按键类事件,③注册。提示:看懂文章的前提是会输入子系统、USB总线驱动框架。

weixin_47545694的博客 567

SAP系统中PP模块全配置文档

配置路径IMG>SAP NetWeaver>常规设置>维护日历>工厂日历事务代码SCAL要求传输工厂代码描述日历代码日历描述起始日期星期一星期二星期三星期四星期五星期六星期日有效开始日期有效结束日期1000南微医学工厂MT南微医学工厂日历√√√√√√√201820502.4定义工厂配置路径IMG>生产>物料清单>常规数据>定义BOM状态事务代码OS23要求传输配置路径IMG>生产>主数据>资源>常规数据>标准值>定义参数。

yanzibing99的博客 1894

Linux下USB鼠标驱动完全注释

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

jemofh159的专栏 980

Gromacs基础教程一:入门建议

本系列教程针对的群体:非计算化学专业,而是偏生物方向的、有少量分子动力学模拟需求的人群。

m0_67843839的博客 8574

ArcGIS通过已知坐标点转面(通过excel文件,有工具可批量生成面要素)

通过使用ArcGIS中的工具,将坐标点XY数据转换成可视化的点线面矢量数据,更加方便快捷有效的获取对应信息

qq_41046162的博客 3万+

linux环境下模拟鼠标键盘驱动

在 Linux 环境下编写模拟键盘和鼠标驱动的指南在虚拟化环境(如 KVM)中,将硬件功能转化为软件功能,并通过 API 调用进行控制,可以实现对键盘和鼠标的模拟驱动。本文将详细介绍模拟键盘和鼠标驱动的原理、实现方法、示意代码,以及在 KVM 上运行的思路和工作流。目录概述模拟键盘和鼠标驱动的目标是将硬件输入设备的功能转化为软件接口,使得应用程序可以通过 API 调用来模拟输入操作。

远方雪的专栏 1678

fluent二维叶型仿真_Fluent案例4【自然对流】

自然对流来了!!江苏的高校好多开学了,我啥时候才能开学另外,刚才看了何同学的Mac Pro深度体验视频,我好酸/(ㄒoㄒ)/~~好想拥有一台跑仿真那种sou~sou~sou~的机器。废话不多说了,进入正题!案例题目:一个矩形空腔内有500K恒温小球,矩形空腔充斥空气,边界条件绝热,模型尺寸如下,试模拟空腔内空气流动状态做出温度变化图。(尺寸大小懒得写了,在建模部分里有)操作平台:workbench...

weixin_39724469的博客 3670

十五、Linux驱动之USB鼠标驱动

1. 如何编写USB鼠标驱动     结合十四、Linux驱动之USB驱动分析中的分析,我们开始写一个USB鼠标驱动。      USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动,通常,对于USB这种标准化的设备,内核已经将主机控制器的驱动编写好了,设备上的Gadget驱动通常只运行固件程序而不是基于Linux, 所以驱动工程师的主要...

墨、白的博客 1575

Windows10下RTABMAP+T265实现三维建图

win10+rtabmap+t265扫描地形

Suxiang1997的博客 3486

【客户案例】母婴行业头部品牌是如何做私域的

各品牌争相跑马圈地,想方设法圈住流量,建立品牌资产;私域运营是一项“重人力”的工作,在传统的品牌运营过程中,私域操盘手经常会由于一对多导致无法兼顾,只能通过提高触达次数的方式加大漏斗,这样难以让每个社群都发挥出应有的价值,甚至还会导致一定程度的用户流失。除了宝妈身份外激发的用户认同感、亲密度外,KOC们作为产品的使用者,自由选择的推品和自由创作的推广文案都更具有真实性、代表性,能够极大程度激发群友们的信任感,从而愿意为产品买单,转化复购水到渠成。不同阶段的宝妈,母婴知识的储存量和经验是不同的,K品牌还会。.

圈量SCRM系统-企微营销工具-私域流量运营软件 948

浅析linux下鼠标驱动的实现

浅析linux下鼠标、键盘驱动的实现       对于鼠标驱动和前面分析过的键盘驱动都是共用input模型,所以,对于事件上报和处理的方式都没有区别,只是mouse鼠标驱动当上报完dx,dy,left,middle,right之后,需要调用input_sync(),将前面上报的仅仅填充在缓冲区中的数据,通过mousedev_notify_readers()发送给open了的挂接在moused

tronteng的专栏 850

PX4从放弃到精通(二十一):使用git管理PX4代码

文章目录前言一、设置git密钥二、将代码上传至gitee 前言 Ubuntu 18.04 PX4 1.11.3 由于github有时网速较慢,本文使用gitee。 一、设置git密钥 ssh-keygen -t rsa -C “your_email@youremail.com” your_email@youremail.com为自己注册的gitee账户邮箱.设置路径与密码时,也直接回车不设置,如下图,密钥生成的位置在红框处. 在密钥目录下按Ctrl+H显示隐藏文件,进入.ssh文件夹用gedit打开id

超维空间科技的博客 3480

linux安装razer鼠标驱动

以我古老的太攀皇蛇和ubuntu为例…官方没有linux驱动,滑轮按键和侧键等没用,github上找到个OpenRazer,安装流程参见官方说明,我也是尝试,说明看的很快没注意细节,并不一定步骤都对 PS:弄完发现我这鼠标也没有设置宏键的… 一、安装OpenRazer 1、添加稳定版或者日常更新版PPA,回车确认 sudo add-apt-repository ppa:openraze...

harima_hario的博客 6076

谁在 SAP 系统里说了算:事务码 SCC4 与 SE06 的分工、优先级与实战管控

SAP系统通过SE06和SCC4两套机制控制变更权限:SE06作为系统级"总闸"管理跨Client对象修改,SCC4作为Client级"分闸"控制Client内配置变更。两者存在明确优先级,SE06的全局设置优先于SCC4。当SE06设为"不可修改"时,即使SCC4开放也无法更改跨Client对象。实际项目中需同时检查两处设置,并遵循"最小开放"原则进行变更管理。这种分层设计既满足日常维护需求,又能实现严格的变更管控。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 229

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

linux虚拟鼠标驱动,虚拟键盘、虚拟鼠标驱动

2009-1-22 02:22找了这篇文,看对你有没有帮助,另外请联系我QQ634308587 一起研究一下。一个鼠标驱动程序的分析(/driver/input/mouse/amimouse.c)一:Input设备驱动,(我称为虚拟输入设备)//drivers/input/input.c文件input设备是一种字符设备在模块初始化时创建设备类"input",注册Input字符设备,input的操作...

weixin_39913648的博客 1052

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Linux USB 鼠标输入驱动详解

USB设备插入时,内核会读取设备信息,接着就把id_table里的信息与读取到的信息做比较,看是否匹配,如果匹配,就调用probe函数。USB设备拔出时会调用disconnect函数。URB在USB设备驱动程序中用来描述与USB设备通信时用到的基本载体和核心数据结构。

Marvin_wu 2887

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...

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

鼠标linux驱动安装失败,usb鼠标驱动?电脑安装不了鼠标驱动?usb鼠标驱动下载?Linux USB 鼠标驱动程序详解...

你是否正在寻找关于usb鼠标驱动的内容?让我把最有用的东西奉献给你:Linux USB 鼠标驱动程序详解USB 总线引出两个重要的链表!一个 USB 总线引出两个重要的链表,一个为 USB 设备链表,一个为 USB 驱动链表。设备链表包含各种系统中的 USB 设备以及这些设备的所有接口,驱动链表包含 USB 设备驱动程序(usb device driver)和 USB 驱动程序(usb drive...

weixin_36219012的博客 159

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的专栏 4852
上一篇: linux 程序里结束进程
下一篇: native方式获取android4.0鼠标指针速度
yaotinging
博客等级 码龄18年 7粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值