Linux驱动系列———USB转串口cp210x设备驱动

USB设备驱动程序用来驱动相应的USB设备,USB设备驱动用usb_driver表示,它主要用来将USB设备挂接到USB核心中,并启动USB设备,让其正常工作。对于USB设备的具体读写操作由放在usb_driver设备中的usb_class_drivers成员来实现,该成员定义了一个file_operations结构体,用来对设备进行读写操作。

1. USB设备驱动模型

设备需要驱动才能正常工作,所以当系统检测到设备时,应该将其与对应的驱动程序绑定。设备与驱动的绑定,只能够在同一总线上的设备与驱动之间进行。总线与设备和驱动的连接,需要相应总线的核心代码来实现。对于USB总线,实现总线与驱动和设备的连接,是通过USB核心(USB core)来完成的。

  • USB core会完成总线的初始化工作,然后再扫描USB总线,看USB总线上连接了那一些设备。当USB core发现设备的时候,会为其分配一个struct device结构体,并将其连接到总线上。当发现所有的设备以后,USB总线上的设备链表就建立好了。
  • 相比设备的连接,将驱动连接到总线上就更简单。每当驱动注册的时候,会将自己在总线上注册,并连接到总线的驱动链表中。这时,驱动会遍历总线的设备链表,寻找合适的设备,并将其通过内部指针联系起来。

2.USB驱动结构

在USB设备驱动模型中,USB设备驱动使用usb_driver结构体来表示,该结构体中包含了与具体设备相关的核心函数,对于不同的设备,需要实现不同功能的函数。usb_driver结构体的定义如下:

在cp210x中该结构体的定义如下:

其中probe函数指向USB驱动的程序的探测函数,当有USB设备插入时,USB核心会调用该函数进行设备的初始化工作。

2.1 usb驱动注册函数usb_register()

在初始化函数中,首先要注册一个USB驱动,注册USB驱动的函数是usb_register()。需要注意的是,调用该函数之前应该要对usb_driver进行必要的初始化,使用MODULE_DEVICE_TABLE(usb,...)宏来展示设备信息。

2.2 设置USB转串口的线路规程

线路规程要为串口的使用定下数据交换的规程。Linux内核中已经存在了许多的规程,如PPP、SLIP、TTY。缺省使用TTY,可以根据自己的需要将规程替换为Linux已经定义的规程结构,甚至是替换为自己的规程结构,当用户要改变线路设置,只需要调用多个termios用户函数中的一个,也可以直接对设备接点调用ioctl,tty核心将会把这两种接口转换为一系列的tty驱动程序的回调函数,或者是ioctl调用,set_termios回调函数需要知道要改变的是哪一个线路设置,然后在tty设备中进行改动。tty驱动程序必须能够对termios结构中所有不同的设置进行解码,并对任何需要的改变作出响应,所有的线路设置被封装在termios结构当中,在tty核心中定义如下:


该结构被用来为tty设备上的某一个特定的端口上保存当前 波特率、数据大小、数据流等参数。

框架函数

1. int usb_serial_register(struct usb_serial_device_type *new_device);//向核心注册USB转串口设备

  1. void usb_serial_deregister(struct usb_serial_device_type *device);//向核心注销USB转串口设备。

3.USB设备驱动程序

USB设备驱动的实现,首先需要定义一个usb_driver结构变量作为要注册到USB核心的设备驱动,在USB转串口中该结构的定义如下:

  • 定义了USB设备驱动的probe()函数,该函数由usb_serial_probe()函数实现。
  • 定义了USB设备驱动的disconnect()函数,该函数由usb_serial_disconnect()函数实现,在设备驱动注销时被调用。
  • 定义了USB设备驱动的id_table为id_table,表示该驱动支持的USB设备。
3.1 探测函数probe()的参数usb_interface

当USB设备插入插槽的时候,会引起一个电信号的变化,主机控制器捕获这个电信号,并命令USB核心处理对设备的加载工作。USB核心读取到USB设备固件中相关的信息,并与挂接到USB总线上的驱动程序相比较,如果找到合适的驱动程序usb_driver,就会调用驱动程序的probe()函数。该函数的原型如下:
int usb_serial_probe(struct usb_interface *interface,const struct usb_device_id *id);
第一个参数usb_interface是USB驱动中最重要的一个结构体,它代表着设备的一种功能,与一个usb_driver相对应。usb_interface在USB驱动中只有一个,由USB核心负责维护。USB核心调用probe()函数并传递进struct usb_interface和struct usb_device_id *类型的参数。

