APM启动流程及ArduPilot函数入口

本文详细介绍了PX4 (APM)从脚本运行阶段到ArduPilot程序执行的启动流程。在脚本阶段,执行rcS脚本挂载RGBLED、SD卡,并启动rc.APM脚本。接着,rc.APM脚本启动px4io、传感器及ArduPilot主程序。ArduPilot的启动涉及ArduCopter.cpp、HAL_PX4_Class.cpp等文件,通过hal.run()调用进入main_loop任务执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

PX4 (APM)的启动流程

1.  脚本运行阶段

PX4的软件主要可分为Bootloader,Nuttx内核,ROMFS文件系统的挂载,和ArduPilot程序的执行,我们首先讨论ROMFS文件系统挂载完成到ArduPilot执行的过程。

ROMFS挂载完成后,会先执行/etc/init.d/rcS脚本,在源代码中的位置为mk/PX4/ROMFS/init.d/rcS,其内容见附录一

在px4-v2上,正常运行时,此脚本可以简化为下:

set MODE autostart

set USB autoconnect

rgbled start

set HAVE_RGBLED 1

rgbled rgb 16 16 16

 

echo "[init] looking for microSD..."

mount -t vfat /dev/mmcsd0 /fs/microsd

echo "[init] card mounted at /fs/microsd"

set HAVE_MICROSD 1

tone_alarm 1

      

sercon

echo "[init] USB interface connected"

 

echo Running rc.APM

sh /etc/init.d/rc.APM

 

可以看到此脚本的功能就是,挂载rgbled设备并置成白色,挂载SD卡,注册CDC/ACM驱动,执行rc.APM脚本。

 

rc.APM脚本位于源代码mk/PX4/ROMFS/init.d路径下,其内容见附录二。

在px4-v2上正常运行时,此脚本可以简化如下:

set deviceA /dev/ttyACM0

 

echo "Mounting binfs"

mount -t binfs /dev/null /bin

echo "binfs mounted OK"

 

set sketch NONE

 

rm /fs/microsd/APM/boot.log

set logfile /fs/microsd/APM/BOOT.LOG

 

mkdir /fs/microsd/APM > /dev/null

 

echo "Detected FMUv2 board"

set BOARD FMUv2

 

set deviceC /dev/ttyS1

set deviceD /dev/ttyS2

 

uorb start

echo "uorb started OK"

 

echo "Trying PX4IO board"

set HAVE_PX4IO false

px4io start norc

set HAVE_PX4IO true

 

echo "PX4IO board OK"

px4io checkcrc /etc/px4io/px4io.bin

echo "PX4IO CRC OK"

 

fmu mode_pwm4

echo "Set FMU mode_pwm4"

 

echo "Starting APM sensors"

 

ms5611 start

echo "ms5611 started OK"

 

adc start

echo "adc started OK"

 

echo "Starting FMUv2 sensors"

 

hmc5883 -C -T -X start

echo "Have external hmc5883"

hmc5883 -C -T -I -R 4 start

echo "No internal hmc5883"

 

 

mpu6000 -X -R 4 start

mpu9250 -X -R 4 start

echo "No MPU6000 or MPU9250 external"

set HAVE_FMUV3 false

 

mpu6000 start

echo "Found MPU6000"

 

l3gd20 start

echo "l3gd20 started OK"

lsm303d start

echo "lsm303d started OK"

 

ets_airspeed start

 

meas_airspeed start

meas_airspeed start -b 2

 

ll40ls -X start

ll40ls -I start

 

trone start

 

mb12xx start

 

px4flow start

 

pwm_input start

echo "started pwm_input driver"

 

mtd start /fs/mtd

echo "started mtd driver OK"

 

 

 

mtd readtest /fs/mtd

echo "mtd readtest OK"

 

 

oreoled start autoupdate

echo "oreoled started OK"

 

batt_smbus -b 2 start

echo "Found batt_smbus"

 

irlock start

 

mtd rwtest /fs/mtd

echo "mtd rwtest OK"

 

echo Starting ArduPilot $deviceA $deviceC $deviceD

ArduPilot -d $deviceA -d2 $deviceC -d3 $deviceD start

echo ArduPilot started OK

 

echo "rc.APM finished"

可以看到,此脚本主要是启动px4io及各个传感器,最后启动了ArduPilot主程序。下面我们来来看看ArduPilot主程序。

2.  ArduPilot程序的启动

在ArduCopter下的ArduCopter.cpp的最后一行为:

AP_HAL_MAIN_CALLBACKS(&copter);

而AP_HAL_MAIN_CALLBACKS定义在libraries/AP_HAL/ AP_HAL_Main.h中

#define AP_MAIN __EXPORT ArduPilot_main

 

#define AP_HAL_MAIN_CALLBACKS(CALLBACKS) extern "C" { \

    int AP_MAIN(int argc, char* const argv[]); \

    int AP_MAIN(int argc, char* const argv[]) { \

        hal.run(argc, argv, CALLBACKS); \

        return 0; \

    } \

    }

 

所以,这句可以修改为如下形式:

int __EXPORT ArduPilot_main(int argc, char* const argv[]);

int __EXPORT ArduPilot_main(int argc, char* const argv[])

{

         hal.run(argc, argv, &copter);

}

 

copter为全局变量,在ArduCopter/Copter.cpp文件中定义并初始化,全局变量hal也在该文件中定义。

在rc.APM中执行的命令ArduPilot-d $deviceA -d2 $deviceC -d3 $deviceD start,其实就是执行hal.run(argc,argv, &copter);

px4的hal类定义在libraries/ AP_HAL_PX4/ HAL_PX4_Class.cpp文件中,HAL_PX4::run相当于main函数。

通过此页的usage函数,可以看到此命令可以带4个参数,-d 第一个电台使用串口,-d2第二个电台使用串口,-d3 第三个电台使用串口,-d4第二个GPS使用串口。命令start后,通过px4_task_spawn_cmd创建了一个任务,其入口函数为main_loop,相当于单片机中的while(1)循环。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

附录一rcS源码

set MODE autostart

set USB autoconnect

if rgbled start

then

        set HAVE_RGBLED 1

        rgbled rgb 16 16 16

else

        set HAVE_RGBLED 0

fi

echo "[ini

APM 2.5 启动过程中 mavlink 1.0 协议监听 > text: Demo Servos! severity=1; text=68; >>> GCS Msg: MAVLINK_MSG_ID_HEARTBEAT ( 0/0x00) >>> FE 09 75 FF BE 00 00 00 00 00 06 03 00 00 03 90 B8 , W:1 >>> custom_mode=0; type=6; autopilot=3; base_mode=0; system_status=0; mavlink_version=3; > Apm Msg : MAVLINK_MSG_ID_HEARTBEAT ( 0/0x00) > FE 09 38 01 01 00 10 00 00 00 01 03 11 02 03 37 5F , W:1 > custom_mode=16; type=1; autopilot=3; base_mode=17; system_status=2; mavlink_version=3; > Apm Msg : MAVLINK_MSG_ID_SYS_STATUS ( 1/0x01) > FE 1F 39 01 01 01 0F FC FF FF 0F 00 00 00 0F FC FF FF 00 00 60 27 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF 4B 3D , W:1 > onboard_control_sensors_present=-1009; onboard_control_sensors_enabled=15; onboard_control_sensors_health=-1009; load=0; voltage_battery=10080; current_battery=-1; drop_rate_comm=0; errors_comm=0; errors_count1=0; errors_count2=0; errors_count3=0; errors_count4=0; battery_remaining=-1; > Apm Msg : MAVLINK_MSG_ID_STATUSTEXT (253/0xFD) > FE 33 3A 01 01 FD 01 44 65 6D 6F 20 53 65 72 76 6F 73 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 2C , W:1 > text: Demo Servos! severity=1; text=68; >>> GCS Msg: MAVLINK_MSG_ID_HEARTBEAT ( 0/0x00) >>> FE 09 76 FF BE 00 00 00 00 00 06 03 00 00 03 AE 3B , W:1 >>> custom_mode=0; type=6; autopilot=3; base_mode=0; system_status=0; mavlink_version=3; > Apm Msg : MAVLINK_MSG_ID_HEARTBEAT ( 0/0x00) > FE 09 3B 01 01 00 10 00 00 00 01 03 11 02 03 09 DC , W:1 > custom_mode=16; type=1; autopilot=3; base_mode=17; system_status=2; mavlink_version=3; > Apm Msg : MAVLINK_MSG_ID_SYS_STATUS ( 1/0x01) > FE 1F 3C 01 01 01 0F FC FF FF 0F 00 00 00 0F FC FF FF 00 00 60 27 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF 1A 30 , W:1 > onboard_control_sensors_present=-1009; onboard_control_sensors_enabled=15; onboard_control_sensors_health=-1009; load=0; voltage_battery=10080; current_battery=-1; dro
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值