电子文章 | 电子资料下载 | 家电维修 | 维修资料下载 | 加入收藏 | 全站地图
您现在所在位置:电子爱好者电子文章arm嵌入式usb鼠标驱动注解及测试

usb鼠标驱动注解及测试

11-20 15:53:39 | http://www.5idzw.com | arm嵌入式 | 人气:872
标签:arm嵌入式系统,arm系统,arm开发,http://www.5idzw.com usb鼠标驱动注解及测试,http://www.5idzw.com

  if (dev->product)

  sprintf(mouse->name, "%s %s", mouse->name, dev->product);

  if (!strlen(mouse->name))

  sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x",

  mouse->dev.id.vendor, mouse->dev.id.product);

  usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,

  (maxp > 8 ? 8 : maxp),

  usb_mouse_irq, mouse, endpoint->bInterval);

  /*

  static inline void usb_fill_int_urb (struct urb *urb,

  struct usb_device *dev,

  unsigned int pipe,

  void *transfer_buffer,

  int buffer_length,

  usb_complete_t complete,

  void *context,

  int interval)

  {

  spin_lock_init(&urb->lock);

  urb->dev = dev;

  urb->pipe = pipe;

  urb->transfer_buffer = transfer_buffer;//如果不使用DMA传输方式,则使用这个缓冲指针。如何用DMA则使用transfer_DMA,这个值会在后面单独给URB赋

  urb->transfer_buffer_length = buffer_length;

  urb->complete = complete;

  urb->context = context;

  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\n", 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\n");

  exit(0);

  }

  printf ("\nmouse opened, fd=%d\n",fd);

  while(1)

  {

  printf("...............................................\n");

  count=read(fd, ev_mouse, sizeof(struct input_event));

  for(i=0;i<(int)count/sizeof(struct input_event);i++)

  {

  printf("type=%d\n",ev_mouse[i].type);

  if(EV_REL==ev_mouse[i].type)

  {

  printf("time:%ld.%d",ev_mouse[i].time.tv_sec,ev_mouse[i].time.tv_usec);

上一页  [1] [2] [3] [4]  下一页

,usb鼠标驱动注解及测试
关于《usb鼠标驱动注解及测试》的更多文章