ARMC语言的裸机开发
本文介绍如何搭建一个ARM实验环境
今天,我看了某些教程,做了一个C语言的,裸机开发ARM的实验。但我依然觉得教程讲得过于复杂,没有在最少的篇幅内讲清楚实验的来龙去脉。我根据自己的理解,记录实验过程如下。
我使用的芯片是IMX6ULL,以下简称"芯片"。
芯片刚上电,会执行内部的ROM,把代码从SD卡复制到运行地址,然后从运行地址处开始执行。这里设定运行地址为=0x87800000.它位于DDR中,开发板的DDR地址范围是(0X80000000~0X9FFFFFFF)。
如此一来,在ARM上用C语言开发裸机,只需要做到以下几步:
1,最开始执行的代码是把栈寄存器SP的值设置好,因为之后运行C语言需要用到栈。这部分代码自然不能用C,需要使用汇编。
2,跳转到C语言函数。 如void MyMain()。
为了防止引入其他无关知识,凸显出本文重点,所以汇编代码(code.s)很简单
SetSpValue:
LDR SP,=0x80200000
BL MyMain
设置成这样后,0x80000000~0x801FFFFF都是栈空间,有2kB。
而C语言代码(Main.c)只是循环的将LED一亮一灭罢了。也就是给对应的内存空间读写值罢了。
#define SET_MEM(ADDRESS, VALUE) *(unsigned int *)(ADDRESS) = VALUE
#define GET_MEM(ADDRESS) *(unsigned int *)(ADDRESS)
void LED_Red_Init()
{
unsigned int Temp=0;
//设置IOMUXC
SET_MEM(0x020E0068, 0x05);
SET_MEM(0x020E02F4, 0x10B0);
//设置GPIO——GDIR
Temp = GET_MEM(0x0209C004);
SET_MEM(0x0209C004, Temp | (1<<3));
}
void LED_Red_On()
{
unsigned int Temp=0;
Temp = GET_MEM(0x0209C000 );
SET_MEM(0x0209C000, Temp & ~(1<<3));
}
void LED_Red_Off()
{
unsigned int Temp=0;
Temp = GET_MEM(0x0209C000);
SET_MEM(0x0209C000, Temp | (1<<3));
}
void delay(unsigned int d)
{
unsigned int i,j;
for(i=0;i<d;i++)
for(j=0;j<0xFFFF;j++)
{
}
}
void MyMain()
{
LED_Red_Init();
while(1)
{
LED_Red_On();
delay(5);
LED_Red_Off();
delay(5);
}
}
至于makefile文件,其实不是本文的重点。
GCC = arm-linux-gnueabihf
#objs = code.o Main.o
objs = code.o Main.o
Main.bin:$(objs)
$(GCC)-ld -Ttext 0x87800000 -o Main.elf $^
$(GCC)-objcopy -O binary -S Main.elf [email protected]
$(GCC)-objdump -D -m arm Main.elf >Main.dis
%.o:%.s
$(GCC)-gcc -Wall -nostdlib -c -o [email protected] $<
%.o:%.c
$(GCC)-gcc -Wall -nostdlib -c -o [email protected] $<
clean:
rm -rf *.o Main.bin Main.elf Main.dis
download:
./imxdownload Main.bin /dev/sdc
Linux终端下进行操作。
效果是,还真闪了。