回顾一下上一节:【ARM 裸机】NXP 官方 SDK 使用,我们发现工程文件夹里面各种文件非常凌乱;
那么为了模块化整理代码,使得同一个属性的文件存放在同一个目录里面,所以学习 BSP 工程管理非常有必要。
1、准备工作
新建文件夹,准备将同一个属性的文件存放在一起;
将 .h 文件放在 imx6u 目录里面;
将 main.c 与 start.s 放在 project 目录里面;
进入 bsp 目录,新建三个目录(clk,delay,led);
现在在工程目录(5_ledc_bsp)的结构如下;
删除 ledc_sdk.code-workspace 工作区文件,然后在 VSCcode 中打开文件夹 5_ledc_bsp,然后将工作区另存为 ledc_bsp;
2、处理驱动文件
上面已经创建了 clk、delay、led 目录,但并未存放文件,需要创建对应的驱动文件并放在对应的目录;
2.1、clk
选择 clk,新建 bsp_clk.c 与 bsp_clk.h;
2.2、delay
选择 delay,新建 bsp_delay.c 与 bsp_delay.h;
2.3、led
选择 led,新建 bsp_led.c 与 bsp_led.h;
2.4、main.h
为了方便起见,在 project 目录下创建一个 main.h;
在 main.c 中的头文件包含如下;
2.5、设置 VScode 头文件路径
先创建 vscode 目录(在 VScode 中不好创建,直接在终端创建);
打开 c/c++ 配置器,在 VScode 中按住 ctrl + shift + p,输入 c/c++:ed 即可打开;
修改 c_cpp_properties.json 文件如下;
经过整理之后,现在的工程结构如下;
显然清晰且明,不再是乱乱的了。
3、重新编写 Makefile
原来的 Makefile 已经不能用了,需要重新编写才行,首先指定头文件和源文件;
需要使用 patsubst 函数,
测试一下 patsubst 函数的使用是否正确;
wildcard 是关键字,可以让通配符在变量中展开,测试一下;
再来处理 obj 目录;
指定搜索路径;
使用了 Makefile 的静态模式,$(SOBJS) : obj/%.o : %.s 这一行的意思是将所有的 .s 文件编译为 .o 文件并且存放到 obj 目录下, $(SOBJS) : obj/%.o : %.c 这一行的意思是将所有的 .c 文件编译为 .o 文件并且存放到 obj 目录下;
完整的 Makefile 文件如下;
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET ?= ledc
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
INCUDIRS := imx6u \
bsp/clk \
bsp/delay \
bsp/led \
SRCDIRS := project \
bsp/clk \
bsp/delay \
bsp/led \
INCLUDE := $(patsubst %,-I %, $(INCUDIRS))
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 $(OBJS)
rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).dis
print:
@echo INCLUDE = $(INCLUDE)
@echo SFILES = $(SFILES)
@echo CFILES = $(CFILES)
@echo SFILENDIR = $(SFILENDIR)
@echo CFILENDIR = $(CFILENDIR)
@echo SOBJS = $(SOBJS)
@echo COBJS = $(COBJS)
4、编译
编译之前,修改一下 imx6u.lds,将原来的 start.o 改为 obj/start.o,main.o 可以去掉,保存;
在终端输入 make,可以看到 obj 目录下有很多输出文件;
在终端输入 make clean,可以看到 obj 目录下的输出文件被清理了;
5、烧写验证
在终端输入 ./imxdownload ledc.bin /dev/sdb 即可;
可以看到开发板上 led1 以 500 ms 的间隔进行亮灭。
好了,总结一下,可以说本节(BSP 工程管理)创建了一个基本的 ARM 裸机开发的模板,本节又添加了很多东西在 Makefile 里面,现在已经比较完善了,以后对于不同的工程,只需要修改一下工程名,头文件路径,源文件路径即可,连接脚本也是不需要修改什么,为我们的学习提供了大大的方便,打下了基础。