Chinaunix首页 | 论坛 | 博客
  • 博客访问: 32340
  • 博文数量: 12
  • 博客积分: 445
  • 博客等级: 下士
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-06 16:49
文章分类

全部博文(12)

文章存档

2012年(12)

我的朋友

分类: 嵌入式

2012-10-21 22:58:42

10、u-boot增加USB下载功能  


    u-boot默认是不支持USB下载功能的,需要自己添加。在这里我们增加usb slave驱动,该驱动用于开发板连接PC机用USB接口下载程序。移植的usb slave驱动的步骤如下:
(1)在drivers/usb/目录下增加一个slave目录,加入以下文件
(2)修改u-boot根目录下的Makefile文件,修改的代码如下:
  1. LIBS += drivers/usb/musb/libusb_musb.a
  2. LIBS += drivers/usb/phy/libusb_phy.a
  3. LIBS += drivers/usb/slave/libusb_slave.a
  4. LIBS += drivers/video/libvideo.a

(3)修改include/asm-arm/arch-s3c24x0/s3c24x0.h文件,修改的代码如下:
  1. struct s3c24x0_usb_device {
  2. #ifdef __BIG_ENDIAN
  3.     u8    res1[3];
  4.     u8    FUNC_ADDR_REG;
  5.     u8    res2[3];
  6.     u8    PWR_REG;
  7.     u8    res3[3];
  8.     u8    EP_INT_REG;
  9.     u8    res4[15];
  10.     u8    USB_INT_REG;
  11.     u8    res5[3];
  12.     u8    EP_INT_EN_REG;
  13.     u8    res6[15];
  14.     u8    USB_INT_EN_REG;
  15.     u8    res7[3];
  16.     u8    FRAME_NUM1_REG;
  17.     u8    res8[3];
  18.     u8    FRAME_NUM2_REG;
  19.     u8    res9[3];
  20.     u8    INDEX_REG;
  21.     u8    res10[7];
  22.     u8    MAXP_REG;
  23.     u8    res11[3];
  24.     u8    EP0_CSR_IN_CSR1_REG;
  25.     u8    res12[3];
  26.     u8    IN_CSR2_REG;
  27.     u8    res13[7];
  28.     u8    OUT_CSR1_REG;
  29.     u8    res14[3];
  30.     u8    OUT_CSR2_REG;
  31.     u8    res15[3];
  32.     u8    OUT_FIFO_CNT1_REG;
  33.     u8    res16[3];
  34.     u8    OUT_FIFO_CNT2_REG;
  35. #else /* little endian */
  36.     u8    FUNC_ADDR_REG;
  37.     u8    res1[3];
  38.     u8    PWR_REG;
  39.     u8    res2[3];
  40.     u8    EP_INT_REG;
  41.     u8    res3[15];
  42.     u8    USB_INT_REG;
  43.     u8    res4[3];
  44.     u8    EP_INT_EN_REG;
  45.     u8    res5[15];
  46.     u8    USB_INT_EN_REG;
  47.     u8    res6[3];
  48.     u8    FRAME_NUM1_REG;
  49.     u8    res7[3];
  50.     u8    FRAME_NUM2_REG;
  51.     u8    res8[3];
  52.     u8    INDEX_REG;
  53.     u8    res9[7];
  54.     u8    MAXP_REG;
  55.     u8    res10[3];    /* zjw modify from 7 to 3 */
  56.     u8    EP0_CSR_IN_CSR1_REG;
  57.     u8    res11[3];
  58.     u8    IN_CSR2_REG;
  59.     u8    res12[7];            /* zjw modify from 3 to 7 */
  60.     u8    OUT_CSR1_REG;
  61.     u8    res13[3];     /* zjw modify from 7 to 3 */
  62.     u8    OUT_CSR2_REG;
  63.     u8    res14[3];
  64.     u8    OUT_FIFO_CNT1_REG;
  65.     u8    res15[3];
  66.     u8    OUT_FIFO_CNT2_REG;
  67.     u8    res16[3];
  68. #endif /* __BIG_ENDIAN */

  69. #if 0 
  70.     struct s3c24x0_usb_dev_fifos    fifo[5];
  71.     struct s3c24x0_usb_dev_dmas    dma[5];
  72. #endif

  73.     u32    res17[8];
  74.     struct s3c24x0_usb_dev_fifos    fifo[5];
  75.     u32    res18[11];
  76.     struct s3c24x0_usb_dev_dmas    ep1;
  77.     struct s3c24x0_usb_dev_dmas    ep2;
  78.     u8    res19[16];
  79.     struct s3c24x0_usb_dev_dmas    ep3;
  80.     struct s3c24x0_usb_dev_dmas    ep4;
  81. };

(4)修改smdk2440.h,增加usb slave的配置,修改的代码如下:
  1. //#undef CONFIG_USE_IRQ      /* we don't need IRQ/FIQ stuff */

  2. #define CONFIG_USB_DEVICE 1
  3. #ifdef CONFIG_USB_DEVICE
  4. #define CONFIG_USE_IRQ 1
  5. #endif

(5)修改cpu/arm920t/start.S文件,修改的代码如下:
  1. #ifdef CONFIG_USE_IRQ

  2.     .align    5
  3. irq:

  4. #if 0 
  5.     get_irq_stack
  6.     irq_save_user_regs
  7.     bl    do_irq
  8.     irq_restore_user_regs
  9. #endif

  10.     /* use IRQ for USB and DMA */
  11.     sub lr, lr, #4 @ the return address
  12.     ldr sp, IRQ_STACK_START @ the stack for irq
  13.     stmdb { r0-r12,lr } @ save registers
  14.         
  15.     ldr lr, =int_return @ set the return addr
  16.     ldr pc, =IRQ_Handle @ call the isr
  17. int_return:
  18.     ldmia { r0-r12,pc }^ @ return from interrupt

