pixhawk make文件分析

2023-05-16

由于笔者没学过Linux等系统,对make文件所知甚少,本节分析可能有大量错误,只提供参考,随着技术积累,以后会回过头改正错误的地方,也非常欢迎提出指导意见。

其中分析大多数参考网上解释,加上自己的理解,对make源码逐行阅读并做了相关注释和分析。

统一规定:红字是注释分析;代码部分左边是程序,右边是注释。

下面开始分析

首先打开ardupilot/Arducopter/makefile

include ../mk/apm.mk  

引用其他mk所以去看看apm.mk是什么

# find the mk/ directory, which is where this makefile fragment
# lives. (patsubst strips the trailing slash.)
SYSTYPE			:=	$(shell uname)     系统环境是win还是Linux?

下述程序是为了根据系统的类型确定不同的工作目录MK_DIR

我们始终需要记住一件事,那就是我们在哪个目录编译,以及我们的编译命令。编译目录为: ardupilot/ArduCopter,编译命令我们用的是make px4”,但我们也可以改变命令编译我们需要的。

ifneq ($(findstring CYGWIN, $(SYSTYPE)),)   ifeq (<arg1>, <arg2>)比较参数“arg1”和“arg2”的值是否相同,
  (判断系统环境是否不为CYGWIN)                      不同为真;ifneq (<arg1>, <arg2>),相同为真
                                    $(findstring find,in)  
                                    $(findstring a,a b c)  $(findstring a,b c)  结果分别为‘a’ and ‘’
MK_DIR := $(shell cygpath -m ../mk)   cygpath用于转换Unix和Windows的格式路径  
                                    -m, --mixed  like --windows, but with regular slashes (C:/WINNT)
                                    -w, --windows         print Windows form of NAMEs (C:\WINNT)
else
MK_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) $应该是取值的意思
         根据gnu make定义,gnu make 会自动将所有读取的makefile路径都会加入到MAKEFILE_LIST变量中, 
               而且是按照读取的先后顺序添加。例如
#If a makefile named Makefile has this content:

name1 := $(lastword $(MAKEFILE_LIST))

include inc.mk

name2 := $(lastword $(MAKEFILE_LIST))

all:
        @echo name1 = $(name1)
        @echo name2 = $(name2)
#then you would expect to see this output:

#name1 = Makefile
#name2 = inc.mk

格式:$(patsubst ,,)
名称:模式字符串替换函数——patsubst
功能:查找中的单词(单词以空格“Tab”回车”“换行分隔)是否符合模式,如果匹配的话,则以替换。这里,可以包括通配符“%”,表示任意长度的字串。如果中也包含“%”,那么,中的这个“%”将是中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)
返回:函数返回被替换过后的字符串。
示例:
$(patsubst %.c,%.o,x.c.c bar.c)
把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”
dir是提取路径

$(dir src/foo.c hacks)
#produces the result ‘src/ ./’.

所以$(patsubst%/,%,$(dir $(lastword $(MAKEFILE_LIST))))返回了当前的mk路径,到这里也就得出了 MK_DIR 信息。

endif
include $(MK_DIR)/environ.mk     添加environ.mk文件,关键的环境变量在里面实现

# short-circuit build for the configure target
ifeq ($(MAKECMDGOALS),configure) 如果编译参数是configure,则添加configure.mk
include $(MK_DIR)/configure.mk    configure.mk的内容为
configure:
else                                       @echo "make configure is no longer required"
                                      所以可以直接执行下面的程序
# short-circuit build for the help target
include $(MK_DIR)/help.mk         添加help.mk   help.mk的内容主要是打印一些信息,对理解pixhawk程序有点帮助

# common makefile components     添加常用makefile
include $(MK_DIR)/targets.mk     添加targets.mk
include $(MK_DIR)/sketch_sources.mk    添加sketch_sources.mk

ifneq ($(MAKECMDGOALS),clean)    判断命令不为clean是否为真

# board specific includes         根据板子添加相应的.mk文件
ifeq ($(HAL_BOARD),HAL_BOARD_SITL)
include $(MK_DIR)/board_native.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_LINUX)
include $(MK_DIR)/board_linux.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_PX4)
include $(MK_DIR)/board_px4.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_VRBRAIN)
include $(MK_DIR)/board_vrbrain.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_FLYMAPLE)
include $(MK_DIR)/board_flymaple.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_QURT)
include $(MK_DIR)/board_qurt.mk
endif

endif

endif

这个时候可能我们会很迷惑, $(HAL_BOARD)的值到底是多少?

    但其实我们在执行“make px4”命令编译的时候会有一行信息:

HAL_BOARD=HAL_BOARD_PX4HAL_BOARD_SUBTYPE= TOOLCHAIN=NATIVEEXTRAFLAGS=-DGIT_VERSION="b6d361a3" -DNUTTX_GIT_VERSION="eba6b56f"-DPX4_GIT_VERSION="cf208916"

这行信息非常清楚地告诉了我们用的是“$(MK_DIR)/board_px4.mk”文件。

所以apm.mk根据各种判断,添加environ.mk文件(关键的环境变量在里面实现), 添加help.mk(打印相关信息),添加targets.mk,添加sketch_sources.mk,添加board_px4.mk

接下来就分别分析environ.mk,targets.mk,sketch_sources.mk,board_px4.mk


environ.mk  关键的环境变量在里面实现

windows下的环境变量简单来说就是将某些数据,文件或文件夹设置为系统默认值,这样你调用的时候就不用给出完整路径和地址或进行设置,直接用名字就可以了。

这里实现的是查找 SKETCHBOOK 的位置,根据源文件路径判断 SKETCH 名称, 算出要 build 的哪里,建立 BUILDROOT 目录,根据编译参数确定 HAL_BOARD 类型,等等为系统实现做基础工作。

以下是部分代码分析:

GIT_VERSION := $(shell git rev-parse HEAD | cut -c1-8)   获得git 版本

#
# Locate the sketch sources based on the initial Makefile's path
#
SRCROOT			:=	$(realpath $(dir $(firstword $(MAKEFILE_LIST)))) 通过判断是否有libraries来获取当前
ifneq ($(findstring CYGWIN, $(SYSTYPE)),)                             make的真实路径,不存在则返回为空
  # Workaround a $(realpath ) bug on Cygwin                    libraries下的测试 makefile都是指向apm
  ifeq ($(SRCROOT),)
    SRCROOT	:=	$(shell cygpath -m ${CURDIR})
    $(warning your realpath function is not working)
    $(warning > setting SRCROOT to $(SRCROOT))
  endif
