- 原理分析
- 源码
硬件平台:jz2440
软件平台:Ubuntu16.04 arm-linux-gcc-3.4.5
源码位置: https://github.com/lian494362816/C/tree/master/2440/004_led_parma
1原理分析
当使用汇编调用C函数,碰到需要传参时,可以使用R0-R3来传递参数。
R0代表第1个参数,R1代表第2个参数.......当参数超过4个时,就需要靠SP来实现了。
更详细的说明可以去查“ATPCS规则“。
这里只讨论参数不超过4个时的情况。
2源码
led_on.c
void delay(int delay_time)
{
while(delay_time --)
{
/* nothing */
}
}
int led_on(int led_num)
{
unsigned int *pGPF4CON = (unsigned int *)0x56000050;
unsigned int *pGPFDAT = (unsigned int *)0x56000054;
if (4 == led_num)
{^M
*pGPF4CON = 0x100;
}
else if (5 == led_num)
{
*pGPF4CON = 0x400;
}
*pGPFDAT = 0x0;
return 0;
}
先看C文件,包含了2个函数,delay 和 led_on。
led_on:传入4或5来点亮2个不同的LED灯
delay:对传进来的参数做递减, 以此来实现简单的延时
start.s
.global _start
_start:
ldr sp, =4096 /* for nand */
/*ldr sp, =0x40000000 + 4096 /* for nor */
mov r0, #4
bl led_on
ldr r0,=10000
bl delay
mov r0, #5
bl led_on
loop:
b loop
如之前所说的,R0代表第1个参数。 而led_on 和delay都只接收1个参数,所以需要把参数的值都赋值给R0。
(1)先将4赋值给R0然后调用led_on, 相当于调用led_on(4),
(2)然后把10000赋值给R0,再调用delay, 相当于调用delay(10000),
(3)再次把5赋值给R0, 然后调用led_on,相当于调用led_on(5)
这样就实现了汇编给C传参,点亮不同的led灯。 这样简单的led函数可以在调试u-boot时使用,尤其是当串口还未初始化时,可以通过点亮/熄灭 不同的led灯来判断代码执行到了什么位置。