PX4-Bootloader/Makefile学习

  1 #
  2 # Common Makefile for the PX4 bootloaders
  3 #
  4
  5 #
  6 # Paths to common dependencies
  7 #
  8 export BUILD_DIR_ROOT ?= build
  9 export BL_BASE          ?= $(wildcard .)
 10 export LIBOPENCM3       ?= $(wildcard libopencm3)
 11 export LIBKINETIS       ?= $(wildcard lib/kinetis/NXP_Kinetis_Bootloader_2_0_0)
 12 MKFLAGS=--no-print-directory

export BUILD_DIR_ROOT ?= build #指定构建目录的路径,如果没有定义,则使用右侧的默认值

export BL_BASE ?= $(wildcard .) #使用wildcard获取当前目录作为bootloader的基础路径

export LIBOPENCM3 ?= $(wildcard libopencm3) #使用wildcard查找libopencm3(一个处理ARM Cortex-M微控制器的低级硬件接口)的目录

export LIBKINETIS ?= $(wildcard lib/kinetis/NXP_Kinetis_Bootloader_2_0_0) #定义NXP Kinetis系列微处理器的bootloader库路径

MKFLAGS=--no-print-directory #设置Make的选项标志,这里设定不打印进入子目录的消息

export 将文件内的变量导出为环境变量

wildcard 一个Makefile的内置函数用于查找文件或目录

Makefile中的赋值

延迟展开赋值 VAR = value #赋值时立即展开右边的值

FOO = $(BAR)

BAR = hello

all:

        @echo $(FOO)

输出结果为hello


立即展开赋值 VAR := $(shell uname -r) #右侧表达式在赋值时立即求值,后续引用 VAR 时不会重新计算

FOO := $(BAR)
BAR = hello

all:
    @echo $(FOO)
 

条件赋值 VAR ?= default_value #如果 VAR 之前已经被赋值,则不会覆盖