endif

#
# We need to know the location of the sketchbook.  If it hasn't been overridden,
# try the parent of the current directory.  If there is no libraries directory
# there, assume that we are in a library's examples directory and try backing up
# further.             通过判断是否有libraries来获取当前SKETCHBOOK的位置
#                       查找SKETCHBOOK的位置
ifeq ($(SKETCHBOOK),) wildcard通配符,如:列出该目录下所有的C文件为$(wildcard *.c)
  SKETCHBOOK		:=	$(shell cd $(SRCROOT)/.. && pwd) 
  ifeq ($(wildcard $(SKETCHBOOK)/libraries),) 此位置为该项目的根目录
    SKETCHBOOK		:=	$(shell cd $(SRCROOT)/../.. && pwd)
  endif
  ifeq ($(wildcard $(SKETCHBOOK)/libraries),)
    SKETCHBOOK		:=	$(shell cd $(SRCROOT)/../../.. && pwd)
  endif
  ifeq ($(wildcard $(SKETCHBOOK)/libraries),)
    SKETCHBOOK		:=	$(shell cd $(SRCROOT)/../../../.. && pwd)
  endif
  ifeq ($(wildcard $(SKETCHBOOK)/libraries),)
    $(error ERROR: cannot determine sketchbook location - please specify on the commandline with SKETCHBOOK=<path>)
  endif
else
  ifeq ($(wildcard $(SKETCHBOOK)/libraries),)
    $(warning WARNING: sketchbook directory $(SKETCHBOOK) contains no libraries)
  endif
endif
ifneq ($(findstring CYGWIN, $(SYSTYPE)),) 如果是在win平台,转换为win格式的路径
    # Convert cygwin path into a windows normal path
    SKETCHBOOK	:= $(shell cygpath ${SKETCHBOOK})
endif

ifneq ($(wildcard $(SKETCHBOOK)/config.mk),) 如果config.mk不是空,include他
$(info Reading $(SKETCHBOOK)/config.mk)
include $(SKETCHBOOK)/config.mk
endif

ifneq ($(wildcard $(SKETCHBOOK)/developer.mk),) 如果developer.mk不是空,include他
$(info Reading $(SKETCHBOOK)/developer.mk)
include $(SKETCHBOOK)/developer.mk
endif

#
# Work out the sketch name from the name of the source directory.
#找出是哪个sketch,他的名字
SKETCH			:=	$(lastword $(subst /, ,$(SRCROOT))) 根据源文件路径判断SKETCH名称
# Workaround a $(lastword ) bug on Cygwin               subst是将源文件路径中所有的/替换为空格。
ifeq ($(SKETCH),)
  WORDLIST		:=	$(subst /, ,$(SRCROOT))
  SKETCH		:=	$(word $(words $(WORDLIST)),$(WORDLIST))
Endif

#
# Work out where we are going to be building things
#算出哪是我们要build的事
TMPDIR			?=	/tmp

ifneq ($(findstring px4, $(MAKECMDGOALS)),)
# when building px4 we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it
BUILDROOT		:=	$(SKETCHBOOK)/Build.$(SKETCH) 建立BUILDROOT目录:根据编译目标$(MAKECMDGOALS)建
Endif                                                    立相关目录,如果编译目标不匹配,建立临时目录。

ifneq ($(findstring vrbrain, $(MAKECMDGOALS)),)
# when building vrbrain we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it
BUILDROOT		:=	$(SKETCHBOOK)/Build.$(SKETCH)
endif

ifneq ($(findstring vrubrain, $(MAKECMDGOALS)),)
# when building vrbrain we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it
BUILDROOT		:=	$(SKETCHBOOK)/Build.$(SKETCH)
endif

ifneq ($(findstring vrhero, $(MAKECMDGOALS)),)
# when building vrbrain we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it
BUILDROOT		:=	$(SKETCHBOOK)/Build.$(SKETCH)
Endif

ifneq ($(APPDIR),) 
# this is a recusive PX4 build
HAL_BOARD = HAL_BOARD_PX4
endif

# handle target based overrides for board type根据编译参数确定HAL_BOARD类型。
ifneq ($(findstring px4, $(MAKECMDGOALS)),) 
HAL_BOARD = HAL_BOARD_PX4
endif

