您的位置:首页 > 其它

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

2011-12-02 16:00 489 查看
转自:http://www.linuxidc.com/Linux/2011-05/35982p8.htm

移植环境

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 <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,定位到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 ...\n\n");

#ifdef CONFIG_USB_DEVICE

{

extern void udc_disconnect (void);

//udc_disconnect ();

}

#endif

否则编译报错。

【11】解决编译告警问题:

(1)warning: suggest parentheses around arithmetic in operand of '|'

打开/drivers/usb/slave/usbsetup.c,定位到47行附近,需分别在下面表达式中加上括号,修改如下:

// ===================================================================

// All following commands will operate only in case

// - ep0_csr is valid.

// ===================================================================

//warning: suggest parentheses around arithmetic in operand of '|'

#define CLR_EP0_OUT_PKT_RDY() usbdevregs->EP0_CSR_IN_CSR1_REG=((
ep0_csr & (~EP0_WR_BITS
) ) | \

EP0_SERVICED_OUT_PKT_RDY )

#define CLR_EP0_OUTPKTRDY_DATAEND() usbdevregs->EP0_CSR_IN_CSR1_REG=( ( ep0_csr & (~EP0_WR_BITS)
) | \

(EP0_SERVICED_OUT_PKT_RDY|EP0_DATA_END) )

#define SET_EP0_IN_PKT_RDY() usbdevregs->EP0_CSR_IN_CSR1_REG=( ( ep0_csr & (~EP0_WR_BITS) ) | \

(EP0_IN_PKT_READY) )

#define SET_EP0_INPKTRDY_DATAEND() usbdevregs->EP0_CSR_IN_CSR1_REG=( (
ep0_csr & (~EP0_WR_BITS ) ) | \

(EP0_IN_PKT_READY|EP0_DATA_END) )

#define CLR_EP0_SETUP_END() usbdevregs->EP0_CSR_IN_CSR1_REG=( (
ep0_csr & (~EP0_WR_BITS ) ) | \

(EP0_SERVICED_SETUP_END) )

#define CLR_EP0_SENT_STALL() usbdevregs->EP0_CSR_IN_CSR1_REG=( ep0_csr & (~EP0_WR_BITS)& \

(~EP0_SENT_STALL) )

#define FLUSH_EP0_FIFO() {while(usbdevregs->OUT_FIFO_CNT1_REG)usbdevregs->fifo[0].EP_FIFO_REG;}

打开/drivers/usb/slave/usbin.c,定位到35行附近,修改如下:

// ===================================================================

// All following commands will operate in case

// - in_csr1 is valid.

// ===================================================================

#define SET_EP1_IN_PKT_READY() usbdevregs->EP0_CSR_IN_CSR1_REG= ( (
in_csr1 &(~ EPI_WR_BITS ) )
\

| EPI_IN_PKT_READY )

#define SET_EP1_SEND_STALL() usbdevregs->EP0_CSR_IN_CSR1_REG= ( (
in_csr1 & (~EPI_WR_BITS ) )
\

| EPI_SEND_STALL) )

#define CLR_EP1_SENT_STALL() usbdevregs->EP0_CSR_IN_CSR1_REG= (in_csr1 & (~EPI_WR_BITS ) \

&(~EPI_SENT_STALL) )

#define FLUSH_EP1_FIFO() usbdevregs->EP0_CSR_IN_CSR1_REG= ( (
in_csr1 & (~EPI_WR_BITS ) )
\

| EPI_FIFO_FLUSH)

打开/drivers/usb/slave/usbinit.c,定位到482行附近,修改如下:

void Clk0_Enable(int clock_sel)

{ // 0:MPLLin, 1:UPLL, 2:FCLK, 3:HCLK, 4:PCLK, 5:DCLK0

gpioregs->MISCCR = ( gpioregs->MISCCR&~(7<<4)
) | (clock_sel<<4);

gpioregs->GPHCON = ( gpioregs->GPHCON&~(3<<18)
) | (2<<18);

}

void Clk1_Enable(int clock_sel)