追加赋值 VAR += more_value #追加赋值用于在现有变量的基础上追加新内容


 13
 14 SRC_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
 15
 16 COLOR_BLUE = \033[0;94m
 17 NO_COLOR   = \033[m
 18
 19 define colorecho
 20 +@echo -e '${COLOR_BLUE}${1} ${NO_COLOR}'
 21 endef
 22

SRC_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) #获取当前Makefile所在的目录路径

COLOR_BLUE = \033[0;94m #定义颜色变量,\033[0;94m表示浅蓝色。用法为COLOR_BLUE"AAA",会输出浅蓝色的AAA字符串

NO_COLOR = \033[m #定义无颜色变量,\033[m表示清除颜色

define colorecho #定义名为colorecho的函数

+@echo -e '${COLOR_BLUE}${1} ${NO_COLOR}' #输出特定的颜色${1}是调用colorecho传入的第一个参数,

endef

MAKEFILE_LIST Makefile内置的特殊变量,包含了所有Makefile文件的列表

lastword 函数,取MAKEFILE_LIST中最后一个Makefile文件

realpath 函数,返回输入路径的绝对路径

shell dirname shell是一个Makefile函数,允许用户在Makefile内使用Shell命令;dirname是一个Shell命令,用于提取文件路径的目录部分,dirname /path/to/file会返回/path/to

确保echo命令不会在并行模式下和其他任务同时执行,避免并发问题

@ 抑制echo命令本身的输出,只显示输出结果(带颜色的文本)


 23 #
 24 # Tools
 25 #
 26 export CC                = arm-none-eabi-gcc
 27 export OBJCOPY           = arm-none-eabi-objcopy
 28
 29 #
 30 # Common configuration
 31 #
 32 export FLAGS             = -std=gnu99 \
 33                            -Os \
 34                            -g \
 35                            -Wundef \
 36                            -Wall \
 37                            -fno-builtin \
 38                            -I$(BL_BASE)/$(LIBOPENCM3)/include \
 39                            -I$(BL_BASE)/. \
 40                            -ffunction-sections \
 41                            -nostartfiles \
 42                            -lnosys \
 43                            -Wl,-gc-sections \
 44                            -Wl,-g \
 45                            -Werror
 46

export CC                = arm-none-eabi-gcc #定义编译器变量CC并导出,该变量默认为gcc或clang。arm-none-eabi-gcc是一种交叉编译器,用于编译在arm架构上运行的代码。
export OBJCOPY           = arm-none-eabi-objcopy #定义并导出变量OBJCOPY,objcopy可以将编译生成的目标文件或可执行文件转换为其他格式,例如.ELF——>.bin

export FLAGS = -std=gnu99 \ ...... #定义并导出FLAGS变量,该变量包含了一系列编译选项,用于控制 C 编译器和链接器的行为。因为将多个信息换行,所以有\。

arm-none-eabi-gcc 一种交叉编译器,用于编译在arm架构上运行的代码。

arm-none-eabi-objcopy 是objcopy的交叉编译版本,适用于 ARM 架构的目标系统。

-std=gnu99 指定使用gnu99标准

-Os 优化选项,表示优化代码大小

-g 包含调试信息

-Wundef 启用对未定义宏的警告

-Wall 开启所有常见的警告

-fno-builtin 禁用对编译器内置函数的优化,防止编译器将某些标准函数替换为其内置实现

-I$(BL_BASE)/$(LIBOPENCM3)/include 添加头文件搜索路径,-I是编译器的一个选项,用于指定额外的头文件搜索路径

-I$(BL_BASE)/. 添加当前目录为头文件搜索路径

-ffunction-sections 将每个函数放入单独的section(段)中。使得每个函数有自己独立的内存段,这与链接器的--gc-sections选项结合使用,可以在链接时移除未使用的函数,从而减小最终生成的二进制文件的大小

-nostartfiles 不使用标准的启动文件。告诉链接器不要使用标准C库的启动文件。这个选项通常用于嵌入式系统开发,因为嵌入式系统通常有自己定制的启动代码。

-lnosys  链接 nosys 库,nosys 是一个轻量级库,提供对某些 C 标准库功能的基本支持,但不包含完整的操作系统支持。通常用于没有操作系统的嵌入式环境。

-Wl,-gc-sections 链接器选项,启用垃圾回收未使用的段,用于减小二进制文件大小

-Wl,-g 将调试信息传递给链接器

-Werror 将所有警告视为错误,一旦出现任何警告,编译将终止,并视为错误


 47 ifneq ($(CRYPTO_HAL),)
 48 include crypto_hal/$(CRYPTO_HAL)/Makefile.include
 49 endif
 50
 51 export COMMON_SRCS       = bl.c $(CRYPTO_SRCS)
 52
 53 export ARCH_SRCS         = cdcacm.c  usart.c
 54
 55

ifneq ($(CRYPTO_HAL),) #if not equal,条件判断指令,如果CRYPTO_HAL不等于空
include crypto_hal/$(CRYPTO_HAL)/Makefile.include #包含路径
endif

export COMMON_SRCS = bl.c $(CRYPTO_SRCS) #定义并导出存储源文件列表的变量COMMON_SRCS

export ARCH_SRCS         = cdcacm.c  usart.c #ARCH_SRCS,与特定平台架构有关的变量

cdcacm.c 可能与 USB CDC(Communication Device Class)相关。CDC 通常用于实现串行通信,如虚拟串口(VCP)

usart.c 通常与 USART(Universal Synchronous and Asynchronous Receiver-Transmitter)通信有关。USART 是用于串行数据传输的硬件模块,常用于嵌入式系统的串行通信。


 58 # Note: px4fmuv3_bl is the same as px4fmuv2_bl except for a different USB devic    e
 59 # string
 60 #
 61 TARGETS = \
 62         aerofcv1_bl \
 63         auavx2v1_bl \
 64         avx_v1_bl \
 65         crazyflie21_bl \
 66         crazyflie_bl \
 67         cube_f4_bl \
 68         fmuk66e_bl \
 69         fmuk66v3_bl \
 70         kakutef7_bl \
 71         mindpxv2_bl \
 72         modalai_fc_v1_bl \
 73         modalai_voxl2_io_bl \
 74         omnibusf4sd_bl \
 75         pix32v5_bl \
 76         px4aerocore_bl \
 77         px4discovery_bl \
 78         px4flow_bl \
 79         px4fmu_bl \
 80         px4fmuv2_bl \
 81         px4fmuv3_bl \
 82         px4fmuv4_bl \
 83         px4fmuv4pro_bl \
 84         px4fmuv5_bl \
 85         px4fmuv5x_bl \
 86         px4io_bl \
 87         px4iov3_bl \
 88         smartap_airlink_bl \
 89         smartap_pro_bl \
 90         tapv1_bl \
 91         uvify_core_bl \
 92         atl_mantis_edu_bl \
 93         thepeach_k1_bl \
 94         thepeach_r1_bl
 95
 96 all:    $(TARGETS) sizes
 97

定义了 Makefile 的 TARGETS 变量,其中列出了一系列 bootloader 目标文件。每个目标都代表一个不同的硬件平台或设备的 bootloader。这些目标通常会对应不同的硬件板卡,或者是同一硬件平台的不同版本,可能会有不同的功能配置,如 USB 设备字符串的不同。

这里没有列出px4fmuv6_bl,也就是pixhawk 6C对应的架构,有两种方法:1、看看px4fmuv5_bl和px4fmuv6_bl有什么相似之处,能不能用v5编译的代替;2、在TARGETS中添加px4fmuv6_bl。

all:    $(TARGETS) sizes #all是一个规则名,通常用来定义默认的构建目标。如果你在命令行中运行 make,默认情况下会执行 make all

sizes 通常用于计算和输出生成的二进制文件(例如ELF)或目标文件的大小。

这里要引入Makefile中目标(target)和依赖(dependences)的概念。

目标(Target):表示需要生成的文件或执行的任务。

依赖(Dependencies):目标所依赖的文件或其他目标。

命令(Commands):实现目标的具体步骤,通常是命令行工具的命令,例如 gcccp 等。命令通常使用 Shell 语言。


98 clean:                                                                       
99          cd libopencm3 && make --no-print-directory clean && cd ..           
100         rm -f *.elf *.bin *.map # Remove any elf or bin files contained dire    ctly in the Bootloader directory
101         rm -rf build # Remove build directories
102

clean #定义了一个目标,即要执行的任务,clean后面是目标的具体内容

cd libopencm3 && make --no-print-directory clean && cd .. #进入libopencm3目录并删除该库目录下生成的中间文件和构建产物。--no-print-directory 参数使得执行时不打印该目录的切换信息。

rm -f *.elf *.bin *.map #删除Bootloader目录下的.elf .bin .map文件,-f表示如果文件不存在,也不提示

rm -rf build #删除build目录

103 #
104 # Specific bootloader targets.                                              
105 #                                                                           
106                                                                             
107 fmuk66v3_bl: $(MAKEFILE_LIST) $(LIBKINETIS)                                 
108         ${MAKE} ${MKFLAGS} -f  Makefile.k66 TARGET_HW=FMUK66_V3  LINKER_FILE    =kinetisk66.ld TARGET_FILE_NAME=$@                                          
109                                                                             
110 fmuk66e_bl: $(MAKEFILE_LIST) $(LIBKINETIS)                                  
111         ${MAKE} ${MKFLAGS} -f  Makefile.k66 TARGET_HW=FMUK66_E  LINKER_FILE=    kinetisk66.ld TARGET_FILE_NAME=$@                                           
112                                                                             
113 auavx2v1_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)                                 
114         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=AUAV_X2V1  LINKER_FILE=    stm32f4.ld TARGET_FILE_NAME=$@                                              
115                                                                             
116 kakutef7_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)                                 
117         ${MAKE} ${MKFLAGS} -f  Makefile.f7 TARGET_HW=KAKUTEF7 LINKER_FILE=st    m32f7.ld TARGET_FILE_NAME=$@                                                
118                                                                             
119 pix32v5_bl:$(MAKEFILE_LIST) $(LIBOPENCM3)                                   
120         ${MAKE} ${MKFLAGS} -f  Makefile.f7 TARGET_HW=HOLYBRO_PIX32_V5 LINKER    _FILE=stm32f7.ld TARGET_FILE_NAME=$@                                        
121                                                                             
122 px4fmu_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)                                   
123         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=PX4_FMU_V1 LINKER_FILE=    stm32f4.ld TARGET_FILE_NAME=$@                                              
124                                                                             
125 px4fmuv2_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)                                 
126         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=PX4_FMU_V2  LINKER_FILE    =stm32f4.ld TARGET_FILE_NAME=$@                                             
127                                                                             
128 px4fmuv3_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)                                 
129         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=PX4_FMU_V3  LINKER_FILE    =stm32f4.ld TARGET_FILE_NAME=$@                                             
130                                                                             
131 px4fmuv4_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)                                 
132         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=PX4_FMU_V4  LINKER_FILE    =stm32f4.ld TARGET_FILE_NAME=$@                                             
133                                                                             
134 px4fmuv4pro_bl:$(MAKEFILE_LIST) $(LIBOPENCM3)                               
135         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=PX4_FMU_V4_PRO LINKER_F    ILE=stm32f4.ld TARGET_FILE_NAME=$@ EXTRAFLAGS=-DSTM32F469                   
136                                                                             
137 px4fmuv5_bl:$(MAKEFILE_LIST) $(LIBOPENCM3)                                  
138         ${MAKE} ${MKFLAGS} -f  Makefile.f7 TARGET_HW=PX4_FMU_V5 LINKER_FILE=    stm32f7.ld TARGET_FILE_NAME=$@                                              
139                                                                             
140 px4fmuv5x_bl:$(MAKEFILE_LIST) $(LIBOPENCM3)                                 
141         ${MAKE} ${MKFLAGS} -f  Makefile.f7 TARGET_HW=PX4_FMU_V5X LINKER_FILE    =stm32f7.ld TARGET_FILE_NAME=$@           