(6)修改lib_arm/board.c文件,增加usb slave初始化函数,修改的代码如下:
  1. #ifndef CONFIG_IDENT_STRING
  2. #define CONFIG_IDENT_STRING ""
  3. #endif

  4. #ifdef CONFIG_USB_DEVICE
  5. extern void usb_init_slave(void);
  6. #endif


在start_armboot函数中做如下修改:
  /* enable exceptions */
enable_interrupts ();

 #ifdef CONFIG_USB_DEVICE
usb_init_slave();
 #endif

(7)在common目录中增加usbslave命令,把cmd_usbslave.c文件放在common目录下,该文件的代码如下:
  1. #include
  2. #include
  3. #include

  4. #ifdef CONFIG_USB_DEVICE

  5. #ifdef CONFIG_USE_IRQ
  6.     #define IRQ_STACK_START (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4)
  7.     #define FIQ_STACK_START (IRQ_STACK_START - CONFIG_STACKSIZE_IRQ)
  8.     #define FREE_RAM_END (FIQ_STACK_START - CONFIG_STACKSIZE_FIQ - CONFIG_STACKSIZE)
  9.     #define FREE_RAM_SIZE (FREE_RAM_END - PHYS_SDRAM_1)
  10. #else
  11.     #define FREE_RAM_END (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4 - CONFIG_STACKSIZE)
  12.     #define FREE_RAM_SIZE (FREE_RAM_END - PHYS_SDRAM_1)
  13. #endif



  14. int g_bUSBWait = 1;
  15. u32 g_dwDownloadLen = 0;

  16. extern int download_run;
  17. extern volatile unsigned int dwUSBBufBase;
  18. extern volatile unsigned int dwUSBBufSize;

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

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

  25.     download_run = 1;
  26.     switch (argc) {
  27.         case 1:
  28.         {
  29.             break;
  30.         }
  31.         case 2:
  32.         {
  33.             g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
  34.             break;
  35.         }

  36.         case 3:
  37.         {
  38.             g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
  39.             load_addr = simple_strtoul(argv[2], NULL, 16);
  40.             download_run = 0;
  41.             break;
  42.         }
  43.         
  44.         default:
  45.         {
  46.             printf ("Usage:\n%s\n", cmdtp->usage);
  47.             return 1;
  48.         }
  49.     }

  50.     dwUSBBufBase = load_addr;
  51.     dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));
  52.     if (g_bUSBWait)
  53.         len = FREE_RAM_SIZE;

  54.     g_dwDownloadLen = usb_receive(dwUSBBufBase, len, g_bUSBWait);
  55.     sprintf(buf, "%X", g_dwDownloadLen);
  56.     setenv("filesize", buf);
  57.     
  58.     return 0;
  59. }

  60. U_BOOT_CMD(
  61.     usbslave, 3, 0, do_usbslave,
  62.     "usbslave - get file from host(PC)\n",
  63.     "[wait] [loadAddress]\n"
  64.     "\"wait\" is 0 or 1, 0 means for return immediately, not waits for the finish of transferring\n"
  65. );

  66. #endif

   修改common目录下的Makefile文件,加入cmd_usbslave.c的编译选项,修改的代码如下:
  1. COBJS-$(CONFIG_UPDATE_TFTP) += update.o
  2. COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
  3. COBJS-$(CONFIG_USB_DEVICE) += cmd_usbslave.o 

(8)初始化USB中断管脚
    
     我使用的开发板上 USB DEVICE中断管脚接的是S3C2440处理器的GPG12,应该把这个管脚设置为输出,初始化电平为0,在初始化usb slave时,再把它拉高。

     修改smdk2440.c中的board_init函数,修改的代码如下:
  1.     gpio->GPFCON = 0x000055AA;
  2.     gpio->GPFUP = 0x000000FF;
  3.     gpio->GPGCON = 0xFD95FFBA;      
  4.     gpio->GPGUP = 0x0000FFFF;
  5.     gpio->GPGDAT &= ~(1<<12); 
  6.     gpio->GPHCON = 0x002AFAAA;
  7.     gpio->GPHUP = 0x000007FF;

    在drivers/usb/slave/目录下的usbinit.c文件中的usb_init_slave函数中,会将GPG12管脚拉高。

(9)修改cpu/arm920t/s3c24x0/目录下的interrupts.c文件,修改的代码如下:
  1. #include

  2. #include
  3. #include
  4. #include  

  5. void do_irq (struct pt_regs *pt_regs)
  6. {
  7.     struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt();
  8.     u_int32_t intpnd = readl(&irq->INTPND);

  9. }

  10. int arch_interrupt_init (void)
  11. {
  12.     return 0;
  13. }

   重新编译u-boot,下载到NandFlash中,会在启动信息中看到USB slave is enable!,效果如下:

   现在就可以在u-boot中使用usbslave命令进行下载了, 例如命令 usbslave 0x30008000,后面的地址可以省略,使用DNW默认设置的地址。

   如果usb成功连接,则会提示:
 
   此时用DNW软件选择要下载的文件,然后就可以对下载的内容进行操作了。


   如果usb连接失败,则会提示:

阅读(1239) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~