宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

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文件夹下。
Linux嵌入式开发–bsp管理模式 及其 Makefile(主要介绍Makefile)-风君子博客
如上即为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