移植官方SDK库
首先新建cc.h文件,存放一些SDK库文件用到的数据类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #ifndef _cc_h #define _cc_h
#define __I volatile #define __O volatile #define __IO volatile
typedef signed char int8_t; typedef signed short int int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; typedef signed char s8; typedef signed short int s16; typedef signed int s32; typedef signed long long int s64; typedef unsigned char u8; typedef unsigned short int u16; typedef unsigned int u32; typedef unsigned long long int u64;
#endif
|
将我们用到的fsl_comon.h、fsl_iomuxc.h、MCIMX6Y2.h复制进文件夹中,可以在vscode中看到产生了许多报错,我们先在三个文件顶部添加cc.h头文件解决掉标识符错误的报错。
#include “cc.h”
接着,我们将没有复制进来但包含的头文件全部删除,然后将报错的地方一一删除即可。(此举动仅针对本次实验)
将上一次的main.c文件复制进文件夹,并做以下改动:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include "fsl_common.h" #include "fsl_iomuxc.h" #include "MCIMX6Y2.h" void Clk_En() { CCM->CCGR1 = 0XFFFFFFFF; }
void LED_Init() { IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0); IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0); GPIO1->GDIR |= (1 << 3); GPIO1->DR &= ~(1 << 3); }
void delay_short(volatile unsigned int n) { while(n--); }
void delay(volatile unsigned int ms) { while(ms--) { delay_short(0x7ff); } }
void Led_Set_Pin(int a) { if(a == 0) { GPIO1->DR &= ~(1 << 3); } else if(a == 1) { GPIO1->DR |= (1 << 3); } else return; }
int main() { Clk_En(); LED_Init(); while(1) { delay(500); Led_Set_Pin(1); delay(500); Led_Set_Pin(0); } return 0; }
|
编写Makefile脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| CROSS_COMPILE ?= arm-linux-gnueabihf- NAME ?= ledc
CC := $(CROSS_COMPILE)gcc LD := $(CROSS_COMPILE)ld OBJCOPY := $(CROSS_COMPILE)objcopy OBJDUMP := $(CROSS_COMPILE)objdump
OBJS := start.o main.o
$(NAME).bin:$(OBJS) $(LD) -Timx6ul.lds -o $(NAME).elf $^ $(OBJCOPY) -O binary -S $(NAME).elf $@ $(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis
%.o:%.s $(CC) -Wall -nostdlib -c -O2 -o $@ $< %.o:%.S $(CC) -Wall -nostdlib -c -O2 -o $@ $< %.o:%.c $(CC) -Wall -nostdlib -c -O2 -o $@ $< clean: rm -rf *.o $(NAME).bin $(NAME).elf $(NAME).dis
|
三个赋值号的区别
?= 若外部未指定,则赋值
= 与外部绑定
:= 不绑定,只赋值
编译器后不同关键字的意思
-Wall 打开常用编译警告
-nostdlib 不链接任何标准库
-c 只编译 不链接
-O2 开启中等级别优化
-o <file> 指定输出文件名
-S(objcopy 参数)去除符号表和调试信息
烧写后运行,正常闪烁LED。
BSP工程管理
我们建立如下图所示的文件夹。
图 1 文件夹
其中,bsp用来存放驱动文件;imx6ul用来存放跟芯片相关的文件,obj用来存放编译生成的.o文件,project存放应用文件(即start.s和main.c文件)。
图 2 文件树
以下是makefile文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| CROSS_COMPILE ?= arm-linux-gnueabihf- TARGET ?= bsp
CC := $(CROSS_COMPILE)gcc LD := $(CROSS_COMPILE)ld OBJCOPY := $(CROSS_COMPILE)objcopy OBJDUMP := $(CROSS_COMPILE)objdump
INCDIRS := imx6ul \ bsp/clk \ bsp/led \ bsp/delay SRCDIRS := project \ bsp/clk \ bsp/led \ bsp/delay INCLUDE := $(patsubst %, -I %, $(INCDIRS))
SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S)) CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
SFILENDIR := $(notdir $(SFILES)) CFILENDIR := $(notdir $(CFILES))
SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o)) COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o)) OBJS := $(SOBJS) $(COBJS)
VPATH := $(SRCDIRS)
.PHONY: clean $(TARGET).bin : $(OBJS) $(LD) -Timx6ul.lds -o $(TARGET).elf $^ $(OBJCOPY) -O binary -S $(TARGET).elf $@ $(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis
$(SOBJS) : obj/%.o : %.S $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<
$(COBJS) : obj/%.o : %.c $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $< clean: rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
|
第 1~7 行定义了一些变量,除了第 2 行以外其它的都是跟编译器有关的,如果使用其它编译器的话只需要修改第 1 行即可。第 2 行的变量 TARGET 目标名字,不同的例程肯定名字不一样。
第 9 行的变量 INCDIRS 包含整个工程的.h 头文件目录,文件中的所有头文件目录都要添加到变量INCDIRS 中。比如本例程中包含.h 头文件的目录有 imx6ul、 bsp/clk、 bsp/delay 和 bsp/led,所以就需要在变量 INCDIRS 中添加这些目录。
第 14 行是变量 SRCDIRS,和变量 INCDIRS 一样,只是 SRCDIRS 包含的是整个工程的所有.c 和.S 文件目录。比如本例程包含有.c 和.S 的目录有 bsp/clk、 bsp/delay、 bsp/led 和 project。
$(patsubst 原模式, 新模式, 文本)
在文本中,把所有符合原模式的部分,替换成新模式。
第22、23行找出所有的.S、.c文件,25、26行则去掉了路径名、只保留文件名。28-30行将.c、.o文件编译为.o文件并将其放入obj文件夹中。
32行含义是当规则里写 %.c 或 %.S make 会自动去project/ bsp clk/ … 里找
运行
编译并烧录,实验结果正常。