ifneq ($(findstring sitl, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_SITL
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif

ifneq ($(findstring linux, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_NONE
endif

board_px4.mk文件代码

TOOLCHAIN = NATIVE
include $(MK_DIR)/find_tools.mk        
include $(MK_DIR)/px4_targets.mk

find_tools.mk就是寻找编译工具
FIND_TOOL    =  $(firstword $(wildcard $(addsuffix /$(1),$(TOOLPATH)))) 快速查找

px4_targets.mk
部分代码分析
NUTTX_GIT_VERSION := $(shell cd $(NUTTX_SRC) && git rev-parse HEAD | cut -c1-8) 获取NUTTX_GIT_VERSION
PX4_GIT_VERSION:= $(shell cd $(PX4_ROOT) && git rev-parse HEAD | cut -c1-8) 及PX4_GIT_VERSION版本

EXTRAFLAGS += -DNUTTX_GIT_VERSION="\"$(NUTTX_GIT_VERSION)\""  添加EXTRAFLAGS
EXTRAFLAGS += -DPX4_GIT_VERSION="\"$(PX4_GIT_VERSION)\""  = 是最基本的赋值   := 是覆盖之前的值
EXTRAFLAGS += -DUAVCAN=1                               ?= 是如果没有被赋值过就赋予等号后面的值 
                                                       += 是添加等号后面的值
PX4_V2_CONFIG_FILE=$(MK_DIR)/PX4/config_px4fmu-v2_APM.mk      更新PX4_V2_CONFIG_FILE配置文件
在这里又调用了px4_common.mk,这是一个很重要的东西;如定义了ROMFS_ROOT,定义了BUILTIN_COMMANDS,其中strip为去除空格;

SKETCHFLAGS=$(SKETCHLIBINCLUDES) -DARDUPILOT_BUILD -DTESTS_MATHLIB_DISABLE -DCONFIG_HAL_BOARD=HAL_BOARD_PX4 -DSKETCHNAME="\\\"$(SKETCH)\\\"" -DSKETCH_MAIN=ArduPilot_main -DAPM_BUILD_DIRECTORY=APM_BUILD_$(SKETCH)

WARNFLAGS = -Wall -Wextra -Wlogical-op -Werror -Wno-unknown-pragmas -Wno-redundant-decls -Wno-psabi -Wno-packed -Wno-error=double-promotion -Wno-error=unused-variable -Wno-error=reorder -Wno-error=float-equal -Wno-error=pmf-conversions -Wno-error=missing-declarations -Wno-error=unused-function
OPTFLAGS = -fsingle-precision-constant
定义SKETCHFLAGS/WARNFLAGS/OPTFLAGS,其中-D表示为define,-I为添加库

PYTHONPATH=$(SKETCHBOOK)/mk/PX4/Tools/genmsg/src:$(SKETCHBOOK)/mk/PX4/Tools/gencpp/src确定PYTHONPATH路径

PX4_MAKE = $(v)+ GIT_SUBMODULES_ARE_EVIL=1 ARDUPILOT_BUILD=1 $(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)
PX4_MAKE_ARCHIVES = $(MAKE) -C $(PX4_ROOT) -f $(PX4_ROOT)/Makefile.make NUTTX_SRC=$(NUTTX_SRC) CCACHE=$(CCACHE) archives MAXOPTIMIZATION="-Os"
定义PX4_MAKE及PX4_MAKE_ARCHIVES
$(MAKE) –C  表示进入指定文件夹执行
$(PX4_ROOT)/Makefile.make  编译PX4原生代码的

HASHADDER_FLAGS += --ardupilot "$(SKETCHBOOK)" 添加HASHADDER_FLAGS
ifneq ($(wildcard $(PX4_ROOT)),)
HASHADDER_FLAGS += --px4 "$(PX4_ROOT)"
endif
ifneq ($(wildcard $(NUTTX_SRC)/..),)
HASHADDER_FLAGS += --nuttx "$(NUTTX_SRC)/.."
endif
HASHADDER_FLAGS += --uavcan "$(UAVCAN_DIR)"

.PHONY: module_mk
module_mk:            生成module_mk
$(v) echo "Building $(SKETCHBOOK)/module.mk"
$(RULEHDR)
$(v) echo "# Auto-generated file - do not edit" > $(SKETCHBOOK)/module.mk.new
$(v) echo "MODULE_COMMAND = ArduPilot" >> $(SKETCHBOOK)/module.mk.new
$(v) echo "SRCS = $(wildcard $(SRCROOT)/*.cpp) $(SKETCHLIBSRCSRELATIVE)" >>$(SKETCHBOOK)/module.mk.new
$(v) echo "MODULE_STACKSIZE = 4096" >> $(SKETCHBOOK)/module.mk.new
$(v) echo "EXTRACXXFLAGS = -Wframe-larger-than=1300" >> $(SKETCHBOOK)/module.mk.new
	$(v) cmp $(SKETCHBOOK)/module.mk $(SKETCHBOOK)/module.mk.new 2>/dev/null || mv $(SKETCHBOOK)/module.mk.new $(SKETCHBOOK)/module.mk
$(v) rm -f $(SKETCHBOOK)/module.mk.new

px4-v2: $(BUILDROOT)/make.flags CHECK_MODULES $(MAVLINK_HEADERS)   最后建立px4的相关目标$(PX4_ROOT)/Archives/px4fmu-v2.export $(SKETCHCPP) module_mk px4-io-v2
	$(RULEHDR)           注意:px4-v2的依赖条件中包含了$(SKETCHCPP),从这里调用该工程下的源文件;
	$(v) cp $(PX4_V2_CONFIG_FILE) $(PX4_ROOT)/makefiles/nuttx/   cp  复制copy
	$(PX4_MAKE) px4fmu-v2_APM
	$(v) arm-none-eabi-size $(PX4_ROOT)/Build/px4fmu-v2_APM.build/firmware.elf
	$(v) cp $(PX4_ROOT)/Images/px4fmu-v2_APM.px4 $(SKETCH)-v2.px4
	$(v) $(SKETCHBOOK)/Tools/scripts/add_git_hashes.py $(HASHADDER_FLAGS) "$(SKETCH)-v2.px4" "$(SKETCH)-v2.px4"
	$(v) echo "PX4 $(SKETCH) Firmware is in $(SKETCH)-v2.px4"

这个步骤就是编译 px4fmu-v2_APM的过程,仔细分析这段代码

首先 通过 echo 命令将 $(xxx) 真正意思打印出来,分别用 1 7 对应起来
echo "1$(BUILDROOT) 2$(MAVLINK_HEADERS) 3$(PX4_ROOT) 4$(PX4_V2_CONFIG_FILE)5$(PX4_MAKE) 6$(SKETCH) 7$(SKETCHBOOK)"
1/c/ardupilot/Build.ArduCopter 2/c/ardupilot/Build.ArduCopter/libraries/GCS_MAVLink/include/mavlink/v1.0/ardupilotmega/mavlink.h   
3/c/ardupilot/modules/PX4Firmware 
4../mk/PX4/config_px4fmu-v2_APM.mk 
5@+ GIT_SUBMODULES_ARE_EVIL=1 ARDUPILOT_BUILD=1 make -C /c/ardupilot -f /c/ardupilot/modules/PX4Firmware/Makefile.make EXTRADEFINES=-I/c/ardupilot/libraries/ -I/c/ardupilot/Build.ArduCopter/libraries/ -I/c/ardupilot/Build.ArduCopter/libraries/GCS_MAVLink/ -DARDUPILOT_BUILD -DTESTS_MATHLIB_DISABLE -DCONFIG_HAL_BOARD=HAL_BOARD_PX4 -DSKETCHNAME=\"ArduCopter\" -DSKETCH_MAIN=ArduPilot_main -DAPM_BUILD_DIRECTORY=APM_BUILD_ArduCopter -Wall -Wextra -Wlogical-op -Werror -Wno-unknown-pragmas -Wno-redundant-decls -Wno-psabi -Wno-packed -Wno-error=double-promotion -Wno-error=unused-variable -Wno-error=reorder -Wno-error=float-equal -Wno-error=pmf-conversions -Wno-error=missing-declarations -Wno-error=unused-function -fsingle-precision-constant '-DGIT_VERSION="3c5287e8" -I/c/ardupilot/libraries/AP_Common/missing -DNUTTX_GIT_VERSION="579e82d4" -DPX4_GIT_VERSION="55491083" -DUAVCAN=1 -DHAVE_STD_NULLPTR_T=0 -I/c/ardupilot/Build.ArduCopter/libraries/GCS_MAVLink/include/mavlink' APM_MODULE_DIR=/c/ardupilot SKETCHBOOK=/c/ardupilot CCACHE= PX4_ROOT=/c/ardupilot/modules/PX4Firmware NUTTX_SRC=/c/ardupilot/modules/PX4NuttX/nuttx/ MAXOPTIMIZATION=-Os UAVCAN_DIR=/c/ardupilot/modules/uavcan/ 
6ArduCopter 
7/c/ardupilot

然后根据脚本的语法,可知主要是$(PX4_MAKE)px4fmu-v2_APM完成编译任务

$(PX4_MAKE)真正意思对应上面第5条,再根据脚本基本语法可知

make-C /c/ardupilot -f /c/ardupilot/modules/PX4Firmware/Makefile.make主要完成编译任务

-D是定义、-I是添加库、=是赋值

由此可定位到/c/ardupilot/modules/PX4Firmware/Makefile.make

但是Makefile.make文件里没有px4fmu-v2_APM的目标,说明目标被处理过了。于是只好去看编译输出信息

%%%%
%%%% Building px4fmu-v2_APM in /c/ardupilot/modules/PX4Firmware/Build/px4fmu-v2_APM.build/
%%%%

通过这串信息,匹配到了这样一个目标

#
# Generate FIRMWARES.
#
.PHONY: $(FIRMWARES)
$(BUILD_DIR)%.build/firmware.px4: config   = $(patsubst $(BUILD_DIR)%.build/firmware.px4,%,$@)
$(BUILD_DIR)%.build/firmware.px4: work_dir = $(BUILD_DIR)$(config).build/
$(FIRMWARES): $(BUILD_DIR)%.build/firmware.px4:	generateuorbtopicheaders checksubmodules
	@$(ECHO) %%%%
	@$(ECHO) %%%% Building $(config) in $(work_dir)
	@$(ECHO) %%%%
	$(Q) $(MKDIR) -p $(work_dir)
	$(Q)+ $(MAKE) -r -C $(work_dir) \               从这开始,完成编译工作
		-f $(PX4_MK_DIR)firmware.mk \               语句尾部“\”表示语句连接
		CONFIG=$(config) \
		WORK_DIR=$(work_dir) \
		$(FIRMWARE_GOAL)
$(PX4_MK_DIR)firmware.mk的真正意思是/c/ardupilot/modules/PX4Firmware/makefiles/firmware.mk

这样就定位到firmware.mk文件  此处主要分析px4_targets.mkfirmware.mk文件内容较多,下节再分析。

px4-io-v2: $(PX4_ROOT)/Archives/px4io-v2.export
	$(v)+ $(MAKE) -C $(PX4_ROOT) -f $(PX4_ROOT)/Makefile.make px4io-v2_default EXTRADEFINES="-DARDUPILOT_BUILD"
	$(v) cp $(PX4_ROOT)/Images/px4io-v2_default.bin px4io-v2.bin
	$(v) cp $(PX4_ROOT)/Build/px4io-v2_default.build/firmware.elf px4io-v2.elf
	$(v) mkdir -p $(MK_DIR)/PX4/ROMFS/px4io/        mkdir  创建目录
	$(v) cp px4io-v2.bin $(MK_DIR)/PX4/ROMFS/px4io/px4io.bin
	$(v) mkdir -p $(MK_DIR)/PX4/ROMFS/bootloader/
	$(v) cp $(SKETCHBOOK)/mk/PX4/bootloader/px4fmuv2_bl.bin $(MK_DIR)/PX4/ROMFS/bootloader/fmu_bl.bin
	$(v) echo "PX4IOv2 Firmware is in px4io-v2.bin"
实际的内容是
make -C /e/ardupilot/modules/PX4Firmware px4io-v2_default 编译firmware基本文件
/bin/rm -f px4io-v2.bin
cp /e/ardupilot/modules/PX4Firmware/Build/px4io-v2_default.build/firmware.bin px4io-v2.bin
cp /e/ardupilot/modules/PX4Firmware/Images/px4io-v2_default.bin px4io-v2.bin
cp /e/ardupilot/modules/PX4Firmware/Build/px4io-v2_default.build/firmware.elf px4io-v2.elf
mkdir -p ../mk/PX4/ROMFS/px4io/
rm -f ../mk/PX4/ROMFS/px4io/px4io.bin
cp px4io-v2.bin ../mk/PX4/ROMFS/px4io/px4io.bin
mkdir -p ../mk/PX4/ROMFS/bootloader/
rm -f ../mk/PX4/ROMFS/bootloader/fmu_bl.bin
cp /c/ardupilot/mk/PX4/bootloader/px4fmuv2_bl.bin ../mk/PX4/ROMFS/bootloader/fmu_bl.bin
PX4IOv2 Firmware is in px4io-v2.bin
生成.bin .elf 文件

.NOTPARALLEL: \
	$(PX4_ROOT)/Archives/px4fmu-v1.export \
	$(PX4_ROOT)/Archives/px4fmu-v2.export \
	$(PX4_ROOT)/Archives/px4fmu-v4.export \
	$(PX4_ROOT)/Archives/px4io-v1.export \
	$(PX4_ROOT)/Archives/px4io-v2.export
NOTPARALLEL 新语法: Makefile 中,如果出现目标“ .NOPARALLEL ”,则所有命令按照串行方式执行,即使存在 make 的命令行参数“ -j ”。但在递归调用的字 make 进程中,命令可以并行执行。此目标不应该有依赖文件,所有出现的依赖文件将被忽略。

px4_targets.mk

px4_common.mk添加驱动、系统命令等模块

firmware.mk  注释:GenericMakefile for PX4 firmware images. 通用MakefilePX4固件镜像。

include $(MK_DIR)/setup.mk     /c/ardupilot/modules/PX4Firmware/makefiles/setup.mk
目的是Get path and tool config 即设置路径和tool
include $(PX4_MK_DIR)/$(PX4_TARGET_OS).mk  /c/ardupilot/modules/PX4Firmware/makefiles/nuttx.mk
目的是Rules and definitions related to handling the NuttX export archives when building firmware.
即Nuttx输出的相关规则和定义
# Make a list of the object files we expect to build from modules
# Note that this path will typically contain a double-slash at the WORK_DIR boundary; this must be
# preserved as it is used below to get the absolute path for the module.mk file correct.
#
MODULE_OBJS		:= $(foreach path,$(dir $(MODULE_MKFILES)),$(WORK_DIR)$(path)module.pre.o)

# rules to build module objects
.PHONY: $(MODULE_OBJS)
$(MODULE_OBJS):		relpath = $(patsubst $(WORK_DIR)%,%,$@)
$(MODULE_OBJS):		mkfile = $(patsubst %module.pre.o,%module.mk,$(relpath))
$(MODULE_OBJS):		workdir = $(@D)
$(MODULE_OBJS):		$(GLOBAL_DEPS) $(NUTTX_CONFIG_HEADER)
	$(Q) $(MKDIR) -p $(workdir)
	$(Q)+ $(MAKE) -r -f $(PX4_MK_DIR)module.mk \
		-C $(workdir) \
		MODULE_WORK_DIR=$(workdir) \
		MODULE_OBJ=$@ \
		MODULE_MK=$(mkfile) \
		MODULE_NAME=$(lastword $(subst /, ,$(workdir))) \
		Module

这段是moduleobj文件生成规则,规定了module的路径、makefile文件路径、工作目录等,并生成obj文件


# make a list of phony clean targets for modules
MODULE_CLEANS		:= $(foreach path,$(dir $(MODULE_MKFILES)),$(WORK_DIR)$(path)/clean)

# rules to clean modules
.PHONY: $(MODULE_CLEANS)
$(MODULE_CLEANS):	relpath = $(patsubst $(WORK_DIR)%,%,$@)
$(MODULE_CLEANS):	mkfile = $(patsubst %clean,%module.mk,$(relpath))
$(MODULE_CLEANS):
	@$(ECHO) %% cleaning using $(mkfile)
	$(Q)+ $(MAKE) -r -f $(PX4_MK_DIR)module.mk \
	MODULE_WORK_DIR=$(dir $@) \
	MODULE_MK=$(mkfile) \
	Clean

这段是clean module的规则,清除的路径、makefile的路径。

# Make a list of the archive files we expect to build from libraries
# Note that this path will typically contain a double-slash at the WORK_DIR boundary; this must be
# preserved as it is used below to get the absolute path for the library.mk file correct.
#
LIBRARY_LIBS		:= $(foreach path,$(dir $(LIBRARY_MKFILES)),$(WORK_DIR)$(path)library.a)

# rules to build module objects
.PHONY: $(LIBRARY_LIBS)
$(LIBRARY_LIBS):	relpath = $(patsubst $(WORK_DIR)%,%,$@)
$(LIBRARY_LIBS):	mkfile = $(patsubst %library.a,%library.mk,$(relpath))
$(LIBRARY_LIBS):	workdir = $(@D)
$(LIBRARY_LIBS):	$(GLOBAL_DEPS) $(NUTTX_CONFIG_HEADER)
	$(Q) $(MKDIR) -p $(workdir)
	$(Q)+ $(MAKE) -r -f $(PX4_MK_DIR)library.mk \
		-C $(workdir) \
		LIBRARY_WORK_DIR=$(workdir) \
		LIBRARY_LIB=$@ \
		LIBRARY_MK=$(mkfile) \
		LIBRARY_NAME=$(lastword $(subst /, ,$(workdir))) \
		Library

这段是库的obj文件生成规则,规定了库的路径、makefile文件路径、工作目录等,并生成obj文件


# make a list of phony clean targets for modules
LIBRARY_CLEANS		:= $(foreach path,$(dir $(LIBRARY_MKFILES)),$(WORK_DIR)$(path)/clean)

# rules to clean modules
.PHONY: $(LIBRARY_CLEANS)
$(LIBRARY_CLEANS):	relpath = $(patsubst $(WORK_DIR)%,%,$@)
$(LIBRARY_CLEANS):	mkfile = $(patsubst %clean,%library.mk,$(relpath))
$(LIBRARY_CLEANS):
	@$(ECHO) %% cleaning using $(mkfile)
	$(Q)+ $(MAKE) -r -f $(PX4_MK_DIR)library.mk \
	LIBRARY_WORK_DIR=$(dir $@) \
	LIBRARY_MK=$(mkfile) \
	clean

这段是clean 库的规则,清除的路径、makefile的路径。


以下是直接复制的,主要实现相关的编译功能,有相应的注释。

################################################################################
# Builtin command list generation
################################################################################

#
# Builtin commands can be generated by the configuration, in which case they
# must refer to commands that already exist, or indirectly generated by modules
# when they are built.
#
# The configuration supplies builtin command information in the BUILTIN_COMMANDS
# variable. Applications make empty files in $(WORK_DIR)/builtin_commands whose
# filename contains the same information.
#
# In each case, the command information consists of four fields separated with a
# period. These fields are the command's name, its thread priority, its stack size
# and the name of the function to call when starting the thread.
#
# BUILTIN_COMMANDS
#	Contains a list of built-in commands not explicitly provided
#	by modules / libraries. Each entry in this list is formatted
#	as <command>.<priority>.<stacksize>.<entrypoint>
BUILTIN_CSRC		 = $(WORK_DIR)builtin_commands.c

# command definitions from modules (may be empty at Makefile parsing time...)
MODULE_COMMANDS		 = $(subst COMMAND.,,$(notdir $(wildcard $(WORK_DIR)builtin_commands/COMMAND.*)))

# We must have at least one pre-defined builtin command in order to generate
# any of this.
#
ifneq ($(BUILTIN_COMMANDS),)

# (BUILTIN_PROTO,<cmdspec>,<outputfile>)
define BUILTIN_PROTO
	$(ECHO) 'extern int $(word 4,$1)(int argc, char *argv[]);' >> $2;
endef

# (BUILTIN_DEF,<cmdspec>,<outputfile>)
define BUILTIN_DEF
	$(ECHO) '    {"$(word 1,$1)", $(word 2,$1), $(word 3,$1), $(word 4,$1)},' >> $2;
endef

# Don't generate until modules have updated their command files
$(BUILTIN_CSRC):	$(GLOBAL_DEPS) $(MODULE_OBJS) $(MODULE_MKFILES) $(BUILTIN_COMMAND_FILES)
	@$(ECHO) "CMDS:    $@"
	$(Q) $(ECHO) '/* builtin command list - automatically generated, do not edit */' > $@
	$(Q) $(ECHO) '#include <nuttx/config.h>' >> $@
	$(Q) $(ECHO) '#include <nuttx/binfmt/builtin.h>' >> $@
	$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@))
	$(Q) $(foreach spec,$(MODULE_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@))
	$(Q) $(ECHO) 'const struct builtin_s g_builtins[] = {' >> $@
	$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@))
	$(Q) $(foreach spec,$(MODULE_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@))
	$(Q) $(ECHO) '    {NULL, 0, 0, NULL}' >> $@
	$(Q) $(ECHO) '};' >> $@
	$(Q) $(ECHO) 'const int g_builtin_count = $(words $(BUILTIN_COMMANDS) $(MODULE_COMMANDS));' >> $@

