10、u-boot增加USB下载功能
u-boot默认是不支持USB下载功能的,需要自己添加。在这里我们增加usb slave驱动,该驱动用于开发板连接PC机用USB接口下载程序。移植的usb slave驱动的步骤如下:
(1)在drivers/usb/目录下增加一个slave目录,加入以下文件
(2)修改u-boot根目录下的Makefile文件,修改的代码如下:
- LIBS += drivers/usb/musb/libusb_musb.a
- LIBS += drivers/usb/phy/libusb_phy.a
- LIBS += drivers/usb/slave/libusb_slave.a
- LIBS += drivers/video/libvideo.a
(3)修改include/asm-arm/arch-s3c24x0/s3c24x0.h文件,修改的代码如下:
- struct s3c24x0_usb_device {
- #ifdef __BIG_ENDIAN
- u8 res1[3];
- u8 FUNC_ADDR_REG;
- u8 res2[3];
- u8 PWR_REG;
- u8 res3[3];
- u8 EP_INT_REG;
- u8 res4[15];
- u8 USB_INT_REG;
- u8 res5[3];
- u8 EP_INT_EN_REG;
- u8 res6[15];
- u8 USB_INT_EN_REG;
- u8 res7[3];
- u8 FRAME_NUM1_REG;
- u8 res8[3];
- u8 FRAME_NUM2_REG;
- u8 res9[3];
- u8 INDEX_REG;
- u8 res10[7];
- u8 MAXP_REG;
- u8 res11[3];
- u8 EP0_CSR_IN_CSR1_REG;
- u8 res12[3];
- u8 IN_CSR2_REG;
- u8 res13[7];
- u8 OUT_CSR1_REG;
- u8 res14[3];
- u8 OUT_CSR2_REG;
- u8 res15[3];
- u8 OUT_FIFO_CNT1_REG;
- u8 res16[3];
- u8 OUT_FIFO_CNT2_REG;
- #else /* little endian */
- u8 FUNC_ADDR_REG;
- u8 res1[3];
- u8 PWR_REG;
- u8 res2[3];
- u8 EP_INT_REG;
- u8 res3[15];
- u8 USB_INT_REG;
- u8 res4[3];
- u8 EP_INT_EN_REG;
- u8 res5[15];
- u8 USB_INT_EN_REG;
- u8 res6[3];
- u8 FRAME_NUM1_REG;
- u8 res7[3];
- u8 FRAME_NUM2_REG;
- u8 res8[3];
- u8 INDEX_REG;
- u8 res9[7];
- u8 MAXP_REG;
- u8 res10[3]; /* zjw modify from 7 to 3 */
- u8 EP0_CSR_IN_CSR1_REG;
- u8 res11[3];
- u8 IN_CSR2_REG;
- u8 res12[7]; /* zjw modify from 3 to 7 */
- u8 OUT_CSR1_REG;
- u8 res13[3]; /* zjw modify from 7 to 3 */
- u8 OUT_CSR2_REG;
- u8 res14[3];
- u8 OUT_FIFO_CNT1_REG;
- u8 res15[3];
- u8 OUT_FIFO_CNT2_REG;
- u8 res16[3];
- #endif /* __BIG_ENDIAN */
- #if 0
- struct s3c24x0_usb_dev_fifos fifo[5];
- struct s3c24x0_usb_dev_dmas dma[5];
- #endif
- u32 res17[8];
- struct s3c24x0_usb_dev_fifos fifo[5];
- u32 res18[11];
- struct s3c24x0_usb_dev_dmas ep1;
- struct s3c24x0_usb_dev_dmas ep2;
- u8 res19[16];
- struct s3c24x0_usb_dev_dmas ep3;
- struct s3c24x0_usb_dev_dmas ep4;
- };
(4)修改smdk2440.h,增加usb slave的配置,修改的代码如下:
- //#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
- #define CONFIG_USB_DEVICE 1
- #ifdef CONFIG_USB_DEVICE
- #define CONFIG_USE_IRQ 1
- #endif
(5)修改cpu/arm920t/start.S文件,修改的代码如下:
- #ifdef CONFIG_USE_IRQ
- .align 5
- irq:
- #if 0
- get_irq_stack
- irq_save_user_regs
- bl do_irq
- irq_restore_user_regs
- #endif
- /* use IRQ for USB and DMA */
- sub lr, lr, #4 @ the return address
- ldr sp, IRQ_STACK_START @ the stack for irq
- stmdb { r0-r12,lr } @ save registers
-
- ldr lr, =int_return @ set the return addr
- ldr pc, =IRQ_Handle @ call the isr
- int_return:
- ldmia { r0-r12,pc }^ @ return from interrupt
(6)修改lib_arm/board.c文件,增加usb slave初始化函数,修改的代码如下:
- #ifndef CONFIG_IDENT_STRING
- #define CONFIG_IDENT_STRING ""
- #endif
- #ifdef CONFIG_USB_DEVICE
- extern void usb_init_slave(void);
- #endif
在start_armboot函数中做如下修改:
/* enable exceptions */
enable_interrupts ();
#ifdef CONFIG_USB_DEVICE
usb_init_slave();
#endif
(7)在common目录中增加usbslave命令,把cmd_usbslave.c文件放在common目录下,该文件的代码如下:
- #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;
- 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%s\n", 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 transferring\n"
- );
- #endif
修改common目录下的Makefile文件,加入cmd_usbslave.c的编译选项,修改的代码如下:
- COBJS-$(CONFIG_UPDATE_TFTP) += update.o
- COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
- COBJS-$(CONFIG_USB_DEVICE) += cmd_usbslave.o
(8)初始化USB中断管脚
我使用的开发板上 USB DEVICE中断管脚接的是S3C2440处理器的GPG12,应该把这个管脚设置为输出,初始化电平为0,在初始化usb slave时,再把它拉高。
修改smdk2440.c中的board_init函数,修改的代码如下:
- gpio->GPFCON = 0x000055AA;
- gpio->GPFUP = 0x000000FF;
- gpio->GPGCON = 0xFD95FFBA;
- gpio->GPGUP = 0x0000FFFF;
- gpio->GPGDAT &= ~(1<<12);
- gpio->GPHCON = 0x002AFAAA;
- gpio->GPHUP = 0x000007FF;
在drivers/usb/slave/目录下的usbinit.c文件中的usb_init_slave函数中,会将GPG12管脚拉高。
(9)修改cpu/arm920t/s3c24x0/目录下的interrupts.c文件,修改的代码如下:
- #include
- #include
- #include
- #include
- void do_irq (struct pt_regs *pt_regs)
- {
- struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt();
- u_int32_t intpnd = readl(&irq->INTPND);
- }
- int arch_interrupt_init (void)
- {
- return 0;
- }
重新编译u-boot,下载到NandFlash中,会在启动信息中看到USB slave is enable!,效果如下:
现在就可以在u-boot中使用usbslave命令进行下载了, 例如命令 usbslave 0x30008000,后面的地址可以省略,使用DNW默认设置的地址。
如果usb成功连接,则会提示:
此时用DNW软件选择要下载的文件,然后就可以对下载的内容进行操作了。
如果usb连接失败,则会提示:
阅读(1239) | 评论(0) | 转发(0) |