{ // 0:MPLLout, 1:UPLL, 2:RTC, 3:HCLK, 4:PCLK, 5:DCLK1

gpioregs->MISCCR = ( gpioregs->MISCCR&~(7<<8)
) | (clock_sel<<8);

gpioregs->GPHCON = ( gpioregs->GPHCON&~(3<<20)
) | (2<<20);

}

(2) warning: function declaration isn't a prototype ...

打开/drivers/usb/slave/interrupt.c,定位到113行附近,修改如下:

void IRQ_Handle(void)

(3) warning: implicit declaration of function 'ClearPending_my'

打开/drivers/usb/slave/usbmain.c,定位到27行,加入其引用声明:

extern S3C24X0_USB_DEVICE * usbdevregs;

extern S3C24X0_DMAS * dmaregs;

extern void ClearPending_my(int bit);


打开/drivers/usb/slave/usbout.c,定位到38行,加入其引用声明:

extern S3C24X0_INTERRUPT * intregs;

extern S3C24X0_USB_DEVICE * usbdevregs;

extern S3C24X0_DMAS * dmaregs;

extern void ClearPending_my(int bit);


(4)warning: passing argument 1 of 'usb_receive' makes pointer from integer without a cast

打开/common/cmd_usbslavet.c,分别定位到71行附近,修改如下:

dwUSBBufBase = load_addr;

dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));

if (g_bUSBWait)

len = FREE_RAM_SIZE;

g_dwDownloadLen = usb_receive( (char*)
dwUSBBufBase, len, g_bUSBWait);

sprintf(buf, "%X", g_dwDownloadLen);

setenv("filesize", buf);

(5)warning:'PrintEpoPkt' defined but not used

打开/drivers/usb/slave/usbout.c,定位到27行,

#if 0

void PrintEpoPkt(U8 *pt,int cnt)

{

int i;

DbgPrintf("[BOUT:%d:",cnt);

for(i=0;i<cnt;i++)

DbgPrintf("%x,",pt[i]);

DbgPrintf("]");

}

#endif

定位到40行附近,将其声明注释掉:

//static void PrintEpoPkt(U8 *pt,int cnt);

static void RdPktEp3_CheckSum(U8 *buf,int num);

warning: 'tempBuf' defined but not used

定位到69行,将其注释掉:

U8 ep3Buf[EP3_PKT_SIZE];

//static U8 tempBuf[64+1];

打开/cpu/arm920t/s3c24x0/interrupts.c,定位到45行附近,修改如下:

void do_irq (struct pt_regs *pt_regs)

{

S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();

u_int32_t intpnd = irq->INTPND;

intpnd = intpnd;

}

其它warning: unused variable... ...处理方法相同,这里就不再列出。

8.2,usb slave 下载功能编译测试

[root@localhost u-boot-2009.08]# make distclean

[root@localhost u-boot-2009.08]# make

编译完成后得到u-boot.bin,将开发板断电,拨到nor档上电用 supervivi的a命令下载后在拨到nand档启动:

... ...

source - run script from memory

tftpboot- boot image via network using TFTP protocol

unzip - unzip a memory region

usbslave- usbslave - get file from host(PC)

version - print monitor version

[u-boot@MINI2440]# usbslave

USB host is connected. Waiting a download.

Now, Downloading [ADDRESS:31000000h,TOTAL:2022422]

[u-boot@MINI2440]# bootm 31000000

## Booting kernel from Legacy Image at 31000000 ...

Image Name: mini2440_linux

Created: 2011-05-12 3:37:00 UTC

Image Type: ARM Linux Kernel Image (uncompressed)

Data Size: 2022348 Bytes = 1.9 MB

Load Address: 30008000

Entry Point: 30008040

Verifying Checksum ... OK

Loading Kernel Image ... OK

OK

Starting kernel ...

可以看内核在启动。

8.3 开启usb host功能

【1】打开/include/configs/mini2440.h,定位到112行附近:加入下面代码:

/*

* Command line configuration.

*/

#include <config_cmd_default.h>

