USB驱动程序之鼠标用做键盘

我们还是接着来看看我们的例子程序 usbmouse.c


这里它接着判断了他是不是鼠标,

得到它的usb_host_interface,interface=intf->cur_alsetting就是当前接口的设置



这里有个接口描述符,我们来看看接口描述符


接口描述符里面有个__u8  bNumEndpoints端点的个数

这个端点的个数是除了端点0之外还有多少个端点


这里首先判断如果除了端点0之外,端点个数不是1的话就返回错误,不是我能够支持的设备

如果只有一个端点,那就把这个端点放到endpoint这个数组里面,这个并不是端点0,而是除了端点0之外第一个端点

得到一个端点描述符

if(!usb_endpoint_is_int_in(endpoint))这个是指如果他不是中断类似的端点,不是输入端点,注意了我们这里输入输出是站在主机的角度说的,站在主机角度,我们的鼠标是输入设备,数据是输入给主机的。如果不是输入类型端点,中断类型端点,就返回一个错误。这个怎么回事呢,怎么知道你是不是中断输入端点呢,端点描述符里面不是有个属性吗,属性里面就是表示它是什么类型的,方向。


我们在我们自己的程序里就不做判断了,我们回到我们的主题,我们就认为就是一个鼠标,



我们硬件相关的操作要用到USB总线驱动程序里面的读写函数

我们只需要记住数据传输3要素,把这个三要素找出就可以实现这一点

1.源   在我们这里是USB设备的某个端点


这个就是源

我们来看看usb_rcvintpipe这个宏


这个源是个整数,pipe_interrupt是指中断类型端点,USB_DIR_IN是端点的方向。我们进入__create_pipe(dev,endpoint)这个宏


devnum是设备的地址,endpoint是端点的地址也是端点编号


2.目的

我们从USB设备里面读数据,读到哪里去,肯定读到缓冲区,但这个缓冲区肯定不能用kmallioc函数,

用这函数

返回一个void* 是个虚拟地址

最后一个参数是指的物理地址


3.长度就是我们的端点描述符最大包大小


使用我们三要素

怎么用呢,看一下我们的例子


分配一个urb urb是什么意思呢,就是USB请求快的意思 usb request block

然后使用这个3要素设置我们的urb  来看我们的例子程序




看看这个函数原型


第一个参数是urb,第二个参数是设备,第三个参数是源,第四个参数是目的,第五个参数是长度 ,第6个参数是完成函数,第7个参数是给那个完成函数用的,我们不需要,第8个参数是查询的频率。

我们前面说过usb设备不能打断主机控制器,只能让主机控制器查询,不断的去查询,等有数据之后才能中断CPU。当它得到数据之后,总线驱动程序就会调用这个complete_fn这个函数,查询多频繁呢就是int interval 。

端点描述符里面有个binterval就是的



我们USB主机控制器,得到数据之后是往某个地方写,但是我们主机控制器没那么聪明,所以我们要告诉它,例子里面


第一句就是告诉物理地址,下面一句是设置某些标记


我们构造了URB 就要使用urb

怎么使用urb


使用usb_submit_urb提交urb



usb鼠标数据含义

我们前面说框架的时候说过,USB设备驱动程序知道数据的含义,USB总线驱动程序提供识别设备,给设备找到驱动,提供读写函数,但是不知道数据的含义。这些数据需要由设备驱动程序来解析,


data[0] bit 0表示左键,1表示按下,0表示松开

     bit 1表示右键,1表示按下,0表示松开

     bit  2表示中键    1表示按下,0表示松开



代码如下

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


static struct input_dev *usb_key;
static char * usb_buf;
static dma_addr_t usb_buf_phys;
static int len;
static struct urb *uk_urb;
static struct usb_device_id usbmouse_as_key_id_table[] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) },
{ } /* Terminating entry */
};


static void usbmouse_as_key_irq(struct urb *urb)
{
static unsigned char pre_val;
/* USB鼠标数据含义
* data[0]: bit0-左键, 1-按下, 0-松开
*          bit1-右键, 1-按下, 0-松开
*          bit2-中键, 1-按下, 0-松开 
*/
if((pre_val & (1<<0)) != (usb_buf[0] & (1<<0)))
{
//左键发生了变化
input_event(usb_key, EV_KEY, KEY_L, (usb_buf[0] & (1<<0)) ? 1 : 0);
input_sync(usb_key);
}
if ((pre_val & (1<<1)) != (usb_buf[0] & (1<<1)))
{
/* 右键发生了变化 */
input_event(usb_key, EV_KEY, KEY_S, (usb_buf[0] & (1<<1)) ? 1 : 0);
input_sync(usb_key);
}
if ((pre_val & (1<<2)) != (usb_buf[0] & (1<<2)))
{
/* 中键发生了变化 */
input_event(usb_key, EV_KEY, KEY_ENTER, (usb_buf[0]  & (1<<2)) ? 1 : 0);
input_sync(usb_key);
}

pre_val = usb_buf[0];


/* 重新提交urb */
usb_submit_urb(uk_urb, GFP_KERNEL);
}


static int usbmouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int pipe;//源


interface = intf->cur_altsetting;


