与上一次不同,本次使用C语言的方式来点亮LED,那么关键的问题来了,程序怎么跳到C语言的main函数的入口呢?即便程序跳到了main函数入口,我们通过c定义的变量存到哪里呢?这些内存该怎么分配呢?因此,在进入C函数之前,需要设置堆栈来存储一些变量,start.S汇编代码如下:
.text
.global _start
_start:
/*硬件相关设置*/
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
/*关看门狗*/
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]
/* 设置C程序运行的栈*/
ldr sp, =8*1024
bl main
halt:
b halt
S3C6410.h具体代码如下:
#ifndef S3C6410_H
#define S3C6410_H
#define GPMCON (*(volatile unsigned int *)(0x7F008820))
#define GPMDAT (*(volatile unsigned int *)(0x7F008824))
#endif
Led.c具体代码如下:
#include "led.h"
void LedInit()
{
GPMCON = 0x11111; //输出模式
GPMDAT = 0x1f; //暂时全部熄灭
}
void delay(int time)
{
volatile unsigned int i,j;
for(i = 0; i < 20000; i++)
for(j=0; j<time; j++);
}
int main()
{
LedInit();
while(1)
{
LED1_ON;
delay(1);
LED1_OFF;
LED2_ON;
delay(1);
LED2_OFF;
LED3_ON;
delay(1);
LED3_OFF;
LED4_ON;
delay(1);
LED4_OFF;
}
return 0;
}
Led.h具体代码如下
#ifndef _LED_H
#define _LED_H
#include "s3c6410.h"
#define LED1_ON (GPMDAT&=~(1<<0))
#define LED2_ON (GPMDAT&=~(1<<1))
#define LED3_ON (GPMDAT&=~(1<<2))
#define LED4_ON (GPMDAT&=~(1<<3))
#define LED1_OFF (GPMDAT|=(1<<0))
#define LED2_OFF (GPMDAT|=(1<<1))
#define LED3_OFF (GPMDAT|=(1<<2))
#define LED4_OFF (GPMDAT|=(1<<3))
#endif
最重要的就是makefile了,它告诉arm-linux-gcc如何去编译、链接以及输出.bin文件
led.bin: start.o led.o
arm-linux-ld -Ttext 0 -o led.elf start.o led.o
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led.dis
start.o : start.S
arm-linux-gcc -o start.o start.S -c -O2
led.o : led.c
arm-linux-gcc -o led.o led.c -c -O2
clean:
rm *.o led.elf led.bin led.dis