002 用C写第一个Liunx LED

和前面那个例程一样,硬件不变。这次改用C语言来点亮n_LED1。

这一节我们主要是用指针指向内存地址,来操作n_LED1的亮灭。

准备工作是先了解一下指针:

所有的变量在c语言中都有一块内存区域。

例:    int  a;

            char  c;

           int  *pa;

           int  *pc;

002 用C写第一个Liunx LED

type  *p1  = val1;

           *p2  = val2;

把val2写入地址val1的内存,写入 sizeof(type) 字节。

注:指针的实质也是一个数值,只是这个数值表示了内存的地址。

002 用C写第一个Liunx LED

这里要了解一下指针:

如上图中:

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灯程序的时候有如下问题:

  1. 我们写的main函数由谁来调用它?
  2. 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的前面才行。切记切记。