fmuk66v3_bl: $(MAKEFILE_LIST) $(LIBKINETIS)
                ${MAKE} ${MKFLAGS} -f  Makefile.k66 TARGET_HW=FMUK66_V3  LINKER_FILE    =kinetisk66.ld TARGET_FILE_NAME=$@         #目标fmuk66v3_bl依赖于MAKEFILE_LIST和LIBKINETIS,指定 Makefile为Makefile.f4,设置目标硬件为 PX4_FMU_V1,使用链接器脚本 stm32f4.ld

MAKEFILE_LIST 一个自动变量,用于记录当前 Makefile 列表中包含的所有 Makefile 文件的名称。它在执行过程中会动态更新,包含每个被处理的 Makefile 的路径

$@ 当前目标的名称,这里就是fmu66v3

MAKE 调用 Make 命令,通常是 make 的别名

-f Makefile.k66 指定使用 Makefile.k66 作为要执行的 Makefile 文件。这允许你针对特定平台或配置进行构建


194 # Default bootloader delay is *very* short, just long enough to catch
195 # the board for recovery but not so long as to make restarting after a      196 # brownout problematic.
197 #                                                                           
198 px4io_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)
199         ${MAKE} ${MKFLAGS} -f  Makefile.f1 TARGET_HW=PX4_PIO_V1 LINKER_FILE=    stm32f1.ld TARGET_FILE_NAME=$@
200
201 px4iov3_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)
202         ${MAKE} ${MKFLAGS} -f  Makefile.f3 TARGET_HW=PX4_PIO_V3 LINKER_FILE=    stm32f3.ld TARGET_FILE_NAME=$@
203                                                                             
204 tapv1_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)
205         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=TAP_V1 LINKER_FILE=stm3    2f4.ld TARGET_FILE_NAME=$@
206                                                                             
207 aerofcv1_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)
208         ${MAKE} ${MKFLAGS} -f  Makefile.f4 TARGET_HW=AEROFC_V1 LINKER_FILE=s    tm32f4.ld TARGET_FILE_NAME=$@
209                                                                             
210 atl_mantis_edu_bl: $(MAKEFILE_LIST) $(LIBOPENCM3)
211         ${MAKE} ${MKFLAGS} -f  Makefile.f7 TARGET_HW=ATL_MANTIS_EDU LINKER_F    ILE=stm32f7.ld TARGET_FILE_NAME=$@
212                                      

 px4io_bl: $(MAKEFILE_LIST) $(LIBOPENCM3) ${MAKE} ${MKFLAGS} -f Makefile.f1 TARGET_HW=PX4_PIO_V1 LINKER_FILE=stm32f1.ld TARGET_FILE_NAME=$@     #用于构建px4io的目标


