原创 nand做闪存2440_Gadget移植步骤(转载)

2011-7-16 23:26 1705 7 7 分类: MCU/ 嵌入式

 

 

2440 Gadget移植手册


1.       Gadget可以将开发板上的存储设备作为U盘挂载到Windows下,该技术主要用于MP3等带有存储文件功能的电子产品和U盘等。

2.       2.6.22之前的版本默认没有s3c2410_udc的驱动文件(笔者自己的内核代码里没有,而使用较新的内核版本里2.6.32.2带有),所以对于2.6.22需要将找到对应的udc驱动文件。如下操作:

l  s3c2410UDC驱动s3c2410_udc.c s3c2410_udc.h放到source根目录下driver/usb/gadget/

l  修改对应的gadget Kconfig文件和Makefile文件:

Kconfig增加下面内核选项,使其出现在Menuconfig选项内:

config USB_GADGET_S3C2410

       boolean "S3C2410 USB Device Controller"

       depends on ARCH_S3C2410

       help

       Michael Tang add for s3c2440 processor.

config USB_S3C2410

        tristate

        depends on USB_GADGET_S3C2410

        default USB_GADGET

        select USB_GADGET_SELECTED

config USB_S3C2410_DEBUG

        boolean "S3C2410 udc debug messages"

        depends on USB_GADGET_S3C2410

l  修改Makefile文件,使其可以编译进内核:

增加:

       obj-$(CONFIG_USB_S3C2410)       += s3c2410_udc.o

 

3.       udc驱动编译进内核:

Device Drivers -à

       

  • USB Support -à

    <*>   USB Gadget Support  --->
                USB Peripheral Controller (S3C2410 USB Device Controller)  --->
                 S3C2410 USB Device Controller
        

  •        S3C2410 udc debug messages
        <M>   USB Gadget Drivers
        <M>     File-backed Storage Gadget

    20110716232523001.jpg

     

           由于linux2.6.32将平台相关代码的目录结构进行了调整,所以如果是2.6.22的内核应该将上述头文件改为:

             删除下面的头文件引用:

             #include <linux/gpio.h>

    #include <linux/usb/gadget.h>

    #include <mach/irqs.h>

    #include <mach/hardware.h>

    #include <plat/regs-udc.h>

    #include <plat/udc.h>

    893行,删除头文件

    #include <mach/regs-irq.h>

    增加下面头文件引用:

    #include <linux/usb_gadget.h>

    #include <asm/arch-s3c2410/regs-udc.h>

    #include <asm/arch/regs-gpio.h>

    #include <asm/arch-s3c2410/gpio.h>

    #include <asm/arch/regs-clock.h>

    #include <asm/arch-s3c2410/udc.h>

    #include <asm/delay.h>

    #include <asm/arch-s3c2410/regs-irq.h>

    如果上述头文件找不到,去smdk2410相关目录里去找(find命令),然后cparch/arm/mach-s3c2440/中。

     

    4.       修改arch/arm/mach-s3c2440/mach-smdk2440.c文件,增加开发板相关的代码,修改该文件使之可以在系统启动时被加载。

    增加下面的头文件

    #include <mach/regs-gpio.h>

    #include <mach/regs-clock.h>

    #include <mach/gpio-fns.h>

    #include <plat/udc.h>

    #include <asm/delay.h>

     

    5.       增加下面代码用于UDC使能操作,加粗部分要根据自己的开发板的使能引脚进行设置。

    static void smdk2410_udc_pullup(enum s3c2410_udc_cmd_e cmd)

    {

            u8 *s3c2410_pullup_info[] = {

                " ",

                "Pull-up enable",

                "Pull-up disable",

                "UDC reset, in case of"

            };

            printk("smdk2410_udc: %s\n",s3c2410_pullup_info[cmd]);

            s3c2410_gpio_cfgpin(S3C2410_GPG(12), (1<<24));

            switch (cmd)

            {

                case S3C2410_UDC_P_ENABLE :

                    s3c2410_gpio_setpin(S3C2410_GPG(12), 1);   //set gpg9 output HIGH

                    break;

                case S3C2410_UDC_P_DISABLE :

                    s3c2410_gpio_setpin(S3C2410_GPG(12), 0);   //set gpg9 output LOW

                    break;

                case S3C2410_UDC_P_RESET :

                    //FIXME!!!

                    break;

                default:

                    break;

            }

    }

    static struct s3c2410_udc_mach_info smdk2410_udc_cfg __initdata = {

            .udc_command    = smdk2410_udc_pullup,

    };

     

    在开发板初始化函数smdk2440_machine_init内增加下面代码

    // 增加下面的宏

    #define S3C2410_PLLCON_MDIVSHIFT     12

    #define S3C2410_PLLCON_PDIVSHIFT     4

    #define S3C2410_PLLCON_SDIVSHIFT     0

    static void __init smdk2440_machine_init(void)

    {

            s3c24xx_fb_set_platdata(&smdk2440_fb_info);

            s3c_i2c0_set_platdata(NULL);

    /* Michael Tang add start */

            s3c24xx_udc_set_platdata(&smdk2410_udc_cfg); /* 初始化*/

            printk("=====MT===== Run to here [smdk2440_machine_init]");

            s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |

                     S3C2410_MISCCR_USBSUSPND0 |

                     S3C2410_MISCCR_USBSUSPND1, 0x0);

            /* 设置USB时钟 */

            u32 upll_value = (

                    0x78 << S3C2410_PLLCON_MDIVSHIFT)

                    | (0x02 << S3C2410_PLLCON_PDIVSHIFT)

                    | (0x03 << S3C2410_PLLCON_SDIVSHIFT);

            while (upll_value != readl(S3C2410_UPLLCON)) {

                    writel(upll_value, S3C2410_UPLLCON);

                    udelay(20);

            }

    /* Michael Tang add end */

     

            platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));

    ….

    在平台设备注册结构体数组里加入usbgadget的平台设备注册结构体

    static struct platform_device *smdk2440_devices[] __initdata = {

            &s3c_device_usb,

            &s3c_device_lcd,

            &s3c_device_wdt,

            &s3c_device_i2c0,

            &s3c_device_iis,

    // Michael Tang add

            &s3c_device_usbgadget,

    // Michael Tang add

    };

     

    6.       source根目录下执行make uImage,会生成对应的映像文件,不过,UDC驱动的文件传输需要使用到file_storge.c驱动,不过该驱动文件有点问题,如果不修改,传输速度很慢,在传输过程还还会不停的重启gadget,修改如下:

    修改drivers/usb/gadget/file_storage.c

    static int fsg_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)函数中

    删除: fsg->ep0req->zero = rc < w_length;

    增加: fsg->ep0req->zero = rc < w_length \

    && (rc % gadget->ep0->maxpacket) == 0;

    修改drivers/usb/gadget/s3c2410_udc.c

    static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)函数中

        struct s3c2410_request *req;

    int is_in = ep->bEndpointAddress & USB_DIR_IN;

        u32 ep_csr1;

        u32 idx;

     增加: handle_ep_again:

     ……

    if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {

    s3c2410_udc_read_fifo(ep,req);

    增加: if (s3c2410_udc_fifo_count_out())

       goto handle_ep_again;

    }

    7.       执行make modules,生成g_file_storage.ko,将内核烧入后,执行:

    insmod g_file_storage.ko file=/dev/mtdblock2 stall=0 removable=1

    插入usb device接口,然后在windows下可以被识别了,执行文件写入和读出速度都还可以。


    附件:修正文件传输速度慢的patch代码:

    1----------------------------------------------------------------------------------
    --- a/drivers/usb/gadget/file_storage.c    2008-09-01 11:13:03.000000000 -0400
    +++ b/drivers/usb/gadget/file_storage.c    2008-09-01 11:16:41.000000000 -0400
    @@ -1463,7 +1463,8 @@
        if (rc >= 0 && rc != DELAYED_STATUS) {
            rc = min(rc, w_length);
            fsg->ep0req->length = rc;
    -        fsg->ep0req->zero = rc < w_length;
    +        fsg->ep0req->zero = rc < w_length
    +            && (rc % gadget->ep0->maxpacket) == 0;
            fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
                    "ep0-in" : "ep0-out");
            rc = ep0_queue(fsg);

    2------------------------------------------------------------------------
    Index: linux-2.6.28.8/drivers/usb/gadget/s3c2410_udc.c
    ===================================================================
    --- linux-2.6.28.8.orig/drivers/usb/gadget/s3c2410_udc.c    2009-03-17 21:14:28.000000000 +0100
    +++ linux-2.6.28.8/drivers/usb/gadget/s3c2410_udc.c    2009-03-17 21:14:46.000000000 +0100
    @@ -843,6 +843,7 @@
         u32            ep_csr1;
         u32            idx;

    +handle_ep_again:
         if (likely (!list_empty(&ep->queue)))
             req = list_entry(ep->queue.next,
                     struct s3c2410_request, queue);
    @@ -882,6 +883,8 @@

             if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
                 s3c2410_udc_read_fifo(ep,req);
    +            if (s3c2410_udc_fifo_count_out())
    +                goto handle_ep_again;
             }
         }
    }

  • PARTNER CONTENT

    文章评论0条评论)

    登录后参与讨论
    EE直播间
    更多
    我要评论
    0
    7
    关闭 站长推荐上一条 /3 下一条