您的位置:首页 > 其它

mini2440 u-boot实现usb slave下载功能!

2012-04-13 22:28 323 查看
原文地址: http://www.arm9home.net/read.php?tid-4902.html

友善公司不知为何,一直没有发布一个好用的u-boot。之前已移植过2008.10版的u-boot,最近,又移植了2009.08的u-boot。

移植完毕后,总觉得友善自带的dnw下的usb下载功能真的很好用,于是,决定在u-boot中,也加上此功能。搜索网络后,发现,已

有人,即百问网的老大,在u-boot1.1.6上实现了此功能,并发布了源代码,于是,接下来的工作,就是把这些代码移植到u-boot

2009.08上来。为此,利用春节休假,仔细研究了u-boot关于USB方面的代码,原来,u-boot已实现usb host功能,而usb 下载所需

的usb device功能未实现(源码中,已有部分代码,不过未完成)。对照百问网的源代码,经过一番曲折,总算完成了移植。

记录一下过程。

首先,把百问网原先的usb相关代码整理一下,把原先零散的代码归总到一个目录下。

然后,修改u-boot 2009.08的代码,修改如下。

//以下修改,是参考http://blog.chinaunix.net/u3/105764/showart_2144192.html的,其中有些错误,做了修改。

1、复制usb slave驱动源代码

创建drivers/usb/slave 目录,复制usb slave驱动源代码到此目录(详见附件)

2、修改uboot根目录下的Makefeils,添加红色部分代码

LIBS += drivers/usb/musb/libusb_musb.a

# Apollo +

LIBS += drivers/usb/slave/libusb_slave.a

# Apollo -

LIBS += drivers/video/libvideo.a

3、修改lib_arm/board.c文件,添加红色部分代码

//Apollo +

Port_Init();

/* enable exceptions */

enable_interrupts ();

usb_init(); //这里原文是错的,应为usb_init_slave();

//Apollo -

4、修改平台头文件,include/configs/utu2440.h,添加红色部分,此文件根据你自已移植的u-boot,名字可能不一样。

#define CONFIG_USB_DEVICE 1

#ifdef CONFIG_USB_DEVICE

#define CONFIG_USE_IRQ 1

#endif

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

5、修改cpu/arm920t/s3c24x0/interrupts.c 文件,添加arch_interrupt_init函数定义

//Apollo +

int arch_interrupt_init (void)

{

return 0;

}

//Apollo -

6、修改cpu/arm920t/start.S,文件

#ifdef CONFIG_USE_IRQ

.align 5

irq:

//Apollo +,此处开始修改

/*

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

sb { r0-r12,lr } @ save registers //这里原文错误,应为sb sp!, { r0-r12,lr }

ldr lr, =int_return @ set the return addr

ldr pc, =IRQ_Handle @ call the isr

int_return:

ldmia { r0-r12,pc }^ @ return from interrupt //这里原文错误,应为ldmia sp,{ r0-r12,pc }^

//Apollo -,修改结束

7、修改include/s3c24x0.h,文件

//Apollo +

S3C24X0_REG8 MAXP_REG;

// S3C24X0_REG8 res10[7];

S3C24X0_REG8 res10[3];

S3C24X0_REG8 EP0_CSR_IN_CSR1_REG;

S3C24X0_REG8 res11[3];

S3C24X0_REG8 IN_CSR2_REG;

// S3C24X0_REG8 res12[3];

S3C24X0_REG8 res12[7];

S3C24X0_REG8 OUT_CSR1_REG;

// S3C24X0_REG8 res13[7];

S3C24X0_REG8 res13[3];

//Apollo -

8、添加usbslave命令

在common目录下创建cmd_usbslave.c

#include <common.h>

#include <command.h>

#include <asm/byteorder.h>

#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%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

COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o

# Apollo +

COBJS-$(CONFIG_USB_DEVICE) += cmd_usbslave.o

# Apollo -

补充几个修改,在原文中的usbmain.c,要把include <s3c24x0.h>注释掉,否则编译报错。

在lib_arm/bootm.c中,udc_disconnect ();此句也要注释掉,否则编译报错。在百问网的uboot中,此句也是注释掉的,估计原文

作者漏写了。

编译成功,将u-boot.bin烧入mini2440的nand flash中,进行测试。

将mini2440的usb device口与pc的usb口连接

在u-boot的命令行中输入 usbslave 1 0x31000000,回车,这时,就可以在dnw中发送数据了,这里,发送uImage,发送完成后,在u-boot命令行中输入bootm 0x31000000,内核正确引导,证明移植成功。

另,百问网的u-boot仿照友善的mini vivi作了一个菜单命令选择,我没有加入。如有需要,可以参照百问网的代码加入。这个比较

容易,不多说了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: