当前位置:   article > 正文

px4启动流程

px4启动流程

PX4操作系统介绍

Nuttx 是一个实时嵌入式操作系统(Embedded RTOS),它很小巧,在微控制器环境中使用。Nuttx完全可扩展,可从从小型(8位)至中型嵌入式(32位)系统。它的设计目的还在于完全符合POSIX标准,完全实时,并完全开放。
从编程的角度来看,Nuttx文件系统看起来与Linux文件系统非常类似,但是,有一个根本的区别:Nuttx根文件系统是一个伪文件系统,而真正的文件系统可以挂载在伪文件系统中;相比之下,在典型的Linux安装中,Linux根文件系统是一个真正的文件系统,伪文件系统挂载在真正的根文件系统中。Nuttx选择的方法,旨在提供从非常小的平台到中等平台等的支持,以便具备更好的可扩展性。

PX4启动流程

px4操作系统nuttx为嵌入式实时操作系统,该系统类linux系统,在unix基础上进行裁剪。初学者对于程序的认知,大多数都是从main()函数开始启动, 实际上我们接触的所有软件程序,使用到的main函数都不是程序实际开始运行的入口,只是用户程序的入口而已。从这个角度而言,PX4的每个任务的main函数都是该任务的入口。这一篇我们分析一下PX4是如何从单片机的启动入口引导到应用任务启动的。
Nuttx操作系统和大多数操作系统相似,都先进入Bootloader启动引导程序,然后再启动fmu和io的操作系统。
PX4的启动流程分为两个部分,第一部分为Nuttx的启动,到加载nsh启动脚本;第二部分为PX4启动脚本的执行,用于启动PX4的所有应用程序。

在这里插入图片描述
一、第一部分Nuttx的启动流程:飞控程序跑起来之前的操作——bootloader
Bootloader是系统上电后启动的一段引导程序,负责引导进入Nuttx系统。

1.1bootloader和Nuttx启动
在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。

Bootloader是嵌入式系统在上电后执行的第一段代码,在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌入式应用程序装在到内存中然后跳转到操作系统所在的空间,启动操作系统运行.

1.2主处理器和协处理器的固件烧写和运行流程
在这里插入图片描述
上图为主处理器和协处理器,固件下载到固件运行的流程图。值得说明的一点是分别给两个处理器下载blootloader以后,主处理器等待下载飞控固件,用地面站通过USB向飞控固件,下载完以后,主处理器的飞控固件启动,这时候通过串口给协处理器下载固件(固件只是下载一次)。这个工作完成之后,主处理器和协处理器同时开始工作。

Firmware\src\modules\px4iofirmware 这里面主要是一些,IO口的操作和安全开关的操作。他会在编译飞控固件的时候,一起被编译成为px4io-v2.bin,放在NUTTX文件系统中,在主处理器运行的时候把这个固件烧写进入协处理器。具体的烧写到单片机的FLASH哪个位置由px4io.cpp文件设置。

从编译后文件.map文件中,可以观察到fmu和io板都是从stm32_start.o文件开始启动。在这里插入图片描述
在这里插入图片描述
对应路径

/platforms/nuttx/NuttX/nuttx/arch/arm/src/stm32/stm32_start.c
  • 1

void __start(void)描述:This is the reset entry point.就是复位进入的函数,跟32的启动文件进入main函数一个意思。

一开始进行了一系列初始化一系列初始化:

stm32_clockconfig();
stm32_fpuconfig();
stm32_lowsetup();
stm32_gpioinit();
showprogress(‘A’);
  • 1
  • 2
  • 3
  • 4
  • 5

跟踪下去函数,会发现会根据不同的宏定义去配置不同的东西,也就是说不同的芯片对应宏定义不同。

以stm32_gpioinit为例子,它进入stm32_gpioremap函数
关于stm32_gpioremap函数的说明是:

Based on configuration within the .config file, this function will remaps positions of alternative functions.
  • 1

里面有一些宏定义CONFIG_STM32_STM32F10XX来自于nuttx/config.h
config.h说自己是自动生成的,它是根据.config生成的。

这里说一下这个.config文件怎么来的,如果之前做过linux驱动移植,那么这东西一定比较眼熟了,他是通过剪裁得来的,NuttX的所有操作都对标的unix规范。

目前先不纠结这个,知道它是根据不同的.config生成不同的宏定义,在同样的上层文件里配置不同的初始化工作就行,这些初始化的宏定义和初始化函数不会去人为的去改动,统一由nuttx的剪裁来完成,并且自动生成。

继续看void __start(void)
最终由go_nx_start进入nx_start()
函数定义在/platforms/nuttx/NuttX/nuttx/sched/init/nx_start.c
整个系统的启动在这里,启动了内存分配,时间调度,调试中端和log等等
感兴趣区域在最下方:

/_ Then start the other CPUs _/
DEBUGVERIFY(nx_smp_start());/_ Create initial tasks and bring-up the system _/
DEBUGVERIFY(nx_bringup());
nx_smp_start()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

启动了所有cpu,PIXHAWK包含一个F4和一个F1,启动操作最终指向了nuttx底层,最终进入:

/_ Create initial tasks and bring-up the system _/
DEBUGVERIFY(nx_bringup());
nx_bringup()
  • 1
  • 2
  • 3

在这个里面进入了 nx_create_initthread();
然后进入nx_start_application();

执行nx_start_application();

 pid = nxtask_create("init", CONFIG_USERMAIN_PRIORITY,
                      CONFIG_USERMAIN_STACKSIZE,
                      (main_t)CONFIG_USER_ENTRYPOINT,
                      (FAR char * const *)NULL);
  • 1
  • 2
  • 3
  • 4
进入CONFIG_USER_ENTRYPOINT
  • 1

这个CONFIG_USER_ENTRYPOINT开始就是最关注的应用层启动啦

对于FMU芯片,是nsh_main
对于IO芯片,是user_start
  • 1
  • 2

user_start是直接进入了一个死循环for (;声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】

推荐阅读
相关标签