上篇文章中的代码使用的都是汇编代码,这次我们使用汇编跳转到C代码,来实现点亮led,其中注意的一点是sp的设置,其他就比较简单。
转载请注明出处,谢谢,张同浩:http://blog.csdn.net/muge0913/article/details/15026221
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