endpoint = &interface->endpoint[0].desc;
/*a.分配一个input_device结构体*/
usb_key=input_allocate_device();
/*b.设置*/
/*b.1能产生哪类事件*/
//能够产生按键类事件
set_bit(EV_KEY,usb_key->evbit);
set_bit(EV_REP,usb_key->evbit);//能够产生重复类事件,就是只我们按下一个字母不动就会不断的打印出来


/*b.2能产生这类事件的哪些事件*/
set_bit(KEY_L,usb_key->keybit);
set_bit(KEY_S,usb_key->keybit);
set_bit(KEY_ENTER,usb_key->keybit);


/*c.注册*/
input_register_device(usb_key);
/*d.硬件相关的操作*/
/*数据传输3要素 源,目的,长度*/
/*1.源 :USB设备的某个端点*/
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);


//长度 等于端点描述符的最大包大小
len=endpoint->wMaxPacketSize;


/*2.目的 */
usb_buf = usb_alloc_coherent(dev,len, GFP_ATOMIC, &usb_buf_phys);


//使用三要素
/*分配一个urb usb request block*/
uk_urb= usb_alloc_urb(0, GFP_KERNEL);
//使用3要素设置这个urb
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf,len,usbmouse_as_key_irq,NULL, endpoint->bInterval);
uk_urb->transfer_dma = usb_buf_phys;
uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
//使用URB
usb_submit_urb(uk_urb, GFP_KERNEL);


return 0;
}


static void usbmouse_as_key_disconnect(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev(intf);
usb_kill_urb(uk_urb);
usb_free_urb(uk_urb);
usb_free_coherent(dev, len, usb_buf, usb_buf_phys);
input_unregister_device(usb_key);
input_free_device(usb_key);




}
/*1.分配/设置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,
};
static int usbmouse_as_key_init(void)
{
/*2.注册usb_driver结构体*/
usb_register(&usbmouse_as_key_driver);
return 0;
}

static void usbmouse_as_key_exit(void)
{
usb_deregister(&usbmouse_as_key_driver);
}


module_init(usbmouse_as_key_init);
module_exit(usbmouse_as_key_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EIGHT");


测试结构如下图







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Win7USB是指在Windows 7操作系统下使用USB接口实现数据传输和设备连接。使用USB接口可方便地实现电脑与其他设备的连接和数据传输,如打印机、移动存储设备、鼠标键盘、摄像头等。为了保证设备的正常工作,需要安装相应的驱动程序。对于鼠标键盘来说,Win7USB鼠标键盘驱动文件就是实现鼠标键盘与操作系统之间通信的桥梁。如果驱动程序缺失或者有问题,则鼠标键盘无法正常使用。为了解决这一问题,需要从官方网站或者其他可靠的网站下载并安装对应的驱动程序。安装驱动程序的过程较为简单,只需要按照提示进行即可完成。如果不确定具体的驱动程序或者遇到其他问题,可以查看设备的说明书或者向厂家或专业人士咨询。总之,在Win7USB鼠标键盘使用过程中,驱动程序是必不可少的一环,只有保证驱动程序的正常工作,才能保证设备的稳定和可靠性。 ### 回答2: win7usb 鼠标键盘驱动文件是指用于兼容Windows 7操作系统USB接口鼠标键盘设备所需的驱动程序。Windows 7的鼠标键盘驱动已经内置在系统中,但是对于一些特殊的设备需要下载额外的驱动程序,以确保设备能够正常运行并且避免出现兼容性问题。 一般来说,USB接口的鼠标键盘设备可以直接插入Windows 7系统USB接口中,系统会自动识别设备并加载驱动程序,从而实现设备的正常使用。但是,在某些情况下,Windows 7系统未能自动识别设备或者设备存在兼容性问题,就需要手动安装或者更新驱动程序,以解决设备无法使用或者性能不佳的问题。 在下载和安装驱动程序时,用户需要确保选择兼容Windows 7操作系统驱动程序,并且按照驱动程序提供的安装指南进行操作。这样才能确保设备能够正常运行,并且最大程度地发挥其性能优势。 总而言之,win7usb 鼠标键盘驱动文件是Windows 7操作系统中必不可少的程序,用户需要根据设备的具体情况,选择和安装对应的驱动程序,以确保设备能够正常工作并且发挥其最大性能优势。 ### 回答3: Win7 USB鼠标键盘驱动文件是为Windows 7操作系统设计的一种驱动程序,它可以在Win7上支持USB鼠标键盘以及其他相关的设备。 在Win7系统上,如果你的计算机USB接口无法检测鼠标键盘或其他外设,那么就说明你需要安装或更新驱动文件。通过安装Win7的USB鼠标键盘驱动文件,你可以很容易地解决这些问题。 驱动文件是计算机硬件的核心程序之一,它可以让计算机操作系统了解硬件的功能和工作方式,并且能够与之进行交互。在使用Win7系统时,安装适合自己计算机硬件的驱动文件非常重要。 总而言之,Win7 USB鼠标键盘驱动文件是一种非常重要的驱动程序,可以帮助计算机用户协调USB外设和操作系统之间的通信,提高用户的使用体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值