Skip to content

驱动开发

PX4 设备驱动基于 Device 框架。

创建驱动程序

PX4 几乎完全从 uORB 中获取数据。常见外设类型的驱动程序必须发布正确的 uORB 消息(例如:陀螺仪、加速度计、压力传感器等)。

创建新驱动的最佳方法是从一个类似的驱动作为模板开始(参见 src/drivers)。

INFO

有关使用特定 I/O 总线和传感器的更详细信息可能可以在 传感器和执行器总线 部分找到。

INFO

发布正确的 uORB 主题是驱动程序 必须 遵循的唯一模式。

核心架构

PX4 是一个 反应式系统,并使用 uORB 的发布/订阅机制来传输消息。系统的核心操作不需要也不使用文件句柄。主要使用两个 API:

  • 发布/订阅系统具有文件、网络或共享内存后端,具体取决于 PX4 运行的系统。
  • 全局设备注册表,可用于枚举设备并获取/设置其配置。这可以像链接列表或映射到文件系统一样简单。

设备 ID

以系统上有三个磁力计为例,使用飞行日志(.px4log)来转储参数。这三个参数对传感器 ID 进行编码,并且 MAG_PRIME 标识哪个磁力计被选为主要传感器。每个 MAGx_ID 是一个 24 位的数字,手动解码时应在左侧补零。

传感器的顺序(例如,如果有 /dev/mag0 和备用的 /dev/mag1)并不决定优先级——优先级反而作为发布的 uORB 主题的一部分进行存储。

解码示例

这是通过 SPI 连接的内部 HMC5983,总线 1,从选择插槽 5。它将在日志文件中显示为 IMU1.MagX。这三个参数对传感器 ID 进行编码,并且 MAG_PRIME 标识哪个磁力计被选为主要传感器。每个 MAGx_ID 是一个 24 位的数字,手动解码时应在左侧补零。

CAL_MAG0_ID = 73225.0
CAL_MAG1_ID = 66826.0
CAL_MAG2_ID = 263178.0
CAL_MAG_PRIME = 73225.0

这是通过 I2C 连接的外部 HMC5983,总线 1,地址为 0x1E:它将在日志文件中显示为 IMU.MagX

# 24 位二进制表示的设备 ID 73225:
00000001  00011110  00001 001

# 解码为:
HMC5883   0x1E    总线 1 I2C

根据此格式,设备 ID 是一个 24 位数字。它将在日志文件中显示为 IMU1.MagX

# 24 位二进制表示的设备 ID 66826:
00000001  00000101  00001 010

# 解码为:
HMC5883   设备 5   总线 1 SPI

这是通过 SPI 连接的内部 MPU9250 磁力计,总线 1,从选择插槽 4。它将在日志文件中显示为 IMU2.MagX

# 24 位二进制表示的设备 ID 263178:
00000100  00000100  00001 010

# 解码为:
MPU9250   设备 4   总线 1 SPI

设备 ID 编码

设备 ID 是一个按照此格式的 24 位数字。请注意,在上述解码示例中,前几个字段是最低有效位。

C
struct DeviceStructure {
  enum DeviceBusType bus_type : 3;
  uint8_t bus: 5;    // 总线类型的实例编号
  uint8_t address;   // 总线上的地址(例如 I2C 地址)
  uint8_t devtype;   // 设备类特定的设备类型
};

bus_type 根据以下内容进行解码:

C
enum DeviceBusType {
  DeviceBusType_UNKNOWN = 0,
  DeviceBusType_I2C     = 1,
  DeviceBusType_SPI     = 2,
  DeviceBusType_UAVCAN  = 3,
};

devtype 根据以下内容进行解码:

C
#define DRV_MAG_DEVTYPE_HMC5883  0x01
#define DRV_MAG_DEVTYPE_LSM303D  0x02
#define DRV_MAG_DEVTYPE_ACCELSIM 0x03
#define DRV_MAG_DEVTYPE_MPU9250  0x04
#define DRV_ACC_DEVTYPE_LSM303D  0x11
#define DRV_ACC_DEVTYPE_BMA180   0x12
#define DRV_ACC_DEVTYPE_MPU6000  0x13
#define DRV_ACC_DEVTYPE_ACCELSIM 0x14
#define DRV_ACC_DEVTYPE_GYROSIM  0x15
#define DRV_ACC_DEVTYPE_MPU9250  0x16
#define DRV_GYR_DEVTYPE_MPU6000  0x21
#define DRV_GYR_DEVTYPE_L3GD20   0x22
#define DRV_GYR_DEVTYPE_GYROSIM  0x23
#define DRV_GYR_DEVTYPE_MPU9250  0x24
#define DRV_RNG_DEVTYPE_MB12XX   0x31
#define DRV_RNG_DEVTYPE_LL40LS   0x32

调试

有关一般调试主题,请参阅:调试/日志记录

使用操纵杆

驱动程序(和其他模块)默认输出最少详细信息的日志字符串(例如,对于 PX4_DEBUGPX4_WARNPX4_ERR 等)。

日志详细程度在构建时使用 RELEASE_BUILD(默认)、DEBUG_BUILD(详细)或 TRACE_BUILD(极其详细)宏来定义。

在驱动的 px4_add_module 函数(CMakeLists.txt)中使用 COMPILE_FLAGS 更改日志级别。 下面的代码片段展示了为单个模块或驱动启用 DEBUG_BUILD 级别的调试所需的更改。

px4_add_module(
	MODULE templates__module
	MAIN module
	COMPILE_FLAGS
		-DDEBUG_BUILD
	SRCS
		module.cpp
	DEPENDS
		modules__uORB
	)

TIP

也可以通过在 .cpp 文件的最顶部(在任何包含语句之前)添加 #define DEBUG_BUILD,按文件启用详细日志记录。