过去有个“傻瓜相机”,现在的软件开发也是越来越傻瓜化,在一个没有各种库,没有各种GUI的乌起码黑的世界里,LED神灯犹如"希望",值得我们去膜拜。
一个6410的例子,现在看来有点过时。
.globl _start .globl delay _start: /* 硬件相关设置 */ 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] /* 设置栈 */ ldr sp, =8*1024 //6410's cpu上的8K mov r0, #2 mov r1, #8 bl led_ctl //asm->c halt: b halt delay: delay_loop: cmp r0, #0 sub r0, r0, #1 bne delay_loop mov pc, lr
汇编调用c 函数,同时给c传递参数,也就是参数寄存器赋值,(r0,r1)。
void delay(int count); int led_ctr(int a, int b) { int i = 0; int k = a + b; //传进来2和8,那么k = 10 volatile unsigned long *gpmcon = (volatile unsigned long *)0x7F008800; volatile unsigned long *gpmdat = (volatile unsigned long *)0x7F008808; /* gpm 0,1,2,3设为输出引脚 */ *gpmcon = 0x11110000; while (k--) /*循环10次,灯闪烁10次*/ { *gpmdat = i; i += 16; if (i == 240) i = 16; delay(5000000); //c->asm } return 0; }
这里c函数又调用汇编,而r0自然等于5000000。
没有定时器,用循环实现延时。
然后将程序编译成.bin烧入内存一个地址,比如0c000000,然后go 0c000000。
哈哈,神灯就这么闪了十下,asm->c 的参数传对了。但延时比较短,因为是汇编的缘故,灯闪烁的较快,若用c实现delay,灯会慢许多。
一直以来,将心思放在内核代码,偶然发现,仔细研究下arm五花八门的控制器,也是一种乐趣,毕竟软件的基础是硬件,硬件的大脑就是这么个arm,若能充分了解arm寄存器的控制,对内核的理解才会突破瓶颈,柳暗花明。