****************************************************************************************************************************************************************************************

 cpu         : s3c2440(arm9)

linux内核:linux-3.0

开发板    :fl2440

开发模块:USB-DEVICE(gadget)

*************************************************************************************************************************************

  前言:生活中我们经常会将智能手机用数据线插上pc,然后PC对智能手机识别为存储设备,进而我们可以进行读写文件,那么本文介绍的技术就是如何将fl2440开发板模拟成类似于智能手机插上pc的存储设备,也就是模拟U盘      

                  这个功能是参照我同学的博客实现的,我没有对gadget驱动进行深入的了解,只是简单的实现这一功能,要是想了解更多关于这方面的内容可以参考我同学的博客:   http://blog.csdn.net/edroid1530/article/details/71194942

       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






 

  

Logo

更多推荐