002 用C写第一个Liunx LED
和前面那个例程一样,硬件不变。这次改用C语言来点亮n_LED1。
这一节我们主要是用指针指向内存地址,来操作n_LED1的亮灭。
准备工作是先了解一下指针:
所有的变量在c语言中都有一块内存区域。
例: int a;
char c;
int *pa;
int *pc;
type *p1 = val1;
*p2 = val2;
把val2写入地址val1的内存,写入 sizeof(type) 字节。
注:指针的实质也是一个数值,只是这个数值表示了内存的地址。
这里要了解一下指针:
如上图中:
a = 123;
c = ‘t’;
pa = &a;
pc = &c;
pd = &pa;
pd是指针的指针:pd本身是pa的指针,pa是a的指针。所以pd是a的指针的指针。
**pd = a;当我们修改**pd的值的时候,a的值就被改变。 因为这个时候我们修改pd指针所指向的内容的值,而*pd所指向的内容是a的地址也就是pa的值所指向的内容。
当我们用C语言写LED灯程序的时候有如下问题:
- 我们写的main函数由谁来调用它?
- Main函数中变量保存在内存中,这个内存地址是多少?
答:我们需要些一个汇编文件,来给main函数设置内存。并且调用main函数。
指针准备完成后我们一样撸代码:
先是 led_on.c
int main(void)
{
#if 0
/*在这里我们要先用到指针,指向内存,然后再操作这些指针来点亮n_LED1*/
unsigned int * pGPFCON = (unsigned int *)0x56000050;
unsigned int * pGPFDAT = (unsigned int *)0x56000054;
/* 配置GPF4为输出mode */
*pGPFCON = 0x100; //设置[9:8] = b01
/* 设置GPF4为低电平 */
*pGPFDAT = 0;
return 0;
#endif
unsigned int *pGPFCON = (unsigned int *)0x56000050;
unsigned int *pGPFDAT = (unsigned int *)0x56000054;
/* 配置GPF4为输出引脚 */
*pGPFCON = 0x100;
/* 设置GPF4输出0 */
*pGPFDAT = 0;
return 0;
}
然后是汇编部分 start.S:
.text
.global _start
_start:
/* 设置栈 */
ldr sp,=1024*4 //设置nand启动,从nandFlash拷贝前4K到SRAM启动
/* 调用main函数 */
bl main //调用main结束后,返回到此处继续往下执行
halt:
b halt
最后是Makefile:
all:
arm-linux-gcc -c -o led_on.o led_on.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0 start.o led_on.o -o led_on.elf
arm-linux-objcopy -O binary -S led_on.elf led_on.bin
clean:
rm -f *.bin *.o *.elf
在这里我卡了很久,为什么编译也不报错,程序和韦东山老师的对比没有缺少任何东西,但是烧录进去后就是不对!灯怎么都不亮。
arm-linux-ld -Ttext 0 led_on.o start.o -o led_on.elf
查了好久才发现问题出在这一句,连接的时候一定要讲究顺序。
arm-linux-ld -Ttext 0 start.o led_on.o -o led_on.elf
start.o 一定要在led_on.o的前面才行。切记切记。