PX4开源工程结构简明介绍

PX4开源工程结构简明介绍

  • Step1 获取开源代码
    • 1.1 开源代码版本
    • 1.2 克隆开源代码
  • Step2 了解工程情况
    • 2.1 支持模型类型
    • 2.2 支持特性&功能
    • 2.3 安装&文档链接
    • 2.4 配置工具下载
    • 2.5 其他介绍(略)
  • Step3 Makefile研读
    • 3.1 make help
    • 3.2 Makefile阅读
      • 3.2.1 有效git工程检查
      • 3.2.2 设置默认目标
      • 3.2.3 获取不同os的目标板列表
      • 3.2.4 参数解析
      • 3.2.5 设置job数
      • 3.2.6 ninja构建 or Make构建
      • 3.2.7 源代码路径
      • 3.2.8 replay环境变量检测
      • 3.2.9 CMake选项添加
      • 3.2.10 cmake-build & cmake-cache-check
      • 3.2.11 颜色函数 colorecho
      • 3.2.12 获取所有的飞控的编译文件
      • 3.2.13 定义编译方式
      • 3.2.14 获取 elf 文件大小
      • 3.2.15 定义编译测试
      • 3.2.16 创建uorb消息的订阅发布图
      • 3.2.17 生成文档的编译选项
      • 3.2.18 格式化代码
      • 3.2.19 一些测试编译配置
      • 3.2.20 静态编译分析
      • 3.2.21 clean 选项
      • 3.2.22 过滤Make目标
      • 3.2.23 帮助文件
  • Step4 CMakeLists结构
    • 4.1 CMakeLists顶层脚本结构
    • 4.2 CMakeLists顶层源代码结构
  • Step5 工程目录结构
    • 5.1 目录结构
    • 5.2 Kakute F7 AIO
      • 5.2.1 目标板配置
      • 5.2.2 固件menuconfig
      • 5.2.3 固件编译
  • Step6 工程分析回顾

PX4具有高度可移植性,且是一个不依赖于操作系统的无人机解决方案。

PX4开源工程结构简明介绍_第1张图片

从业界的角度确实是非常优秀且庞大的一款开源软件解决方案,支持的硬件除Pixhawk系列外,还有很多AutoPilot硬件支持厂家,详见链接。

注1:笔者采用的就是Kakute F7 AIO(老版本);新版本采用MPU6000。后续介绍不做特殊说明,默认都是针对这款飞控控制器的一些代码理解。

注2:这款Kakute F7 AIO版本可以使用的开源固件相对来说也比较广泛,比如:Paparazzi/BetaFlight/PX4等等;关于BetaFlight的介绍可以参考链接。

这里依然采用类似方法进行相关工程结构介绍:

  1. 获取开源代码
  2. 了解工程情况
  3. Makefile研读
  4. CMakeLists结构
  5. 工程目录结构
  6. 工程分析回顾

Step1 获取开源代码

1.1 开源代码版本

首先,获取代码的步骤很便捷的,直接通过github下载来获取,要注意的是版本(本次实验采用master最新分支,具体version不用太在意,结构化的东西只要大版本差异不大,基本是类似的)

$ git log -n 1
commit ffb0097052227e1b7dc2665463b6b9de33bbf835 (HEAD -> master, origin/master, origin/HEAD)
Author: CR <christopher.ruwisch@tu-berlin.de>
Date:   Wed Jun 22 21:50:30 2022 +0200

    removed unused code - _constrainOneSide and _constrainAbs
$ git remote -v
origin  https://github.com/PX4/PX4-Autopilot.git (fetch)
origin  https://github.com/PX4/PX4-Autopilot.git (push)

1.2 克隆开源代码

$ git clone https://github.com/PX4/PX4-Autopilot.git 

Step2 了解工程情况

2.1 支持模型类型

目前,支持众多无人机机体类型:

  • 多旋翼(Multicopters)
  • 固定翼(Fixed wing)
  • 垂直起降(VTOL)
  • 旋翼机(Autogyro)
  • 无人车(Rover)
  • 其他模型 (Blimps, Boats, Submarines, High altitude balloons etc.)

2.2 支持特性&功能

  • 基本飞控功能
  • RTK GPS
  • 精准着陆
  • RockBlock SatCom卫通系统
  • 空中交通避障 ADSB/FLARM
  • 自主避障
  • 安全着陆
  • 防撞检测
  • 路径规划

2.3 安装&文档链接

官方的文档链接详见:https://docs.px4.io/master/en/
典型机型的组装指南:https://docs.px4.io/master/en/assembly/

2.4 配置工具下载

QGroundControl下载链接详见:https://docs.qgroundcontrol.com/master/en/getting_started/download_and_install.html
QGroundControl飞控设置链接详见:https://docs.qgroundcontrol.com/master/en/SetupView/SetupView.html

2.5 其他介绍(略)

注:这里暂时先保留下,因为PX4的整体设计是相对复杂的,整个工程也比较复杂,留一个小章节,后续或许再做扩展。


其从框架角度考虑了以下形态的硬件(有兴趣的可以先看看):

  • 飞控
  • RC遥控
  • 伴飞电脑
  • 地面站
  • ROS(Robotic Operation System)

下面是一个复杂应用的硬件构架

  • ROS Enabled Computer:双链路(MAVLink)监控
  • qGroundControl:常用的地面站软件
  • Companion Computer:大量本地复杂计算
  • AutoPilot:飞控+传感器

比如:高精度悬停就需要结合AutoPilot+Companion Computer来计算,常伴有雷达测距和视频分析。
略… 略… 略… 跑题了,这个感觉还是很酷的,值得深入看下里面设计框架。我们后续慢慢深入!!!
PX4开源工程结构简明介绍_第2张图片

Step3 Makefile研读

3.1 make help

首先,看下make help都有哪些动作可以执行。

$ make help
Usage: make 
Where  is one of:

airframe_metadata
airmind_mindpx-v2
all
all_config_targets
all_default_targets
ark_can-flow
ark_can-gps
ark_cannode
ark_can-rtk-gps
atl_mantis-edu
av_x-v1
beaglebone_blue
bitcraze_crazyflie
bitcraze_crazyflie21
bootloaders_update
check
check_format
check_linux
check_nuttx
check_nxp
check_px4
check_rtps
clang-tidy
clang-tidy-fix
clang-tidy-quiet
clean
coverity_scan
cppcheck
cuav_can-gps-v1
cuav_nora
cuav_x7pro
cubepilot_cubeorange
cubepilot_cubeyellow
cubepilot_io-v2
diatone_mamba-f405-mk2
distclean
doxygen
emlid_navio2
extract_events
format
freefly_can-rtk-gps
gazeboclean
help
holybro_can-gps-v1
holybro_durandal-v1
holybro_kakutef7
holybro_kakuteh7
holybro_pix32v5
list_config_targets
matek_gnss-m9n-f4
matek_h743
matek_h743-mini
matek_h743-slim
misc_qgc_extra_firmware
modalai_fc-v1
modalai_fc-v2
module_documentation
mro_ctrl-zero-classic
mro_ctrl-zero-f7
mro_ctrl-zero-f7-oem
mro_ctrl-zero-h7
mro_ctrl-zero-h7-oem
mro_pixracerpro
mro_x21
mro_x21-777
nxp_fmuk66-e
nxp_fmuk66-v3
nxp_fmurt1062-v1
nxp_ucans32k146
omnibus_f4sd
parameters_metadata
px4fmu_firmware
px4_fmu-v2
px4_fmu-v3
px4_fmu-v4
px4_fmu-v4pro
px4_fmu-v5
px4_fmu-v5x
px4_fmu-v6c
px4_fmu-v6u
px4_fmu-v6x
px4io_update
px4_io-v2
px4_metadata
px4_raspberrypi
px4_sitl
px4_sitl_default-clang
python_coverage
qgc_firmware
quick_check
raspberrypi_pico
rostest
rostest_run
scan-build
scumaker_pilotpi
shellcheck_all
sizes
sky-drones_smartap-airlink
spracing_h7extreme
submodulesclean
submodulesupdate
tests
tests_avoidance
tests_coverage
tests_integration
tests_integration_coverage
tests_mission
tests_mission_coverage
tests_offboard
uorb_graphs
updateconfig
update_px4_msgs
update_px4_ros_com
update_ros2_bridge
uvify_core
validate_module_configs

Or, make  []
Use 'make list_config_targets' for a list of configuration targets.

3.2 Makefile阅读

Makefile对于做C开发的同学来说,确实非常的关键。不是说一定要会写,至少得会看。随手一查(哈哈),找到一份资料(希望大家有空可以翻阅):跟我一起写Makefile

希望对大家有帮助,其实在BetaFlight那份资料里面也有链接,可能是不同的网址。总体来说大家可以查,可以理解就好了。

PX4的代码在其根目录有唯一一份Makefile文件,细看下来,了解到工程实际上使用的是CMake工具来构建的。

CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice.

关于Makefile研读部分,看到其实已经有大牛做了介绍,不过有些脚本内容有点出入,这里重新整理下。

同时也采用最新git代码的Makefile。有兴趣的也可以参考下PX4编译文件Makefile剖析。

3.2.1 有效git工程检查

整个git工程里面,是有git submodule管理的。

$ git submodule
 f47ce7b5fbbb3aa43d33d2be1f6cd3746b13d5bf Tools/flightgear_bridge (heads/master)
 66b764ada522893c05224950aa6268c809f8e48a Tools/jMAVSim (heads/master)
 68de2cc63ded9a0d6641d45e9eb3ed2b43454cba Tools/jsbsim_bridge (heads/master)
 483193d9b8b89211c3b970c735b4fbb5f724b63a Tools/simulation-ignition (heads/master)
 5610c3fb441a2f3babc8ad7a63c8c4ce3e40abfa Tools/sitl_gazebo (heads/master)
 6d9010f47e7b00d9d86bbdd4630c78cd8d57ba35 platforms/nuttx/NuttX/apps (nuttx-8.2-1137-g6d9010f47)
 91bece51afbe7da9db12e3695cdbb4f4bba4bc83 platforms/nuttx/NuttX/nuttx (nuttx-8.2-6636-g91bece51af)
 36a01e428b110ff84c8babe5b65667b5e3037d5e src/drivers/cyphal/legacy_data_types (remotes/origin/legacy)
 db87ea32aa092c48ea103963138b6346dd3e9008 src/drivers/cyphal/libcanard (3.0.0)
 d0bd6516dac8ff61287fe49a9f2c75e7d4dc1b8e src/drivers/cyphal/public_regulated_data_types (d0bd651)
 8c09c5426d23ea4db4e462c1f4e3a1de33d253cc src/drivers/gps/devices (heads/master)
 9c09983f737de0dd224d26025f8f439d6d860b27 src/drivers/uavcan/libuavcan (9c09983f)
 673f5ce29015a9bba3c96792920a10601b5b0718 src/lib/crypto/libtomcrypt (1.17-2055-g673f5ce2)
 fd73d7630b9d3ed5a79d613ff680a549e9780de7 src/lib/crypto/libtommath (v1.2.0-247-gfd73d76)
 baca5d31259c598540e4d1284bc8d8f793abf83a src/lib/crypto/monocypher (3.1.2)
 6329c909a7b16bb6f97c94cbb598815635b94982 src/lib/events/libevents (heads/master)
 05864e218e204f1ebeee5555988150fcddbd873e src/modules/mavlink/mavlink (1.0.12-516-g05864e21)
 b5187a9f399e34cda7d2cdce8823295f83d9f3cc src/modules/microdds_client/Micro-XRCE-DDS-Client (v1.0.0beta2-244-gb5187a9)
 21d3cfe3ae570d1674da0105ab23b80958e0449a src/modules/micrortps_bridge/micro-CDR (v1.0.0beta2-54-g21d3cfe)

因此在编译过程中,会检查这些被依赖的git子模块是否已经被下载。当.git目录不存在的时候,就无法进行相应的检查。

34 # Enforce the presence of the GIT repository
35 #
36 # We depend on our submodules, so we have to prevent attempts to
37 # compile without it being present.
38 ifeq ($(wildcard .git),)
39     $(error YOU HAVE TO USE GIT TO DOWNLOAD THIS REPOSITORY. ABORTING.)
40 endif

3.2.2 设置默认目标

显示设置默认的编译目标px4_sitl_default

59 # explicity set default build target
60 all: px4_sitl_default

3.2.3 获取不同os的目标板列表

65 define make_list
66      $(shell [ -f .github/workflows/compile_${1}.yml ] && cat .github/workflows/compile_${1}.yml | sed -E 's|[[:space:]]+(.*),|check_\1|g' | grep check_${2})
67 endef

从这里我们可以看出不同OS平台支持的单板类型。


daniel@daniel-ThinkPad-SL410:~/RCCode/PX4-Autopilot$ ls .github/workflows/compile_*
.github/workflows/compile_linux_arm64.yml  .github/workflows/compile_linux.yml  .github/workflows/compile_macos.yml  .github/workflows/compile_nuttx.yml
daniel@daniel-ThinkPad-SL410:~/RCCode/PX4-Autopilot$ cat .github/workflows/compile_linux_arm64.yml | sed -E 's|[[:space:]]+(.*),|check_\1|g' | grep check_
check_scumaker_pilotpi_arm64
daniel@daniel-ThinkPad-SL410:~/RCCode/PX4-Autopilot$ cat .github/workflows/compile_linux.yml | sed -E 's|[[:space:]]+(.*),|check_\1|g' | grep check_
check_beaglebone_blue_default
check_emlid_navio2_default
check_px4_raspberrypi_default
check_scumaker_pilotpi_default
daniel@daniel-ThinkPad-SL410:~/RCCode/PX4-Autopilot$ cat .github/workflows/compile_macos.yml | sed -E 's|[[:space:]]+(.*),|check_\1|g' | grep check_
check_px4_fmu-v5_default
check_#tests # includes px4_sitl
daniel@daniel-ThinkPad-SL410:~/RCCode/PX4-Autopilot$ cat .github/workflows/compile_nuttx.yml | sed -E 's|[[:space:]]+(.*),|check_\1|g' | grep check_
check_airmind_mindpx-v2
check_ark_can-flow
check_ark_can-gps
check_ark_can-rtk-gps
check_ark_cannode
check_atl_mantis-edu
check_av_x-v1
check_bitcraze_crazyflie
check_bitcraze_crazyflie21
check_cuav_can-gps-v1
check_cuav_nora
check_cuav_x7pro
check_cubepilot_cubeorange
check_cubepilot_cubeyellow
check_diatone_mamba-f405-mk2
check_freefly_can-rtk-gps
check_holybro_can-gps-v1
check_holybro_durandal-v1
check_holybro_kakutef7
check_holybro_kakuteh7
check_holybro_pix32v5
check_matek_gnss-m9n-f4
check_matek_h743
check_matek_h743-mini
check_matek_h743-slim
check_modalai_fc-v1
check_modalai_fc-v2
check_mro_ctrl-zero-f7
check_mro_ctrl-zero-f7-oem
check_mro_ctrl-zero-h7
check_mro_ctrl-zero-h7-oem
check_mro_pixracerpro
check_mro_x21
check_mro_x21-777
check_nxp_fmuk66-e
check_nxp_fmuk66-v3
check_nxp_fmurt1062-v1
check_nxp_ucans32k146
check_omnibus_f4sd
check_px4_fmu-v2
check_px4_fmu-v3
check_px4_fmu-v4
check_px4_fmu-v4pro
check_px4_fmu-v5
check_px4_fmu-v5x
check_px4_fmu-v6c
check_px4_fmu-v6u
check_px4_fmu-v6x
check_raspberrypi_pico
check_sky-drones_smartap-airlink
check_spracing_h7extreme

3.2.4 参数解析

第一个参数是目标板,其他作为入参保存下来(比如:make holybro_kakutef7 menuconfig )

69 # Parsing
70 # --------------------------------------------------------------------
71 # assume 1st argument passed is the main target, the
72 # rest are arguments to pass to the makefile generated
73 # by cmake in the subdirectory
74 FIRST_ARG := $(firstword $(MAKECMDGOALS))
75 ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

3.2.5 设置job数

设置开多少jobs进行Make并行执行。

77 # Get -j or --jobs argument as suggested in:
78 # https://stackoverflow.com/a/33616144/8548472
79 MAKE_PID := $(shell echo $$PPID)
80 j := $(shell ps T | sed -n 's|.*$(MAKE_PID).*$(MAKE).* \(-j\|--jobs\) *\([0-9][0-9]*\).*|\2|p')

3.2.6 ninja构建 or Make构建

设置是否用构建工具ninja生成CMake文件。

由于默认没有设置 NO_NINJA_BUILD,所以会尝试设置编译生成器为Ninja。

如果尝试失败了,则在 windows 上编译生成器目标会设置为 MSYS Makefiles,在 Linux 上则会编译生成器目标会设置为Unix Makefiles。

注:Ninja是一个比 Make 要轻量级的编译系统。

85 NINJA_BIN := ninja
86 ifndef NO_NINJA_BUILD
87 	NINJA_BUILD := $(shell $(NINJA_BIN) --version 2>/dev/null)
88
89 	ifndef NINJA_BUILD
90 		NINJA_BIN := ninja-build
91 		NINJA_BUILD := $(shell $(NINJA_BIN) --version 2>/dev/null)
92 	endif
93 endif
94
95 ifdef NINJA_BUILD
96 	PX4_CMAKE_GENERATOR := Ninja
97 	PX4_MAKE := $(NINJA_BIN)
98
99 	ifdef VERBOSE
100		PX4_MAKE_ARGS := -v
101	else
102		PX4_MAKE_ARGS :=
103	endif
104
105	# Only override ninja default if -j is set.
106	ifneq ($(j),)
107		PX4_MAKE_ARGS := $(PX4_MAKE_ARGS) -j$(j)
108	endif
109 else
110	ifdef SYSTEMROOT
111		# Windows
112		PX4_CMAKE_GENERATOR := "MSYS\ Makefiles"
113	else
114		PX4_CMAKE_GENERATOR := "Unix\ Makefiles"
115	endif
116
117	# For non-ninja builds we default to -j4
118	j := $(or $(j),4)
119	PX4_MAKE = $(MAKE)
120	PX4_MAKE_ARGS = -j$(j) --no-print-directory
121 endif

注:笔者环境已经安装ninjia 1.10.0,所以没有 "Unix\ Makefiles"目录生成。

$ ninja --version
1.10.0

3.2.7 源代码路径

首先,用 lastword 函数获取了当前的 Makefile 的名称,然后用realpath 获取了这个 Makefile 的完整路径,最后调用 shell 的 dirname 命令获取了文件的目录路径:

123 SRC_DIR := $(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))")

3.2.8 replay环境变量检测

一旦有了真正的飞行日志(.px4log),则可以在PX4固件根目录中的使用以下命令来run运行重放

$ make posix_sitl_replay replay logfile=<absolute_path_to_log_file>/my_log_file.px4log
125 # check if replay env variable is set & set build dir accordingly
126 ifdef replay
127 	BUILD_DIR_SUFFIX := _replay
128 else
129 	BUILD_DIR_SUFFIX :=
130 endif

3.2.9 CMake选项添加

给 cmake 添加了一些选项,包括是否包括外部模块, 及 cmake 的build 的类型。

132 # additional config parameters passed to cmake
133 ifdef EXTERNAL_MODULES_LOCATION
134 	CMAKE_ARGS += -DEXTERNAL_MODULES_LOCATION:STRING=$(EXTERNAL_MODULES_LOCATION)
135 endif
136
137 ifdef PX4_CMAKE_BUILD_TYPE
138 	CMAKE_ARGS += -DCMAKE_BUILD_TYPE=${PX4_CMAKE_BUILD_TYPE}
139 else
140
141	# Address Sanitizer
142	ifdef PX4_ASAN
143		CMAKE_ARGS += -DCMAKE_BUILD_TYPE=AddressSanitizer
144	endif
145
146	# Memory Sanitizer
147	ifdef PX4_MSAN
148		CMAKE_ARGS += -DCMAKE_BUILD_TYPE=MemorySanitizer
149	endif
150
151	# Thread Sanitizer
152	ifdef PX4_TSAN
153		CMAKE_ARGS += -DCMAKE_BUILD_TYPE=ThreadSanitizer
154	endif
155
156	# Undefined Behavior Sanitizer
157	ifdef PX4_UBSAN
158		CMAKE_ARGS += -DCMAKE_BUILD_TYPE=UndefinedBehaviorSanitizer
159	endif
160
161	# Fuzz Testing
162	ifdef PX4_FUZZ
163		CMAKE_ARGS += -DCMAKE_BUILD_TYPE=FuzzTesting
164	endif
165
166 endif
167
168 # Pick up specific Python path if set
169 ifdef PYTHON_EXECUTABLE
170 	CMAKE_ARGS += -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
171 endif
172
173 # Check if the microRTPS agent is to be built
174 ifdef BUILD_MICRORTPS_AGENT
175  CMAKE_ARGS += -DBUILD_MICRORTPS_AGENT=ON
176 endif

3.2.10 cmake-build & cmake-cache-check

定义了两个函数:

  • 第一个是后面编译各个选项时主要用到的 cmake-build
  • 另一个是用来检查之前的cmake 编译生成的 cache 是否和当前的编译选项一致的cmake-cache-check

注1:在cmake-build 中调用了cmake-cache-check 来确定是否需要重新生成目录和编译配置文件。
注2:这里就是调用CMakelist.txt的位置,详见3.2.13 定义编译方式。

178 # Functions
179 # --------------------------------------------------------------------
180 # describe how to build a cmake config
181 define cmake-build
182		$(eval CMAKE_ARGS += -DCONFIG=$(1))
183		@$(eval BUILD_DIR = "$(SRC_DIR)/build/$(1)")
184		@# check if the desired cmake configuration matches the cache then CMAKE_CACHE_CHECK stays empty
185		@$(call cmake-cache-check)
186		@# make sure to start from scratch when switching from GNU Make to Ninja
187		@if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ -e $(BUILD_DIR)/Makefile ]; then rm -rf $(BUILD_DIR); fi
188		@# make sure to start from scratch if ninja build file is missing
189		@if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ ! -f $(BUILD_DIR)/build.ninja ]; then rm -rf $(BUILD_DIR); fi
190		@# only excplicitly configure the first build, if cache file already exists the makefile will rerun cmake automatically if necessary
191		@if [ ! -e $(BUILD_DIR)/CMakeCache.txt ] || [ $(CMAKE_CACHE_CHECK) ]; then \
192			mkdir -p $(BUILD_DIR) \
193			&& cd $(BUILD_DIR) \
194			&& cmake "$(SRC_DIR)" -G"$(PX4_CMAKE_GENERATOR)" $(CMAKE_ARGS) \
195			|| (rm -rf $(BUILD_DIR)); \
196		fi
197		@# run the build for the specified target
198		@cmake --build $(BUILD_DIR) -- $(PX4_MAKE_ARGS) $(ARGS)
199 endef
200
201 # check if the options we want to build with in CMAKE_ARGS match the ones which are already configured in the cache inside BUILD_DIR
202 define cmake-cache-check
203		@# change to build folder which fails if it doesn't exist and CACHED_CMAKE_OPTIONS stays empty
204		@# fetch all previously configured and cached options from the build folder and transform them into the OPTION=VALUE format without type (e.g. :BOOL)
205		@$(eval CACHED_CMAKE_OPTIONS = $(shell cd $(BUILD_DIR) 2>/dev/null && cmake -L 2>/dev/null | sed -n 's|\([^[:blank:]]*\):[^[:blank:]]*\(=[^[:blank:]]*\)|\1\2|gp' ))
206		@# transform the options in CMAKE_ARGS into the OPTION=VALUE format without -D
207		@$(eval DESIRED_CMAKE_OPTIONS = $(shell echo $(CMAKE_ARGS) | sed -n 's|-D\([^[:blank:]]*=[^[:blank:]]*\)|\1|gp' ))
208		@# find each currently desired option in the already cached ones making sure the complete configured string value is the same
209		@$(eval VERIFIED_CMAKE_OPTIONS = $(foreach option,$(DESIRED_CMAKE_OPTIONS),$(strip $(findstring $(option)$(space),$(CACHED_CMAKE_OPTIONS)))))
210		@# if the complete list of desired options is found in the list of verified options we don't need to reconfigure and CMAKE_CACHE_CHECK stays empty
211		@$(eval CMAKE_CACHE_CHECK = $(if $(findstring $(DESIRED_CMAKE_OPTIONS),$(VERIFIED_CMAKE_OPTIONS)),,y))
212 endef

3.2.11 颜色函数 colorecho

214 COLOR_BLUE = \033[0;94m
215 NO_COLOR   = \033[m
216
217 define colorecho
218 +@echo -e '${COLOR_BLUE}${1} ${NO_COLOR}'
219 endef

3.2.12 获取所有的飞控的编译文件

221 # Get a list of all config targets boards/*/*.px4board
222 ALL_CONFIG_TARGETS := $(shell find boards -maxdepth 3 -mindepth 3 -name '*.px4board' -print | sed -e 's|boards\/||' | sed -e 's|\.px4board||' | sed -e 's|\/|_|g' | sort)

3.2.13 定义编译方式

定义了所有编译选项的默认编译方式和以_default结尾的编译选项的编译方式。

228 # All targets.
229 $(ALL_CONFIG_TARGETS):
230 	@$(call cmake-build,$@$(BUILD_DIR_SUFFIX))
231
232 # Filter for only default targets to allow omiting the "_default" postfix
233 CONFIG_TARGETS_DEFAULT := $(patsubst %_default,%,$(filter %_default,$(ALL_CONFIG_TARGETS)))
234 $(CONFIG_TARGETS_DEFAULT):
235 	@$(call cmake-build,$@_default$(BUILD_DIR_SUFFIX))
236
237 all_config_targets: $(ALL_CONFIG_TARGETS)
238 all_default_targets: $(CONFIG_TARGETS_DEFAULT)

3.2.14 获取 elf 文件大小

287 .PHONY: sizes check quick_check check_rtps uorb_graphs
288 
289 sizes:
290 	@-find build -name *.elf -type f | xargs size 2> /dev/null || :

3.2.15 定义编译测试

292 # All default targets that don't require a special build environment
293 check: check_px4_sitl_default px4fmu_firmware misc_qgc_extra_firmware tests check_format
294
295 # quick_check builds a single nuttx and SITL target, runs testing, and checks the style
296 quick_check: check_px4_sitl_test check_px4_fmu-v5_default tests check_format
297 
298 check_%:
299 	@echo
300 	$(call colorecho,'Building' $(subst check_,,$@))
301 	@$(MAKE) --no-print-directory $(subst check_,,$@)
302 	@echo

3.2.16 创建uorb消息的订阅发布图

309 uorb_graphs:
310 	@./Tools/uorb_graph/create.py --src-path src --exclude-path src/examples --exclude-path src/lib/parameters --merge-depends --file Tools/uorb_graph/graph_full
311 	@./Tools/uorb_graph/create.py --src-path src --exclude-path src/examples --exclude-path src/lib/parameters --exclude-path src/modules/mavlink --merge-depends --file Tools/uorb_graph/graph_full_no_mavlink
312 	@$(MAKE) --no-print-directory px4_fmu-v2_default uorb_graph
313 	@$(MAKE) --no-print-directory px4_fmu-v4_default uorb_graph
314 	@$(MAKE) --no-print-directory px4_fmu-v5_default uorb_graph
315 	@$(MAKE) --no-print-directory px4_sitl_default uorb_graph

3.2.17 生成文档的编译选项

341 # Documentation
342 # --------------------------------------------------------------------
343 .PHONY: parameters_metadata airframe_metadata module_documentation extract_events px4_metadata doxygen
344
345 parameters_metadata:
346 	@$(MAKE) --no-print-directory px4_sitl_default metadata_parameters ver_gen
347
348 airframe_metadata:
349 	@$(MAKE) --no-print-directory px4_sitl_default metadata_airframes ver_gen
350
351 module_documentation:
352 	@$(MAKE) --no-print-directory px4_sitl_default metadata_module_documentation
353
354 extract_events:
355 	@$(MAKE) --no-print-directory px4_sitl_default metadata_extract_events ver_gen
356
357 px4_metadata: parameters_metadata airframe_metadata module_documentation extract_events
358
359 doxygen:
360 	@mkdir -p "$(SRC_DIR)"/build/doxygen
361 	@cd "$(SRC_DIR)"/build/doxygen && cmake "$(SRC_DIR)" $(CMAKE_ARGS) -G"$(PX4_CMAKE_GENERATOR)" -DCONFIG=px4_sitl_default -DBUILD_DOXYGEN=ON
362 	@$(PX4_MAKE) -C "$(SRC_DIR)"/build/doxygen
363 	@touch "$(SRC_DIR)"/build/doxygen/Documentation/.nojekyll

3.2.18 格式化代码

365 # Astyle
366 # --------------------------------------------------------------------
367 .PHONY: check_format format
368
369 check_format:
370 	$(call colorecho,'Checking formatting with astyle')
371 	@"$(SRC_DIR)"/Tools/astyle/check_code_style_all.sh
372 	@cd "$(SRC_DIR)" && git diff --check
373
374 format:
375 	$(call colorecho,'Formatting with astyle')
376 	@"$(SRC_DIR)"/Tools/astyle/check_code_style_all.sh --fix

3.2.19 一些测试编译配置

378 # Testing
379 # --------------------------------------------------------------------
380 .PHONY: tests tests_coverage tests_mission tests_mission_coverage tests_offboard tests_avoidance
381 .PHONY: rostest python_coverage
382 
383 tests:
384 	$(eval CMAKE_ARGS += -DTESTFILTER=$(TESTFILTER))
385 	$(eval ARGS += test_results)
386 	$(eval ASAN_OPTIONS += color=always:check_initialization_order=1:detect_stack_use_after_return=1)
387 	$(eval UBSAN_OPTIONS += color=always)
388 	$(call cmake-build,px4_sitl_test)
389
390 tests_coverage:
391 	@$(MAKE) clean
392 	@$(MAKE) --no-print-directory tests PX4_CMAKE_BUILD_TYPE=Coverage
393 	@mkdir -p coverage
394 	@lcov --directory build/px4_sitl_test --base-directory build/px4_sitl_test --gcov-tool gcov --capture -o coverage/lcov.info
395
396
397 rostest: px4_sitl_default
398 	@$(MAKE) --no-print-directory px4_sitl_default sitl_gazebo
399
400 tests_integration: px4_sitl_default
401 	@$(MAKE) --no-print-directory px4_sitl_default sitl_gazebo
402 	@$(MAKE) --no-print-directory px4_sitl_default mavsdk_tests
403 	@"$(SRC_DIR)"/test/mavsdk_tests/mavsdk_test_runner.py --speed-factor 20 test/mavsdk_tests/configs/sitl.json
404
405 tests_integration_coverage:
406 	@$(MAKE) clean
407 	@$(MAKE) --no-print-directory px4_sitl_default PX4_CMAKE_BUILD_TYPE=Coverage
408 	@$(MAKE) --no-print-directory px4_sitl_default sitl_gazebo
409 	@$(MAKE) --no-print-directory px4_sitl_default mavsdk_tests
410 	@"$(SRC_DIR)"/test/mavsdk_tests/mavsdk_test_runner.py --speed-factor 20 test/mavsdk_tests/configs/sitl.json
411 	@mkdir -p coverage
412 	@lcov --directory build/px4_sitl_default --base-directory build/px4_sitl_default --gcov-tool gcov --capture -o coverage/lcov.info
413 
414 tests_mission: rostest
415 	@"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_missions.test
416
417 rostest_run: px4_sitl_default
418 	@$(MAKE) --no-print-directory px4_sitl_default sitl_gazebo
419 	@"$(SRC_DIR)"/test/rostest_px4_run.sh $(TEST_FILE) mission:=$(TEST_MISSION) vehicle:=$(TEST_VEHICLE)
420 
421 tests_mission_coverage:
422 	@$(MAKE) clean
423 	@$(MAKE) --no-print-directory px4_sitl_default PX4_CMAKE_BUILD_TYPE=Coverage
424 	@$(MAKE) --no-print-directory px4_sitl_default sitl_gazebo PX4_CMAKE_BUILD_TYPE=Coverage
425 	@"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=VTOL_mission_1 vehicle:=standard_vtol
426 	@$(MAKE) --no-print-directory px4_sitl_default generate_coverage
427
428 tests_offboard: rostest
429 	@"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_offboard_attctl.test
430 	@"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_offboard_posctl.test
431 	@"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_offboard_rpyrt_ctl.test
432
433 tests_avoidance: rostest
434 	@"$(SRC_DIR)"/test/rostest_avoidance_run.sh mavros_posix_test_avoidance.test
435 	@"$(SRC_DIR)"/test/rostest_avoidance_run.sh mavros_posix_test_safe_landing.test
436 
437 python_coverage:
438 	@mkdir -p "$(SRC_DIR)"/build/python_coverage
439 	@cd "$(SRC_DIR)"/build/python_coverage && cmake "$(SRC_DIR)" $(CMAKE_ARGS) -G"$(PX4_CMAKE_GENERATOR)" -DCONFIG=px4_sitl_default -DPYTHON_COVERAGE=ON
440 	@$(PX4_MAKE) -C "$(SRC_DIR)"/build/python_coverage
441 	@$(PX4_MAKE) -C "$(SRC_DIR)"/build/python_coverage metadata_airframes
442 	@$(PX4_MAKE) -C "$(SRC_DIR)"/build/python_coverage metadata_parameters
443 	#@$(PX4_MAKE) -C "$(SRC_DIR)"/build/python_coverage module_documentation # TODO: fix within coverage.py
444 	@coverage combine `find . -name .coverage\*`
445 	@coverage report -m

3.2.20 静态编译分析

448 # static analyzers (scan-build, clang-tidy, cppcheck)
449 # --------------------------------------------------------------------
450 .PHONY: scan-build px4_sitl_default-clang clang-tidy clang-tidy-fix clang-tidy-quiet
451 .PHONY: cppcheck shellcheck_all validate_module_configs
452 
453 scan-build:
454 	@export CCC_CC=clang
455 	@export CCC_CXX=clang++
456 	@rm -rf "$(SRC_DIR)"/build/px4_sitl_default-scan-build
457 	@rm -rf "$(SRC_DIR)"/build/scan-build/report_latest
458 	@mkdir -p "$(SRC_DIR)"/build/px4_sitl_default-scan-build
459 	@cd "$(SRC_DIR)"/build/px4_sitl_default-scan-build && scan-build cmake "$(SRC_DIR)" -GNinja -DCONFIG=px4_sitl_default
460 	@scan-build -o "$(SRC_DIR)"/build/scan-build cmake --build "$(SRC_DIR)"/build/px4_sitl_default-scan-build
461 	@find "$(SRC_DIR)"/build/scan-build -maxdepth 1 -mindepth 1 -type d -exec cp -r "{}" "$(SRC_DIR)"/build/scan-build/report_latest \;
462 
463 px4_sitl_default-clang:
464 	@mkdir -p "$(SRC_DIR)"/build/px4_sitl_default-clang
465 	@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && cmake "$(SRC_DIR)" $(CMAKE_ARGS) -G"$(PX4_CMAKE_GENERATOR)" -DCONFIG=px4_sitl_default -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
466 	@$(PX4_MAKE) -C "$(SRC_DIR)"/build/px4_sitl_default-clang
467
468 clang-tidy: px4_sitl_default-clang
469 	@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -p .
470 
471 # to automatically fix a single check at a time, eg modernize-redundant-void-arg
472 #  % run-clang-tidy-4.0.py -fix -j4 -checks=-\*,modernize-redundant-void-arg -p .
473 clang-tidy-fix: px4_sitl_default-clang
474 	@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -fix -p .
475
476 # modified version of run-clang-tidy.py to return error codes and only output relevant results
477 clang-tidy-quiet: px4_sitl_default-clang
478 	@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -p .
479 
480 # TODO: Fix cppcheck errors then try --enable=warning,performance,portability,style,unusedFunction or --enable=all
481 cppcheck: px4_sitl_default
482 	@mkdir -p "$(SRC_DIR)"/build/cppcheck
483 	@cppcheck -i"$(SRC_DIR)"/src/examples --enable=performance --std=c++14 --std=c99 --std=posix --project="$(SRC_DIR)"/build/px4_sitl_default/compile_commands.json --xml-version=2 2> "$(SRC_DIR)"/build/cppcheck/cppcheck-result.xml > /dev/null
484 	@cppcheck-htmlreport --source-encoding=ascii --file="$(SRC_DIR)"/build/cppcheck/cppcheck-result.xml --report-dir="$(SRC_DIR)"/build/cppcheck --source-dir="$(SRC_DIR)"/src/
485
486 shellcheck_all:
487 	@"$(SRC_DIR)"/Tools/run-shellcheck.sh "$(SRC_DIR)"/ROMFS/px4fmu_common/
488 	@make px4_fmu-v5_default shellcheck
489 
490 validate_module_configs:
491 	@find "$(SRC_DIR)"/src/modules "$(SRC_DIR)"/src/drivers "$(SRC_DIR)"/src/lib -name *.yaml -type f \
492 	-not -path "$(SRC_DIR)/src/lib/mixer_module/*" -not -path "$(SRC_DIR)/src/lib/crypto/libtommath/*" -print0 | \
493 	xargs -0 "$(SRC_DIR)"/Tools/validate_yaml.py --schema-file "$(SRC_DIR)"/validation/module_schema.yaml

3.2.21 clean 选项

主要用来清理上一次的编译结果

495 # Cleanup
496 # --------------------------------------------------------------------
497 .PHONY: clean submodulesclean submodulesupdate gazeboclean distclean
498
499 clean:
500 	@[ ! -d "$(SRC_DIR)/build" ] || find "$(SRC_DIR)/build" -mindepth 1 -maxdepth 1 -type d -exec sh -c "echo {}; cmake --build {} -- clean || rm -rf {}" \; # use generated build system to clean, wipe build directory if it fails
501 	@git submodule foreach git clean -dX --force # some submodules generate build artifacts in source
502 
503 submodulesclean:
504 	@git submodule foreach --quiet --recursive git clean -ff -x -d
505 	@git submodule update --quiet --init --recursive --force || true
506 	@git submodule sync --recursive
507 	@git submodule update --init --recursive --force --jobs 4
508 
509 submodulesupdate:
510 	@git submodule update --quiet --init --recursive --jobs 4 || true
511 	@git submodule sync --recursive
512 	@git submodule update --init --recursive --jobs 4
513 	@git fetch --all --tags --recurse-submodules=yes --jobs=4
514 
515 gazeboclean:
516 	@rm -rf ~/.gazebo/*
517 
518 distclean: gazeboclean
519 	@git submodule deinit --force $(SRC_DIR)
520 	@rm -rf "$(SRC_DIR)/build"
521 	@git clean --force -X "$(SRC_DIR)/msg/" "$(SRC_DIR)/platforms/" "$(SRC_DIR)/posix-configs/" "$(SRC_DIR)/ROMFS/" "$(SRC_DIR)/src/" "$(SRC_DIR)/test/" "$(SRC_DIR)/Tools/"

3.2.22 过滤Make目标

当Make目标不存在,直接停止命令执行,报错!!!同时打印帮助提示。

526 # All other targets are handled by PX4_MAKE. Add a rule here to avoid printing an error.
527 %:
528 	$(if $(filter $(FIRST_ARG),$@), \
529 		$(error "Make target $@ not found. It either does not exist or $@ cannot be the first argument. Use '$(MAKE) help|list_config_targets' to get a list of all possible [configuration] targets."),@#)

3.2.23 帮助文件

列出所有可以选的编译选项

531 # Print a list of non-config targets (based on http://stackoverflow.com/a/26339924/1487069)
532 help:
533 	@echo "Usage: $(MAKE) "
534 	@echo "Where  is one of:"
535 	@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | \
536 		awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | \
537 		egrep -v -e '^[^[:alnum:]]' -e '^($(subst $(space),|,$(ALL_CONFIG_TARGETS)))$$' -e '_default$$' -e '^(Makefile)'
538 	@echo
539 	@echo "Or, $(MAKE)  []"
540 	@echo "Use '$(MAKE) list_config_targets' for a list of configuration targets."
541 
542 # Print a list of all config targets.
543 list_config_targets:
544 	@for targ in $(patsubst %_default,%[_default],$(ALL_CONFIG_TARGETS)); do echo $$targ; done

Step4 CMakeLists结构

4.1 CMakeLists顶层脚本结构

根据 CMake Tutorial的语法,整理主要以下cmake文件,来模块化处理编译需要的功能。

注:相关cmake文件名字基本上表示了其主要用途,详细脚本内容,需要深入的时候我们着重研读并与实际命令和代码结合。

CMakeLists.txt
 ├──> cmake/px4_parse_function_args.cmake
 ├──> cmake/px4_git.cmake
 ├──> cmake/px4_add_module.cmake
 ├──> cmake/px4_config.cmake
 ├──> cmake/kconfig.cmake
 ├──> platforms/${PX4_PLATFORM}/cmake/px4_impl_os.cmake  //Kakute F7 PX4_PLATFORM=nuttx
 ├──>        //Kakute F7 PX4_PLATFORM=nuttx, 有该文件
 ├──> 
 │   ├──> cmake/coverage.cmake
 │   └──> cmake/sanitizers.cmake
 ├──> cmake/ccache.cmake
 ├──> cmake/px4_add_common_flags.cmake
 ├──> <${PX4_BOARD_DIR}/cmake/init.cmake>  //Kakute F7 无该文件
 ├──> cmake/px4_metadata.cmake
 ├──> cmake/gtest/px4_add_gtest.cmake
 ├──> 
 ├──> cmake/x4_add_library.cmake
 ├──> cmake/doxygen.cmake
 ├──> cmake/metadata.cmake
 └──> cmake/package.cmake

4.2 CMakeLists顶层源代码结构

 ├──> add_subdirectory(msg EXCLUDE_FROM_ALL)
 ├──> 
 │   └──> add_subdirectory("${EXTERNAL_MODULES_LOCATION}/src" external_modules)
 │       └──> foreach(external_module ${config_module_list_external})
 │           └──> add_subdirectory(${EXTERNAL_MODULES_LOCATION}/src/${external_module} external_modules/${external_module})
 ├──> add_subdirectory(src/lib EXCLUDE_FROM_ALL)
 ├──> add_subdirectory(platforms/${PX4_PLATFORM}/src/px4)
 ├──> add_subdirectory(platforms EXCLUDE_FROM_ALL)
 ├──> 
 │   └──> add_subdirectory(${PX4_BOARD_DIR})
 ├──> foreach(module ${config_module_list})
 │   └──> add_subdirectory(src/${module})
 ├──> add_subdirectory(src/lib/events EXCLUDE_FROM_ALL)
 ├──> add_subdirectory(src/lib/metadata EXCLUDE_FROM_ALL)
 ├──> 
 │   ├──> [kernel_parameters]
 │   │   ├──> target_link_libraries(kernel_parameters_interface INTERFACE parameters)
 │   │   └──> add_library(kernel_parameters_interface INTERFACE)
 │   └──> [parameters]
 │       ├──> add_subdirectory(src/lib/parameters EXCLUDE_FROM_ALL)
 │       ├──> target_link_libraries(parameters_interface INTERFACE usr_parameters)
 │       └──> add_library(parameters_interface INTERFACE)
 ├──> 
 │   └──> [parameters]
 │       ├──> add_subdirectory(src/lib/parameters EXCLUDE_FROM_ALL)
 │       ├──> target_link_libraries(parameters_interface INTERFACE parameters)
 │       └──> add_library(parameters_interface INTERFACE)
 └──> add_subdirectory(platforms/${PX4_PLATFORM})

注1:如果某个target或subdirectory被设置为EXCLUDE_FROM_ALL属性,那么这个target(或这个subdirectory中的所有target)就会被排除在all target列表之外,这样,当执行默认的make(或nmake)时,这个target(或这个subdirectory中的所有target)就不会被编译。
注2:对于一些实际不需要编译的git仓库, 我们可以使用 IMPORTED 和 INTERFACE 来帮我管理。

Step5 工程目录结构

5.1 目录结构

这里针对PX4工程代码的目录结构进行了功能解释和整理,大体如下:

.

├── boards                  //板级配置及代码
├── build                   //固件构建目录,未编译之前该目录不存在
├── cmake                   //CMake模块化脚本
├── Documentation           //CMake使用doxygen配置文件
├── integrationtests        //集成测试
├── launch                  //launch脚本
├── msg                     //uorb(Micro Object Request Broker), 类似Paparazzi的[Ivy software bus](https://www.eei.cena.fr/products/ivy/)
├── platforms               //Px4基于Nuttx/posix + common的嵌入式平台代码
│   ├── common
│   ├── nuttx
│   └── posix
├── posix-configs           //Posix系统配置时,配置及脚本(随板子有差异)
├── ROMFS                   //Rom文件映像构建配置
├── src                     //业务代码(功能&特性)
│   ├── drivers
│   ├── examples
│   ├── include
│   ├── lib
│   │   ├── airspeed
│   │   ├── avoidance
│   │   ├── battery
│   │   ├── bezier
│   │   ├── button
│   │   ├── cdev
│   │   ├── circuit_breaker
│   │   ├── collision_prevention
│   │   ├── component_information
│   │   ├── controllib
│   │   ├── conversion
│   │   ├── crypto
│   │   ├── drivers
│   │   ├── events
│   │   ├── field_sensor_bias_estimator
│   │   ├── geo
│   │   ├── hysteresis
│   │   ├── l1
│   │   ├── landing_slope
│   │   ├── led
│   │   ├── mathlib
│   │   ├── matrix
│   │   ├── metadata
│   │   ├── mixer
│   │   ├── mixer_module
│   │   ├── motion_planning
│   │   ├── npfg
│   │   ├── parameters
│   │   ├── perf
│   │   ├── pid
│   │   ├── pid_design
│   │   ├── pwm
│   │   ├── rc
│   │   ├── sensor_calibration
│   │   ├── slew_rate
│   │   ├── system_identification
│   │   ├── systemlib
│   │   ├── tecs
│   │   ├── terrain_estimation
│   │   ├── tunes
│   │   ├── version
│   │   ├── weather_vane
│   │   ├── wind_estimator
│   │   └── world_magnetic_model
│   ├── modules
│   │   ├── airship_att_control
│   │   ├── airspeed_selector
│   │   ├── angular_velocity_controller
│   │   ├── attitude_estimator_q
│   │   ├── battery_status
│   │   ├── camera_feedback
│   │   ├── commander
│   │   ├── control_allocator
│   │   ├── dataman
│   │   ├── ekf2
│   │   ├── esc_battery
│   │   ├── events
│   │   ├── flight_mode_manager
│   │   ├── fw_att_control
│   │   ├── fw_autotune_attitude_control
│   │   ├── fw_pos_control_l1
│   │   ├── gimbal
│   │   ├── gyro_calibration
│   │   ├── gyro_fft
│   │   ├── land_detector
│   │   ├── landing_target_estimator
│   │   ├── load_mon
│   │   ├── local_position_estimator
│   │   ├── logger
│   │   ├── mag_bias_estimator
│   │   ├── manual_control
│   │   ├── mavlink
│   │   ├── mc_att_control
│   │   ├── mc_autotune_attitude_control
│   │   ├── mc_hover_thrust_estimator
│   │   ├── mc_pos_control
│   │   ├── mc_rate_control
│   │   ├── microdds_client
│   │   ├── micrortps_bridge
│   │   ├── navigator
│   │   ├── px4iofirmware
│   │   ├── rc_update
│   │   ├── replay
│   │   ├── rover_pos_control
│   │   ├── sensors
│   │   ├── sih
│   │   ├── simulator
│   │   ├── temperature_compensation
│   │   ├── uuv_att_control
│   │   ├── uuv_pos_control
│   │   └── vtol_att_control
│   ├── systemcmds
│   └── templates
├── test                    //测试用例
├── test_data               //测试数据
├── Tools                   //辅助工具
└── validation

5.2 Kakute F7 AIO

5.2.1 目标板配置

针对该飞控板,整理了一下相关信息:

  • 飞控控制板:
  1. 板级包支持路径:PX4_BOARD_DIR=/PX4-Autopilot/boards/holybro/kakutef7
  2. 引导二进制文件:${PX4_BOARD_DIR}/extras/holybro_kakutef7_bootloader.bin
  • 配置信息:
  1. 板级配置:${PX4_BOARD_DIR}/default.px4board
  2. 固件信息:${PX4_BOARD_DIR}/firmware.prototype
  3. 自动生成的menuconfig文件:${PX4_BOARD_DIR}/nuttx-config/nsh/defconfig
  • 应用信息:
  1. 启动脚本:${PX4_BOARD_DIR}/init/rc.board_sensors, ${PX4_BOARD_DIR}/init/rc.board_defaults, ${PX4_BOARD_DIR}/init/rc.board_extras
  2. 链接脚本:${PX4_BOARD_DIR}/nuttx-config/scripts
  3. 代码构成:${PX4_BOARD_DIR}/src/CMakeLists.txt

5.2.2 固件menuconfig

默认配置文件

boards/holybro\kakutef7/nuttx-config/nsh/defconfig

修改后保存配置文件

boards/holybro\kakutef7/nuttx-config/nsh/.config

PX4开源工程结构简明介绍_第3张图片

$ make holybro_kakutef7 menuconfig
[0/1] Re-running CMake...
-- PX4 version: v1.13.0-beta1-293-gffb0097052
-- PX4 config file: /RCCode/PX4-Autopilot/boards/holybro/kakutef7/default.px4board
-- PLATFORM nuttx
-- TOOLCHAIN arm-none-eabi
-- ARCHITECTURE cortex-m7
-- ROMFSROOT px4fmu_common
-- CONSTRAINED_FLASH y
-- NO_HELP y
-- EXTERNAL_METADATA y
-- SERIAL_GPS1 /dev/ttyS3
-- SERIAL_TEL1 /dev/ttyS0
-- SERIAL_TEL2 /dev/ttyS1
-- SERIAL_RC /dev/ttyS4
-- PX4 config: holybro_kakutef7_default
-- PX4 platform: nuttx
-- cmake build type: MinSizeRel
-- ROMFS: ROMFS/px4fmu_common
-- ROMFS:  Adding platforms/nuttx/init/stm32f7/rc.board_arch_defaults -> /etc/init.d/rc.board_arch_defaults
-- ROMFS:  Adding boards/holybro/kakutef7/init/rc.board_defaults -> /etc/init.d/rc.board_defaults
-- ROMFS:  Adding boards/holybro/kakutef7/init/rc.board_sensors -> /etc/init.d/rc.board_sensors
-- ROMFS:  Adding boards/holybro/kakutef7/init/rc.board_extras -> /etc/init.d/rc.board_extras
-- ROMFS:  Adding boards/holybro/kakutef7/extras/holybro_kakutef7_bootloader.bin -> /etc/extras/holybro_kakutef7_bootloader.bin
-- Configuring done
-- Generating done
-- Build files have been written to: /RCCode/PX4-Autopilot/build/holybro_kakutef7_default
[1/3] Running NuttX make menuconfig for nsh
LN: include/arch to arch/arm/include
LN: include/arch/board to /RCCode/PX4-Autopilot/platforms/nuttx/NuttX/nuttx/../../../../boards/holybro/kakutef7/nuttx-config/include
LN: include/arch/chip to arch/arm/include/stm32f7
LN: arch/arm/src/board to /RCCode/PX4-Autopilot/platforms/nuttx/NuttX/nuttx/../../../../boards/holybro/kakutef7/nuttx-config/src
LN: arch/arm/src/chip to arch/arm/src/stm32f7
LN: /RCCode/PX4-Autopilot/platforms/nuttx/NuttX/nuttx/drivers/platform to /RCCode/PX4-Autopilot/platforms/nuttx/NuttX/nuttx/drivers/dummy
LN: platform/board to /RCCode/PX4-Autopilot/platforms/nuttx/NuttX/apps/platform/dummy


Your configuration changes were NOT saved.

[2/3] Running make nuttx_menuconfig then savedefconfig for nsh
LN: include/arch/board to /RCCode/PX4-Autopilot/platforms/nuttx/NuttX/nuttx/../../../../boards/holybro/kakutef7/nuttx-config/include
LN: platform/board to /RCCode/PX4-Autopilot/platforms/nuttx/NuttX/apps/platform/dummy

5.2.3 固件编译

$ make holybro_kakutef7
-- PX4 version: v1.13.0-beta1-293-gffb0097052
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.8.10", minimum required is "3")
-- PX4 config file: /RCCode/PX4-Autopilot/boards/holybro/kakutef7/default.px4board
-- PLATFORM nuttx
-- TOOLCHAIN arm-none-eabi
-- ARCHITECTURE cortex-m7
-- ROMFSROOT px4fmu_common
-- CONSTRAINED_FLASH y
-- NO_HELP y
-- EXTERNAL_METADATA y
-- SERIAL_GPS1 /dev/ttyS3
-- SERIAL_TEL1 /dev/ttyS0
-- SERIAL_TEL2 /dev/ttyS1
-- SERIAL_RC /dev/ttyS4
-- PX4 config: holybro_kakutef7_default
-- PX4 platform: nuttx
-- cmake build type: MinSizeRel
-- The CXX compiler identification is GNU 9.2.1
-- The C compiler identification is GNU 9.2.1
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
-- Check for working CXX compiler: /usr/bin/arm-none-eabi-g++
-- Check for working CXX compiler: /usr/bin/arm-none-eabi-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- ROMFS: ROMFS/px4fmu_common
-- ROMFS:  Adding platforms/nuttx/init/stm32f7/rc.board_arch_defaults -> /etc/init.d/rc.board_arch_defaults
-- ROMFS:  Adding boards/holybro/kakutef7/init/rc.board_defaults -> /etc/init.d/rc.board_defaults
-- ROMFS:  Adding boards/holybro/kakutef7/init/rc.board_sensors -> /etc/init.d/rc.board_sensors
-- ROMFS:  Adding boards/holybro/kakutef7/init/rc.board_extras -> /etc/init.d/rc.board_extras
-- ROMFS:  Adding boards/holybro/kakutef7/extras/holybro_kakutef7_bootloader.bin -> /etc/extras/holybro_kakutef7_bootloader.bin
-- Configuring done
-- Generating done
-- Build files have been written to: /RCCode/PX4-Autopilot/build/holybro_kakutef7_default
[6/636] git submodule src/modules/mavlink/mavlink
[9/636] git submodule platforms/nuttx/NuttX/nuttx
[11/636] Generating Mavlink standard: src/modules/mavlink/mavlink/message_definitions/v1.0/standard.xml
Validating /RCCode/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/standard.xml
Parsing /RCCode/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/standard.xml
Validating /RCCode/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/common.xml
Parsing /RCCode/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/common.xml
Validating /RCCode/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/minimal.xml
Parsing /RCCode/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/minimal.xml
Found 219 MAVLink message types in 3 XML files
Generating C implementation in directory /RCCode/PX4-Autopilot/build/holybro_kakutef7_default/mavlink/standard
Generating C implementation in directory /RCCode/PX4-Autopilot/build/holybro_kakutef7_default/mavlink/common
Generating C implementation in directory /RCCode/PX4-Autopilot/build/holybro_kakutef7_default/mavlink/minimal
Copying fixed headers for protocol 2.0 to /RCCode/PX4-Autopilot/build/holybro_kakutef7_default/mavlink
[634/636] Linking CXX executable holybro_kakutef7_default.elf
Memory region         Used Size  Region Size  %age Used
            itcm:          0 GB      2016 KB      0.00%
           flash:      871433 B       928 KB     91.70%
            dtcm:          0 GB       128 KB      0.00%
           sram1:       32812 B       368 KB      8.71%
           sram2:          0 GB        16 KB      0.00%
[636/636] Creating /RCCode/PX4-Autopilot/build/holybro_kakutef7_default/holybro_kakutef7_default.px4
  • 二进制固件:
$ ls build/holybro_kakutef7_default/holybro_kakutef7_default.* -lhs
852K -rwxrwxr-x 1 daniel daniel 852K Jul  1 06:48 build/holybro_kakutef7_default/holybro_kakutef7_default.bin
 19M -rwxrwxr-x 1 daniel daniel  19M Jul  1 06:48 build/holybro_kakutef7_default/holybro_kakutef7_default.elf
3.9M -rw-rw-r-- 1 daniel daniel 3.9M Jul  1 06:48 build/holybro_kakutef7_default/holybro_kakutef7_default.map
788K -rw-rw-r-- 1 daniel daniel 787K Jul  1 06:48 build/holybro_kakutef7_default/holybro_kakutef7_default.px4

Step6 工程分析回顾

总体来说:国内PX4的介绍的文章相对来说比较多,且官网上也有比较详细的介绍。

后续考虑:

  1. 在第二层或以后层次的CMakeLists.txt与模块代码分析时,深入了解CMake的脚本语言。
  2. 在源代码架构的角度理解PX4整体设计是如何做模块化切割,应用了哪些API切割技术(通常我们采用的是函数API、消息API来解耦)。
  3. 在无人机应用方面PX4是怎样从更高的维度来解决实际应用问题的。

暂时写这些把,后续围绕PX4开源软件框架简明简介展开。

你可能感兴趣的:(PX4,git,bash,linux,gcc,make)