该说明,是在windows平台下,ardupilot的版本是3.5.3;
使用eclipse来编译的;编译的时候,要先在eclipse的Make Target窗口中的Ardupilot/ArduCopter目录下
新建编译目标:px4-v2. 编译的时候,双击该px4-v2即可以开始编译.
ArduPlane下面执行 make px4-v2
-> ../mk/apm.mk -> environ.mk
apm.mk中首先加载设置环境变量的mk文件(environ.mk),及其它相关的一个mk文件;
然后再依据被编译的目标对像来调用对应的makefile文件.
***apm.mk =====1.设置MK_DIR变量为源码下面的mk目录.
MK_DIR = ../mk
2.include其它mk文件
3.依据编译目标include下面这些mk文件
environ.mk ---- 用来配置上面提到的环境变量.
针对px4-v2来说,变量值如下:
EXTRAFLAGS=-DGIT_VERSION="\"b8461671\""
SRCROOT = /d/AutoPilot/Firmware/Ardupilot/ArduCopter
SKETCHBOOK= /d/AutoPilot/Firmware/Ardupilot
SKETCH = ArduCopter
BUILDROOT = Build.ArduCopter
HAL_BOARD = HAL_BOARD_PX4
configure.mk --用来响应make configure指令;
help.mk -------用来响应 make help指令,显示帮助信息.
targets.mk ----用来执行目标程序的编译动作,脚本会依据BOARDS和FRAMES
变量定义的关键字来在make的命令行里查找目标,然后编译它;
该文件用来动态生成一个编译依赖关系,通过eval函数;
同时,clean 的动作在此定义;脚本会include modules.mk
和mavgen.mk两个文件;
modules.mk -->用来从git服务器检索子模块源码的完整性,并下载这些子模块;
make module-update 命令在此定义;
所以,如果没有网络,想做离线编译,可以将该mk模块注释掉;
代码更新是通过check_modules.sh来实现的.
mavgen.mk --->生成MAVLINK消息模块,并设置如下变量:
MAVLINK_DIR,MESSAGE_DEFINITIONS,MAVLINK_HEADERS,
MAVLINK_OUTPUT_DIR;用python工具来生成mavlink协议,脚本
文件为:/modules/mavlink/pymavlink/tools/mavgen.py,所以
要分析mavgen.py来理解如何生成及生成的内容.
sketch_sources.mk ---加载所有类型项目的源文件到指定变量,并设置其目标obj文件,
这两个变量为 SKETCHSRCS 和 SKETCHOBJS;
并加载make.inc文件中的列表目录到变量 LIBTOKENS 中,然后
再去添加具体平台相关的库目录;脚本设置如下一些变量:
SKETCHLIBS -------所有库文件路径列表(绝对路径);
SKETCHLIBNAMES ---所有库文件路径列表(相对路径);
SKETCHLIBSRCDIRS--为SKETCHLIBS列表中每一项添加/utility
子路径,因为有些库目录下面还有utility子目录;
SKETCHLIBSRCS-----所有库源文件绝对路径;
SKETCHLIBOBJS-----SKETCHLIBSRCS对应的.o文件,路径在Build目录下面;
SKETCHLIBINCLUDES----所有依据路径(libraries),和GCS_MAVLink路径;
SKETCHLIBSRCSRELATIVE--SKETCHLIBSRCS的相对路径;
接下来,apm.mk会依据编译目标(HAL_BOARD)的不同来加载不同的mk文件,以px4-v2为例,会加载:
board_px4.mk ---- 1.设置变量 TOOLCHAIN = NATIVE
2.加载 find_tools.mk
3.加载px4_targets.mk
find_tools.mk ->配置编译中所使和到工具的路径及名称,使用的都是绝对路径,
如px4-v2:
ARM_CXX := $(call FIND_TOOL,arm-none-eabi-g++)
ARM_CC := $(call FIND_TOOL,arm-none-eabi-gcc)
ARM_AS := $(call FIND_TOOL,arm-none-eabi-gcc)
ARM_AR := $(call FIND_TOOL,arm-none-eabi-ar)
ARM_LD := $(call FIND_TOOL,arm-none-eabi-g++)
ARM_GDB := $(call FIND_TOOL,arm-none-eabi-gdb)
ARM_OBJCOPY := $(call FIND_TOOL,arm-none-eabi-objcopy)
上面指令,通过FIND_TOOL宏来设置工具的绝对路径,从$PATH中找;
而最终的编译工具由下面变量表示:
CXX = $(CCACHE) $($(TOOLCHAIN)_CXX)
CC = $(CCACHE) $($(TOOLCHAIN)_CC)
AS = $($(TOOLCHAIN)_AS)
AR = $($(TOOLCHAIN)_AR)
LD = $($(TOOLCHAIN)_LD)
GDB = $($(TOOLCHAIN)_GDB)
OBJCOPY = $($(TOOLCHAIN)_OBJCOPY)
这里有一个全局临时变量 : CCACHE ,用来加快编译速度,通过
export CCACHE来声名;
***px4_targets.mk--->这个才是最终执行编译的地方;
1.先设置变量:
PX4FIRMWARE_DIRECTORY = modules/PX4Firmware
PX4NUTTX_DIRECTORY = modules/PX4NuttX
UAVCAN_DIRECTORY = modules/uavcan
PX4_ROOT = modules/PX4Firmware
NUTTX_ROOT = modules/PX4Nuttx
NUTTX_SRC = modules/PX4Nuttx/nuttx/
UAVCAN_DIR = modules/uavcan/
还有其它一些编译器相关参数;
2.获取GIT版本,并存储到变量 EXTRAFLAGS中,最终的EXTRAFLAGS值为(针对版本3.5.3):
EXTRAFLAGS=-DGIT_VERSION="\"b8461671\"" -DNUTTX_GIT_VERSION="\"a5146c68\""
-DPX4_GIT_VERSION="\"4e5cccf6\"" -DUAVCAN=1
可以看出,这里一共设置了三个版本值(为了离线编译,本人将版本设成了固定值),且
使能了UAVCAN功能:
GIT_VERSION=b8461671
NUTTX_GIT_VERSION =a5146c68
PX4_GIT_VERSION = 4e5cccf6
UAVCAN=1
设置PX4_V2_CONFIG_FILE = mk/PX4/config_px4fmu-v2_APM.mk
用来指定该版本的固件需要哪些驱动(或Modules),因此,如果有算定义的驱动,可以在此
加入到系统固件中.
3.设置phthon脚本位置,并导出为临时环境变量:
PYTHONPATH=/mk/PX4/Tools/genmsg/src:/mk/PX4/Tools/gencpp/src
4.PX4_MAKE_ARCHIVES变量用来生成内核库文件,执行modules/PX4Firmware下的
Makefile.make,具体指令为:
modules/PX4Firmware/Makefile.make NUTTX_SRC=
modules/PX4Nuttx/nuttx/ CCACHE=
ccache archives MAXOPTIMIZATION="-Os"
5.复制mk/PX4/config_px4fmu-v2_APM.mk 到modules/PX4Firmware/makefiles/nuttx目录下面,
用来告诉nuttx系统需要编译哪些驱动;
6.PX4_MAKE 用来生成PX4平台的目标固件;
$(PX4_MAKE) px4fmu-v2_APM 展开后如下:
$(MAKE) -C $(SKETCHBOOK) -f $(PX4_ROOT)/Makefile.make
EXTRADEFINES="$(SKETCHFLAGS) $(WARNFLAGS)
$(OPTFLAGS) "'$(EXTRAFLAGS)' APM_MODULE_DIR=$(SKETCHBOOK)
SKETCHBOOK=$(SKETCHBOOK) CCACHE=$(CCACHE)
PX4_ROOT=$(PX4_ROOT) NUTTX_SRC=$(NUTTX_SRC)
MAXOPTIMIZATION="-Os" UAVCAN_DIR=$(UAVCAN_DIR) px4fmu-v2_APM
其中px4fmu-v2_APM为编译的目标文件;
通过-C参数来将make的工作目录切换到源码的顶层目录下,然后指定的makefile文件
为modules/PX4Firmware/Makefile.make
7.最后执行 $(PX4_MAKE) px4fmu-v2_APM 来编译目标固件,即:
modules/PX4Firmware/Makefile.make **** px4fmu-v2_APM
***************************************************************
modules/PX4Firmware/Makefile.make 分析
***************************************************************
下面是图片组织顺序关系图,更加简洁表示的调用关系(png版和pdf版,因为导出工具原因便的pdf版的文字更清楚而png版的清楚度不太好,将就着用吧):
Make_Process.png
Make_Process.pdf