其他的一些有关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,有三个分区。
执行:
连接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转串口命令
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中的部分程序:
参考部分:
官方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