SRCS			+= $(BUILTIN_CSRC)

EXTRA_CLEANS		+= $(BUILTIN_CSRC)

endif
endif

################################################################################
# Default SRCS generation     
################################################################################

#
# If there are no SRCS, the build will fail; in that case, generate an empty
# source file.
#
ifeq ($(SRCS),)
EMPTY_SRC		 = $(WORK_DIR)empty.c
$(EMPTY_SRC):
	$(Q) $(ECHO) '/* this is an empty file */' > $@

SRCS			+= $(EMPTY_SRC)
endif

################################################################################
# Build rules
################################################################################

ifeq ($(PX4_TARGET_OS),nuttx)
#
# What we're going to build.
#
PRODUCT_BUNDLE		 = $(WORK_DIR)firmware.px4
PRODUCT_BIN		 = $(WORK_DIR)firmware.bin
PRODUCT_ELF		 = $(WORK_DIR)firmware.elf
PRODUCT_PARAMXML = $(WORK_DIR)/parameters.xml

.PHONY:			firmware
firmware:		$(PRODUCT_BUNDLE)
endif

#
# Object files we will generate from sources
#
OBJS			:= $(foreach src,$(SRCS),$(WORK_DIR)$(src).o)

#
# SRCS -> OBJS rules        将源文件编译成obj文件
#

