系统启动
PX4 系统的启动由 shell 脚本文件控制。在 NuttX 系统中,这些脚本文件位于 ROMFS/px4fmu_common/init.d 文件夹,其中一些脚本在 Posix(Linux/MacOS)系统中也会被使用。仅用于 Posix 系统的脚本位于 ROMFS/px4fmu_common/init.d-posix。
所有以数字和下划线开头的文件(例如 10000_airplane
)都是预定义的机架配置。在构建时,这些配置会被导出到一个 airframes.xml
文件中,QGroundControl 会解析该文件以提供机架选择界面。关于添加新配置的内容可参考 此处。
其他文件则是系统常规启动逻辑的一部分。第一个执行的文件是 init.d/rcS 脚本(在 Posix 系统中是 init.d-posix/rcS),它会调用其他所有脚本。
根据 PX4 运行的操作系统,本文后续内容分为以下各小节。
Posix (Linux/MacOS)
在 Posix 操作系统上,系统的 shell 会作为脚本文件的解释器(例如,在 Ubuntu 中 /bin/sh 与 Dash 建立了符号链接)。为了使 PX4 能在 Posix 中正常运行,需要满足以下几点:
模块可执行化处理
PX4 的各个模块需要看起来像系统的单个可执行文件。这可以通过创建符号链接来实现。对于每个模块,在构建文件夹的 bin
目录中会创建一个符号链接 px4-<module> -> px4
。当执行时,会检查二进制文件的路径(argv[0]
),如果是一个模块(以 px4-
开头),它会将命令发送到主 px4 实例(见下文)。
TIP
使用 px4-
前缀是为了避免与系统命令冲突(例如 shutdown
),并且通过输入 px4-<TAB>
还可以实现简单的自动补全。
环境变量配置
Shell 需要知道在哪里可以找到上述符号链接。为此,在执行启动脚本之前,会将包含符号链接的 bin
目录添加到 PATH
变量中。
进程与通讯机制
Shell 将每个模块作为一个新的(客户端)进程进行启动,每个客户端进程都需要与 PX4 主实例(服务器)进行通讯,实际的模块以线程的形式运行。这是通过 UNIX socket 实现的。服务器监听一个 socket,然后客户端将连接该 socket 并通过它发送指令。服务器收到客户端的指令后,会将指令运行的输出结果及返回代码重新发送给客户端。
脚本调用方式
启动脚本会直接调用模块,例如 commander start
,而不是使用 px4-
前缀。这是通过别名实现的:对于每个模块,在文件 bin/px4-alias.sh
中会创建一个形式为 alias <module>=px4-<module>
的别名。
主实例执行流程
rcS
脚本由主 px4 实例执行。它不会启动任何模块,而是首先更新 PATH
变量,然后简单地以 rcS
文件作为参数运行一个 shell。
多实例支持
除此之外,在进行多飞行器仿真时还可以启动多个服务器实例。客户端通过 --instance
选择实例。实例在脚本中可以通过 $px4_instance
变量获取。
当 PX4 在操作系统上处于运行状态时,可以从任意终端直接运行各个模块。例如:
cd <PX4-Autopilot>/build/px4_sitl_default/bin
./px4-commander takeoff
./px4-listener sensor_accel
动态模块
通常,所有模块都被编入一个 PX4 可执行程序。然而,在 Posix 系统上,可以选择将一个模块编译成一个单独的文件,然后使用 dyn
命令将其加载到 PX4 中。
dyn ./test.px4mod
NuttX
NuttX 有一个集成的 shell 解释器(NuttShell (NSH)),因此脚本可以直接执行。
替换系统的启动文件
软件组件的失效不会中止 PX4 系统的启动,这是通过在启动脚本中使用 set +e
来控制的。
可以通过连接 系统控制台 并对板卡进行电源循环来调试启动序列。由此生成的启动引导日志文件中包含了引导序列的详细信息,同时也应包含了解释启动中止的线索。
启动失败的常见原因
- 自定义应用程序方面:系统内存不足。可以运行
free
命令查看可用内存量。 - 软件故障或断言:导致堆栈跟踪信息出现。
自定义系统的启动文件
可以通过在 microSD 卡上创建一个文件 /etc/rc.txt
并使用新的配置来替换整个启动过程(旧配置中的任何内容都不会自动启动,如果文件为空,则什么都不会启动)。
根据默认启动程序来进行定制化是一个比较好的开始方式,相关文档如下。
自定义系统的启动文件
自定义系统启动的最佳方法是引入一个 新的机架配置。机架配置文件可以在固件中,也可以在 SD 卡上。
如果只需要对现有配置进行“微调”,例如启动一个额外的应用程序或设置几个参数的值,可以通过在 SD 卡的 /etc/
目录下创建两个文件来指定:
- /etc/config.txt:修改参数值
- /etc/extras.txt:启动应用程序
文件的具体信息将在后面介绍。
WARNING
系统启动文件是 UNIX 文件,需要使用 UNIX 换行符。如果在 Windows 上编辑,需要使用合适的编辑器。
INFO
这些文件在 PX4 代码中被引用为 /fs/microsd/etc/config.txt
和 /fs/microsd/etc/extras.txt
,其中 microSD 卡的根文件夹由路径 /fs/microsd
标识。
自定义配置(config.txt)
config.txt
文件可用于修改参数。它会在主系统配置完成之后、启动之前加载。
例如,可以在 SD 卡上创建一个文件 etc/config.txt
,并设置参数值如下:
param set-default PWM_MAIN_DIS3 1000
param set-default PWM_MAIN_MIN3 1120
启动附加应用程序 (extras.txt)
extras.txt
可用于在主系统启动后启动额外的应用程序。通常,额外启动的将是有效载荷控制器或类似的可选自定义组件。
WARNING
在系统启动文件中调用未知命令可能会导致启动失败。通常情况下,系统在启动失败后不会发送 mavlink 消息,在这种情况下请检查系统控制台上输出的错误消息。
下面的示例演示了如何启动自定义应用程序:
- 在 SD 卡上创建一个文件
etc/extras.txt
,内容如下:shcustom_app start
- 可以使用
set +e
和set -e
命令来使一个命令变为可选的:shset +e optional_app start # 如果 optional_app 未知或启动失败,不会导致启动失败 set -e mandatory_app start # 如果 mandatory_app 未知或启动失败,将中止启动