- start.s
/*
* 文件名: start.s
* 描述 : i.mx6u-alpha开发板启动文件, 完成C环境初始化。
*/
/* 全局标号 */
.global _start
/**
* 描述: _start函数, 程序从此函数开始执行, 此函数主要功能是设置C运行环境
*/
_start:
/* 进入SVC模式 */
mrs r0, cpsr
bic r0, r0, #0x1F /* 将r0的低5位清零, 也就是cpsr的M0~M4 */
orr r0, r0, #0x13 /* r0或0x13, 表示使用SVC模式 */
msr cpsr, r0 /* 将r0的值写入到cpsr_c中 */
ldr sp, =0x80200000 /* 设置栈指针 */
b main /* 跳转到main函数 */
- imx6ul.lds
SECTIONS{
. = 0x87800000;
.text :
{
start.o
main.o
*(.text)
}
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : {*(.data)}
__bss_start = .;
.bss ALIGN(4) : {*(.bss) *(COMMON)}
__bss_end = .;
}
- main.c
在这里插入代/*
* 文件名 : main.c
* 描述 : i.mx6u C语言点亮LED程序
*/
#include "main.h"
/**
* @brief : 使能I.MX6U所有外设时钟
* @para : none
* @return : none
*/
void clk_enable(void)
{
CCM_CCGR0 = 0xffffffff;
CCM_CCGR1 = 0xffffffff;
CCM_CCGR2 = 0xffffffff;
CCM_CCGR3 = 0xffffffff;
CCM_CCGR4 = 0xffffffff;
CCM_CCGR5 = 0xffffffff;
CCM_CCGR6 = 0xffffffff;
}
/**
* @brief : 初始化LED对应的GPIO
* @para : none
* @return : none
*/
void gpio_led_init(void)
{
/* 初始化IO复用, 复用为GPIO1_IO03 */
SW_MUX_GPIO1_IO03 = 0x05;
/* 配置GPIO1_IO03的IO属性 */
SW_PAD_GPIO1_IO03 = 0x10B0;
/* 初始化GPIO1_IO03设置为输出 */
GPIO1_GDIR = 0x00000008;
/* 设置GPIO1_IO03输出低电平, 打开LED0 */
GPIO1_DR = 0x00;
}
/**
* @brief : 打开LED灯
* @para : none
* @return : none
*/
void led_on(void)
{
/* 将GPIO1_DR的bit3清零 */
GPIO1_DR &= ~(1 << 3);
}
/**
* @brief : 关闭LED灯
* @para : none
* @return : none
*/
void led_off(void)
{
/* 将GPIO_DR的bit3置1 */
GPIO1_DR |= (1 << 3);
}
/**
* @brief : 延时
* @para : none
* @return : none
*/
void delay(volatile unsigned int n)
{
volatile unsigned int dly = 0x7FF;
while (n--) {
while (dly--) {
}
dly = 0x7FF;
}
}
/**
* @brief : main函数
* @para : none
* @return : none
*/
int main(void)
{
clk_enable(); /* 使能时钟 */
gpio_led_init(); /* 初始化LED的GPIO引脚 */
while(1) {
led_on(); /* 打开LED */
delay(500);
led_off(); /* 关闭LED */
delay(500); /* 延时约500ms */
}
return 0;
}
- Makefile
objs := start.o main.o
led.bin:$(objs)
# $^是所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那这个变量会去除重复的依赖目标,只保留一份。在这里$^就是start.o main.o
arm-linux-gnueabihf-ld -Timx6ul.lds -o led.elf $^
# $@表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,“$@”就是匹配于目标中模式定义的集合。在这里就是led.bin
arm-linux-gnueabihf-objcopy -O binary -S led.elf $@
arm-linux-gnueabihf-objdump -D -m arm led.elf > led.dis
%.o:%.s
# $<是依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的, 在这里$<就是start.s文件。在这里$@就是start.o
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
%.o:%.S
# $<是依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的, 在这里$<无匹配文件。在这里$@无匹配文件
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
%.o:%.c
# $<是依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的, 在这里$<就是main.c文件。在这里$@就是main.o
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
.PHONY clean:
rm -rf *.o *.bin *.elf *.dis