$(OBJS):		$(GLOBAL_DEPS)

$(filter %.c.o,$(OBJS)): $(WORK_DIR)%.c.o: %.c $(GLOBAL_DEPS)
	$(call COMPILE,$<,$@)

$(filter %.cpp.o,$(OBJS)): $(WORK_DIR)%.cpp.o: %.cpp $(GLOBAL_DEPS)
	$(call COMPILEXX,$<,$@)

$(filter %.S.o,$(OBJS)): $(WORK_DIR)%.S.o: %.S $(GLOBAL_DEPS)
	$(call ASSEMBLE,$<,$@)

ifeq ($(PX4_TARGET_OS),nuttx)
#
# Built product rules
#

$(PRODUCT_BUNDLE):	$(PRODUCT_BIN)
	@$(ECHO) %% Generating $@
ifdef GEN_PARAM_XML
	$(Q) $(PYTHON) $(PX4_BASE)/Tools/px_process_params.py --src-path $(PX4_BASE)/src --board CONFIG_ARCH_BOARD_$(CONFIG_BOARD) --xml
	$(Q) $(MKFW) --prototype $(IMAGE_DIR)/$(BOARD).prototype \
		--git_identity $(PX4_BASE) \
		--parameter_xml $(PRODUCT_PARAMXML) \
		--image $< > $@
