Linux内核中usb设备侧驱动程序分成3个层次:UDC驱动程序、Gadget API和Gadget驱动程序。UDC驱动程序(USB控制器)直接访问硬件,控制USB设备和主机间的底层通信,向上层提供与硬件相关操作的回调函数。Gadget API是UDC驱动程序回调函数的简单包装,这部分程序内核都已经写好。Gadget驱动程序具体控制USB设备功能的实现,使设备表现出“U盘”、“虚拟串口”等特性。

1、配置内核

这里之所以都选择为模块的形式,是为了调试方便,有些模块,比如U盘加载时还需要提供介质,就是说加载模块时还需要参数,否则加载不上

   Device Drivers  ---> 

   [*] USB support  ---> 

 <*>   USB Gadget Support  --->  

    USB Gadget Drivers                                                                                                         
< >     USB functions configurable through configfs                                                                        
< >     Gadget Zero (DEVELOPMENT)                                                                                                 
< >     Ethernet Gadget (with CDC Ethernet support)                                                                             
< >     Network Control Model (NCM) support                                                                                      
< >     Gadget Filesystem                                                                                                         
< >     Function Filesystem                                                                                                   
< >     Mass Storage Gadget                                                                                                        
< >     USB Gadget Target Fabric Module                                                                                               
Serial Gadget (with CDC ACM and CDC OBEX support)                                                                         
< >     Printer Gadget    

    Gadget Zero, 类似于 dummy hcd, 该驱动用于测试 udc 驱动。它会帮助您通过 USB-IF 测试。

  Ethernet Gadget, 该驱动模拟以太网网口,它支持多种运行方式:

  CDC Ethernet: usb 规范规定的 Communications Device Class “Ethernet Model” protocol。

  RNDIS: 微软公司对 CDC Ethernet 的变种实现。

   Gadget Filesystem:提供一个基于API的文件系统,可以在用户空间访问

  File-backed Storage Gadget最常见的 U 盘功能实现。

  Serial Gadget:虚拟串口

    Printer Gadget:打印机功能

保存退出,编译内核。在drivers/usb/gadget目录下会生成以下驱动文件
g_serial.ko
libcomposite.ko
usb_f_acm.ko
usb_f_obex.ko
usb_f_serial.ko
u_serial.ko

2、操作开发板

把编译好的内核烧入开发板,加载生成的驱动文件,注意加载顺序,否则会出现错误。

insmod  u_serial.ko
insmod  libcomposite.ko
insmod  usb_f_serial.ko
insmod  usb_f_obex.ko
insmod  usb_f_acm.ko
insmod  g_serial.ko

出现内核信息如下:

[   27.310000] --------file=composite.c-------usb_composite_probe------1830
[   27.320000] ------------402[   27.320000] -----usb_gadget_probe_driver------411
[   27.330000] -------udc_bind_to_driver-----342
[   27.330000] g_serial gadget: Gadget Serial v2.4
[   27.340000] g_serial gadget: g_serial ready
[   18.960000] g_serial gadget: high-speed config #2: CDC ACM config

说明加载成功。

Win7操作系统可以自动加载基于udc标准的serial驱动。

安装成功后,在设备管理器中可以看到 “Gadget Serial (COM11) '这个端口。

开发板的/dev/下会出现/dev/ttyGS0这个设备。当然如果你怕这个设备重名,可以更改这个设备节点。操作如下:

cat /proc/devices

Character devices:  1 mem  2 pty  3 ttyp  4 /dev/vc/0  4 tty  4 ttyS  5 /dev/tty  5 /dev/console  5 /dev/ptmx  7 vcs 10 misc 13 input 90 mtd128 ptm136 pts153 spi251 ttyGS

mknod /dev/usb_serial c 251 0

以后可以直接按照串口通讯的方式打开该节点 /dev/usb_serial ,进行数据读写操作。

3、通信测试

开发板上执行命令  cat /dev/usb_serial(当然你也可以编写程序,打开设备读写),这里只是简单的测试设备通信是否正常 ,pc机上打开串口调试助手,打开com10,通过字符串输入框发送数据。此时发现开发板没有收到数据,而串口助手却收到自己发送的数据。这让我很是纳闷,折腾了2天,终于睡醒了。

又测试了另一通路:开发板给pc发。echo 12345 > /dev/usb_serial 

这是完全正常的,通过串口助手收到的数据来看。每次收到的数据都有换行现象,会不会是数据没有从缓冲区中刷出来?我就换了数据格式,发送简单文件

111111111111111111222222222222222222222222222222222222444444444444444444

此时开发板收到数据

# cat /dev/usb_serial 111111111111111111222222222222222222222222222222222222444444444444444444

原来真的是 "\n" 在作怪!!!,如果你的文件只有一行,且没有换行。那么你的开发板是收不到数据的,这些数据并没有丢失,而是存储在串口的缓冲区中,直到遇到 "\n",才会把数据一股脑发出来。

至此测试完毕。

文章来源:http://www.myexception.cn/linux-unix/1853061.html

10-08 16:18