IMX6ULL裸机学习(5)— 编写C语言程序点亮LED

IMX6ULL裸机学习(5)— 编写C语言程序点亮LED

一、前言

使用c语言时,要用到的一个很重要的就是栈,所以我们要在汇编中就设置好栈;

二、编写汇编代码

编写start.s如下所示:


.text                               /* .text段保存代码,是只读和可执行的,后面的指令都属于.text段。 */
.global  _start                     /* .global表示_start是一个全局符号,会在链接器链接时用到 */

_start:                             /* 标签_start,汇编程序的默认入口是_start */
    /* 1、设置栈 */
    ldr sp, =(0x80000000+0x100000)  /* 设置栈顶地址 */
    /* 2、跳转到led函数 */
    bl led
    /* 3、原地循环 */
    b .

三、编写C文件

新建led.c文件,编写代码如下所示

int delay(int ndelay)
{
	volatile int n = ndelay;
	while(n--);
	
	return 0;
}

int led(void)
{
	volatile unsigned int *pReg;
	
	/* 1、设置 GPIO1_IO03 复用为 GPIO1_IO03 */
	pReg = (unsigned int *)(0x020e0000 + 0x68);
	*pReg |= (0x05);
	
	/* 2、设置GPIO1_IO03 为输出引脚 */
	pReg = (unsigned int *)(0x0209c000 + 0x04);
	*pReg |= (1<<3);

	pReg = (unsigned int *)(0x0209c000);
	
	while (1)
	{
		/* 3、设置GPIO1_IO03输出1 */
		*pReg |= (1<<3);
		
		delay(1000000);

		/* 4、设置GPIO1_IO03输出0 */
		*pReg &= ~(1<<3);
		
		delay(1000000);		
	}
}

四、修改Makefile

修改Makefile如下,

PREFIX=arm-linux-gnueabihf-
CC=$(PREFIX)gcc
LD=$(PREFIX)ld
AR=$(PREFIX)ar
OBJCOPY=$(PREFIX)objcopy
OBJDUMP=$(PREFIX)objdump

led.img : start.s  led.c
	$(CC) -nostdlib -c -g start.s -o start.o
	$(CC) -nostdlib -c -g led.c -o led.o
	$(LD) -g start.o led.o -Ttext 0X80100000 -o led.elf
	$(OBJCOPY) led.elf -O binary -S led.bin
	$(OBJDUMP) -D -m arm led.elf > led.dis
	mkimage -T imximage -n ./tools/imximage.cfg.cfgtmp -e 0x80100000 -d led.bin led.imx
	dd if=/dev/zero of=1k.bin bs=1024 count=1
	cat 1k.bin led.imx > led.img

clean:
	rm -rf *.o led.bin led.elf led.dis led.imx led.img

使用make执行后如下
在这里插入图片描述

编译烧录后可以看到LED闪烁
在这里插入图片描述

五、优化

修改led.c文件如下所示

int delay(int ndelay)
{
	volatile int n = ndelay;
	while(n--);
	
	return 0;
}

int led_init(void)
{
	volatile unsigned int *pReg;
	
	/* 1、设置 GPIO1_IO03 复用为 GPIO1_IO03 */
	pReg = (unsigned int *)(0x020e0000 + 0x68);
	*pReg |= (0x05);
	
	/* 2、设置GPIO1_IO03 为输出引脚 */
	pReg = (unsigned int *)(0x0209c000 + 0x04);
	*pReg |= (1<<3);
}

void led_on(void)
{
    volatile unsigned int *pReg;
    pReg = (unsigned int *)(0x0209c000);
    *pReg &= ~(1<<3);	/* 设置GPIO1_IO03输出0 */
}

void led_off(void)
{
    volatile unsigned int *pReg;
    pReg = (unsigned int *)(0x0209c000);
	*pReg |= (1<<3);    /* 设置GPIO1_IO03输出1 */
}

新建led.h文件如下

#ifndef __LED_H
#define __LED_H

int delay(int ndelay);
int led_init(void);
void led_on(void);
void led_off(void);

#endif

新建main.c如下所示

#include "led.h"

int main(void)
{
    led_init();

    while(1)
    {
        led_on();
        delay(1000000);
        led_off();
        delay(1000000);
    }
}

修改Makefile如下所示

PREFIX=arm-linux-gnueabihf-
CC=$(PREFIX)gcc
LD=$(PREFIX)ld
AR=$(PREFIX)ar
OBJCOPY=$(PREFIX)objcopy
OBJDUMP=$(PREFIX)objdump

led.img : start.s led.c main.c
	$(CC) -nostdlib -c -g start.s -o start.o
	$(CC) -nostdlib -c -g led.c -o led.o
	$(CC) -nostdlib -c -g main.c -o main.o
	$(LD) -g start.o led.o main.o -Ttext 0X80100000 -o led.elf
	$(OBJCOPY) led.elf -O binary -S led.bin
	$(OBJDUMP) -D -m arm led.elf > led.dis
	mkimage -T imximage -n ./tools/imximage.cfg.cfgtmp -e 0x80100000 -d led.bin led.imx
	dd if=/dev/zero of=1k.bin bs=1024 count=1
	cat 1k.bin led.imx > led.img

clean:
	rm -rf *.o led.bin led.elf led.dis led.imx led.img

修改start.s如下所示

.text                               /* .text段保存代码,是只读和可执行的,后面的指令都属于.text段。 */
.global  _start                     /* .global表示_start是一个全局符号,会在链接器链接时用到 */

_start:                             /* 标签_start,汇编程序的默认入口是_start */
    /* 1、设置栈 */
    ldr sp, =(0x80000000+0x100000)  /* 设置栈顶地址 */
    /* 2、跳转到led函数 */
    bl main
    /* 3、原地循环 */
    b .

然后编译链接烧录,可以看到led闪烁

六、附录

上一篇:IMX6ULL裸机学习(4)— 编写汇编程序点亮LED
下一篇:IMX6ULL裸机学习(6)— 编写uart串口打印程序
代码存放:https://gitee.com/william_william/imx6ull_noos/tree/master/01_led

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值