else
	$(Q) $(MKFW) --prototype $(IMAGE_DIR)/$(BOARD).prototype \
		--git_identity $(PX4_BASE) \
		--image $< > $@
endif

$(PRODUCT_BIN):		$(PRODUCT_ELF)
	$(call SYM_TO_BIN,$<,$@)

$(PRODUCT_ELF):		$(OBJS) $(MODULE_OBJS) $(LIBRARY_LIBS) $(GLOBAL_DEPS) $(LINK_DEPS) $(MODULE_MKFILES)
	$(call LINK,$@,$(OBJS) $(MODULE_OBJS) $(LIBRARY_LIBS))

#
# Utility rules         实用的规则
#

.PHONY: upload
upload:	$(PRODUCT_BUNDLE) $(PRODUCT_BIN)
	$(Q) $(MAKE) -f $(PX4_MK_DIR)/upload.mk \
		METHOD=serial \
		CONFIG=$(CONFIG) \
		BOARD=$(BOARD) \
		BUNDLE=$(PRODUCT_BUNDLE) \
		BIN=$(PRODUCT_BIN)

.PHONY: clean
clean:			$(MODULE_CLEANS)
	@$(ECHO) %% cleaning
	$(Q) $(REMOVE) $(PRODUCT_BUNDLE) $(PRODUCT_BIN) $(PRODUCT_ELF)
	$(Q) $(REMOVE) $(OBJS) $(DEP_INCLUDES) $(EXTRA_CLEANS)
	$(Q) $(RMDIR) $(NUTTX_EXPORT_DIR)
endif

# Include the OS specific build rules
# The rules must define the "firmware" make target
#

ifeq ($(PX4_TARGET_OS),nuttx)
# TODO
# Move above nuttx specific rules to $(MK_DIR)/nuttx_romfs.mk
endif
ifeq ($(PX4_TARGET_OS),posix)
include $(MK_DIR)/posix_elf.mk
endif
ifeq ($(PX4_TARGET_OS),qurt)
include $(MK_DIR)/qurt_elf.mk
endif