213 #
214 # Show sizes                                                                
215 #
216 .PHONY: sizes                                                               
217 sizes:
218         @-find build/*/ -name '*.elf' -type f | xargs size 2> /dev/null || :
219

#定义一个伪目标sizes用于显示所有生成的ELF文件的大小

-name '*.elf':只查找以 .elf 为后缀的文件

-type f:指定只查找常规文件(排除目录和其他文件类型)

xargs sizexargs 命令将 find 查找到的文件传递给 size 命令,size 会输出这些 ELF 文件中各个段(如代码段、数据段等)的大小

2> /dev/null:这部分将所有来自标准错误的输出(如错误消息)重定向到 /dev/null,使得终端中不会显示这些错误

|| :  这是一个保护机制。如果 find 没有找到任何 ELF 文件,整个命令可能会失败。|| : 表示即使前面的命令失败(返回非零退出状态),后面执行的命令也会返回成功(: 是一个空操作命令,总是返回成功状态)。 


220 #
221 # Binary management
222 #
223 .PHONY: deploy
224 deploy:
225         zip -j Bootloader.zip build/*/*.bin
226

 #定义了一个名为deploy的伪目标,用于打包所有生成的.bin文件到一个压缩包中。运行 make deploy 后,你将得到一个包含所有 .bin 文件的 Bootloader.zip 压缩包

  • .PHONY .PHONY 是 Makefile 中的一个指示符,表示目标并不实际指向一个文件。它告诉 make,即使文件系统中存在一个叫deploy的文件,make 仍然应将这个目标作为命令而不是文件来处理。这可以避免文件与命令名称冲突带来的问题。
  • zip:这是 Unix/Linux 系统中的命令,用于将文件压缩成 .zip 格式。
  • -j:这是 zip 命令的选项,表示将文件直接压缩进目标 zip 文件中而不保留文件的路径结构。也就是说,即使源文件存在于不同的子目录中,它们在压缩包中将位于根目录。
  • Bootloader.zip:这是压缩后的文件名,生成一个名为 Bootloader.zip 的压缩包。
  • build/*/*.bin:这个模式表示在 build 目录下查找所有子目录中的 .bin 文件并将其添加到压缩包中。具体来说:
    • build/*/:查找 build 目录下的所有子目录。
    • *.bin:查找以 .bin 为后缀的二进制文件。

