u-boot-2009.08在mini2440上的移植 增加USB功能

发布时间:2024-07-01  

移植环境

1,主机环境:VMare下CentOS 5.5 ,1G内存。

2,集成开发环境:Elipse IDE

3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-eabi-gcc v4.5.1。

4,开发板:mini2440,2M nor flash,128M nand flash。

5,u-boot版本:u-boot-2009.08

6,参考文章:

8.1,实现u-boot的usb slave下载功能

友善自带的dnw下的usb下载功能真的很好用,于是也想实现此功能,现参考博文为u-boot-2009.08 添加 dnw usb下载功能,操作如下(红色字体部分为修改或添加的代码):

【1】复制usb slave驱动源代码,源码下载uboot-usb_slave.tar.bz2 下载在 http://www.linuxidc.net/thread-2238-1-1.html

下载后将源码解压到u-boot-2009.08/drivers/usb/目录下:

[root@localhost ~]# cd ./u-boot-test/u-boot-2009.08/drivers/usb
[root@localhost usb]# tar -jxf /root/100109001526.bz2
[root@localhost usb]# ls
gadget  host  musb  slave
[root@localhost usb]#

【2】用gedit打开u-boot-2009.08/Makefile,定位到243行附近,修改如下:

LIBS += drivers/usb/host/libusb_host.a
LIBS += drivers/usb/musb/libusb_musb.a
LIBS += drivers/usb/slave/libusb_slave.a
LIBS += drivers/video/libvideo.a

【3】打开/lib_arm/board.c,定位到423行附近,修改如下:

#if defined(CONFIG_MISC_INIT_R)
 /* miscellaneous platform dependent initialisations */
 misc_init_r ();
#endif
 extern void port_init(void);
 port_init();
 /* enable exceptions */
 enable_interrupts ();
 #if defined(CONFIG_USB_DEVICE)
 extern int usb_init_slave(void);
 usb_init_slave();
#endif

 /* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC

这里要强调下hugerat 博主说得很对,usb_init() 应改为 usb_init_slave()。详情请参见mini2440 实现u-boot的usb slave下载功能。

【4】打开/include/configs/mini2440.h,定位到48行附近,注释掉下面代码:

#define USE_920T_MMU  1
//#undef CONFIG_USE_IRQ   /* we don't need IRQ/FIQ stuff */

定位到173行附近,加入如下代码:

/* valid baudrates */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }

#define CONFIG_SYS_CONSOLE_IS_IN_ENV //It's important to serial console !
//Define this if you want stdin, stdout &/or stderr to be set to usbtty
/*
USB device support
*/
#define CONFIG_USB_DEVICE   1

#ifdef CONFIG_USB_DEVICE
#define CONFIG_USE_IRQ    1
#endif

/*-----------------------------------------------------------------------
 * Stack sizes

注意,#define CONFIG_SYS_CONSOLE_IS_IN_ENV 配置非常重要,不配置此项,只能看到控制台信息在LCD上的显示,而在串口终端没有输出!

【5】打开/cpu/arm920t/s3c24x0/interrupts.c,定位到文件末尾处添加arch_interrupt_init函数定义:
void do_irq (struct pt_regs *pt_regs)
{
 S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
 u_int32_t intpnd = irq->INTPND;

}

int arch_interrupt_init (void)
{
    return 0;

}

【6】/cpu/arm920t/start.S,定位到625行附近,加入下面代码:

#ifdef CONFIG_USE_IRQ

 .align 5
irq:
/*
 get_irq_stack
 irq_save_user_regs
 bl do_irq
 irq_restore_user_regs
*/
/* use IRQ for USB and DMA */
    sub    lr, lr, #4                     @ the return address
    ldr    sp, IRQ_STACK_START            @ the stack for irq
    stmdb    sp!,     { r0-r12,lr }     @ save registers
   
    ldr    lr,    =int_return             @ set the return addr
    ldr    pc, =IRQ_Handle                @ call the isr
int_return:
    ldmia    sp!,     { r0-r12,pc }^     @ return from interrupt

 .align 5
fiq:
 get_fiq_stack
 /* someone ought to write a more effiction fiq_save_user_regs */
 irq_save_user_regs
 bl do_fiq
 irq_restore_user_regs

#else

【7】打开/include/s3c24x0.h,定位到330行附近,修改如下:

 S3C24X0_REG8 MAXP_REG;
 S3C24X0_REG8    res10[3]; //S3C24X0_REG8 res10[7];
 S3C24X0_REG8 EP0_CSR_IN_CSR1_REG;
 S3C24X0_REG8 res11[3];
 S3C24X0_REG8 IN_CSR2_REG;
 S3C24X0_REG8    res12[7]; //S3C24X0_REG8 res12[3];
 S3C24X0_REG8 OUT_CSR1_REG;
 S3C24X0_REG8    res13[3]; //S3C24X0_REG8 res13[7];
 S3C24X0_REG8 OUT_CSR2_REG;
 S3C24X0_REG8 res14[3];
 S3C24X0_REG8 OUT_FIFO_CNT1_REG;
 S3C24X0_REG8 res15[3];
 S3C24X0_REG8 OUT_FIFO_CNT2_REG;
 S3C24X0_REG8 res16[3];