#
# DEP_INCLUDES is defined by the toolchain include in terms of $(OBJS)
#
-include $(DEP_INCLUDES)

通过firmware.mk文件阅读,终于知道.px4是如何编译出来的了,如何添加lib、module,从而用于裁剪程序。其实.mk文件只是将ccs或者kile等软件的编译工作完成,自行设置编译规则、编译什么文件、分配芯片占用空间等等。至于具体程序的裁剪,若在.mk文件中去掉lib或者module,最后下载进板子的程序就不会有这部分内容,就没法运行;若.mk添加了,但在rcS、Rc.APM中不启动,只是占有了板子内存,并没有运行。

targets.mk,sketch_sources.mk 暂时先放着



如果您觉得此文对您的发展有用,请随意打赏。 
您的鼓励将是笔者书写高质量文章的最大动力^_^!!


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pixhawk make文件分析 的相关文章

  • PX4/PixHawk无人机飞控应用开发

    最近做的一个国防背景的field UAV项目 xff0c 细节不能多谈 xff0c 简单写点技术体会 1 PX4 Pixhawk飞控软件架构简介 PX4是目前最流行的开源飞控板之一 PX4的软件系统实际上就是一个firmware xff0c
  • pixhawk mc_pos_control.cpp源码解读

    好久没跟新blog了 xff0c 这段时期边调试边看程序 xff0c 所以有点慢 要开始着手调试了 这篇blog是顺着上一篇pixhawk 整体架构的认识写的 xff0c 接下来看程序的话 xff0c 打算把各个功能模块理解一遍 xff0c
  • pixhawk position_estimator_inav.cpp思路整理及数据流

    写在前面 xff1a 这篇blog主要参考pixhawk的高度解算算法解读 xff0c 并且加以扩展 xff0c 扩展到其他传感器 xff0c 其实里面处理好多只是记录了流程 xff0c 至于里面实际物理意义并不是很清楚 xff0c 也希望
  • 转:make cmake和catkin_make的区别

    程序在cmake编译是这样的流程 cmake指令依据你的CMakeLists txt 文件 生成makefiles文件 make再依据此makefiles文件编译链接生成可执行文件 catkin make是将cmake与make的编译方式做
  • catkin_make命令

    catkin make是在catkin工作区中构建代码的便捷工具 catkin make遵循catkin工作区的标准布局 xff0c 如REP 128中所述 用法 假设您的catkin工作区位于 catkin ws中 xff0c 则应始终在
  • catkin_make

    普通情况下编译文件都是使用cmake make工具 xff0c 与此有关的内容可以参考 xff1a cmake CMakeLists txt make makefile的关系 但ROS中还有catkin make xff0c 不清楚他们之间
  • cmake, make, CMakeLists.txt, Makefile简介

    文章目录 cmake make CMakeList txt Makefile之间的关系参考文章链接 xff1a 转自个人博客 在各种开源项目中 xff0c 经常会发现项目中除了代码源文件 xff0c 还包含了 CMakeList txt M
  • APM(pixhawk)飞控疑难杂症解决方法汇总(持续更新)

    原文链接 xff1a http www nufeichuiyun com p 61 28
  • DroneKit教程(三):连接Pixhawk飞控

    DroneKit教程 xff08 三 xff09 xff1a 连接Pixhawk飞控 DroneKit提供了非常简便的代码 xff0c 可通过多种方式与飞控连接 连接飞控 使用DroneKit中的connect函数 xff0c 可以方便地连
  • 树莓派3B使用mavlink串口连接PIXHAWK_V5

    参考网址 xff1a http ardupilot org dev docs raspberry pi via mavlink html https dev px4 io en robotics dronekit html https do
  • make与cmake入门

    文章目录 1 手动链接与编译2 make编译工具2 1 介绍makefile2 2 makefile三要素2 3 make工作原理2 4 实战案例1案例2案例3案例4 2 5 常见的自动化变量解析 3 使用cmake进行编译3 1 介绍cm
  • On make and cmake

    你或许听过好几种 Make 工具 xff0c 例如 GNU Make xff0c QT 的 qmake xff0c 微软的MS nmake xff0c BSD Make xff08 pmake xff09 xff0c Makepp xff0
  • pixhawk之NSH调试

    一 ardupilot固件 windows环境 前期准备 1 xff1a pix烧录程序 xff0c Arducopter或者library中的example都可以实现 2 xff1a 拔掉SD卡 xff08 脚本中提到的没有SD卡进入ns
  • make和cmake

    编程人员已经使用CMake和Make很长一段时间了 当你加入一家大公司或者开始在一个具有大量代码的工程上开展工作时 xff0c 你需要注意所有的构建 你需要看到处跳转的 CMakeLists txt 文件 你应该会在终端使用 cmake 和
  • 如何实现make工具的降版本?

    为什么要降make版本 因为编译MTK 平台的Android source code报错 而且是莫名奇妙的错误 困扰很久 一 问题背景 Ubuntu 15 04以上的make版本都已经是4 0 官方目前推荐的编译环境还是基于Ubuntu 1
  • 从零开始学习makefile(4)makefile中%、$@、$<、$^的作用

    目录 示例 头文件fun h main cpp fun cpp makefile 与 lt 是通配符 https www quora com What does o cpp in a Makefile mean是这样描述 的作用的 for
  • CMake编程实践(五) 编译静态库和动态库

    使用Cmake 编译库 本篇使用CMake编译一个动态库和静态库 并安装到系统中 对应的工程是cmake utilsbox lib 编译静态库 指定编译静态库 关键词为static 不添加关键字默认静态库 add library utils
  • VSCode+arm-none-eabi+msys使用Make实现STM32交叉编译

    记录一下在Windows平台下 利用VSCode的arm none eabi扩展和msys使用Make实现STM32的交叉编译 准备 1 安装arm none eabi扩展 在VSCode的扩展窗口 搜索eabi 安装windows arm
  • Android.mk的使用以及常用模板

    Android mk使用 一个Android mk file首先必须定义好LOCAL PATH变量 它用于在开发树中查找源文件 在这个例子中 宏函数 my dir 由编译系统提供 用于返回当前路径 即包含Android mk file文件的
  • 【小沐学C++】C++ 常用命令行开发工具(Linux)

    文章目录 1 简介 2 gcc g 2 1 system 执行shell 命令 2 2 popen 建立管道I O 2 3 vfork exec 新建子进程 3 clang 3 1 下载和安装clang 3 2 clang和gcc比较 3