227 #
228 # Submodule management
229 #
230
231 $(LIBOPENCM3): checksubmodules
232         ${MAKE} -C $(LIBOPENCM3) lib
233
234 .PHONY: checksubmodules
235 checksubmodules:
236         $(Q) ($(BL_BASE)/Tools/check_submodules.sh)
237

$(LIBOPENCM3): checksubmodules #定义目标LIBOPENCM3,依赖为伪目标checksubmodules
            ${MAKE} -C $(LIBOPENCM3) lib #切换到LIBOPENCM3目录,再执行make                        #这个目标是113~211行的目标的依赖

.PHONY: checksubmodules #声明checksubmodules是一个伪目标
checksubmodules:
                $(Q) ($(BL_BASE)/Tools/check_submodules.sh) #执行脚本文件;Q的作用与@类似,如果Q的值为@,则在执行脚本文件的时候不打印该命令,但因为之前没定义Q,其为空字符串,所以会打印命令($(BL_BASE)/Tools/check_submodules.sh)


238 # Astyle
239 # --------------------------------------------------------------------
240 .PHONY: check_format format
241
242 check_format:
243         $(call colorecho,'Checking formatting with astyle')
244         @$(SRC_DIR)/Tools/check_code_style_all.sh
245         @cd $(SRC_DIR) && git diff --check
246
247 format:
248         $(call colorecho,'Formatting with astyle')
249         @$(SRC_DIR)/Tools/check_code_style_all.sh --fix

Makefile中没有明显的针对fmuv6的bootloader,但是根据下面的fmuv5和fmuv5x的编译信息,编译这两个架构需要的是Makefile.f7,可能意味着针对stm32f7芯片,6C的fmu芯片是stm32h743,h7系列。

137 px4fmuv5_bl:$(MAKEFILE_LIST) $(LIBOPENCM3)                                  
138         ${MAKE} ${MKFLAGS} -f  Makefile.f7 TARGET_HW=PX4_FMU_V5 LINKER_FILE=    stm32f7.ld TARGET_FILE_NAME=$@                                              
139                                                                             
140 px4fmuv5x_bl:$(MAKEFILE_LIST) $(LIBOPENCM3)                                 
141         ${MAKE} ${MKFLAGS} -f  Makefile.f7 TARGET_HW=PX4_FMU_V5X LINKER_FILE    =stm32f7.ld TARGET_FILE_NAME=$@    

stm32h743和stm32f7系列的相同点和不同点:

相同点:内核,都是ARM Cortex-M7;开发环境,都可以用stm32CubeMX、stm32CubeIDE开发;调试,都支持SWD(Serial Wire Debug)和JTAG。

不同点:主频,H743——480MHz,F7——216MHz,等等。

最关键的,两者的架构相同。

看看Makefile.f7 

  1 #
  2 # PX4 bootloader build rules for STM32F7 targets.
  3 # Since the STM32F7 is not supported fully in libopencm3 at this time,
  4 # this build is a bit of a hack to use the similar IP blocks of the F469
  5 # for USB by telling libopencm3 it is an STM32F4
  6 ARCH=stm32
  7 OPENOCD         ?= openocd
  8
  9 JTAGCONFIG ?= interface/olimex-jtag-tiny.cfg
 10 #JTAGCONFIG ?= interface/jtagkey-tiny.cfg
 11

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值