微波EDA网,见证研发工程师的成长!
首页 > 测试测量 > 测试测量技术文库 > usb鼠标驱动注解及测试

usb鼠标驱动注解及测试

时间:10-12 来源:互联网 点击:

xt;

  if (dev->speed == USB_SPEED_HIGH)

  urb->interval = 1 (interval - 1);

  else

  urb->interval = interval;

  urb->start_frame. = -1;

  }

  此处只是构建好一个urb,在open方法中会实现向usb core递交urb

  */

  mouse->irq->transfer_dma = mouse->data_dma;

  mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

  /*

  #define URB_NO_TRANSFER_DMA_MAP 0x0004? //urb->transfer_dma valid on submit

  #define URB_NO_SETUP_DMA_MAP??? 0x0008? //urb->setup_dma valid on submit

  , 这里是两个DMA 相关的flag,一个是URB_NO_SETUP_DMA_MAP,而另一个是

  URB_NO_TRANSFER_DMA_MAP.注意这两个是不一样的,前一个是专门为控制传输准备的,因为只有控制传输需要有这么一个setup 阶段需要准备一个setup packet。

  transfer_buffer 是给各种传输方式中真正用来数据传输的,而setup_packet 仅仅是在控制传输中发送setup 的包,控制传输除了setup 阶段之外,也会有数据传输阶段,这一阶段要传输数据还是得靠transfer_buffer,而如果使用dma 方式,那么就是使用transfer_dma.

  因为这里使用了mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP,所以应该给urb的transfer_dma赋值。所以用了:

  mouse->irq->transfer_dma = mouse->data_dma;

  */

  input_register_device(mouse->dev);

  //向input系统注册input设备

  printk(KERN_INFO "input: %s on %s", mouse->name, path);

  usb_set_intfdata(intf, mouse);

  /*

  usb_set_intfdata().的结果就是使得

  %intf->dev->driver_data= mouse,而其它函数中会调用usb_get_intfdata(intf)的作用就是把mouse从中取出来

  */

  return 0;

  }

  三、open部分

  当应用层打开鼠标设备时,usb_mouse_open将被调用

  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;

  //向usb core递交了在probe中构建好的中断urb,注意:此处是成功递交给usb core以后就返回,而不是等到从设备取得鼠标数据。

  return 0;

  }

  四、urb回调函数处理部分

  当出现传输错误或获取到鼠标数据后,urb回调函数将被执行

  static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)

  {

  struct usb_mouse *mouse = urb->context;

  //在usb_fill_int_urb中有对urb->context赋值

  signed char *data = mouse->data;

  struct input_dev *dev = mouse->dev;

  int status;

  switch (urb->status) {

  case 0: /* success */

  break;

  case -ECONNRESET: /* unlink */

  case -ENOENT:

  case -ESHUTDOWN:

  return;

  /* -EPIPE:? should clear the halt */

  default: /* error */

  goto resubmit;

  }

  input_regs(dev, regs);

  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系统报告key事件,分别是鼠标LEFT、RIGHT、MIDDLE、SIDE、EXTRA键,

  static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)中的value非0时表示按下,0表示释放

  input_report_rel(dev, REL_X, data[1]);

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

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

  //向input系统报告rel事件,分别是x方向位移、y方向位移、wheel值

  input_sync(dev);

  //最后需要向事件接受者发送一个完整的报告。这是input系统的要求。

  resubmit:

  status = usb_submit_urb (urb, SLAB_ATOMIC);

  //重新递交urb

  if (status)

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

  mouse->usbdev->bus->bus_name,

  mouse->usbdev->devpath, status);

  }

  五、应用层测试代码编写

  在应用层编写测试鼠标的测试程序,在我的系统中,鼠标设备为/dev/input/event3. 测试代码如下:

  /*

  * usb_mouse_test.c

  *by lht

  */

  #include stdio.h>

  #include sys/types.h>

  #include unistd.h>

  #include fcntl.h>

  #include linux/input.h>

  int main (void)

  {

  int fd,i,count;

  struct input_event ev_mouse[2];

  fd = open ("/dev/input/event3",O_RDWR);

  if (fd 0) {

  printf ("fd open failed");

  exit(0);

  }

  printf ("mouse opened, fd=%d",fd);

whi

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top