接口(interface):在USB协议中,接口(usb_interface)代表一个基本的功能。USB接口只处理一种USB逻辑连接,每一个USB驱动程序(usb_driver)控制一个接口。内核使用struct usb_interface结构体来表述USB接口。USB核心在设备插入的时候,会读取USB设备接口的信息,并创建一个usb_interface的结构体。接着USB核心在USB总线上找到合适的USB驱动程序,并调用驱动程序的probe()函数,将usb_interface传递给驱动程序。probe()函数的第一个参数就是指向USB核心分配的usb_interface结构体的指针,驱动程序从这里得到这个接口结构体,并且负责控制该结构体。因为一个接口代表一种基本的功能,所以驱动程序也只是负责该接口所代表的功能。probe()函数的第二个参数从设备读取usb_device_id的信息,用来与驱动程序匹配。

USB核心处理usb_interface中的大量成员,只有少数几个成员驱动程序会用到,usb_interface中的重要成员是:

  • altsetting表示一组可选的设置,用这个指针指向一个可选设置数组。
  • cur_altsetting表示当前正在使用的设置。
  • num_altsetting表示可选设置altsetting的数量。
  • minor表示分配给设备的次设备号。
  • condition表示接口和驱动的绑定状态,在Linux的设备驱动模型中,设备和驱动是彼此关联相互依靠的。每一个设备或者是驱动都在USB总线中等待属于他的另一半,如果找到则彼此绑定在一起。这里的condition变量被定义为enum usb_interface_conditiion的类型,表示这个接口的状态。
    enum usb_interface_condition{ USB_INTERFACE_UNBOUND = 0, //usb_interface为绑定状态 USB_INTERFACE_BINDING, //正在绑定中 USB_INTERFACE_BOUND, //已经绑定 USB_INTERFACE_UNBINDING, //在取消绑定这个过程中 };
  • needs_remote_wakeup、pm_usage_cnt定义的是与电源管理有关的变量。
  • struct device dev是设备驱动模型中device内嵌在usb_interface结构体中的设备。而struct device *usb_dev则不是内嵌的设备对象。当接口使用USB_MAJOR作为主设备号时,usb_dev才会被用到。在整个内核中,只有usb_register_dev()和usb_deregister_dev()两个函数里才会用到usb_dev变量,usb_dev指向的就是usb_register_dev()函数中创建的usb class device

3.2 设置

在上面所述的usb_interface结构体中介绍了altsetting和cur_altersetting,他们都是usb_host_interface的结构体,定义如下:

  • desc是一个结构描述符。
  • endpoint是一个数组,表示这个设置所用到的端点。USB协议中规定了端点的结构,在Linux中,使用struct usb_host_endpoint结构体来表示。
  • string 字符串指针用来保存从设备固件中取出来的字符串描述信息,可有可无。
  • extra和extralen表示额外的描述符。除了设备、配置、接口、端点这4个不能缺少的描述符和字符串描述符外,设备还可能有一些另外的字符信息描述符。这些信息有开发商自己指定需要的信息。

3.3 探测函数usb_serial_probe()

usb_serial_probe()函数作用是实现热插拔的机制,用来对设备进行识别和对设备进行最初的设置,使其能够进行正常的工作。要理解设备对设备进行了怎样的初始化工作,必须要详细的分析这一部分的代码:
struct usb_device *dev = interface_to_usbdev(interface);
首先是将usb_interface结构转化为usb_device结构,然后是定义了一些结构体指针和变量.
type = search_serial_device(interface);
search_serial_device的定义如下:


该函数的作用是检查所插入的USB设备的id是否匹配一个在定义的设备表中的已知的设备,返回值是一个usb_serial_driver类型的结构体,如果返回的指针为空,则说明没有查找到该设备匹配的驱动则返回。
若是成功则执行try_module_get(type->driver.owner),该函数用来获取设备所匹配的模块,即设备的驱动,

未完待续......``

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • linux设备模型bus,device,driver作者 codercjg 在 10 十一月 2015, 2:43...
    codercjg阅读 541评论 0 1
  • Linux usb system(driver) USB的应用用来用广泛了,键盘、鼠标、打印机、摄像头、网卡......
    Creator_Ly阅读 2,626评论 0 5
  • linux设备模型bus,device,driver作者 codercjg 在 10 十一月 2015, 2:43...
    codercjg阅读 403评论 0 1
  • 1.1PAD作为USB Device设备 USB Device的功能很丰富,其支持的协议越来越多包括:MTP、AD...
    android之子阅读 18,067评论 0 13
  • 1.下面一句话,选自《就因为没时间,才什么都能办到》一书中第33页,深有感触,分享给大家: “的确,我想念书,想往...
    NJ_LIFE阅读 2,975评论 0 2