RVDS的CodeWarrior配置如下:
Linker(链接)设置
RealView Linker->Output:
Linkertype选Simple;Simple image中RO Base填0x50200000、RW Base填0x50203000。
RealView Linker->Options:
Image entry point填0x50200000。
RealView Linker->Layout:
Object/Symbol填Startup.o;Section填start。
其他设置不再说明。
一、汇编代码段完成工作(主要是初始化堆栈)
RO设为0x5020 0138 //RO段,代码段结束地址(起始0x5020 0000)
R1设为0x5020 0478 //ZI段,未初始化全局变量段结束地址
R2设为0x0000 0000 //初始化全局变量
R3设为0x5020 0138 //ZI段,未初始化全局变量段起始地址
1.Startup.s
; 启动文件。初始化C程序的运行环境,然后进入C程序代码。
;导入连接器事先定义好的运行域中三个段变量
;ARM的可执行映像文件由RO、RW、ZI三个段组成
;RO为代码段,RW为已初始化的全局变量,ZI为未初始化的全局变量
preserve8
IMPORT |Image$$RO$$Limit| ; RO段结束地址
IMPORT |Image$$RW$$Base| ; RW段起始地址
IMPORT |Image$$ZI$$Base| ; ZI段起始地址
IMPORT |Image$$ZI$$Limit| ; ZI段结束地址
IMPORT main ; 声明C程序中的Main()函数
AREA Start,CODE,READONLY ; 声明代码段Start
ENTRY ; 标识程序入口
CODE32 ; 声明32位ARM指令
USR_STACK_LEGTH EQU 128
; 初始化C程序的运行环境
LDR R0,=|Image$$RO$$Limit|
LDR R1,=|Image$$RW$$Base|
LDR R3,=|Image$$ZI$$Base|
CMP R0,R1
BEQ LOOP1
LOOP0
CMP R1,R3
LDRCC R2,[R0],#4
STRCC R2,[R1],#4
BCC LOOP0
LOOP1
LDR R1,=|Image$$ZI$$Limit|
MOV R2,#0
LOOP2
CMP R3,R1
STRCC R2,[R3],#4
BCC LOOP2
;设置系统模式堆栈,SP/r13寄存器
;MSR CPSR_c, #0xdf
LDR SP, StackUsr
BL main ; 跳转到C程序代码Main()函数
StackUsr DCD UsrStackSpace + (USR_STACK_LEGTH - 1)*4
AREA MyStacks, DATA, NOINIT, ALIGN=2
UsrStackSpace SPACE USR_STACK_LEGTH * 4 ; 用户(系统)模式堆栈空间
END
2.main.c
#define LED1_ON ~(1<<4) //1111 1111 1111 1111 1111 1111 1110 1111 GPKDAT31~GPKDAT0
#define LED2_ON ~(1<<5)
#define LED3_ON ~(1<<6)
#define LED4_ON ~(1<<7)
#define LED1_OFF (1<<4) //0000 0000 0000 0000 0000 0000 0001 0000
#define LED2_OFF (1<<5)
#define LED3_OFF (1<<6)
#define LED4_OFF (1<<7)
#define LEDALL_OFF (0xf<<4) //0000 0000 0000 0000 0000 0000 1111 0000
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define rGPIOKCON0 (*(volatile u32 *)0x7f008800)
#define rGPIOKDAT (*(volatile u32 *)0x7f008808)
void delay(int times);
int main(void){
u32 uConValue;
uConValue = rGPIOKCON0;
uConValue &= ~(0xffff<<16); //0000 0000 0000 0000 1111 1111 1111 1111 GPKCON7~GPKCON0
uConValue |= 0x1111<<16; //0001 0001 0001 0001 0000 0000 0000 0000
rGPIOKCON0 = uConValue;
rGPIOKDAT |= LEDALL_OFF;
while(1){
rGPIOKDAT &= LED1_ON;
delay(1000);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED2_ON;
delay(1000);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED3_ON;
delay(1000);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED4_ON;
delay(1000);
rGPIOKDAT |= LEDALL_OFF;
}
}
void delay(int times){
int i;
for(;times>0;times--)
for(i=0;i<3000;i++);
}
====================================================================================================================================
3.如果不用RVDS集成编译环境,以下是基于Window平台下armcc编译器在DOS中执行的Makefile
all:
armasm -o Startup.o Startup.s --debug --keep --cpu=ARM1176JZF-S
armcc -c main.o main.c --debug --cpu=ARM1176JZF-S -O0
armlink -o myled.axf Startup.o main.o --ro_base=0x50200000 --rw_base=0x50203000 --first=Startup.o(start) --entry=0x50200000
fromelf -o myled.bin --bin myled.axf
clean:
del *.o *.axf *.bin
#armasm -o Startup.o Startup.s --debug --keep --cpu=ARM1176JZF-S
#armcc -c main.o main.c --debug --cpu=ARM1176JZF-S -O0
#armlink -o inclc.axf Startup.o main.o --entry Main --ro_base=0x50200000 --first=Startup.o(start)
#fromelf -o inclc.bin --bin inclc.axf
4.以上完了之后直接调出AXD即可。