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引脚控制上拉电阻
[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
(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/
注意:做完上面的步骤之后,当我们将usb数据线插入pc上时,开发板上会打印g_file_storage gadget: full speed config #1信息,且PC上出现了一个名为H,大小为32M的磁盘,里面没有任何文件,如图所示
我们可以看到/media/目录下有内容System Volume Information,我们再往里面写文件测试一下
在开发板上写文件之后,再看看Windows上发现里面还是没有任何内容,重新拔插usb线之后,发现里面出现了一个test.txt文件如图:
再往Windows上写一个test1.txt文件,查看开发板上发现并没有出现test1.txt文件,重新挂载文件系统映像到 /media目录后出现了该文件如图:
经测试发现模拟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
本文永久更新地址://m.ajphoenix.com/linux/31336.html