#endif /*  __BIG_ENDIAN */
 //S3C24X0_USB_DEV_FIFOS fifo[5];
 //S3C24X0_USB_DEV_DMAS dma[5];
 S3C24X0_REG32   res17[8];
 S3C24X0_USB_DEV_FIFOS   fifo[5];
 S3C24X0_REG32   res18[11];
 S3C24X0_USB_DEV_DMAS    ep1;
 S3C24X0_USB_DEV_DMAS    ep2;
 S3C24X0_REG8    res19[16];
 S3C24X0_USB_DEV_DMAS    ep3;
 S3C24X0_USB_DEV_DMAS    ep4;
} /*__attribute__((__packed__))*/ S3C24X0_USB_DEVICE;

【8】添加usbslave命令

在/common/目录下创建文件cmd_usbslave.c,然后将下面内容粘贴进去:

#include
#include
#include

#ifdef CONFIG_USB_DEVICE

#ifdef CONFIG_USE_IRQ
    #define IRQ_STACK_START    (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4)
    #define FIQ_STACK_START    (IRQ_STACK_START - CONFIG_STACKSIZE_IRQ)
    #define FREE_RAM_END        (FIQ_STACK_START - CONFIG_STACKSIZE_FIQ - CONFIG_STACKSIZE)
    #define FREE_RAM_SIZE        (FREE_RAM_END - PHYS_SDRAM_1)
#else
    #define    FREE_RAM_END    (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4 - CONFIG_STACKSIZE)
    #define    FREE_RAM_SIZE    (FREE_RAM_END - PHYS_SDRAM_1)
#endif

 

int g_bUSBWait = 1;
u32 g_dwDownloadLen = 0;

extern int download_run;
extern volatile unsigned int dwUSBBufBase;
extern volatile unsigned int dwUSBBufSize;

extern __u32 usb_receive(char *buf, size_t len, unsigned int wait);

int do_usbslave (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    int i;
    size_t len = ~0UL;
    char buf[32];

    /* download_run为1时表示将文件保存在USB Host发送工具dnw指定的位置
     * download_run为0时表示将文件保存在参数argv[2]指定的位置
     * 要下载程序到内存,然后直接运行时,要设置download_run=1,这也是这个参数名字的来由
     */
    download_run = 1;
    switch (argc) {
        case 1:
        {
            break;
        }
        case 2:
        {
            g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
            break;
        }

        case 3:
        {
            g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
            load_addr = simple_strtoul(argv[2], NULL, 16);
            download_run = 0;
            break;
        }
       
        default:
        {
            printf ("Usage:n%sn", cmdtp->usage);
            return 1;
        }
    }

    dwUSBBufBase = load_addr;
    dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));
    if (g_bUSBWait)
        len = FREE_RAM_SIZE;

    g_dwDownloadLen = usb_receive(dwUSBBufBase, len, g_bUSBWait);
    sprintf(buf, "%X", g_dwDownloadLen);
    setenv("filesize", buf);
   
    return 0;
}

U_BOOT_CMD(
    usbslave,    3,    0,    do_usbslave,
    "usbslave - get file from host(PC)n",
    "[wait] [loadAddress]n"
    ""wait" is 0 or 1, 0 means for return immediately, not waits for the finish of transferringn"
);

#endif

打开/common/Makefile,定位到163行,加入下面代码:
# others
COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
COBJS-y += flash.o
COBJS-$(CONFIG_CMD_KGDB) += kgdb.o
COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
COBJS-$(CONFIG_LCD) += lcd.o
COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
COBJS-$(CONFIG_UPDATE_TFTP) += update.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
COBJS-$(CONFIG_USB_DEVICE) += cmd_usbslave.o

COBJS := $(sort $(COBJS-y))

【9】打开/include/s3c2410.h,定位到198行附近,加入下面代码:

#define BIT_TICK  (0x1<<8)
#define BIT_WDT   (0x1<<9)
#define BIT_WDT_AC97   (0x1<<9)
#define BIT_TIMER0  (0x1<<10)
#define BIT_TIMER1  (0x1<<11)

【10】编译报错:undefined reference to `udc_disconnect'

打开/lib_arm/bootm.c定位到124行,udc_disconnect ();此句也要注释掉:

 /* we assume that the kernel is in place */
 printf ("nStarting kernel ...nn");

#ifdef CONFIG_USB_DEVICE
 {
  extern void udc_disconnect (void);
  //udc_disconnect ();
 }
#endif

否则编译报错。

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>