Linux Gadget的一点研究之U盘和USB虚拟串口

其他的一些有关Linux USB gadget的博客 http://blog.csdn.net/arnoldlu/article/list/2

Linux kernel2.6以上的版本中,USB设备驱动的接口改为了gadget,在kernel/driver/usb/gadget目录下主要包含了平台USB UDC驱动和gadget接口驱动。

        kernel/driver/usb/gadget目下的serial.c是一个常用的驱动文件,它可以配置为bulk传输驱动或CDC ACM驱动(USB转串口驱动)。配置的方式有两种,一可以在编译前手动更改驱动文件中的变量“use_acm"的默认值,现在默认值为”true“,对应为CDC ACM驱动,改为”false"后对应为bulk驱动;二可以将驱动编译成模块,然后在insmod时传递一个参数就行了。

       运行make menuconfig看一下:


 将“USB Gadget Support -->"选择编译为模块,方便动态加载驱动。

        进行“USB Gadget Support -->"配置子菜单:


配置红色方框标注的模块。

      运行命令: make M=driver/usb/gagdet modules

      编译后在driver/usb/gagdet 下生产g_file_storage.ko和g_serial.ko,分别对应为U盘驱动和USB转串口驱动。

      笔者的嵌入式板上有个SD卡,linux驱动后挂载主目录是/dev/mmcblk0,分区目录是/dev/mmcblk0p1,/dev/mmcblk0p2,/dev/mmcblk0p3,有三个分区。

      执行:

[plain]  view plain copy
  1. root@rfODNCC:/mnt# insmod g_file_storage.ko file=/dev/mmcblk0 stall=0 removable=1  
  2. [   69.783477] g_file_storage gadget: No serial-number string provided!  
  3. [   69.798980] g_file_storage gadget: File-backed Storage Gadget, version: 1 September 2010  
  4. [   69.807495] g_file_storage gadget: Number of LUNs=1  
  5. [   69.812622] g_file_storage gadget-lun0: ro=0, nofua=0, file: /dev/mmcblk0  
  6. [   69.819763] musb-hdrc musb-hdrc.0: MUSB HDRC host driver  
  7. [   69.825622] musb-hdrc musb-hdrc.0: new USB bus registered, assigned bus number 2  
  8. [   69.833801] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002  
  9. [   69.840942] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1  
  10. [   69.848510] usb usb2: Product: MUSB HDRC host driver  
  11. [   69.853668] usb usb2: Manufacturer: Linux 2.6.37-05branch musb-hcd  
  12. [   69.860137] usb usb2: SerialNumber: musb-hdrc.0  
  13. [   69.872558] hub 2-0:1.0: USB hub found  
  14. [   69.876647] hub 2-0:1.0: 1 port detected  
  15. root@rfODNCC:/mnt# [   70.169555] g_file_storage gadget: high speed config #1  

连接USB到PC,可以看到PC端出现SD卡的分区目录。

PS:insmod g_file_storage.ko file=/dev/mmcblk0 stall=0 removable=1 和 insmod g_file_storage.ko file=/dev/mmcblk0有点区别,后续可以查找理解stall 和 removable的具体作用。

接着制作一个嵌入式设备端fat32文件分区,然后挂载到PC上:

1.在主机ubuntu上建立fat32文件映像,大小为2M。

    #dd if=/dev/zero of=fat32.img bs=1k count=2048
    #mkfs.vfat fat32.img

2.向fat32.img中写入一些文件,以用来测试:
    #mkdir fat32
    #sudo mount -t vfat -o loop fat32.img fat32  
    #cd fat32
    #touch hello.txt
    #echo hello,wolrd>hello.txt
    #sync

3.把主机ubuntu上的fat32.img 拷贝到嵌入式设备的根文件系统中。

4.在嵌入式设备中加载g_file_storage驱动

  insmod g_file_storage.ko file=/opt/fat32.img stall=0 removable=1   //我将fat32.img放在/opt下

5.USB线连接设备和PC,弹出发现移动磁盘,打开盘,里面有个hello.txt文件。

