驱动编译与集成:模块化编译方法、将驱动集成到PX4固件、启动脚本编写
好,咱们接着往下走。驱动写完了,测试也通过了,接下来就是把它塞进PX4固件里,让它真正跑起来。这一步,说难不难,说简单也不简单。我见过不少新手,代码写得挺漂亮,结果卡在编译集成这一步,折腾一整天。
今天我就把这块儿掰开了讲。咱们分三块:模块化编译、集成到固件、启动脚本。你跟着我的节奏走,保证一次搞定。
模块化编译方法
先说说编译。PX4的构建系统用的是CMake,这个你应该不陌生。但PX4有自己的模块化编译规则,说白了就是:每个驱动都是一个独立的模块,编译时按需加载。
我个人习惯把驱动放在 src/drivers/ 目录下。比如你写了个气压计驱动,就建个文件夹叫 bmp388。里面放什么呢?至少要有这几个文件:
CMakeLists.txt—— 编译规则bmp388.cpp—— 主代码bmp388.hpp—— 头文件
CMakeLists.txt 怎么写?我给你个模板,直接拿去用:
px4_add_module(
MODULE drivers__bmp388
MAIN bmp388
STACK_MAIN 2000
SRCS
bmp388.cpp
DEPENDS
px4_work_queue
)
这里要注意几个点:
MODULE的名字,我建议用drivers__设备名这种格式,PX4内部就是这么组织的MAIN就是你的入口函数名,比如bmp388STACK_MAIN是栈大小,2000字节一般够用,如果驱动里用了大量局部变量,可以适当调大
将驱动集成到PX4固件
模块写好了,怎么让PX4知道它存在?这里有两个步骤。
第一步:注册模块
在 boards/ 目录下找到你的目标板子配置文件。比如你用 Pixhawk 4,就找 boards/px4/fmu-v5/default.cmake。在里面加上一行:
drivers/bmp388
嗯,就这么简单。PX4的构建系统会自动扫描 src/drivers/ 下的所有模块,你只要在板级配置里声明一下就行。
第二步:编译验证
我个人习惯先单独编译驱动模块,确认没有语法错误:
make px4_fmu-v5_default
如果编译通过,再烧录到板子上测试。这里有个小技巧:你可以用 make px4_fmu-v5_default upload 一步到位,省得手动拷贝固件。
启动脚本编写
驱动集成进去了,但系统启动时不会自动加载它。你需要写一个启动脚本。
PX4的启动脚本放在 ROMFS/px4fmu_common/init.d/ 目录下。比如你想让驱动在 rcS 启动时自动运行,就在 rcS 文件里加一行:
bmp388 start
但更规范的做法是单独写一个脚本文件。比如 rc.driver_bmp388:
#!/bin/sh
#
# @brief BMP388 barometer driver startup
#
bmp388 start
然后在 rcS 里调用它:
sh /etc/init.d/rc.driver_bmp388
为什么要单独写?因为这样方便调试。你可以随时在终端里手动执行这个脚本,不用重启整个系统。
知识体系图
下面这张图,是我自己总结的驱动编译与集成流程。你照着这个走,基本不会迷路。
避坑指南
最后,分享几个我踩过的坑:
- 编译顺序问题: 如果你改了
CMakeLists.txt,一定要先make clean再编译。否则CMake缓存不会更新,你改的东西等于白改。 - 启动脚本权限: 脚本文件要有可执行权限。我一开始忘了加
chmod +x,结果驱动死活起不来,查了半天才发现是权限问题。 - 参数传递: 如果你在启动脚本里传了参数,记得在驱动代码里用
param_find()和param_get()来读取。别问我为什么知道,说多了都是泪。
好了,这一章的内容就这些。你按我说的步骤走,驱动编译和集成这块儿基本不会出问题。下一章咱们聊聊更深入的东西。