bsp管理模式及Makefile
1. bsp管理
bsp管理,说白了,就是只将相同内容或属性的文件放在同一个目录下,不同属性的文件分开存放,这样可以方便文件管理及查找。
以imx6ull芯片实现跑马灯为例:
–led亮灭过程实现三步骤:时钟使能,led初始化GPIO管脚功能设定),延时设定;
–bsp管理:
1)将三部分的文件分别存放不同文件夹下:clk.c/clk.h放于clk文件夹,led.c/led.h存放于led文件夹下,delay.c/delay.h存放于delay文件夹下;
2)我们用到的,对应芯片厂商的sdk包可以放于imx6ull文件夹下;
3)主函数main.c以及汇编编写C运行环境等内容)存放于project文件夹下。
如上即为bsp管理模式。
2. Makefile编写
对于bsp管理模式而言,各个目录下都可能会存放不同的.c和.h文件,所以进行Makefile编写的时候就需要表明.c和.h的路径,否则会在make时找不到相关文件而报错;
仍以跑马灯为例,Makefile相关代码如下,下面会对Makefile各个部分进行解释:
COMPILE := arm-linux-gnueabihf-
TARGET := ledGCC := $COMPILE)gcc
LD := $COMPILE)ld
OBJCOPY := $COMPILE)objcopy
OBJDUMP := $COMPILE)objdumpINCDIRS := imx6ull\bsp/clk\bsp/led\bsp/delay\projectSRCDIRS := project\bsp/clk\bsp/led\bsp/delay
//上方内容很简单,只是通过:=进行赋值操作(:=意义在于符号左方变量只能等于右方变量之前定义过的值,即使右方变量在下文重新定义,左方变量不受到影响)
//$)作用:取括号内变量的值INCLUDE := $patsubst %, -I %, $INCDIRS))
//目的将所有文件夹前方添加-I符号,这样相当于gcc -I + 路径操作,就是查找头文件时也会到指令路径取查找。SFILES := $foreach dir, $SRCDIRS), $wildcard $dir)/*.S))
CFILES := $foreach dir, $SRCDIRS), $wildcard $dir)/*.c))
//遍历所有的.S和.c文件(获取的名称包含路径+文件名),详细会在下方解释SFILENDIR := $notdir $SFILES))
CFILENDIR := $notdir $CFILES))
//去掉路径,只要.S和.c文件名称SOBJS := $patsubst %, obj/%, $SFILENDIR:.S=.o))
COBJS := $patsubst %, obj/%, $CFILENDIR:.c=.o))
//将.S和.c文件后缀改为.o,(这里只是改名字,不是真正编译后的.o文件,名称后续需用于依赖)OBJS := $SOBJS)$COBJS)VPATH := $SRCDIRS)
//表明依赖所在路径,当当前系统找不到相关依赖时,会往该路径下去找$TARGET).bin: $OBJS)$LD) -Timx6ull.lds $^ -o $TARGET).elf$OBJCOPY) -O binary -S $TARGET).elf $@$OBJDUMP) -D -m arm $TARGET).elf > $TARGET).dis$SOBJS): obj/%.o: %.S$GCC) -Wall -nostdlib -c $INCLUDE) -o $@ $<$COBJS): obj/%.o: %.c$GCC) -Wall -nostdlib -c $INCLUDE) -o $@ $<.PHONY: clean:
//伪目标,只有在“make + 伪目标名称”命令下才会执行到rm obj/*.o $TARGET).bin $TARGET).elf $TARGET).dis.PHONY: print:@echo $OBJS)
Makefile中相关函数解释
– patsubst函数(模式字符串替换函数)
用法:$patsubst <pattern>,<replace>, <text>)
<pattern>:待替换字符串,<replace>:替换后的字符串,<text>:需替换字符串的集合,以空格,"Tab","\","回车"分隔,将值依次提供给<pattern>进行替换
以上述代码为例:INCLUDE := $patsubst %, -I %, $INCDIRS))
通过上述代码中伪目标print的方式进行打印观察:每一个目标字符串前都加了一个-I。
raydiumtouch@raydiumtouch-VirtualBox:~/Driver Development/5_led_bsp_manage$ make print
INCLUDE = -I imx6ull -I bsp/clk -I bsp/led -I bsp/delay -I project
–foreach函数(循环函数)
用法:$foreach <var>, <list>, <text>)
功能:将list中的元素依次赋给var,然后在执行text的表达式并返回执行后的内容,返回的每个字符串以空格间隔。
以上述代码为例:CFILES := $foreach dir, $SRCDIRS), $wildcard $dir)/*.c))
该部分作用就是将每个文件夹传给dir,然后再每个dir下找所有.c的文件;
执行函数内容中还包含wildcard,这个的作用为使通配符有效,函数返回可以展开所有.c文件,并以空格间隔。(默认下通配符有效,但在函数中,通配符失效)。
make print观察返回信息:
raydiumtouch@raydiumtouch-VirtualBox:~/Driver Development/5_led_bsp_manage$ make print
CFILES = project/main.c bsp/clk/clk.c bsp/led/led.c bsp/delay/delay.c
–notdir(去掉文件前的路径,只保留文件名)
举例:CFILENDIR := $notdir $CFILES))
打印观察发现:无路径信息,只有文件名
raydiumtouch@raydiumtouch-VirtualBox:~/Driver Development/5_led_bsp_manage$ make print
CFILENDIR = main.c clk.c led.c delay.c