6.在PC端打开U盘,增加一个文件系统,如text.txt,然后在设备端通过命令挂载映像,命令为:

mount -t vfat -o loop /opt/fat32.img /media      //挂载到media目录下

到media目录,cd /media

看到/media目下有两个文件hello.txt和test.txt,且内容和在PC端看到的一致。

注意:如果此时在PC端再次修改了文件。这设备端不能立即看到PC修改的结果。即PC和设备端不能同步。

此时可以在设备进行umount /media,然后重新mount一次就可以看到PC更改的结果。同样在设备端修改的文件,PC端也不能立即看到修改结果,需重新插拔USB线才能看到更新。至于原因,暂时不知道。

卸载g_file_storage

执行加载USB转串口命令

[plain]  view plain copy
  1. root@rfODNCC:/mnt# insmod g_serial.ko   
  2. [  239.675933] g_serial gadget: Gadget Serial v2.4  
  3. [  239.680786] g_serial gadget: g_serial ready  
  4. [  239.685241] musb-hdrc musb-hdrc.0: MUSB HDRC host driver  
  5. [  239.691009] musb-hdrc musb-hdrc.0: new USB bus registered, assigned bus number 2  
  6. [  239.707153] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002  
  7. [  239.714324] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1  
  8. [  239.721893] usb usb2: Product: MUSB HDRC host driver  
  9. [  239.727111] usb usb2: Manufacturer: Linux 2.6.37-05branch musb-hcd  
  10. [  239.733581] usb usb2: SerialNumber: musb-hdrc.0  
  11. [  239.747467] hub 2-0:1.0: USB hub found  
  12. [  239.751434] hub 2-0:1.0: 1 port detected  
  13. root@rfODNCC:/mnt# [  240.044830] g_serial gadget: high speed config #2: CDC ACM config  

PC端安装USB转串口驱动后,可以从PC设备管理器上看到多出了一个串口。

要使得设备端能与PC端通过USB转串口进行通信,设备端还需要手动创建设备文件节点,参考内核文档(Documents/usb/gagdet_serial.txt)中的部分内容:

This will also automatically load the underlying gadget peripheral
controller driver.  This must be done each time you reboot the gadget
side Linux system.  You can add this to the start up scripts, if


desired.


Your system should use mdev (from busybox) or udev to make the
device nodes.  After this gadget driver has been set up you should
then see a /dev/ttyGS0 node:


  # ls -l /dev/ttyGS0 | cat
  crw-rw----    1 root     root     253,   0 May  8 14:10 /dev/ttyGS0
  #


Note that the major number (253, above) is system-specific.  If
you need to create /dev nodes by hand, the right numbers to use
will be in the /sys/class/tty/ttyGS0/dev file.

作者创建设备节点为:先cat /sys/class/tty/ttyGS0/dev,得到主设备号后,mknod /dev/ttyGS0 c major_num 0

然后PC打开一个串口软件,打开对应的串口端口。

设备端执行 echo “hello” > /dev/ttyGS0,PC端串口软件收到相应数据。

PS:UDC(设备控制器)驱动主要是与硬件平台相关的,它会实现gadget功能驱动所需要的接口,一般的UDC仅支持注册一个gadget功能驱动,所以上面是在将g_file_storage驱动卸载后才能重新加载g_serial.ko。否则会出现失败。

看看UDC驱动代码中的注册gadget驱动函数usb_gadget_probe_driver中的部分程序:

[plain]  view plain copy
  1. spin_lock_irqsave(&udc->lock, flags);  
  2. if (udc->driver) {  
  3.     spin_unlock_irqrestore(&udc->lock, flags);  
  4.     return -EBUSY;  
  5. }  
可见第一次注册gadget驱动后udc->driver为true,在不卸载情况下再次注册gadget时出现无法注册的错误。

参考部分:

官方Gadget框架的描述:http://www.linux-usb.org/gadget/

基于9263的配置过程:http://www.cublog.cn/u3/111925/showart_2278264.html

华清讲师刘洪涛的BLOG:http://blog.csdn.net/hongtao_liu/article/details/4555645


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值