linux usb驱动框架 3

news/2024/7/8 3:52:45 标签: linux, struct, semaphore, table, interface, module

下面我们来分析一下usb-skeleton的源码吧。这个范例程序可以在linux-2.6.17/drivers/usb下找到,其他版本的内核程序源码可能有所不同,但相差不大。大家可以先找到源码看一看,先有个整体印象。

  之前已经提到,模块先要向内核注册初始化跟销毁函数:

  static int __init usb_skel_init(void)

  {

  int result;

  /* register this driver with the USB subsystem */

  result = usb_register(&skel_driver);

  if (result)

  err("usb_register failed. Error number %d", result);

  return result;

  }

  static void __exit usb_skel_exit(void)

  {

  /* deregister this driver with the USB subsystem */

  usb_deregister(&skel_driver);

  }

  module_init (usb_skel_init);

  module_exit (usb_skel_exit);

  MODULE_LICENSE("GPL");

    从代码开来,这个init跟exit函数的作用只是用来注册驱动程序,这个描述驱动程序的结构体是系统定义的标准结构struct usb_driver,注册和注销的方法很简单,usb_register(struct *usb_driver), usb_unregister(struct *usb_driver)。那这个结构体需要做些什么呢?他要向系统提供几个函数入口,跟驱动的名字:

  static struct usb_driver skel_driver = {

  .name = "skeleton",

  .probe = skel_probe,

  .disconnect = skel_disconnect,

  .id_table = skel_table,

  };

  从代码看来,usb_driver需要初始化四个东西:模块的名字skeleton,probe函数skel_probe,disconnect函数skel_disconnect,id_table

  在解释skel_driver各个成员之前,我们先来看看另外一个结构体。这个结构体的名字有开发人员自定义,它描述的是该驱动拥有的所有资源及状态:

  struct usb_skel {

  struct usb_device * udev; /* the usb device for this device */

  struct usb_interface * interface; /* the interface for this device */

  struct semaphore limit_sem; /* limiting the number of writes in progress */

  unsigned char * bulk_in_buffer; /* the buffer to receive data */

  size_t bulk_in_size; /* the size of the receive buffer */

  __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */

  __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */

  struct kref kref;

  };

  我们先来对这个usb_skel作个简单分析,他拥有一个描述usb设备的结构体udev,一个接口interface,用于并发访问控制semaphore(信号量) limit_sem,用于接收数据的缓冲bulk_in_buffer及其尺寸bulk_in_size,然后是批量输入输出端口地址 bulk_in_endpointAddr、bulk_out_endpointAddr,最后是一个内核使用的引用计数器。他们的作用我们将在后面的代码中看到。

我们在回过头来看看skel_driver。

  Name用来告诉内核模块的名字是什么,这个注册之后有系统来使用,跟我们关系不大。

  id_table用来告诉内核该模块支持的设备。Usb子系统通过设备的 production ID和vendor ID的组合或者设备的class、subclass跟protocol的组合来识别设备,并调用相关的驱动程序作处理。我们可以看看这个id_table 到底是什么东西:

  /* Define these values to match your devices */

  #define USB_SKEL_VENDOR_ID 0xfff0

  #define USB_SKEL_PRODUCT_ID 0xfff0

  /* table of devices that work with this driver */

  static struct usb_device_id skel_table [] = {

  { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },

  { } /* Terminating entry */

  };

  MODULE_DEVICE_TABLE (usb, skel_table);

  MODULE_DEVICE_TABLE的第一个参是设备的类型,如果是USB设备,那自然是usb(如果是PCI设备,那将是pci,这两个子系统用同一个宏来注册所支持的设备。这设计PCI设备的驱动了,在此先不深究)。后面一个参数是设备表,这个设备表的最后一个元素是空的,用于标识结束。代码定义了USB_SKEL_VENDOR_ID是0xfff0,USB_SKEL_PRODUCT_ID是0xfff0,也就是说,当有一个设备接到集线器时,usb子系统就会检查这个设备的vendor ID和product ID,如果它们的值是0xfff0时,那么子系统就会调用这个skeleton模块作为设备的驱动。


http://www.niftyadmin.cn/n/1117131.html

相关文章

react传递方法 警告

报错现象如下 产生原因如下 分析 在调用 React.cloneElement 的时候 如果第二个属性传入props, 需要看第一个参数传递的是 react组建还是 html标签 如果是html标签就会导致上面的警告 大意是方法会被忽略 因为这样相当于 往 div 等原声元素里 传入 onBd 自定义事件 是会被忽略等…

关于Cordova框架对URL拦截导致通信丢失问题的处理

前言 昨天看了味精大佬关于hybrid框架搭建的系列文章的从零收拾一个hybrid框架(一)-- 从选择JS通信方案开始,不得不说大佬总结的很细致,尤其是基于WKWebView的总结很到位,文章里面提到了UIWebView基于URL拦截的方式不安…

计算机编程情话,[程序员的爱情表白代码]献给程序员们的爱情表白书

图片来自网络Java程序员的情书我能抽象出整个世界,但是我不能抽象出你,因为你在我心中是那么的具体,所以我的世界并不完整。我可以重载甚至覆盖这个世界里的任何一种方法,但是我却不能重载对你的思念。也许命中注定了 你在我的世界…

linux usb驱动框架 4

probe是usb子系统自动调用的一个函数,有USB设备接到硬件集线器时,usb子系统会根据production ID和vendor ID的组合或者设备的class、subclass跟protocol的组合来识别设备调用相应驱动程序的probe(探测)函数,对于skeleton 来说,就是…

Push 本地镜像到 Docker Hub

官方提供的 ubuntu镜像使用的是官方的 apt 源,国内用户使用起来非常慢。之前用一直都是先拉取官方镜像,然后手动修改/etc/apt/sources.list文件。 这效率属实很低,所以就自己打包了一个修改过/etc/apt/sources.list的ubuntu 镜像,…

计算机教师在教学中的德育渗透,浅谈在中职计算机教学中渗透德育

190 Education Research and Practice学习物理不再单调、乏味,相反,学习物理的兴趣更加高涨,积极性和主动性倍加增强.只要我们善于总结、不断创新,学生就会变得乐学、善学,进而带动了教学质量的大面积提高…

sqoop从oracle抽取数据到hbase

2019独角兽企业重金招聘Python工程师标准>>> sqoop import --connect jdbc:oracle:thin://*.*.*.*:1521/orcl --username * --password * --query " select TEST_REPORT_NO as ROWKEY,a.* from V_ESBHL_BLOOD_TRANSFU_ROD a where a.inspection_date > 2018…

ElasticSearch中的bind_host和publish_host有什么区别?

2019独角兽企业重金招聘Python工程师标准>>> 从这个文档的网络设置中,我知道publish_host是群集中的其他节点将与之通信的主机。但我不明白bind_host的功能,这意味着: network.bind_host设置允许控制不同的网络组件将绑定的主机。…