随机推荐

  • JS 防抖与节流的原理分析和代码手写

    目录 前言 作用 防抖 使用场景 分析原理 手写代码 节流 使用场景 原理分析 手写代码 小补充 前言 前一段时间 xff0c 我学习了 JS 的防抖与节流 xff0c 自认为掌握住了它们 xff0c 当我在做面试题的时候 xff0c 遇到
  • ELK-日志收集系统在Centos上环境安装

    ELK 日志收集系统在Centos上环境安装 文章目录 ELK 日志收集系统在Centos上环境安装 前言安装elastcsearch6 5 4安装准备学习资料启动创建新用户取掉只能本机访问的配置配置跨域访问启动命令测试 安装分词ik安装e
  • Linux环境下下载pydicom

    Linux中只要使用命令即可 sudo pip install pydicom 如果出现sudo xff1a pip xff1a command not found 把sudo去掉 xff0c 再操作一次 因为在执行Linux命令时 xff
  • C语言编程实现汉诺塔问题

    C语言编程实现汉诺塔问题 1 首先解释一下 xff0c 汉诺塔问题 xff1a 古代梵塔内有A B C3个座 xff0c 开始时A座上面有64个盘子 xff0c 盘子大小不等 xff0c 大的在下 xff0c 小的在上 一个老和尚想把64个
  • ORA-28000: the account is locked

    原因 xff1a Oracle账户多次以错误密码登录 xff0c 导致数据库服务器宕机 xff0c 账户被锁定 以系统账户sys 登录Oracle xff0c 查看sql SELECT FROM DBA PROFILES WHERE RES
  • Docker镜像编译方式

    1 普通Dockerfile的缺点 我们通常情况下要编译Spring Boot的Docker镜像 xff0c 一般会写一个下面这样的Dockerfile FROM openjdk span class token operator span
  • Python入门第一章笔记 从安装到编写hello world

    1 下载Python安装包 xff1b 可以到官网下载 xff1a https www python org 但是如果没有翻墙的话 xff0c 下载会很慢 25M安装包 xff0c 需要1个小时以上 如果没有耐心等可以在csdn进行下载 x
  • 养老产业政策链接

    江西省养老政策文件 xff1a 江西省养老服务条例 http mzw ganzhou gov cn gzsmzjy c103172 202201 d238525b35bb47b49b3de312c9b63a60 shtml 南昌市养老服务体
  • 我多变的2013

    我多变的2013 第一篇 xff1a 回顾 回顾工作 首先简单的做个自我介绍吧 xff0c 我是87年的 xff0c 北漂已经是第5个年头了 xff0c 一直都从事java开发工作 前后只换过一家公司 xff0c 第一家待了近两年 xff0
  • 我花1200大洋所学的“元学习课”究竟学了些什么?

    我花1200大洋所学的 元学习课 究竟学了些什么 xff1f 讲课的是台湾的一位大牛名叫Xdite xff0c 以及亿万富豪李笑来 能够跟牛人学习怎么学习我想应该不会有错吧 xff0c 对我来说这次做的应该是一次正确的决定 xff0c 所谓
  • 成长记录-开启我的新生 (2016-12-06)

    真的是很惊险 xff0c 我差一点就错过了 获得新生 的机会 xff0c 我在蜻蜓音频中听到了逻辑思维 xff0c 从逻辑思维中了解到了 得到 xff0c 从 得到 中订阅了吴军博士的 硅谷来信 xff0c 却在过去的好几个月里 xff0c
  • 最新Java电子书

    最新Java电子书 JAVA参考大全 J2SE 5EDITION 世界级程序设计大师作品 Thinking in Java第三版 43 第四版 xff08 中文版 43 习题答案 xff09 Java数据库高级编程宝典 Java核心技术第八
  • ELK-ElasticSearch权威指南笔记

    ELK ElasticSearch笔记 文章目录 ELK ElasticSearch笔记 前言测试工具 语法索引 xff0c 文档和类型文档元数据检索索引里文档数据查看当前节点的所有 Index查看所有index的mapping 映射 查看
  • 关于JAVA中内存溢出的解决办法

    关于JAVA中内存溢出的解决办法 J2ee应用系统是运行在J2EE应用服务器上的 xff0c 而j2ee应用服务器又是运行在JVM上的 xff0c 生成环境中JVM参数的优化和设置对于J2EE应用系统性能有着决定性的作用 要优化系统 xff
  • ireport的使用总结

    ireport的使用总结 截图居然都没显示出来 xff0c 如有需要可以到 xff08 http download csdn net detail czp0608 4140640 xff09 下载 相信很多java程序员们 xff0c 在开
  • 卡尔曼滤波C代码分析

    文章下载地址 xff1a http wenku baidu com view 3c42b7733186bceb18e8bb29
  • 作为一个新人,怎样学习嵌入式Linux?

    作为一个新人 xff0c 怎样学习嵌入式Linux xff1f 被问过太多次 xff0c 特写这篇文章来回答一下 在学习嵌入式Linux之前 xff0c 肯定要有C语言基础 汇编基础有没有无所谓 就那么几条汇编指令 xff0c 用到了一看就
  • pixhawk启动脚本分析

    Nuttx系统启动是由ardupilot mk PX4 ROMFS init d里的rcS和rc APM完成的 笔者阅读了rcS和rc APM xff0c 该脚本类似C语言 xff0c 并做了相关注释 主要是一些设备自检 xff0c 启动各
  • pixhawk ArduPilot_main启动与运行分析

    上节分析 2 个系统启动脚本 xff0c 一个是 ardupilot mk PX4 ROMFS init d 里的 rcS xff0c 另一个是 rc APM xff0c 这个脚本在 rcS 里得到了调用 xff0c 也就是说 xff0c
  • pixhawk make文件分析

    由于笔者没学过Linux等系统 xff0c 对make文件所知甚少 xff0c 本节分析可能有大量错误 xff0c 只提供参考 xff0c 随着技术积累 xff0c 以后会回过头改正错误的地方 xff0c 也非常欢迎提出指导意见 其中分析大