u-boot-2014.10移植第3天----LED裸机程序
来源:互联网 发布:微博橱窗导入淘宝商品 编辑:程序博客网 时间:2024/04/27 04:34
硬件平台:tq2440
开发环境:Ubuntu-3.11
u-boot版本:2014.10
本文允许转载,请注明出处:http://blog.csdn.net/fulinus
在移植u-boot之前我们先熟悉一下硬件,以及如何控制硬件:
情况一:
这个情况是你的开发板中有了可以运行的u-boot。因为裸机程序能运行的前提条件是系统初始化了。
下面led.S是一位高人写的代码,完全是用ARM汇编编写的,短小精悍,主要是实现跑马灯的功能:
/*********************************************************************** * File: led.S * Version: 1.0.0 * Copyright: 2011 (c) Guo Wenxue <guowenxue@gmail.com> * Description: This ASM code used to turn LED0~LED4 on/off on TQ2440 board * ChangeLog: 1, Release initial version on "Sun Mar 20 18:41:04 CST 2011" * Modify: fulinux <fulinux@sina.com> ***********************************************************************/#define GPBCON 0x56000010#define GPBDAT 0x56000014#define GPBUP 0x56000018#define OUTPUT 0x01 /*Set GPIO port as output mode*/#define INPUT 0x00 /*Set GPIO port as input mode*/#define LED0 5 /*On TQ2440 board, LED0 use GPB5*/#define LED1 6 /*On TQ2440 board, LED1 use GPB6*/#define LED2 7 /*On TQ2440 board, LED2 use GPB7*/#define LED3 8 /*On TQ2440 board, LED3 use GPB8*/#define DELAY 0X1000000 .text .align 2 .global _start_start: /*Set GPB5,GPB6,GPB7,GPB8 as GPIO OUTPUT mode*/ ldr r0, =GPBCON ldr r1, [r0] bic r1, r1, #0x3FC00 /*Set GPBCON for GPB5,GPB6,GPB7,GPB8 as 0x00 */ orr r1, r1, #0x15400 /*Set GPBCON for GPB5,GPB6,GPB7,GPB8 as GPIOOUT, 0x01*/ str r1, [r0] /*Set internal pullup resister*/ ldr r0, =GPBUP ldr r1, [r0] orr r1, r1, #0x01E0 /*Set bit 5,6,7,8, disable pullup resister*/ @bic r1, r1, #0x01E0 /*Clear bit 5,6,7,8, enable pullup resister*/ str r1, [r0] loopled: /*Turn off LED0, LED1, LED2, LED3*/ ldr r2, =GPBDAT ldr r3, [r2] orr r3, r3, #0x01E0 /*Set bit 5,6,7,8 as high level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED0*/ ldr r3, [r2] bic r3, r3, #(1<<LED0) /*Clear bit 5, set GPB5 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED1*/ ldr r3, [r2] bic r3, r3, #(1<<LED1) /*Clear bit 6, set GPB6 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED2*/ ldr r3, [r2] bic r3, r3, #(1<<LED2) /*Clear bit 7, set GPB7 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED3*/ ldr r3, [r2] bic r3, r3, #(1<<LED3) /*Clear bit 8, set GPB8 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay b loopled /*Loop running LED*/delay: sub r0, r0, #1 cmp r0, #0x0 bne delay mov pc, lr
与他配套的makefile文件如下:
# ***********************************************************************# * File: makefile# * Version: 1.0.0# * Copyright: 2011 (c) Guo Wenxue <guowenxue@gmail.com># * Description: Makefile used to cross compile the ASM and C source code# * ChangeLog: 1, Release initial version on "Mon Mar 21 21:09:52 CST 2011"# *# ***********************************************************************BINAME = ledTEXTBASE = 0x33000000CROSS = /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-CC = $(CROSS)gccLD = $(CROSS)ldAR = $(CROSS)arOBJCOPY = $(CROSS)objcopyOBJDUMP = $(CROSS)objdumpSTRIP = $(CROSS)stripREADELF = $(CROSS)readelfCFLAGS = -g -O2 -Wall -nostdinc -nostdlib -fno-builtinAFLAGS = $(CFLAGS) -D__ASSEMBLY__LDFLAGS = -Ttext $(TEXTBASE)SRC_C = $(wildcard *.c)SRC_S = $(wildcard *.S)OBJ_C = $(patsubst %.c,%.o,$(SRC_C)) OBJ_S = $(patsubst %.S,%.o,$(SRC_S)) OBJ_ALL = $(OBJ_C) $(OBJ_S) .PHONY : allall: ${OBJ_ALL} ${LD} $(LDFLAGS) -o ${BINAME}.elf ${OBJ_ALL} ${OBJCOPY} -O binary -S ${BINAME}.elf ${BINAME}.bin rm -f *.elf *.o%.o: %.S $(CC) $(AFLAGS) -c -o $@ $<%.o: %.c $(CC) $(CFLAGS) -c -o $@ $<install: cp ${BINAME}.bin ~/winxp -f --reply=yesclean: rm -f *.elf *.o rm -f ${BINAME}.bin
编译完成后得到led.bin文件,将其放在D:\kupan\temp\目录中,我们通过J-link,将该段代码写入SDRAM中,起始位置为0x33000000,通过J-link软件J-Link Commander
如图:
通过在命令行中键入如下命令:
hspeed 12000loadbin D:\kupan\temp\led.bin 0x33000000setpc 0x33000000g
这时你既可以看到4个led的跑马灯现象了!
讲下makefile中的几条语句:
SRC_C = $(wildcard *.c)SRC_S = $(wildcard *.S)OBJ_C = $(patsubst %.c,%.o,$(SRC_C))OBJ_S = $(patsubst %.S,%.o,$(SRC_S))OBJ_ALL = $(OBJ_C) $(OBJ_S)
因为当前目录中没有c文件,而只有一个led.S文件,经过上面几条语句就可以得到:
OBJ_ALL = led.o
情况二:
这个情况是你的开发板没有u-boot,那你就需要有一个初始化系统的程序。
下面这个初始化程序可以说如同u-boot中start.S文件的功能。
bootstrap.S:
/******************************************************************************************** * File: bootstrap.S * Version: 1.0.0 * Copyright: 2011 (c) Guo Wenxue <Email: guowenxue@gmail.com QQ:281143292> * Description: If we wanna debug u-boot by J-Link in external SDRAM, we must download this * bootstrap.bin file into s3c24x0 8K internal SRAM(Stepping Stone) and excute * first, which used to initialize the CPU and external SDRAM. Only after init * the SDRAM then we can debug u-boot in it. * ChangeLog: 1, Release initial version on "Tue Jul 12 16:43:18 CST 2011" * *******************************************************************************************/#include "bootstrap.h" .text .align 2 .global _start_start: /* set the cpu to SVC32 mode */ mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0xd3 msr cpsr, r0 /* Disable watchdog */ ldr r0, =S3C_WATCHDOG_BASE mov r1, #0 str r1, [r0] /* Disable Interrupt */ ldr r0, =S3C_INTERRUPT_BASE mov r1, #0xffffffff str r1, [r0, #INTMSK_OFFSET] ldr r1, =0x000007ff str r1, [r0, #INTSUBMSK_OFFSET] /* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0290g/Babjcgjg.html */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache, Invalidate ICache and DCache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ /* disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 /******************************************************************************************* * Init system clock and power, FCLK:HCLK:PCLK = 1:4:8 * Reference to S3C2440 datasheet: Chap 7 Clock&Power Management * * Initialize System Clock FCLK=400MHz HCLK=100MHz PCLK=50MHz * FCLK is used by ARM920T * HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, * the interrupt controller, the LCD controller, the DMA and USB host block. * PCLK is is used for APB bus,which is used by the peripherals such as WDT,IIS,I2C, * PWM timer,MMC interface,ADC,UART,GPIO,RTC and SPI. ******************************************************************************************/ /*Set LOCKTIME as default value 0x00ffffff*/ ldr r0, =S3C_CLOCK_POWER_BASE ldr r1, =0x00ffffff str r1, [r0, #LOCKTIME_OFFSET] /******************************************************************************************* * Reference to S3C2440 datasheet: Chap 7-8 ~ Page 242 * * Set the selection of Dividing Ratio between FCLK,HCLK and PCLK as FCLK:HCLK:PCLK = 1:4:8. * This ratio is determined by HDIVN(here is 2) and PDIVN(here is 1) control register. * Refer to the s3c2440 datasheet *******************************************************************************************/ ldr r0, =S3C_CLOCK_POWER_BASE mov r1, #5 str r1, [r0, #CLKDIVN_OFFSET] /*Set Clock Divider*/ mrc p15, 0, r1, c1, c0, 0 orr r1, r1, #0xc0000000 mcr p15, 0, r1, c1, c0, 0 /*************************************************************************************** * Reference to S3C2440 datasheet: Chap 7-20 ~ Page 254 * * Set MPLLCON(0x4C000004) register as: * [19:12]: MDIV(Main Divider control)=0x7F (value set in MDIV_405) * [9:4]: PDIV(Pre-devider control)=0x02 (value set in PSDIV_405) * [1:0]: SDIV(Post divider control)=0x01 (value set in PSDIV_405) * * MPLL(FCLK) = (2 * m * Fin)/(p * 2^s) * m=(MDIV+8), p=(PDIV+2), s=SDIV * * So FCLK=((2*(127+8)*Fin)) / ((2+2)*2^1) * = (2*135*12MHz)/8 * = 405MHz * For FCLK:HCLK:PCLK=1:4:8, so HCLK=100MHz, PCLK=50MHz ***************************************************************************************/ mov r1, #S3C_CLOCK_POWER_BASE mov r2, #MDIV_405 add r2, r2, #PSDIV_405 str r2, [r1, #MPLLCON_OFFSET]mem_init: /* memory control configuration */ /* make r0 relative the current location so that it */ /* reads SMRDATA out of FLASH rather than memory ! */ ldr r0, =SMRDATA ldr r1, =mem_init sub r0, r0, r1 adr r3, mem_init /* r3 <- current position of code */ add r0, r0, r3 /*r0 =SMRDATA-mem_init+mem_init =SMRDATA*/ ldr r1, =BWSCON /* Bus Width Status Controller */ add r2, r0, #13*40: ldr r3, [r0], #4 str r3, [r1], #4 cmp r2, r0 bne 0b /*Set GPIO5 OUTPUT mode*/ ldr r0, =GPBCON ldr r1, [r0] bic r1, r1, #0xC00 /*Set GPBCON for GPIO5 as 0x00 */ orr r1, r1, #0x0400 /*Set GPBCON for GPIO5 as GPIOOUT, 0x01*/ str r1, [r0] ldr r3, [r2] bic r3, r3, #(1<<LED0) /*Clear bit 5, set GPB5 as low level*/ str r3, [r2] /* everything is fine now */dead_loop: b dead_loop .ltorg/* the literal pools origin */SMRDATA: .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) .word 0xb2 .word 0x30 .word 0x30
bootstrap.h:
[fulinux@ubuntu bootstrap]$ cat bootstrap.h/* * ===================================================================================== * * Filename: bootstrap.h * Version: 1.0.0 * Author: Guo Wenxue<Email: guowenxue@ghlsystems.com QQ:281143292> * CopyRight: 2011 (C) Guo Wenxue * Description: Some Reigster address definition for bootstrap.S * ===================================================================================== */#define S3C_WATCHDOG_BASE 0x53000000#define S3C_INTERRUPT_BASE 0x4a000000#define SRCPND_OFFSET 0x00#define INTMOD_OFFSET 0x04#define INTMSK_OFFSET 0x08#define PRIORITY_OFFSET 0x0c#define INTPND_OFFSET 0x10#define INTOFFSET_OFFSET 0x14#define SUBSRCPND_OFFSET 0x18#define INTSUBMSK_OFFSET 0x1c#define S3C_CLOCK_POWER_BASE 0x4c000000#define LOCKTIME_OFFSET 0x00#define MPLLCON_OFFSET 0x04#define UPLLCON_OFFSET 0x08#define CLKCON_OFFSET 0x0c#define CLKSLOW_OFFSET 0x10#define CLKDIVN_OFFSET 0x14#define CAMDIVN_OFFSET 0x18#define BWSCON 0x48000000#define MDIV_405 0x7f << 12#define PSDIV_405 0x21#define GPBCON 0x56000010#define GPBDAT 0x56000014#define GPBUP 0x56000018#define OUTPUT 0x01 /* Set GPIO port as output mode*/#define INPUT 0x00 /* Set GPIO port as input mode*/#define BEEP 0 /* On FL2440 board, LED0 use GPB0*/#define LED0 5 /* On FL2440 board, LED0 use GPB5*/#define LED1 6 /* On FL2440 board, LED0 use GPB6*/#define LED2 8 /* On FL2440 board, LED0 use GPB8*/#define LED3 10 /* On FL2440 board, LED0 use GPB10*//* BWSCON */#define DW8 (0x0)#define DW16 (0x1)#define DW32 (0x2)#define WAIT (0x1<<2)#define UBLB (0x1<<3)#define B1_BWSCON (DW16)#define B2_BWSCON (DW16)#define B3_BWSCON (DW16 + WAIT + UBLB)#define B4_BWSCON (DW16)#define B5_BWSCON (DW16)#define B6_BWSCON (DW32)#define B7_BWSCON (DW32)#define B0_Tacs 0x0#define B0_Tcos 0x0#define B0_Tacc 0x7#define B0_Tcoh 0x0#define B0_Tah 0x0#define B0_Tacp 0x0#define B0_PMC 0x0#define B1_Tacs 0x0#define B1_Tcos 0x0#define B1_Tacc 0x7#define B1_Tcoh 0x0#define B1_Tah 0x0#define B1_Tacp 0x0#define B1_PMC 0x0 #define B2_Tacs 0x0#define B2_Tcos 0x0#define B2_Tacc 0x7#define B2_Tcoh 0x0#define B2_Tah 0x0#define B2_Tacp 0x0#define B2_PMC 0x0#define B3_Tacs 0xc#define B3_Tcos 0x7#define B3_Tacc 0xf#define B3_Tcoh 0x1#define B3_Tah 0x0#define B3_Tacp 0x0#define B3_PMC 0x0#define B4_Tacs 0x0#define B4_Tcos 0x0#define B4_Tacc 0x7#define B4_Tcoh 0x0#define B4_Tah 0x0#define B4_Tacp 0x0#define B4_PMC 0x0#define B5_Tacs 0xc#define B5_Tcos 0x7#define B5_Tacc 0xf#define B5_Tcoh 0x1#define B5_Tah 0x0#define B5_Tacp 0x0#define B5_PMC 0x0#define B6_MT 0x3 /* SDRAM */#define B6_Trcd 0x1#define B6_SCAN 0x1 /* 9bit */#define B7_MT 0x3 /* SDRAM */#define B7_Trcd 0x1 /* 3clk */#define B7_SCAN 0x1 /* 9bit *//* REFRESH parameter */#define REFEN 0x1 /* Refresh enable */#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */#define Trc 0x3 /* 7clk */#define Tchr 0x2 /* 3clk */#if defined(CONFIG_S3C2440)#define Trp 0x2 /* 4clk */#define REFCNT 1012#else#define Trp 0x0 /* 2clk */#define REFCNT 0x0459#endif
Makefile文件:
# ***********************************************************************# * File: makefile# * Version: 1.0.0# * Copyright: 2011 (c) Guo Wenxue <guowenxue@gmail.com># * Description: Makefile used to cross compile the ASM and C source code# * ChangeLog: 1, Release initial version on "Mon Mar 21 21:09:52 CST 2011"# *# ***********************************************************************BINAME = bootstrapTEXTBASE = 0INST_PATH=${PWD}/../../../binCROSS = arm-linux-CC = $(CROSS)gccLD = $(CROSS)ldAR = $(CROSS)arOBJCOPY = $(CROSS)objcopyOBJDUMP = $(CROSS)objdumpSTRIP = $(CROSS)stripREADELF = $(CROSS)readelfCFLAGS = -g -O2 -Wall -nostdinc -nostdlib -fno-builtinAFLAGS = $(CFLAGS) -D__ASSEMBLY__LDFLAGS = -Ttext $(TEXTBASE)SRC_C = $(wildcard *.c)SRC_S = $(wildcard *.S)OBJ_C = $(patsubst %.c,%.o,$(SRC_C)) OBJ_S = $(patsubst %.S,%.o,$(SRC_S)) OBJ_ALL = $(OBJ_C) $(OBJ_S) .PHONY : all all: ${OBJ_ALL} ${LD} $(LDFLAGS) -o ${BINAME}.elf ${OBJ_ALL} ${OBJCOPY} -O binary -S ${BINAME}.elf ${BINAME}.bin rm -f *.elf *.o make install%.o: %.S $(CC) $(AFLAGS) -c -o $@ $<%.o: %.c $(CC) $(CFLAGS) -c -o $@ $<install: cp -f ${BINAME}.bin ${INST_PATH} uninstall: rm -f ${INST_PATH}/${BINAME}.bin clean: rm -f *.elf *.o rm -f ${BINAME}.bin
这里面的TAXTBASE = 0,这是为了nand和norflash通用。
如果OM[1:0]设置为00时,则是从Nandflash启动,SRAM是被映射到0地址上。所以我们需要将上面的这个初始化程序放到0地址开始的位置,也可以放在4和8地址上,这两个位置有未定义指令异常中断和软件中断,未定义异常指令容易理解,ARM的PC首值为0,在0地址处加载这个位置的值,是个随机数或是0,认为是未定义的指令码,自然会跳到未定义指令异常中断哪里执行,刚好哪里放在起始代码。但是软件中断8地址这个地方就不好理解了,难道起始0地址和4地址都是0时会继续跳到软件中断地址继续运行吗?我确定需要继续深入了解。
如果OM[1:0]设置为01,10时重Nor启动,SRAM是被映射到0x40000000位置的。这时候如果你用J-link的commander是无法将初始化程序bootstrap.bin烧录到0地址的。因为这里是Nor flash或者是没有Norflash,不管是有没有Norflash,都是无法将初始化程序放到0,4,8地址上的。
我们可以通过J-Flash ARM软件将bootstrap初始化程序烧录到Norflash起始位置上,该软件是支持直接烧录到Norflash上的,如同烧录到SDRAM中一样。
在J-link中也显示了这样状态未定义指令异常:
0 0
- u-boot-2014.10移植第3天----LED裸机程序
- u-boot-2014.10移植第5天----LED、button和beep裸机程序
- u-boot-2014.10移植第4天----裸机蜂鸣器程序
- u-boot-2014.10移植第13天----创建开发板
- u-boot-2014.10移植第15天----nor flash操作
- u-boot-2014.10移植第16天----Nor flash启动
- u-boot-2014.10移植第1天----熟悉u-boot(一)
- u-boot-2014.10移植第2天----熟悉u-boot(二)
- ok6410-第06篇-裸机led程序
- mini2440裸机程序测试第一部-LED
- u-boot-2014.10移植
- LED裸机程序(IAR)
- mini2440裸机程序LED
- OK6410裸机程序 ----led
- u-boot-2014.10移植第6天----深入分析代码(一)
- u-boot-2014.10移植第7天----深入分析代码(二)
- u-boot-2014.10移植第8天----深入分析代码(三)
- u-boot-2014.10移植第9天----深入分析代码(四)
- TCP 三次握手是一个Syn+Ack的过程
- Android 平台框架(体系结构)简介
- [LeetCode] Jump Game II
- 报错:memory violation : Exception ACCESS_VIOLATION received
- Android studio error : Failed to find target android-X
- u-boot-2014.10移植第3天----LED裸机程序
- 第九周项目2输出1/3-3/5.....19/21的结果
- ubuntu14.04 Qt5中文输入法问题
- android的休眠和唤醒流程
- windows编程学习笔记(4)GDI绘图
- poj 2353 类似数塔(需标记路径)
- 第9周项目3(3)-输出星号图
- 第9周项目6-穷举法解决组合问题之百钱百鸡问题
- 仿鲁大师界面(实现启动动画和TabHost选项卡切换时滑动动画)