研究PX4一段时间,发现绕了很大的圈子,分析NUTTX系统是费时费力的,其实大可不必,Nuttx只是一个操作系统,作为飞控程序的载体,实际上我们只需要分析启动脚本就可以了。如何找到启动脚本及前面系统的启动本分的分析,参看一篇博文,写的非常好,在这里谢谢了。http://blog.chinaunix.net/uid-29786319-id-4393303.html对于os_start()的分析,这篇写的很不错。http://blog.csdn.net/zhumaill/article/details/23261543博文内容不贴了,最终作者,如查看请移步原帖。前人的工作不说了,直说下他们的分析是基于前面版本,我下到的代码版本已经更新了许多,不过大差不差,对比着看肯定是可以看懂的。现在直接分析现有版本的rCS启动脚本。serconset MODE autostart #设置启动变量模式set FRC /fs/microsd/etc/rc.txt #设置了几个文件路径,后面估计用到set FCONFIG /fs/microsd/etc/config.txtset TUNE_ERR ML<<CP4CP4CP4CP4CP4set LOG_FILE /fs/microsd/bootlog.txtif mount -t vfat /dev/mmcsd0 /fs/microsd #挂载SD卡,失败成功声音不同thenecho "[i] microSD mounted: /fs/microsd"tone_alarm startelsetone_alarm MBAGPif mkfatfs /dev/mmcsd0thenif mount -t vfat /dev/mmcsd0 /fs/microsdthenecho "[i] microSD card formatted"elseecho "[i] format failed"tone_alarm MNBGset LOG_FILE /dev/nullfielseset LOG_FILE /dev/nullfifiif [ -f $FRC ] #找SD卡上的启动文件,如果发现,转入custom modethenecho "[i] Executing script: $FRC"sh $FRCset MODE customfiunset FRCif [ $MODE == autostart ]then#如果是autostart mode,尝试得到USB指令,新版本将其放到了这,系统启动就可以接受usb指令nshterm /dev/ttyACM0 &uorb start #启动uorb uorb为系统间非常重要的消息传递机制set PARAM_FILE /fs/microsd/params #设置参数文件的路径,默认在SD卡里面if mtd start #如果EEPROM启动成功,将参数设置路径设置到EEPROM中,PIXhawk中有 then #EEPROM,这就是在内存卡中无参数配置文件的原因set PARAM_FILE /fs/mtd_paramsfiparam select $PARAM_FILE #加载参数if param loadthenecho "[param] Loaded: $PARAM_FILE"elseecho "[param] FAILED loading $PARAM_FILE"if param resetthenfifiif param compare RC_MAP_THROTTLE 0 #如果RC_MAP_throttle 是0 下面的几个比较都是对遥控器进行检测thenif param compare RC3_MIN 1000thenelseparam set RC_MAP_THROTTLE 3fifiif param compare RC_MAP_ROLL 0thenif param compare RC1_MIN 1000thenelseparam set RC_MAP_ROLL 1fifiif param compare RC_MAP_PITCH 0thenif param compare RC2_MIN 1000thenelseparam set RC_MAP_PITCH 2fifiif param compare RC_MAP_YAW 0thenif param compare RC4_MIN 1000thenelseparam set RC_MAP_YAW 4 #遥控器的四个通道fifiif rgbled start #如果有外界LEDthenelseif blinkm startthenblinkm systemstatefifiset HIL no #设置一些默认参数,后面会被改动,不一一列举set VEHICLE_TYPE noneset MIXER noneset MIXER_AUX noneset OUTPUT_MODE noneset PWM_OUT noneset PWM_RATE noneset PWM_DISARMED noneset PWM_MIN noneset PWM_MAX noneset PWM_AUX_OUT noneset PWM_AUX_RATE noneset PWM_AUX_DISARMED noneset PWM_AUX_MIN noneset PWM_AUX_MAX noneset FAILSAFE_AUX noneset MK_MODE noneset FMU_MODE pwmset AUX_MODE pwmset MAVLINK_F defaultset EXIT_ON_END noset MAV_TYPE noneset LOAD_DAPPS yesset GPS yesset GPS_FAKE noset FAILSAFE noneif param compare SYS_AUTOCONFIG 1 #如果SYS_AUTOCONFIG 是1thenparam reset_nostart RC*set AUTOCNF yeselseset AUTOCNF nofiif param compare SYS_USE_IO 1 #如果SYS_USE_IO 1 是1thenset USE_IO yeselseset USE_IO nofiif param compare SYS_AUTOSTART 0 #如果SYS_AUTOSTART是0thenecho "[i] No autostart"else #如果SYS_AUTOSTART是1的话启动rc_autostart,关于此文件会另 sh /etc/init.d/rc.autostart #外开帖分析fiunset MODEif [ -f $FCONFIG ] #如果用户配置文件config.txt存在,执行里面的设置thenecho "[i] Custom config: $FCONFIG"sh $FCONFIGfiunset FCONFIGif [ $AUTOCNF == yes ] ##如果AUTOCNF为1,清零SYS_AUTOCONFIGthenparam set SYS_AUTOCONFIG 0param savefiunset AUTOCNFset IO_PRESENT no #初始化IO_PRESENT为0if [ $USE_IO == yes ] #如果USE_IO为1,对Firmware更新thenif [ -f /etc/extras/px4io-v2_default.bin ]thenset IO_FILE /etc/extras/px4io-v2_default.binelseset IO_FILE /etc/extras/px4io-v1_default.binfiif px4io checkcrc ${IO_FILE}thenecho "PX4IO CRC OK" >> $LOG_FILEset IO_PRESENT yeselseecho "PX4IO Trying to update" >> $LOG_FILEtone_alarm MLL32CP8MBif px4io startthenif px4io safety_onthenelsepx4io stopfifiif px4io forceupdate 14662 ${IO_FILE}thenusleep 500000if px4io checkcrc $IO_FILEthenecho "PX4IO CRC OK after updating" >> $LOG_FILEtone_alarm MLL8CDEset IO_PRESENT yeselseecho "ERROR: PX4IO update failed" >> $LOG_FILEtone_alarm $TUNE_ERRfielseecho "ERROR: PX4IO update failed" >> $LOG_FILEtone_alarm $TUNE_ERRfifiunset IO_FILEif [ $IO_PRESENT == no ]thenecho "[i] ERROR: PX4IO not found"echo "ERROR: PX4IO not found" >> $LOG_FILEtone_alarm $TUNE_ERRfifiif [ $OUTPUT_MODE == none ] #判断OUTPUT_MODE,初始化为none,最终执行结果将 #OUTPUT_MODE 设置成了fmuthenif [ $USE_IO == yes ]thenset OUTPUT_MODE ioelseset OUTPUT_MODE fmufifiif [ $OUTPUT_MODE == io -a $IO_PRESENT != yes ] #设置FMU modethenset OUTPUT_MODE noneecho "[i] ERROR: PX4IO not found, disabling output"if ver hwcmp PX4FMU_V1thenset FMU_MODE serialfifiif [ $OUTPUT_MODE == ardrone ]thenset FMU_MODE gpio_serialfiif [ $HIL == yes ]thenset OUTPUT_MODE hilset GPS noif ver hwcmp PX4FMU_V1thenset FMU_MODE serialfifiunset HILif dataman startthenfish /etc/init.d/rc.sensors #启动各种传感器if [ $GPS == yes ] #启动GPSthenif [ $GPS_FAKE == yes ]thenecho "[i] Faking GPS"gps start -felsegps startfifiunset GPSunset GPS_FAKEcommander startset TTYS1_BUSY noif [ $OUTPUT_MODE != none ]thenif [ $OUTPUT_MODE == uavcan_esc ]thenif param compare UAVCAN_ENABLE 0thenecho "[i] OVERRIDING UAVCAN_ENABLE = 1"param set UAVCAN_ENABLE 1fifiif [ $OUTPUT_MODE == io -o $OUTPUT_MODE == uavcan_esc ]thenif px4io startthensh /etc/init.d/rc.ioelseecho "ERROR: PX4IO start failed" >> $LOG_FILEtone_alarm $TUNE_ERRfifiif [ $OUTPUT_MODE == fmu -o $OUTPUT_MODE == ardrone ]thenif fmu mode_$FMU_MODEthenecho "[i] FMU mode_$FMU_MODE started" #这个是我们的选项elseecho "[i] ERROR: FMU mode_$FMU_MODE start failed"echo "ERROR: FMU start failed" >> $LOG_FILEtone_alarm $TUNE_ERRfiif ver hwcmp PX4FMU_V1 #判断版本,启动pwmthenif [ $FMU_MODE == pwm -o $FMU_MODE == gpio ]thenset TTYS1_BUSY yesfiif [ $FMU_MODE == pwm_gpio -o $OUTPUT_MODE == ardrone ]thenset TTYS1_BUSY yesfififiif [ $OUTPUT_MODE == mkblctrl ]thenset MKBLCTRL_ARG ""if [ $MKBLCTRL_MODE == x ]thenset MKBLCTRL_ARG "-mkmode x"fiif [ $MKBLCTRL_MODE == + ]thenset MKBLCTRL_ARG "-mkmode +"fiif mkblctrl $MKBLCTRL_ARGthenecho "[i] MK started"elseecho "[i] ERROR: MK start failed"echo "ERROR: MK start failed" >> $LOG_FILEtone_alarm $TUNE_ERRfiunset MKBLCTRL_ARGfiunset MK_MODEif [ $OUTPUT_MODE == hil ]thenif pwm_out_sim mode_port2_pwm8thenecho "[i] PWM SIM output started"elseecho "[i] ERROR: PWM SIM output start failed"echo "ERROR: PWM SIM output start failed" >> $LOG_FILEtone_alarm $TUNE_ERRfifiif [ $IO_PRESENT == yes ]thenif [ $OUTPUT_MODE != io ]thenif px4io startthenecho "[i] PX4IO started"sh /etc/init.d/rc.ioelseecho "[i] ERROR: PX4IO start failed"echo "ERROR: PX4IO start failed" >> $LOG_FILEtone_alarm $TUNE_ERRfifielseif [ $OUTPUT_MODE != fmu -a $OUTPUT_MODE != ardrone ]thenif fmu mode_$FMU_MODEthenecho "[i] FMU mode_$FMU_MODE started"elseecho "[i] ERROR: FMU mode_$FMU_MODE start failed"echo "ERROR: FMU mode_$FMU_MODE start failed" >> $LOG_FILEtone_alarm $TUNE_ERRfiif ver hwcmp PX4FMU_V1thenif [ $FMU_MODE == pwm -o $FMU_MODE == gpio ]thenset TTYS1_BUSY yesfiif [ $FMU_MODE == pwm_gpio -o $OUTPUT_MODE == ardrone ]thenset TTYS1_BUSY yesfififififiif [ $MAVLINK_F == default ] #下面几行启动MSVLINKthenif [ $TTYS1_BUSY == yes ]thenset MAVLINK_F "-r 1200 -d /dev/ttyS0"set EXIT_ON_END yeselseset MAVLINK_F "-r 1200"fifimavlink start $MAVLINK_Funset MAVLINK_Fif ver hwcmp PX4FMU_V2 #如果板子版本为V2,thenif param compare SYS_COMPANION 921600 #检测mavlink存在,如果在则启动,这个不知道是啥thenmavlink start -d /dev/ttyS2 -b 921600 -m onboard -r 80000 -xfiif param compare SYS_COMPANION 57600 #检测mavlink存在,如果在则启动,数传thenmavlink start -d /dev/ttyS2 -b 57600 -m onboard -r 5000 -xfiif param compare SYS_COMPANION 157600 #检测mavlink存在,如果则启动,USBthenmavlink start -d /dev/ttyS2 -b 57600 -m osd -r 1000fiif param compare SENS_EN_LL40LS 1 #检测某个距离传感器,官网上有介绍thenset AUX_MODE pwm4fiif param greater TRIG_MODE 0 #摄像头触发模式检测thenset MIXER_AUX noneset AUX_MODE nonecamera_trigger startfifish /etc/init.d/rc.uavcan #启动了两个脚本,主要用于启动uavcan和sdlog这两个模块sh /etc/init.d/rc.logging #if [ $OUTPUT_MODE == ardrone ]thenardrone_interface start -d /dev/ttyS1fiif [ $VEHICLE_TYPE == fw ] #固定翼的设置,暂时不是研究对象thenecho "[i] FIXED WING"if [ $MIXER == none ]thenset MIXER AERTfiif [ $MAV_TYPE == none ]thenset MAV_TYPE 1fiparam set MAV_TYPE $MAV_TYPEsh /etc/init.d/rc.interfaceif [ $LOAD_DAPPS == yes ]thensh /etc/init.d/rc.fw_appsfifiif [ $VEHICLE_TYPE == mc ] #多旋翼设置thenecho "[i] MULTICOPTER"if [ $MIXER == none ]thenecho "Mixer undefined"fiif [ $MAV_TYPE == none ]thenif [ $MIXER == quad_x -o $MIXER == quad_+ ]thenset MAV_TYPE 2fiif [ $MIXER == quad_w -o $MIXER == sk450_deadcat ]thenset MAV_TYPE 2fiif [ $MIXER == tri_y_yaw- -o $MIXER == tri_y_yaw+ ]thenset MAV_TYPE 15fiif [ $MIXER == hexa_x -o $MIXER == hexa_+ ]thenset MAV_TYPE 13fiif [ $MIXER == hexa_cox ]thenset MAV_TYPE 13fiif [ $MIXER == octo_x -o $MIXER == octo_+ ]thenset MAV_TYPE 14fiif [ $MIXER == octo_cox ]thenset MAV_TYPE 14fifiif [ $MAV_TYPE == none ]thenecho "Unknown MAV_TYPE"param set MAV_TYPE 2elseparam set MAV_TYPE $MAV_TYPEfish /etc/init.d/rc.interface #PWM的设置和接口if [ $LOAD_DAPPS == yes ]thensh /etc/init.d/rc.mc_apps #核心中的核心,在这里启动了位置和高度的计算算法,具体看这个文件fifiif [ $VEHICLE_TYPE == vtol ] #垂直起降机神马的云云,本人只研究四旋翼thenecho "[init] Vehicle type: VTOL"if [ $MIXER == none ]thenecho "Default mixer for vtol not defined"fiif [ $MAV_TYPE == none ]thenif [ $MIXER == caipirinha_vtol ]thenset MAV_TYPE 19fiif [ $MIXER == firefly6 ]thenset MAV_TYPE 21fiif [ $MIXER == quad_x_pusher_vtol ]thenset MAV_TYPE 22fifiif [ $MAV_TYPE == none ]thenecho "Unknown MAV_TYPE"param set MAV_TYPE 19elseparam set MAV_TYPE $MAV_TYPEfish /etc/init.d/rc.interfaceif [ $LOAD_DAPPS == yes ]thensh /etc/init.d/rc.vtol_appsfifiif [ $VEHICLE_TYPE == rover ] #无关飞机类型thenset MAV_TYPE 10sh /etc/init.d/rc.interfaceif [ $LOAD_DAPPS == yes ]thensh /etc/init.d/rc.axialracing_ax10_appsfiparam set MAV_TYPE 10fiunset MIXERunset MAV_TYPEunset OUTPUT_MODEnavigator start #启动导航if [ $VEHICLE_TYPE == none ]thenecho "[i] No autostart ID found"fiset FEXTRAS /fs/microsd/etc/extras.txtif [ -f $FEXTRAS ]thenecho "[i] Addons script: $FEXTRAS"sh $FEXTRASfiunset FEXTRASif [ $LOG_FILE == /dev/null ]thenecho "[i] No microSD card found"tone_alarm errorfifiunset TUNE_ERRmavlink boot_completeif param compare SENS_EN_LL40LS 1thenif pwm_input startthenif ll40ls start pwmthenfififiif ver hwcmp PX4FMU_V2thenpx4flow start & #v2板启动fiif [ $EXIT_ON_END == yes ]thenecho "Exit from nsh"exitfiunset EXIT_ON_END
版权声明:本文为Gen_Ye原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。