• px4飞控是基于nuttx实时操作系统的。

    px4飞控是基于nuttx实时操作系统的。

    操作系统(OS)是什么?

    具体的定义可以去看计算机专业的课本或者百度之,我这里讲我自己对操作系统的理解:
    操作系统相当于在计算机硬件和人或者其它软件之间的一个翻译官,有了它,人和其他软件就不用“说”控制计算机硬件的“艰深”的“语言”。它展示给人的良好的图形界面,提供给其他软件的清晰的API。对于人或者其它软件下达的指令,它自己调度各种计算机硬件设备完成。这一方面方便了用户使用计算机,另一方面它提高了系统资源的使用效率。

    操作系统应该具有的功能有:

    任务调度:
    windows系统可以同时运行多个程序,这是因为多个程序在轮流使用CPU,但是由于切换的速度很快,我们感觉多个程序是在同时运行的。任务调度其实是个程序,它决定哪个程序在什么时候使用CPU。
    内存管理:
    程序的运行需要内存,多个程序同时运行时内存怎么利用,各个程序利用的多少,利用的位置,利用完成后的释放等等,需要一个叫内存管理的程序来控制。
    文件系统:
    文件系统用来整理文件,就是windows的文件目录结构,当然不同系统略微有些差别。
    驱动程序:
    控制硬件设备的软件程序。
    用户界面:
    方便用户控制计算机。不是必须的。

    实时操作系统(RTOS)是什么?

    操作系统分为实时操作系统和非实时操作系统,我们常用的windows就是非实时操作系统。非实时操作系统的任务调度一般采用时间片转轮的方法,同时进行的几项任务轮流使用CPU,所以,非实时操作系统在有任务就绪之后不一定能马上执行,必须等待在它前面的任务挂起或者时间片结束后才能执行。这在一些实时性要求比较高的场合是不能使用的,比如飞控中控制电机的任务,如果它被其它任务堵塞了,那结果就是炸机。实时操作系统是利用中断的方法,当有高优先级的中断到来时,CPU马上移交给它使用。执行完成再返回刚才的任务。
    常见的实时操作系统有:uCOS,VxWorks,RTLinux,Nuttx等。

    Nuttx实时操作系统是什么?

    Nuttx 是一个开源的实时嵌入式操作系统(Embedded RTOS),它很小巧,在8位到32位的微控制器环境中都可使用。px4飞控就是基于这个操作系统开发的。
    官网的介绍文档(全英文):
    http://www.nuttx.org/doku.php?id=documentation
    这个操作系统中文的资料比较少,可以看看csdn上zhumaill的博客
    http://blog.csdn.net/zhumaill/article/details/24197637,有系列讲Nuttx操作系统的内容。

    为什么要用Nuttx实时操作系统?

    1.使用操作系统可以使应用程序代码结构结构清晰,编写难度降低。
    2.提高代码的重用性,方便添加新功能和新设备。
    3.飞行控制的实时要求。
    4.Nuttx是比较小的实时操作系统,适合在微控制器中使用。

    展开全文
  • 注:nuttx可参考的资料实在太少,目前只有操作手册和官网以及一些网上其他的博主的文章。 这一篇自学笔记就是结合一位博主的文章和官方手册写的:http://blog.chinaunix.net/uid-29786319-id-4393303.html写在前面...

    注:

    nuttx可参考的资料实在太少,目前只有操作手册和官网以及一些网上其他的博主的文章。
    这一篇自学笔记就是结合一位博主的文章和官方手册写的:http://blog.chinaunix.net/uid-29786319-id-4393303.html


    写在前面

    在初学nuttx时,先不必注重在意代码的细节,先要掌握整体的代码的结构,把握模块之间的关联即可。另外,nuttx只需会使用他的API即可,于是用户手册就必不可少。


    第一步:系统启动

    因为px4用的是stm32,所以启动文件是stm32_start.c:


    (注意:在了解px4启动之前我们需要了解一下bootloader。Bootloader是在操作系统内核运行之前运行,可以初始化硬件设备,建立内存空间映射图等,整个系统的加载启动任务就是完全由Bootloader来完成的。它还是嵌入式系统在加电后执行的第一段代码,在它完成cpu和相关硬件的初始化后,再将操作系统映像或固化的嵌入式应用程序装在内存中然后跳转到操作系统所在的空间,启动操作系统运行)

    
    /****************************************************************************
     * Included Files
     ****************************************************************************/
    
    #include <nuttx/config.h>
    
    #include <stdint.h>
    #include <assert.h>
    #include <debug.h>
    
    #include <nuttx/init.h>
    #include <arch/board/board.h>
    
    #include "up_arch.h"
    #include "up_internal.h"
    
    #include "stm32.h"
    #include "stm32_gpio.h"
    #include "stm32_userspace.h"
    
    #ifdef CONFIG_ARCH_FPU
    #  include "nvic.h"
    #endif
    
    /****************************************************************************
     * Private Function prototypes
     ****************************************************************************/
    
    #ifdef CONFIG_ARCH_FPU
    static inline void stm32_fpuconfig(void);
    #endif
    #ifdef CONFIG_STACK_COLORATION
    static void go_os_start(void *pv, unsigned int nbytes)
      __attribute__ ((naked, no_instrument_function, noreturn));
    #endif
    
    /****************************************************************************
     * Private Functions
     ****************************************************************************/
    
    /****************************************************************************
     * Name: showprogress
     *
     * Description:
     *   Print a character on the UART to show boot status.
     *
     ****************************************************************************/
    
    #ifdef CONFIG_DEBUG_FEATURES
    #  define showprogress(c) up_lowputc(c)
    #else
    #  define showprogress(c)
    #endif
    
    /****************************************************************************
     * Public Functions
     ****************************************************************************/
    
    #ifdef CONFIG_ARMV7M_STACKCHECK
    /* we need to get r10 set before we can allow instrumentation calls */
    
    void __start(void) __attribute__ ((no_instrument_function));
    #endif
    
    /****************************************************************************
     * Name: stm32_fpuconfig
     *
     * Description:
     *   Configure the FPU.  Relative bit settings:
     *
     *     CPACR:  Enables access to CP10 and CP11
     *     CONTROL.FPCA: Determines whether the FP extension is active in the
     *       current context:
     *     FPCCR.ASPEN:  Enables automatic FP state preservation, then the
     *       processor sets this bit to 1 on successful completion of any FP
     *       instruction.
     *     FPCCR.LSPEN:  Enables lazy context save of FP state. When this is
     *       done, the processor reserves space on the stack for the FP state,
     *       but does not save that state information to the stack.
     *
     *  Software must not change the value of the ASPEN bit or LSPEN bit while either:
     *   - the CPACR permits access to CP10 and CP11, that give access to the FP
     *     extension, or
     *   - the CONTROL.FPCA bit is set to 1
     *
     ****************************************************************************/
    
    #ifdef CONFIG_ARCH_FPU
    #if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU)
    
    static inline void stm32_fpuconfig(void)
    {
      uint32_t regval;
    
      /* Set CONTROL.FPCA so that we always get the extended context frame
       * with the volatile FP registers stacked above the basic context.
       */
    
      regval = getcontrol();
      regval |= (1 << 2);
      setcontrol(regval);
    
      /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend
       * with the lazy FP context save behaviour.  Clear FPCCR.ASPEN since we
       * are going to turn on CONTROL.FPCA for all contexts.
       */
    
      regval = getreg32(NVIC_FPCCR);
      regval &= ~((1 << 31) | (1 << 30));
      putreg32(regval, NVIC_FPCCR);
    
      /* Enable full access to CP10 and CP11 */
    
      regval = getreg32(NVIC_CPACR);
      regval |= ((3 << (2*10)) | (3 << (2*11)));
      putreg32(regval, NVIC_CPACR);
    }
    
    #else
    
    static inline void stm32_fpuconfig(void)
    {
      uint32_t regval;
    
      /* Clear CONTROL.FPCA so that we do not get the extended context frame
       * with the volatile FP registers stacked in the saved context.
       */
    
      regval = getcontrol();
      regval &= ~(1 << 2);
      setcontrol(regval);
    
      /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend
       * with the lazy FP context save behaviour.  Clear FPCCR.ASPEN since we
       * are going to keep CONTROL.FPCA off for all contexts.
       */
    
      regval = getreg32(NVIC_FPCCR);
      regval &= ~((1 << 31) | (1 << 30));
      putreg32(regval, NVIC_FPCCR);
    
      /* Enable full access to CP10 and CP11 */
    
      regval = getreg32(NVIC_CPACR);
      regval |= ((3 << (2*10)) | (3 << (2*11)));
      putreg32(regval, NVIC_CPACR);
    }
    
    #endif
    
    #else
    #  define stm32_fpuconfig()
    #endif
    
    /****************************************************************************
     * Name: go_os_start
     *
     * Description:
     *   Set the IDLE stack to the
     *
     ****************************************************************************/
    
    #ifdef CONFIG_STACK_COLORATION
    static void go_os_start(void *pv, unsigned int nbytes)
    {
      /* Set the IDLE stack to the stack coloration value then jump to
       * os_start().  We take extreme care here because were currently
       * executing on this stack.
       *
       * We want to avoid sneak stack access generated by the compiler.
       */
    
      __asm__ __volatile__
      (
        "\tmovs r1, r1, lsr #2\n"   /* R1 = nwords = nbytes >> 2 */
        "\tbeq  2f\n"               /* (should not happen) */
    
        "\tbic  r0, r0, #3\n"       /* R0 = Aligned stackptr */
        "\tmovw r2, #0xbeef\n"      /* R2 = STACK_COLOR = 0xdeadbeef */
        "\tmovt r2, #0xdead\n"
    
        "1:\n"                      /* Top of the loop */
        "\tsub  r1, r1, #1\n"       /* R1 nwords-- */
        "\tcmp  r1, #0\n"           /* Check (nwords == 0) */
        "\tstr  r2, [r0], #4\n"     /* Save stack color word, increment stackptr */
        "\tbne  1b\n"               /* Bottom of the loop */
    
        "2:\n"
        "\tmov  r14, #0\n"          /* LR = return address (none) */
        "\tb    os_start\n"         /* Branch to os_start */
      );
    }
    #endif
    
    /****************************************************************************
     * Public Functions
     ****************************************************************************/
    
    /****************************************************************************
     * Name: _start
     *
     * Description:
     *   This is the reset entry point.
     *
     ****************************************************************************/
    
    void __start(void)//从这里开始!!!!!!!!!!!!!!!!!
    {
      const uint32_t *src;
      uint32_t *dest;
    
    #ifdef CONFIG_ARMV7M_STACKCHECK
      /* Set the stack limit before we attempt to call any functions */
    
      __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : );
    #endif
    
      /* Configure the UART so that we can get debug output as soon as possible */
    
      stm32_clockconfig();
      stm32_fpuconfig();
      stm32_lowsetup();
      stm32_gpioinit();
      showprogress('A');
    
      /* Clear .bss.  We'll do this inline (vs. calling memset) just to be
       * certain that there are no issues with the state of global variables.
       */
    
      for (dest = _START_BSS; dest < _END_BSS; )
        {
          *dest++ = 0;
        }
    
      showprogress('B');
    
      /* Move the initialized data section from his temporary holding spot in
       * FLASH into the correct place in SRAM.  The correct place in SRAM is
       * give by _sdata and _edata.  The temporary location is in FLASH at the
       * end of all of the other read-only data (.text, .rodata) at _eronly.
       */
    
      for (src = _DATA_INIT, dest = _START_DATA; dest < _END_DATA; )
        {
          *dest++ = *src++;
        }
    
      showprogress('C');
    
    #ifdef CONFIG_ARMV7M_ITMSYSLOG
      /* Perform ARMv7-M ITM SYSLOG initialization */
    
      itm_syslog_initialize();
    #endif
    
      /* Perform early serial initialization */
    
    #ifdef USE_EARLYSERIALINIT
      up_earlyserialinit();
    #endif
      showprogress('D');
    
      /* For the case of the separate user-/kernel-space build, perform whatever
       * platform specific initialization of the user memory is required.
       * Normally this just means initializing the user space .data and .bss
       * segments.
       */
    
    #ifdef CONFIG_BUILD_PROTECTED
      stm32_userspace();
      showprogress('E');
    #endif
    
      /* Initialize onboard resources */
    
      stm32_boardinitialize();
      showprogress('F');
    
      /* Then start NuttX */
    
      showprogress('\r');
      showprogress('\n');
    
    #ifdef CONFIG_STACK_COLORATION
      /* Set the IDLE stack to the coloration value and jump into os_start() */
    
      go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE);
    #else
      /* Call os_start() */
    
      os_start();
    
      /* Shoulnd't get here */
    
      for (; ; );
    #endif
    }

    现在我们来看一下32是如何启动的:

    代码位置:Firmware/build_px4fmu-v2_default/px4fmu-v2/Nuttx/nuttx/arch/arm/src/stm32/stm32_start.c
    __start– #处理器执行的第一条指令(px4使用的是stm32,入口在stm32_start.c中)
    |
    v
    stm32_clockconfig()—— #初始化时钟
    |
    v
    rcc_reset() #复位rcc
    stm32_stdclockconfig() #初始化标准时钟

    rcc_enableperipherals() #使能外设时钟

    stm32_fpuconfig() #配置fpu
    |
    v
    stm32_lowsetup() #基本初始化串口,之后可以使用up_lowputc()
    stm32_gpioinit() #初始化gpio,只是调用stm32_gpioremap()设置重映射
    up_earlyserialinit() #初始化串口,之后可以使用up_putc()
    stm32_boardinitialize()– #板级初始化
    |
    v
    stm32_spiinitialize() #初始化spi,只是调用stm32_configgpio()设置gpio
    stm32_usbinitialize() #初始化usb,只是调用stm32_configgpio()设置gpio
    up_ledinit(); #初始化led,只是调用stm32_configgpio()设置gpio
    |


    在stm32_start.c文件中我们会看到这么一句话:

    os_start()————— #初始化操作系统
    |
    v
    dq_init() #初始化各种状态的任务列表(置为null)
    g_pidhash[i]= #初始化唯一可以确定的元素–进程ID
    g_pidhash[PIDHASH(0)]= #分配空闲任务的进程ID为0
    g_idletcb= #初始化空闲任务的任务控制块
    sem_initialize()– #初始化信号量
    |
    v
    dq_init() #将信号量队列置为null
    sem_initholders() #初始化持有者结构以支持优先级继承
    |
    ——–
    |
    v
    up_allocate_heap() #分配用户模式的堆(设置堆的起点和大小)
    kumm_initialize() #初始化用户模式的堆
    up_allocate_kheap() #分配内核模式的堆
    kmm_initialize() #初始化内核模式的堆
    task_initialize() #初始化任务数据结构
    irq_initialize() #将所有中断向量都指向同一个异常中断处理程序
    wd_initialize() #初始化看门狗数据结构
    clock_initialize() #初始化rtc
    timer_initialize() #配置POSIX定时器
    sig_initialize() #初始化信号
    mq_initialize() #初始化命名消息队列
    pthread_initialize() #初始化线程特定的数据,空函数
    fs_initialize()— #初始化文件系统
    |
    v
    sem_init() #初始化节点信号量为1
    files_initialize() #初始化文件数组,空函数
    |
    ——–
    |
    v
    net_initialize()– #初始化网络
    |
    v
    uip_initialize() #初始化uIP层
    net_initroute() #初始化路由表
    netdev_seminit() #初始化网络设备信号量
    arptimer_init() #初始化ARP定时器
    |
    ——–
    |
    v
    up_initialize()— #处理器特定的初始化
    |
    v
    up_calibratedelay() #校准定时器
    up_addregion() #增加额外的内存段
    up_irqinitialize() #设置中断优先级,关联硬件异常处理函数
    up_pminitialize() #初始化电源管理
    up_dmainitialize() #初始化DMA
    up_timerinit() #初始化定时器中断
    devnull_register() #注册/dev/null
    devzero_register() #注册/dev/zero
    up_serialinit() #注册串口控制台/dev/console和串口/dev/ttyS0
    up_rnginitialize() #初始化并注册随机数生成器
    up_netinitialize() #初始化网络,是arch/arm/src/chip/stm32_eth.c中的
    up_usbinitialize() #初始化usb驱动
    board_led_on() #打开中断使能led,但很快会被其它地方的led操作改变状态
    |
    ——–
    |
    v
    lib_initialize() #初始化c库,空函数
    group_allocate() #分配空闲组
    group_setupidlefiles() #在空闲任务上创建stdout、stderr、stdin
    group_initialize() #完全初始化空闲组
    os_bringup()—— #创建初始任务
    |
    v
    KEKERNEL_THREAD() #启动内核工作者线程
    board_initialize() #最后一刻的板级初始化
    TASK_CREATE() #启动默认应用程序
    |
    ——–
    |
    v
    forup_idle() #空闲任务循环
    |
    ——————–
    |
    v
    for(;;) #不应该到达这里

    展开全文
  • 前面说到px4是基于Nuttx实时操作系统上的,那么px4也是由一些程序所构成,这些程序实现了飞行器的自主控制,只不过这些程序并不是我们通常所见到的单片机或者windows编程那样的程序,但基本编程思想是一致的。...

         前面说到px4是基于Nuttx实时操作系统上的,那么px4也是由一些程序所构成,这些程序实现了飞行器的自主控制,只不过这些程序并不是我们通常所见到的单片机或者windows编程那样的程序,但基本编程思想是一致的。我认为如果要看懂px4的源码,那你一定要了解px4的那些程序是怎么编写出来,怎么运行的。所以本章我就大概介绍一下基于Nuttx的编程,我以一个所有编程入门都会介绍的一个程序作为例子。这个程序就是大名鼎鼎的hello world大笑大笑大笑



         在讲解编程之前,我得交代两个重要的东西,因为这两个东西存在于px4的源码系统当中,非常重要,它们就是makeCmake

          首先谈谈何为make,熟悉linux系统的朋友对make肯定不陌生,它就是用来读取Makefile文件然后执行,把源码编译链接为可执行程序的一个软件。我们只要把待编译的源码文件和这些源码所需要用到的库写到Makefile文件里面执行make命令就能得到可执行或者可烧录的二进制文件。

        

         那何为Cmake呢?

         我们可以这样理解,早期人们直接使用gcc命令编译程序,当源码文件多起了之后,直接用gcc命令过长,链接的库过多,这样就太麻烦了。这时候Make就应运而生,解决了人们对于代码文件过多的困扰。但随着项目越来越大,文件越来越多,人们发现make也捉襟见肘,因为编写Makefile文件又会变得异常复杂。这个时候聪明的程序猿就想能不能有个程序可以帮我写Makefile文件呢?这样就引出了Cmake,当然Cmake不是智能的,它不可能自己去辨别那些是代码,那些是文件,需要什么库。这样就引入了另外一套规则,也引入了一个文件CMakeLists.txt,这个文件就是Cmake程序识别的文件,有这个文件,Cmake就能帮助程序猿自动生成Makefile文件。

       总的来说流程应该是这样的:

                                    cmake                            make

       CMakeLists.txt-------------->Makefile---------------------->可执行文件

                                                                             src,lib


        看过px4源码文件的朋友肯定会发现里面有很多CMakeLists.txt文件,事实上整个px4源码的文件都是基于CMakeLists.txt的(Nuttx系统不是,Nuttx是基于Makefile的,px4源码基本都在Firmware/src下,Nuttx操作系统源码在Firmware/NuttX下)

       有了上面这个两个概念之后,我们就开始着手编写我们的hello world程序。

       首先进入/Firmware/src/examples文件夹,然后在这个文件夹下面建立一个文件夹hello_world,再进入hello_world文件夹,在该文件夹下建立两个文件:CMakeLists.txt,hello_world.c。

       首先编辑hello_world.c文件。

      

    #include <px4_config.h>
    #include <px4_tasks.h>
    #include <px4_posix.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <poll.h>
    #include <string.h>
    
    
    __EXPORT int hello_world_main(int argc, char *argv[]);
    
    int hello_world_main(int argc, char *argv[]){
    
    	PX4_INFO("hello world!");
    
    	return 0;
    }

      然后编辑CMakeLists.txt文件

     

    px4_add_module(
    	MODULE examples__hello_world
    	MAIN hello_world
    	STACK_MAIN 2000
    	SRCS
    		hello_world.c
    	DEPENDS
    		platforms__common
    	)


    最后最重要的是我们要将这个程序注册到Nuttx的系统当中

    找到文件/Firmware/cmake/configs/nuttx_px4fmu-v2_default.cmake

    针对不同的硬件所注册的文件是不同的,下面是不同硬件的注册方式:

    在cmake文件中添加“examples/hello_world”

    像下面这样:

     

    include(nuttx/px4_impl_nuttx)
    
    set(CMAKE_TOOLCHAIN_FILE ${PX4_SOURCE_DIR}/cmake/toolchains/Toolchain-arm-none-eabi.cmake)
    
    set(config_uavcan_num_ifaces 2)
    
    set(config_module_list
    	#
    	# Board support modules
    	#
    	drivers/device
    	drivers/stm32
    	drivers/stm32/adc
    	drivers/stm32/tone_alarm
    	drivers/led
    	drivers/px4fmu
    	drivers/px4io
    	drivers/boards/px4fmu-v2
    	drivers/rgbled
    	drivers/mpu6000
    	#drivers/mpu9250
    	drivers/lsm303d
    	drivers/l3gd20
    	drivers/hmc5883
    	drivers/ms5611
    	#drivers/mb12xx
    	#drivers/srf02
    	drivers/sf0x
    	#drivers/ll40ls
    	drivers/trone
    	drivers/gps
    	drivers/pwm_out_sim
    	#drivers/hott
    	#drivers/hott/hott_telemetry
    	#drivers/hott/hott_sensors
    	#drivers/blinkm
    	drivers/airspeed
    	drivers/ets_airspeed
    	drivers/meas_airspeed
    	#drivers/frsky_telemetry
    	modules/sensors
    	#drivers/mkblctrl
    	drivers/px4flow
    	#drivers/oreoled
    	#drivers/vmount
    	drivers/pwm_input
    	drivers/camera_trigger
    	drivers/bst
    	#drivers/snapdragon_rc_pwm
    	drivers/lis3mdl
    
    	#example
    	examples/px4_simple_app
    	examples/hello_world
    
    	#
    	# System commands
    	#
    	systemcmds/bl_update
    	systemcmds/config
    	systemcmds/dumpfile
    	#systemcmds/esc_calib
    	systemcmds/mixer
    	#systemcmds/motor_ramp
    	systemcmds/mtd
    	systemcmds/nshterm
    	systemcmds/param
    	systemcmds/perf
    	systemcmds/pwm
    	systemcmds/reboot
    	#systemcmds/sd_bench
    	systemcmds/top
    	#systemcmds/topic_listener
    	systemcmds/ver
    
    	#
    	# Testing
    	#
    	#drivers/sf0x/sf0x_tests
    	#drivers/test_ppm
    	#lib/rc/rc_tests
    	#modules/commander/commander_tests
    	#modules/controllib_test
    	#modules/mavlink/mavlink_tests
    	#modules/unit_test
    	#modules/uORB/uORB_tests
    	#systemcmds/tests
    
    	#
    	# General system control
    	#
    	modules/commander
    	modules/load_mon
    	modules/navigator
    	modules/mavlink
    	modules/gpio_led
    	modules/uavcan
    	modules/land_detector
    
    	#
    	# Estimation modules
    	#
    	modules/attitude_estimator_q
    	#modules/position_estimator_inav
    	modules/local_position_estimator
    	modules/ekf2
    
    	#
    	# Vehicle Control
    	#
    	modules/fw_pos_control_l1
    	modules/fw_att_control
    	modules/mc_att_control
    	modules/mc_pos_control
    	modules/vtol_att_control
    
    	#
    	# Logging
    	#
    	#modules/logger
    	modules/sdlog2
    
    	#
    	# Library modules
    	#
    	modules/param
    	modules/systemlib
    	modules/systemlib/mixer
    	modules/uORB
    	modules/dataman
    
    	#
    	# Libraries
    	#
    	lib/controllib
    	lib/mathlib
    	lib/mathlib/math/filter
    	lib/ecl
    	lib/external_lgpl
    	lib/geo
    	lib/geo_lookup
    	lib/conversion
    	lib/launchdetection
    	lib/terrain_estimation
    	lib/runway_takeoff
    	lib/tailsitter_recovery
    	lib/DriverFramework/framework
    	platforms/nuttx
    
    	# had to add for cmake, not sure why wasn't in original config
    	platforms/common
    	platforms/nuttx/px4_layer
    
    	#
    	# OBC challenge
    	#
    	#modules/bottle_drop
    
    	#
    	# Rover apps
    	#
    	#examples/rover_steering_control
    
    	#
    	# Demo apps
    	#
    	#examples/math_demo
    	# Tutorial code from
    	# https://px4.io/dev/px4_simple_app
    	#examples/px4_simple_app
    
    	# Tutorial code from
    	# https://px4.io/dev/daemon
    	#examples/px4_daemon_app
    
    	# Tutorial code from
    	# https://px4.io/dev/debug_values
    	#examples/px4_mavlink_debug
    
    	# Tutorial code from
    	# https://px4.io/dev/example_fixedwing_control
    	#examples/fixedwing_control
    
    	# Hardware test
    	#examples/hwtest
    )
    
    set(config_extra_builtin_cmds
    	serdis
    	sercon
    	)
    
    set(config_io_board
    	px4io-v2
    	)
    
    set(config_extra_libs
    	uavcan
    	uavcan_stm32_driver
    	)
    
    set(config_io_extra_libs
    	)
    
    add_custom_target(sercon)
    set_target_properties(sercon PROPERTIES
    	PRIORITY "SCHED_PRIORITY_DEFAULT"
    	MAIN "sercon" STACK_MAIN "2048"
    	COMPILE_FLAGS "-Os")
    
    add_custom_target(serdis)
    set_target_properties(serdis PROPERTIES
    	PRIORITY "SCHED_PRIORITY_DEFAULT"
    	MAIN "serdis" STACK_MAIN "2048"
    	COMPILE_FLAGS "-Os")


    这样cmake的编译系统就会将这个程序加入到编译链中去了。

     在Firmware文件夹下面执行make px4fmu-v2_default,如果不出问题的话,编译成功会显示下面的画面:


     然后将硬件连接至虚拟机,执行烧录命令:make px4fmu-v2_default upload

      按照上一篇文章所讲的那样同Nuttx shell通信


    ./mavlink_shell.py /dev/ttyACM0




    在nsh中输入help命令之后,你就会在Builtin Apps下面找到hello_world程序


    执行hello_world程序:



    可以看到输出了hello world!

    那么这一切是怎么做到的呢?首先看看代码文件即hello_world.c文件

    首先是include

    #include <px4_config.h>
    #include <px4_tasks.h>
    #include <px4_posix.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <poll.h>
    #include <string.h>

    这些库文件你可以认为是编写基于Nuttx操作系统修改的px4程序程序必不可少的库文件包含(其实px4团队修改了不少Nuttx操作系统的东西,使其使用更加方便,所以这些程序并不是真正意义上的Nuttx程序)


    然后是main函数(这里要提醒一下广大同学,可能px4基于stm32的编译器语法规则过于严格,所以在编写一个函数之前,必须要去申明这个函数,即使这个函数是main函数也要申明,不然编译报错,无法通过)

    int hello_world_main(int argc, char *argv[]){
    
    	PX4_INFO("hello world!");
    
    	return 0;
    }

    可以看到基于Nuttx操作系统的main函数和其它系统的命名有很大不同,但也有自己的规律,那就是函数名+_+main,即 name_main(),程序主函数里的参数(int argc, char *argv[])和其它系统main函数所带的参数没什么不同(如果不懂main函数带形参的同学最好自己百度一下,因为px4的那些程序基本都带参数的)。

     PX4_INFO();是一个类似于printf的函数(事实上他就是是基于printf实现的),用来输出PX4的一些信息的。

     再来看看CMakeLists.txt文件

    px4_add_module(
    	MODULE examples__hello_world
    	MAIN hello_world
    	STACK_MAIN 2000
    	SRCS
    		hello_world.c
    	DEPENDS
    		platforms__common
    	)

    从字面上可以了解到每个程序在CMake里面都是一个模块,最后总的Cmake文件会去自动将这些模块添加到最后的生成的Makefile文件里面。所以我们要做的就是把我们写的模块的一些属性描写清楚,然后将其注册到nuttx_px4fmu-v2_default.cmake文件当中。

      首先是模块名MODULE:这个名字的命名规则是当前文件夹+__+主函数名。

      然后是MIAN :这个就是用来确定代码中那个函数为主函数的,填写主函数名即可。

      STACK_MAIN:目前暂不清楚用途

      SRCS:所用到的源文件。

      DEPENDS :依赖。


     以上就是关于编写一个基于Nuttx操作系统hello world程序的全过程。

    因为我本人对Cmake的一些语法还不是很清楚,所以以上有些东西可能描述的不是很清楚,如有大神,还望指点。


    下面一篇文章我将简介一下大家都很关心和迫切想知道的问题,就是px4的飞控程序是怎么开始执行的,程序入口在哪。



    展开全文
  • PX4自动驾驶仪软件可分为三大部分:实时操作系统、中间件和飞行控制栈。1.NuttX实时操作系统:提供POSIX-style的用户操作环境,进行底层的任务调度。2.PX4中间件:PX4中间件运行于操作系统之上,提供设备驱动和一个...

    PX4自动驾驶仪软件可分为三大部分:实时操作系统、中间件和飞行控制栈。

    1.NuttX实时操作系统:

    提供POSIX-style的用户操作环境,进行底层的任务调度。

    2.PX4中间件:

    PX4中间件运行于操作系统之上,提供设备驱动和一个微对象请求代理(micro object request broker,uORB)用于驾驶仪上运行的单个任务之间的异步通信。我的理解是完全可以将它看成为一种进程间通信机制。

    3.PX4飞行控制栈:

    飞行控制栈可以使用PX4的控制软件栈,也可以使用其他的控制软件,如APM:Plane、APM:Copter,但必须运行于PX4中间件之上。
    此部分又可分为3部分:

    • 决策导航部分:
      根据飞行器当前飞行状态和接收的用户命令,决定工作模式和飞行任务。

    • 位置姿态估计部分:
      通过传感器获取自身的位置和姿态信息。

    • 位置姿态控制部分:
      根据期望与当前的位置和姿态控制飞行状态以达到期望位置和姿态。

    • 控制器输出部分:
      mixer和执行器,pwm限幅。

    展开全文
  • 再也不怕PX4编译失败了……

    欢迎交流~ 个人 Gitter 交流平台,点击直达:Gitter


    更新于2017.3.13

    FAQ

    本文说明针对 PX4 Firmware 1.6.0

    • 问题 1: 找不到python jinja2模块
    CMake Error at /usr/share/cmake-3.2/Modules/FindPackageHandleStandardArgs.cmake:138 (message):
      couldn't find python module jinja2:
    
      		
    
      for debian systems try: 		
    
      	sudo apt-get install python-jinja2 		
    
      or for all other OSs/debian: 		
    
      	pip install jinja2
    
       (missing:  PY_JINJA2) 
    Call Stack (most recent call first):
      /usr/share/cmake-3.2/Modules/FindPackageHandleStandardArgs.cmake:374 (_FPHSA_FAILURE_MESSAGE)
      cmake/common/px4_base.cmake:1295 (find_package_handle_standard_args)
      CMakeLists.txt:276 (px4_find_python_module)
    
    
    -- Configuring incomplete, errors occurred!
    

    解决方案:缺什么安什么

    Windows系统下:
    pip install jinja2

    Linux系统下:
    sudo apt-get install python-jinja2

    • 问题 2: Windows下出现rsync error错误
    The source and destination cannot both be remote
    rsync error: syntax or usage error (code 1) at /usr/src/rsync/rsync-3.0.8/main.c(1148) [receiver=3.0.8]
    make[3]: *** [nuttx_copy_px4fmu-v2.stamp] Error 1
    make[2]: *** [CMakeFiles/nuttx_copy_px4fmu-v2.dir/all] Error 2
    make[2]: *** Waiting for unfilished jobs....
    The source and destination cannot both be remote
    rsync error: syntax or usage error (code 1) at /usr/src/rsync/rsync-3.0.8/main.c(1148) [receiver=3.0.8]
    make[3]: *** [src/modules/px4iofirmware/nuttx_copy_px4fmu-v2.stamp] Error 1
    make[2]: *** [src/modules/px4iofirmware/nuttx_copy_px4fmu-v2.dir/all] Error 2
    make[1]: *** [all] Error 2
    make[1]: *** [px4fmu-v2_default] Error 2
    

    解决方案:cmake nuttx rsync 仅使用相对路径进行复制

    对Firmware/cmake/nuttx/px4_impl_nuttx.cmake文件进行更改,点击传送门

    • **问题 3:**内存溢出
    collect2.exe:error:ld returned 1 exit status
    make[3]: *** [src/firmware/nuttx/firmware_muttx] Error 1
    make[2]: *** [src/firmware/nuttx/CMakeFiles/firmware_muttx.dir/all] Error 2
    make[1]: *** [all] Error 2
    make: *** [px4fmu-v2_default] Error 2
    

    解决方案:移除不是必要的模块. 配置在这里. 为了移除一个模块, 可以直接注释掉它:
    对于FMUv2(Pixhawk1)或者FMUv3(Pixhawk 2)硬件,找到Firmware/cmake/configs/nuttx_px4fmu-v2_default.cmake
    修改为:

    #drivers/trone
    

    即可

    • 问题 4: gcc 版本
    ![fail](https://img-blog.csdn.net/20170111094613912?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3FxRU52WTEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

    解决方案:gcc 4.8.4 已经过时了,目前支持的是 4.9.4还有 5.4.3版本。

    ![Date](https://img-blog.csdn.net/20170111093413714?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3FxRU52WTEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

    正文

    各个论坛以及QQ群中经常有人反应不知道怎么编译Pixhawk原生固件PX4,笔者也为这个问题苦恼了很久,最近一时兴起,想尝试下官网的写一个应用程序,但是原生代码都编译不过这可怎么能行,于是东查西试,解决了在Windows操作系统以及Ubuntu操作系统上编译PX4固件的问题。

    Windows 7 64bit

    软件安装


    首先,需要安装一些软件,CMake32位的Java jdk以及PX4 Toolchain Installer
    CMake的话笔者使用的是CMake-3.3.2-win32-x86版本。
    关于CMake的安装有一点需要注意,在第三步Install Options安装选项中,需要将CMake加入到系统路径中:
    cmake
    Java sdk:
    java
    Eclipse 需要 Java,用命令 java -version 来查看 Java 是否配置 成功。
    cmd

    接下来进行PX4固件相关的配置,安装PX4 Toolchain Installer,默认安装在C盘根目录下,笔者不服,非要安装在D盘,安装的时候一路下一步就行。

    px4

    安装完以后在开始菜单会出现一套工具链包括,PX4Console、PX4Ecplise.
    toolchain

    代码编译


    打开PX4console,下载PX4固件,输入指令:

    git clone https://github.com/PX4/Firmware.git
    

    切换到Firmware文件夹,输入指令:

    cd Firmware
    

    之后输入指令:

    git submodule update --init --recursive
    

    (根据网速耗时有差异,耐心等待)

    关键一步

    在开始最后的编译之前,有一个步骤必不可少,将arm-none-eabi-gcc 4.7.4换成4.9.4或5.4.3,下载4.9.4版本的压缩文件,5.4.3版本

    ![gcc](https://img-blog.csdn.net/20170117091646778?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3FxRU52WTEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

    解压后将这四个文件夹复制并替换到PX4Toolchain安装目录下的toolchain文件夹下,这里笔者替换到的文件夹为D:\px4\toolchain。

    copyto

    随后启动PX4 Console控制台进行编译,先进入Firmware文件夹,输入指令:

    cd Firmware
    

    进行编译

    make px4fmu-v2_default
    

    (漫长的等待,可能需要半个小时)

    编译成功的界面如下:

    done

    如果在没有进行arm-none-eabi-gcc 4.7.4替换的情况下直接进行固件编译,则会出现如下所示的错误:

    nok

    为时不晚,依然来得及将下载好的4.9.4版arm-none-eabi-gcc解压并替换掉Toolchain文件夹下的相应文件。

    之后重启PX4Console控制台,首先还是先进入到Firmware文件夹下:

    cd Firmware
    

    输入指令:

    make clean
    

    清除上一次的编译,然后重新编译,输入指令:

    make px4fmu-v2_default
    

    (又是漫长的等待,但是等待都是值得的)
    done

    固件烧录

    将飞控板通过USB连接电脑,输入以下指令即可完成固件的烧录:

    make px4fmu-v2_default upload
    

    烧录成功的界面如下图:
    uploading

    配置Eclipse


    现在控制台已经编译成功了,接下来就是进行Eclipse的配置了

    • 打开PX4Eclipse。

    第一次启动时,选择好workplace,并勾选Use this as the default and……。由于笔者以D盘作为工作目录,因此这里依然保持将workplace放置在D盘。

    lalal

    • 建立工程

    File -> New -> Makefile Project with Existing Code。
    然后点击Browse……到D:\px4\Firmware,并选择Cross GCC,点击Finish。
    这里写图片描述

    然后进入Workbench:

    goto

    eclipse

    • 创建编译目标

    可以在右边板块中Make Target( 或者菜单 Window -> Show View -> Make Target 也可以打开),选中根文件夹(Firmware),可以创建新的 make Target(绿色圆形按钮)。 如创建目标 px4fmu-v2_default
    detail

    make

    px4fmu-v2_default创建好如下:

    Target

    同理创建目标:all,archives,clean,distclean,px4io-v2_default, px4fmu-v2_default upload

    • 各 make target 说明
      • clean – 删除编译的固件相关文件,不会清除archives
      • px4fmu-v2_default—FMU 固件
      • px4fmu-v2_default upload – 烧录固件到飞控板

    **提示:**与make有关的指令可以用Firmware/Makefile文件中查看

    • 路径配置
      必须配置好Eclipse软件的路径才能进行编译,这一步至关重要
      打开eclipse软件,打开目录栏的Project -> Priorities
      juno
      有点意思的是,你得先打开左边Firmware中的随便一个文件,否则Priorities这一项会是灰色的,无法进行操作。
      打开相应栏,更改CWD、PWD的路径:
      开始的路径(如果装在默认路径则为C:\px4)
      然后你的CWD路径为 C:\px4\Firmware
      这里将路径改为 /D/px4/Firmware
      差别不大,还望仔细,笔者当时在这个问题上可是纠结了特别久,无限的报错,not contain Cmakelists.txt。也是得到高人相助,开始人指出来笔者还根本看不出,然后仔细的发现原来是:“\”、“/”“这样的问题。
      然后再将PWD的路径也做相应的更改。

    • 编译固件
      点击上述Target中的px4fmu-v2_default,即可进行编译。此操作与在Console控制台中输入make有同样的效果。

    finish

    • 烧录固件
      固件的烧录可以直接使用QGC地面站进行。也可以在PX4 Console或者PX4 Eclipse中进行,编译成功后在PX4 Eclipse界面右侧点击Target中的px4fmu-v2_default upload即可进行固件的烧录。这样就可以将自己的算法加入到原生固件中了。

    upload

    至此,在Windows环境下编译Pixhawk原生固件PX4的操作已经完成。



    Ubuntu 14.04 LTS

    笔者同时也进行了Ubuntu上的环境搭建。跟随大流,笔者安装了Ubutnu 14.04 LTS虚拟机,64位操作系统。

    在Ubuntu上搭建环境相对简单许多,按照PX4中文维基官网的教程即可。

    工具链安装


    • 权限设置

    把用户添加到用户组 “dialout”(如果这步没做,会导致很多用户权限问题):

    sudo usermod -a -G dialout $USER
    

    然后注销后,重新登录,因为重新登录后所做的改变才会有效

    • 安装CMake
    sudo add-apt-repository ppa:george-edison55/cmake-3.x -y
    sudo apt-get update
    # 必备软件(python、git、qt)
    sudo apt-get install python-argparse git-core wget zip \
        python-empy qtcreator cmake build-essential genromfs -y
    # 仿真工具
    sudo add-apt-repository ppa:openjdk-r/ppa
    sudo apt-get update
    sudo apt-get install openjdk-8-jre
    sudo apt-get install ant protobuf-compiler libeigen3-dev libopencv-dev openjdk-8-jdk openjdk-8-jre clang-3.5 lldb-3.5 -y
    
    • 卸载模式管理器

    Ubuntu配备了一系列代理管理,这会严重干扰任何机器人相关的串口(或usb串口),卸载掉它也不会有什么影响。

    sudo apt-get remove modemmanager
    
    • 更新包列表和安装下面的依赖包
    sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded -y
    sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
    sudo apt-get update
    sudo apt-get install python-serial openocd \
        flex bison libncurses5-dev autoconf texinfo build-essential \
        libftdi-dev libtool zlib1g-dev \
        python-empy gcc-arm-none-eabi -y
    

    代码编译


    根据PX4中文维基官网教程。

    • 安装Git
    sudo apt-get install git-all
    
    • 下载代码
    mkdir -p ~/src
    cd ~/src
    git clone https://github.com/PX4/Firmware.git
    
    • 初始化
      先进入Firmware文件夹,进而进行初始化、更新子模块操作,耐心的等待……
    cd Firmware
    git submodule update --init --recursive
    
    • 编译
      在上一步的操作结束之后,即可进行编译:
    make px4fmu-v2_default
    

    注意到“make”是一个字符命令编译工具,“px4fmu-v2”是硬件版本,“default”是默认配置,所有的PX4编译目标遵循这个规则。

    与Windows环境中相同,这里也可能因为gcc-arm-none-eabi版本不对,需要进行版本升级到4.9.4,方法如下:

    • 下载gcc-arm-none-eabi 4.9.4,对于的文件夹命名为arm-none-eabi-4_9-2014q3
    wget https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q3-update/+download/gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2
    
    • 去旧迎新
    pushd .
    # => 卸载新版的gcc-arm-none-eabi
    sudo apt-get remove gcc-arm-none-eabi
    # => 安装下载好的gcc-arm-none-eabi
    tar -jxf gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2
    sudo mv gcc-arm-none-eabi-4_9-2015q3 /opt
    exportline="export PATH=/opt/gcc-arm-none-eabi-4_9-2015q3/bin:\$PATH"
    if grep -Fxq "$exportline" ~/.profile; then echo nothing to do ; else echo $exportline >> ~/.profile; fi
    # => 使路径生效
    . ~/.profile
    popd
    

    对于GCC5.4.3版本的下载:

    wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2
    

    其余操作不再赘述

    PX4 中文维基 同步更新。


    笔者装的是Ubuntu 64位系统,而上述arm-none-eabi是直接下载的编译好的32位,还需要安装一个东西

    sudo apt-get install lsb-core
    

    可以检查arm-none-eabi 4.9是否安装成功,输入以下指令:

    arm-none-eabi-gcc --version
    

    如果出现如下信息,交叉编译环境搭建就没有什么问题了

    ~$ arm-none-eabi-gcc --version
    arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977]
    Copyright (C) 2014 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    
    • 编译
    cd ~/src/Firmware
    make px4fmu-v2_default
    

    进入Firmware所在的文件夹,make成功后,显示如下:
    ok

    Ninja

    Ninja比Make更快,并且PX4的CMake生成器可以支持它。不幸的是,Ubuntu目前只支持一个非常过时的版本。

    这里博主下载二进制文件并添加到系统路径来安装最新版本的Ninja

    mkdir -p $HOME/ninja
    cd $HOME/ninja
    wget https://github.com/martine/ninja/releases/download/v1.6.0/ninja-linux.zip
    unzip ninja-linux.zip
    rm ninja-linux.zip
    exportline="export PATH=$HOME/ninja:\$PATH"
    if grep -Fxq "$exportline" ~/.profile; then echo nothing to do ; else echo $exportline >> ~/.profile; fi
    . ~/.profile
    

    按上面的方法配置好ninja之后,以后每次一make都会调用它,这样编译速度会更快。

    如果不想使用ninja的话,可以将其从’~/.profile’中注释掉。

    #export PATH=/home/fantasy/ninja:$PATH

    Qt Creator


    Qt Creator是官方唯一支持的IDE,在Ubuntu上针对PX4固件使用,便于看代码的同时也可以进行编译烧录。

    • 安装Qt
    sudo apt-get install qtcreator
    

    Qt Creator的常见功能如下:
    create

    在打开Qt之前,应该创建project文件:

    cd ~/src/Firmware
    mkdir ../Firmware-build
    cd ../Firmware-build
    cmake ../Firmware -G "CodeBlocks - Unix Makefiles"
    #可以发现Firmware-build目录生成了一些文件
    

    提个醒: 按照官网上面最后一行的命令,当前使用Qt编译得到的将是build px4 ,因为默认的编译指令是make posix_sitl_default,这不是大家所期待的结果。

    解决方案:对于,Pixhawk硬件,将最后一行改成
    cmake ../Firmware -G "CodeBlocks - Unix Makefiles" -DCONFIG=nuttx_px4fmu-v2_default

    其他例如使用FMUv4的用户请根据需求进行替换。

    • 打开Qt
      Qt
      Ubuntu用户只要导入主文件夹里的CMakeLists.txt文件就可以了,打开Qt,通过File -> Open File or Project -> 选择CMakeLists.txt (默认位置在Firmware文件夹根目录下)
      open

    • 项目配置
      选择src/Firmware-build作为构建目录
      build
      运行设置
      run

    • 编译
      runit

    • 上传

    upload2

    笔者刚开始的时候发现Qt中默认显示的固件不全,很多文件都没有显示,如下图所示
    leave

    进行下面的操作就哦可了

    qtt

    file

    Eclipse on Ubuntu

    ![ecl](https://img-blog.csdn.net/20170228131211295?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3FxRU52WTEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

    在Windows下习惯了使用Eclipse的用户也可以直接在Ubuntu下使用Eclipse进行开发,与Qt一样,这也是一款跨平台的IDE。
    就是Java配置有点复杂,用起来却是非常方便的,除了不用更改环境设置,其他的都与Windows下无异,此处不在赘述。

    一个很棒的特点就是Ubuntu下的Eclipse可以直接加中文注释,这是别的编译器没有的,我尝试了用Sublime看代码,定义跳转不太给力,Qt打开工程很慢。

    目前为止最好的方法还是虚拟机,Windows改一行代码编译上传可能需要五分钟,非常费劲,但是Ubuntu可以说是极速。但是Windows下有很多好用的工具便于调试,Source Insight看代码也是很给力。虚拟机完美

    至此,在Windows已经Ubuntu下的环境搭建已经全部搭建成功。

    现在是2016.7.26 19:37 为了确保方法的有效性,笔者已经在都装有Ubuntu虚拟机的笔记本和台式机上用上述方法完成了两种系统下环境搭建、代码编译的复现,亲测有效。

    Tips

    下载特定版本的固件

    PX4Firmware有非常多的发行版,可以从这里看到。

    ![release](https://img-blog.csdn.net/20170319015205379?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3FxRU52WTEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

    也可以在这里进行选择:

    ![tag](https://img-blog.csdn.net/20170319015339786?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3FxRU52WTEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

    其实下载链接都是https://github.com/PX4/Firmware.git。

    ~$:cd ~/src/Firmware
    # 查看标签(版本)
    ~$:git tag
    ...
    v1.4.0rc1
    v1.4.0rc2
    v1.4.0rc3
    v1.4.0rc4
    v1.4.1rc1
    v1.4.1rc2
    ...
    # 新建一个工作分区并切换到目标版本
    git checkout -b branch_name tag_name
    

    这样就可以使用你想要的任意版本固件进行开发了。(因为可能有的版本确实不太稳定)

    Makefile

    # Don't be afraid of this makefile, it is just passing
    # arguments to cmake to allow us to keep the wiki pages etc.
    # that describe how to build the px4 firmware
    # the same even when using cmake instead of make.
    

    Makefile只是将参数传递给cmake。所有与make相关的指令都可以在这里找到,也可以自定义编译指令,比如

    #  explicity set default build target
    fantasy: px4fmu-v2_default
    

    于是博主编译固件变成下面这个样子:

    ~$:~/src/Firmware $ make fantasy
    PX4 CONFIG: px4fmu-v2_default
    ninja: no work to do.
    

    做这些只为让遇到相同问题的人少走弯路,专注核心问题,这也是笔者开展PX4中文维基汉化项目的初衷。
    还望志同道合的你们多多支持!~

    Just Enjoy It .

                                              <font face=“Segoe Script” size 12>By Fantasy

    展开全文
  • /******************************************************************************************... px4硬件:某宝销量最高的pixhawk套件(主机,gps+指南针,数传,pwm转pmm,安全开关,蜂鸣器,电源转换接头)  遥
  • 目前,PX4已经发展了四年多,PX4原生固件也日趋完善。对于工程开发人员,如何准确、...PX4使用了NuttX操作系统,即一款基于POSIX标准的高效嵌入式操作系统。该系统资料少,极大地依赖POSIX标准,对于一般嵌入式开发人
  • Px4源码框架结构图

    2016-06-15 18:04:27
    PX4自动驾驶仪软件可分为三大部分:实时操作系统、中间件和飞行控制栈。 1.NuttX实时操作系统 提供POSIX-style的用户操作环境(如printf(), pthreads,/dev/ttyS1,open(),write(),poll(),ioctl()),进行底层的任务...
  • /*****************************************************************************************... px4硬件:某宝销量最高的pixhawk套件(主机,gps+指南针,数传,pwm转pmm,安全开关,蜂鸣器,电源转换接头)  遥
  • 写在前面虽然有很多关于px4博客,但还是想自己亲手写,一来记录...2.nuttx操作系统介绍 ; 3.px4代码结构; 4.uORB介绍; 5.关键模块代码分析; 6.添加自己的代码; 7.与ros通信; 8.在模拟器中测试所写代码。 等等。
  • PX4开发环境搭建

    2019-08-01 09:13:54
    很多朋友在搭建PX4开发环境的时候都会出现一些环境配置的问题,今天笔者就来总结一下ubuntu系统下搭建PX4开发环境的过程。想要开发PX4的朋友强烈建议安装ubuntu系统,在windows下只会遇到很多问题,既不方便,编译...
  • PX4例程学习

    2018-12-18 20:18:13
    PX4的源代码中提供了一些学习例程,对于PX4的二次开发非常有用。现在学习下,应该有很多能够运用上的东西。例程的目录位于Firmware\src\examples目录下,每个目录是独立的应用程序,包含需要用到的源代码和CMake文件...
  • PX4固件是Pixhawk飞行控制器的官方固件,Pixhawk官网也给出了Linux/windows下搭建开发环境的方法。由于种种原因,搭建开发环境时总会遇到各种各样的bug,致使PX4固件编译失败。虽然官方给出了一键搭建开发环境的...
  • 它实际上是一个操作系统,上面运行着很多应用程序(类比windows),比如姿态解算,位置解算,姿态控制,位置控制等。每个应用之间通过uORB通信。所以要想读懂px4的程序,就不能按照单片机的思维,先找main函数,再看...
  • 在了解px4启动之前我们需要了解一下bootloader。Bootloader是在操作系统内核运行之前运行,可以初始化硬件设备,建立内存空间映射图等,整个系统的加载启动任务就是完全由Bootloader来完成的。它还是嵌入式系统在加...
  • px4源码结构分析Px4源码目录
  • PX4日志文件分析

    2018-04-09 12:10:02
    FlightPlot画图软件:http://www.pixhawk.com/dev/flightplot支持的日志格式:PX4自动驾驶仪日志(.px4log由sdlog2生成)APM二进制日志(.bin存储在SD卡上的文件)(添加到v.0.2.6中)ULog(.ulg文件,由新的PX4记录...
  • px4基本知识

    2017-09-10 11:29:32
    1PX4自驾仪 PX4是与平台无关的自动驾驶仪软件(或称为固件),可以...PX4地面控制站被称为QGroundControl,是PX4自驾系统不可分割的一部分,可以运行在Windows,OS X或Linux等多个平台。 使用QGroundContro
  • 在Ubuntu上搭建环境相对简单许多,按照PX4中文维基官网的教程即可。 工具链安装 权限设置 把用户添加到用户组 “dialout”(如果这步没做,会导致很多用户权限问题): .1 sudo usermod -a -G dialout $...
  • 首先,大体了解PX4IO 与PX4FMU各自的任务 PX4IO(STM32F100)为PIXHAWK 中专用于处理输入输出的部分,输入为支持的各类遥控器(PPM,SPKT/DSM,SBUS), 输出为电调的PWM 驱动信号, 它与PX4FMU(STM32F427)通过串口进行通信...
1 2 3 4 5 ... 20
收藏数 97,158
精华内容 38,863
热门标签