红联Linux门户
Linux帮助

linux-3.0-Gadget驱动移植实现模拟U盘

发布时间:2017-06-08 11:04:56来源:linux网站作者:zouleideboke
cpu: s3c2440(arm9)
Linux内核:linux-3.0
开发板:fl2440
开发模块:USB-DEVICE(gadget)
 
前言:生活中我们经常会将智能手机用数据线插上pc,然后PC对智能手机识别为存储设备,进而我们可以进行读写文件,那么本文介绍的技术就是如何将fl2440开发板模拟成类似于智能手机插上pc的存储设备,也就是模拟U盘。
 
1.修改内核源码
[zoulei@CentOS linux-3.0]$ vim drivers/usb/gadget/file_storage.c
1067 /* Use this for bulk or interrupt transfers, not ep0 */  
1068 static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,  
1069                 struct usb_request *req, int *pbusy,  
1070                 enum fsg_buffer_state *state)  
1071 {  
1072         int     rc;  
1073         udelay(800);  /*增加延时*/  
......  
}  
329 } mod_data = {                // Default values  
......  
/*修改mod_data初始值*/  
332         .removable              = 1,  
333         .can_stall              = 0,  
......  
}
说明:我的内核源码默认就是上面的值,并不需要改动,如果是别的版本内核就需要改动了!
在arch/arm/mach-s3c2440/mach-smdk2440.c中添加gadget设备结构体初始化和 USB device上拉电阻控制,从fl2440原理图可以看到GPG9引脚控制上拉电阻
linux-3.0-Gadget驱动移植实现模拟U盘
[zoulei@CentOS linux-3.0]$ vim arch/arm/mach-s3c2440/mach-smdk2440.c
#include <plat/udc.h>   /*Added by zoulei  for usbgadget 2017.05.07*/  
165 /*usbgadget info was added by zoulei 2017.05.07*/   
167 static struct s3c2410_udc_mach_info s3c_udc_cfg __initdata = {  
168     .pullup_pin = S3C2410_GPG(9),  
169   
170 };  
274 static struct platform_device *smdk2440_devices[] __initdata = {  
......  
285         &s3c_device_usbgadget, /*added by zoulei 2017.05.7*/  
286 };  
311 static void __init smdk2440_machine_init(void)  
312 {  
......  
316         s3c24xx_udc_set_platdata(&s3c_udc_cfg);/*Added pull-up resistor by zoulei 2017 05.07*/  
......  
321 }
注意:添加<plat/udc.h>头文件时,最好放在文件头的最低端,否则编译可能会出错!
 
2.配置make menuconfig
[zoulei@CentOS linux-3.0]$ make menuconfig
Device drivers -->
[*] USB support -->
<*>   USB Gadget Support  --->
[*]       S3C2410 udc debug messages
<M>   USB Gadget Drivers 
<M>   Gadget zero(DEVELOPMENT)
<M>     File-backed Storage Gadget
说明:<M>USB Gadget Support选项主要是编译出s3c2410_udc.ko,按照上面那种选择则此时只编译出g_file_storage.ko
因为加载file-backed驱动的时候,要添加镜像文件,所以这里我们要选择模块编译,也就是选项前面选择M
 
3.编译测试
完成以上修改之后重新编译内核,将在driver/usb/gadget目录下生成g_file_storage.ko模块文件,在内核源码目录下生成
udisk32M.img文件,将这两个文件下载到开发板上进行测试,且编译后的内核一定要烧录到开发板上运行!
(1)制作FAT32文件系统映像,在开发板上依次执行下列命令
dd if=/dev/zero of=udisk32M.img bs=1k count = 32768 
mkfs.vfat udisk32M.img 
linux-3.0-Gadget驱动移植实现模拟U盘
(2)加载g_file_storage.ko驱动,与镜像文件建立关联,挂载loop设备 
我们将其挂载到media目录下,如果没有该目录则新建一个media目录
insmod g_file_storage.ko file=udisk32M.img stall=0 removable=1 
mount -o loop /udisk32M.img /media/
linux-3.0-Gadget驱动移植实现模拟U盘
注意:做完上面的步骤之后,当我们将usb数据线插入pc上时,开发板上会打印g_file_storage gadget: full speed config #1信息,且PC上出现了一个名为H,大小为32M的磁盘,里面没有任何文件,如图所示
linux-3.0-Gadget驱动移植实现模拟U盘
我们可以看到/media/目录下有内容System Volume Information,我们再往里面写文件测试一下
linux-3.0-Gadget驱动移植实现模拟U盘
在开发板上写文件之后,再看看Windows上发现里面还是没有任何内容,重新拔插usb线之后,发现里面出现了一个test.txt文件如图:
再往Windows上写一个test1.txt文件,查看开发板上发现并没有出现test1.txt文件,重新挂载文件系统映像到 /media目录后出现了该文件如图:
linux-3.0-Gadget驱动移植实现模拟U盘
linux-3.0-Gadget驱动移植实现模拟U盘
经测试发现模拟U盘可以正常工作,则将fl2440开发板模拟成U盘的功能成功实现!
 
4.遇到的的问题及解决方法
在制作将fl2440开发板模拟成U盘时,我将/media 目录作为挂载点,可是后来卸载就出现如下错误。
问题:>: umount /media
umount: can't umount /media: Device or resource busy
解决:
>: fuser -km /media
Copyright (C) 2011 fulinux<fulinux@gmail.com>
root login: root
>: df -lh
df: invalid option -- l
BusyBox v1.20.2 (2017-03-01 01:32:52 PST) multi-call binary.
Usage: df [-Pkmhai] [-B SIZE] [FILESYSTEM]...
Print filesystem usage statistics
-P      POSIX output format
-k      1024-byte blocks (default)
-m      1M-byte blocks
-h      Human readable (e.g. 1K 243M 2G)
-a      Show all filesystems
-i      Inodes
-B SIZE Blocksize
>: umount /media
注意: -k(  kill processes accessing the named file杀死访问指定文件的进程) -m( show all processes using the named filesystems)
fuser命令是显示访问某个文件的进程的PID
 
本文永久更新地址:http://www.linuxdiyf.com/linux/31336.html