#define CONFIG_CMD_ASKENV

#define CONFIG_CMD_CACHE

#define CONFIG_CMD_DATE

#define CONFIG_CMD_ELF

#define CONFIG_CMD_NAND

#define CONFIG_CMD_JFFS2 /* JFFS2 Support*/

#define CONFIG_CMD_PING /*ping command support*/

#define CONFIG_CMD_USB

#define CONFIG_CMD_FAT


#define CONFIG_BOOTDELAY 3

其中相关宏定义的作用:

CONFIG_CMD_USB :使能USB相关命令的支持

CONFIG_CMD_FAT :使能FAT文件系统相关命令的支持

定位到194行附近加入下面代码:

/*

USB device support

*/

#define CONFIG_USB_DEVICE 1

#ifdef CONFIG_USB_DEVICE

#define CONFIG_USE_IRQ 1

#endif

#if 1

#define CONFIG_USB_OHCI

#define CONFIG_USB_STORAGE

#define CONFIG_DOS_PARTITION

#define CONFIG_SYS_DEVICE_DEREGISTER

#define CONFIG_SUPPORT_VFAT

#define LITTLEENDIAN

//#define CONFIG_USB_TTY

//#define CONFIG_USB_KEYBOARD

#endif


相关宏定义的作用:

CONFIG_USB_OHCI :使能USB_OHCI协议的支持

CONFIG_USB_STORAGE:使能USB存储设备的支持

CONFIG_DOS_PARTITION : 使能FAT文件系统分区的支持

CONFIG_SUPPORT_VFAT : 使能FAT32文件系统的支持

LITTLEENDIAN : 定义数据为小端模式

CONFIG_USB_TTY:使能USB终端(本次未使用)

CONFIG_USB_KEYBOARD是对USB键盘的支持(本次未使用)

【2】打开/cpu/arm920t/s3c24x0/usb_ohci.c,定位到43行附近,加入下面代码:

#ifdef CONFIG_USB_OHCI

#if defined(CONFIG_S3C2400)

#include <s3c2400.h>

#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

#include <s3c2410.h>

#endif

8.4 usb host 功能编译测试:

【1】先看下USB 操作指令

指令 功能

usb reset 初始化USB 控制器

usb stop [f] 关闭USB 控制器

usb tree 已连接的USB 设备树

usb info [dev] 显示USB 设备[dev]的信息

usb storage 显示已连接的USB 存储设备

usb dev [dev] 显示和设置当前USB 存储设备

usb part [dev] 显示USB 存储设备[dev]的分区信息

usb read addr blk# cnt 读取USB 存储设备数据

【2】准备一个fat32格式的U盘

【3】在编译完成后,nor 档下载nand 档启动,操作如下:

[u-boot@MINI2440]# usb help

USB is stopped. Please issue 'usb start' first.

[u-boot@MINI2440]# usb start

(Re)start USB...

USB: scanning bus for devices... cannot reset port 2!?

2 USB Device(s) found

scanning bus for storage devices... 1 Storage Device(s) found

[u-boot@MINI2440]# usb storage

Device 0: Vendor: USB 2.0 Rev: 5.00 Prod: Flash Drive

Type: Removable Hard Disk

Capacity: 1012.5 MB = 0.9 GB (2073600 x 512)

[u-boot@MINI2440]# usb part 0

print_part of 0

Partition Map for USB device 0 -- Partition Type: DOS

Partition Start Sector Num Sectors Type

1 32 2073568 b

[u-boot@MINI2440]# fatload usb 0:1 0x30008000 uImage_T35

reading uImage_T35

................................................................................

................................................................................

.....................................

2022412 bytes read

[u-boot@MINI2440]# bootm 0x30008000

## Booting kernel from Legacy Image at 30008000 ...

Image Name: mini2440_linux

Created: 2011-05-12 3:37:00 UTC

Image Type: ARM Linux Kernel Image (uncompressed)

可以看到内核开始启动了。

接下来将为u-boot-2009..08增加SD 功能和I2C功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: