在本文中,我們使用匯編跳轉到C代碼,來實現點亮led,其中注意的一點是sp的設置,其他就比較簡單。
bootsect代碼如下:
@******************************************************************************
@ File:bootsect.s
@ 功能:
@******************************************************************************
.equ WATCHDOGCON, 0x7e004000
.equ LEDCON, 0x7f008800
.equ LEDDAT, 0X7f008808
.text
.global _start
_start:
bl setup_peri_port
bl disable_watch_dog
bl setup_sp
bl display_led
bl main
MAIN_LOOP:
b MAIN_LOOP
disable_watch_dog:
@往WATCHDOG寄存器寫0即可
ldr r0,=WATCHDOGCON
mov r1,#0x0
str r1,[r0]
mov pc,lr
setup_sp:
ldr sp, =1024*8 @ 設置堆棧,注意:不能大於8k, 因為現在可用的內存只有8K
@ nand flash中的代碼在復位後會移到內部ram中,此ram只有8K
mov pc,lr
setup_peri_port:
ldr r0,=0x70000013 @base addres:0x70000000,size:256MB
mcr p15,0,r0,c15,c2,4
mov pc,lr
display_led:
ldr r0,=LEDCON @ R0設為LEDCON,即GPKCON0寄存器。此寄存器
@ 用於選擇端口K各引腳的功能:
@ 是輸出、是輸入、還是其他
mov r1,#0x110000
str r1,[r0] @ 設置GPK4,5為輸出口
ldr r0,=LEDDAT @ R0設為GPKDAT寄存器。此寄存器
@ 用於讀/寫端口B各引腳的數據
mov r1,#0x00000000 @ 此值為0x000000,低電平點亮led
str r1,[r0] @ GPK4,5輸出0,LED4,5點亮
mov pc,lr
main.c文件如下:
#define rGPKCON0 (*(volatile unsigned *)(0x7F008800))
#define rGPKCON1 (*(volatile unsigned *)(0x7F008804))
#define rGPKDAT (*(volatile unsigned *)(0x7F008808))
#define rGPKPUD (*(volatile unsigned *)(0x7F00880C))
void Port_Init(void)
{
rGPKCON0 = (rGPKCON0 & ~(0xffffU<<16))|(0x1111U<<16);
rGPKPUD = (rGPKPUD & ~(0xffU << 8))|(0x00U<<8);
}
void Led_Display(int data)
{
rGPKDAT = (rGPKDAT & ~(0xf<<4)) | ((data & 0xf)<<4);
}
static void LedDelay(void)
{
volatile unsigned int k;
for(k = 0; k < 200000; k++);
}
int main()
{
Port_Init();
for(;;) {
Led_Display(0x1); //
LedDelay();
Led_Display(0x2); //
LedDelay();
Led_Display(0x4); //
LedDelay();
Led_Display(0x8); //
LedDelay();
}
return 0;
}
Makefile文件如下:
led_on_c.bin : bootsect.s main.c
arm-linux-gcc -g -c -o bootsect.o bootsect.s
arm-linux-gcc -g -c -o main.o main.c
arm-linux-ld -Ttext 0x0000000 -g bootsect.o main.o -o linux_kernel_elf
arm-linux-objcopy -O binary -S linux_kernel_elf linux_kernel.bin
arm-linux-objdump -D -b binary -m arm linux_kernel.bin > linux_kernel.dis
clean:
rm -f *.dis *.bin *elf *.o
本欄目更多精彩內容:http://www.bianceng.cn/OS/Linux/