要在裸机上运行C语言程序,我们需要在运行C语言程序之前设置栈底指针,因为C语言中的变量与函数调用都是基于堆栈的。
怎么设置栈底指针呢,一句话就可以了
ldr pc,=1024*4
至于为什么设置成4k,是因为的这块板子SRAM最大只有4K的地址空间。
当然,我们还需要做的一件事情是关闭看门狗,这个,我也不是特别清楚,应该照做就好了吧,反正挺简单的
ldr r0, =0x53000000
mov r1, #0
str r1, [r0]
所以程序需要做这几件事情
关闭看门狗设置栈底指针
跳转到C语言的函数中运行(一般是main函数)
.text
.global _start
_start:
@关闭看门狗
ldr r0, =0x53000000
mov r1, #0
str r1, [r0]
@设置栈底指针
ldr sp, =4096
@跳转到C语言中运行
bl main
halt_hoop:
b halt_hoop
#define LEDCON (*(volatile unsigned long *)0x56000050)
#define LEDDAT (*(volatile unsigned long *)0x56000054)
#define E_LED1 (0x01 << 2*4)
#define E_LED2 (0x01 << 2*5)
#define E_LED3 (0x01 << 2*6)
#define ON_LED1 (0x1 << 4)
#define ON_LED2 (0x1 << 5)
#define ON_LED3 (0x1 << 6)
void allLedEnable()
{
LEDCON |= (E_LED1 | E_LED2 | E_LED3);
}
void sleep()
{
int i = 0x5555;
for(; i ; i--);
}
int main()
{
allLedEnable();
while(1){
sleep();
LEDDAT &= ~ON_LED1;
LEDDAT |= ON_LED2;
LEDDAT |= ON_LED3;
sleep();
LEDDAT |= ON_LED1;
LEDDAT &= ~ON_LED2;
LEDDAT |= ON_LED3;
sleep();
LEDDAT |= ON_LED1;
LEDDAT |= ON_LED2;
LEDDAT &= ~ON_LED3;
}
return 0;
}
led_on.bin:led_on.c crt0.S
arm-linux-gcc -g -c -o led_on.o led_on.c
arm-linux-gcc -g -c -o crt.o crt0.S
arm-linux-ld -Ttext 0x00000000 -g crt.o led_on.o -o led_on_elf
arm-linux-objcopy -O binary -S led_on_elf led_on.bin
arm-linux-objdump -S -m arm led_on_elf > led_on_elf.dis
clean:
rm -f led_on.bin led_on_elf *.o *.bak
这个程序之前已经写过两遍了,可是今天写时,无论如何led灯都不亮,后来对着书一个一个查,就是少了个volatile关键字,坑爹啊.