pixhawk PX4FMU和PX4IO最底层启动过程分析
pixhawk PX4FMU和PX4IO最底层启动过程分析
1.1 主处理器和协处理器的固件烧写和运行流程
首先,大体了解PX4IO 与PX4FMU各自的任务。
PX4IO(STM32F100)为PIXHAWK 中专用于处理输入输出的部分,输入为支持的各类遥控器(PPM,SPKT/DSM,SBUS), 输出为电调的PWM 驱动信号, 它与PX4FMU(STM32F427)通过串口进行通信。
PX4FMU :各种传感器数据读取、姿态解算、PWM控制量的计算、与PX4IO通信。负责飞控最主要的工作。
其中这两处理器的固件烧写运行流程如下(也可以搜索相应的文章):
主处理器和协处理器,固件下载到固件运行的流程图。值得说明的一点是分别给两个处理器下载blootloader以后,主处理器等待下载飞控固件,用地面站通过USB向飞控固件下载完以后,主处理器的飞控固件启动,这时候通过串口给协处理器下载固件(固件只是下载一次)。这个工作完成之后,主处理器和协处理器同时开始工作。
详细可以看到如下代码
#if defined(CONFIG_ARCH_BOARD_PX4FMU_V1)
fn[0] = "/etc/extras/px4io-v1.bin";
fn[1] = "/fs/microsd/px4io1.bin";
fn[2] = "/fs/microsd/px4io.bin";
fn[3] = nullptr;
#elif defined(CONFIG_ARCH_BOARD_PX4FMU_V2)
fn[0] = "/etc/extras/px4io-v2.bin";
fn[1] = "/fs/microsd/px4io2.bin";
fn[2] = "/fs/microsd/px4io.bin";
fn[3] = nullptr;
#else
#error "unknown board"
#endif
}
up = new PX4IO_Uploader;
int ret = up->upload(&fn[0]);//向协处理器下载固件
delete up;
这段代码在px4io.cpp中,随着px4io.cpp进程启动而启动。功能就是由主处理器向协处理器烧写代码。
其中协处理器的固件源代码在:
E:\Firmware-master\Firmware\src\modules\px4iofirmware 这里面主要是是一些,IO口的操作和安全开关的操作。他会在编译飞控固件的时候,一起被编译成为px4io-v2.bin,放在NUTTX文件系统中,在主处理器运行的时候把这个固件烧写进入协处理器。具体的烧写到单片机的FLASH那个位置可以在px4io.cpp相关代码找到。
在软件层面的详细流程图如下:
1.2 Bootloader和NUTTX启动详解
在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。Bootloader是嵌入式系统在加电后执行的第一段代码,在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌入式应用程序装在到内存中然后跳转到操作系统所在的空间,启动操作系统运行.
进入px4/Bootloader可以看到main_f1、main_f4,分别对应着PX4IO、PX4FMU的Bootloader.
值得注意的是单片机的二进制代码在单片机的启动位置
我们知道Pixhawk硬件使用STM32的芯片,
Cortex M3的内核有三种启动方式,其分别是:
A.通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;
B.通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;
C.通过boot引脚设置可以将中断向量表定位于内置Bootloader区,
M3单片机复位后,从0x00000000取栈指针(SP),从0x00000004取复位向量(PC),有了栈指针和复位向量后,单片机就按照正常流程运行了,单片机启动默认先运行BootLoader,所以默认的中断向量表位置是BootLoader的中断向量表。我们知道Bootloader是上电执行的第一个代码, Pixhawk的启动是通过B的方式来启动的,所以我们在下Bootloader的时候也是向FLASH这0x8000000地址烧写的固件(具体可以看固件烧写这篇文章),Bootloader烧写成功以后每次上电就会启动,启动的起始地址就是FLASH的0x8000000。Bootloader启动执行到最后,会用汇编语句,自动跳转到FLASH中固件下载的位置,开始执行固件代码。
NUTTX启动(也就是上面的固件代码,汇编语句就是跳转到这个位置来执行stm32_start.c):
此部分摘自于pixhawk自学笔记之px4程序启动顺序
代码位置:Firmware/build_px4fmu-v2_default/px4fmu-v2/Nuttx/nuttx/arch/arm/src/stm32/stm32_start.c
__start-- #处理器执行的第一条指令(px4使用的是stm32,入口在stm32_start.c中)
stm32_clockconfig() #初始化时钟
rcc_reset() #复位rcc
stm32_stdclockconfig() #初始化标准时钟
rcc_enableperipherals()#使能外设时钟
------------------------------------------------------------------
stm32_fpuconfig() #配置fpu
stm32_lowsetup() #基本初始化串口,之后可以使用up_lowputc()
stm32_gpioinit() #初始化gpio,只是调用stm32_gpioremap()设置重映射
up_earlyserialinit() #初始化串口,之后可以使用up_putc()
stm32_boardinitialize()
stm32_spiinitialize() #初始化spi,只是调用stm32_configgpio()设置gpio
stm32_usbinitialize() #初始化usb,只是调用stm32_configgpio()设置gpio
up_ledinit(); #初始化led,只是调用stm32_configgpio()设置gpio
----------------------------------------------------------------------------------------------
在stm32_start.c文件中我们会看到这么一句话:
/* Then start NuttX */
showprogress('\r');
showprogress('\n');
os_start();系统开始启动>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
一下是 os_start()内容:
dq_init() #初始化各种状态的任务列表(置为null)
g_pidhash[i]= #初始化唯一可以确定的元素--进程ID
g_pidhash[PIDHASH(0)]= #分配空闲任务的进程ID为0
g_idletcb= #初始化空闲任务的任务控制块
sem_initialize()-- #初始化信号量
dq_init() #将信号量队列置为null
sem_initholders() #初始化持有者结构以支持优先级继承
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()--- #初始化文件系统
sem_init() #初始化节点信号量为1
files_initialize() #初始化文件数组,空函数
net_initialize()-- #初始化网络
uip_initialize() #初始化uIP层
net_initroute() #初始化路由表
netdev_seminit() #初始化网络设备信号量
arptimer_init() #初始化ARP定时器
up_initialize()--- #处理器特定的初始化
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操作改变状态
lib_initialize() #初始化c库,空函数
group_allocate() #分配空闲组
group_setupidlefiles() #在空闲任务上创建stdout、stderr、stdin
group_initialize() #完全初始化空闲组
os_bringup()------ #创建初始任务
KEKERNEL_THREAD() #启动内核工作者线程
board_initialize() #最后一刻的板级初始化
TASK_CREATE() #启动默认应用程序
forup_idle() #空闲任务循环
for(;;) #不应该到达这里
__start 负责STM32 芯片的底层初始化,包括时钟,FPU,GPIO 等单元的初始化
os_start 负责OS 的底层初始化,包括各种队列和进程结构的初始化
os_bringup 负责OS 基本进程的启动以及用户进程的启动,用户启动入口由(CONFIG_USER_ENTRYPOINT)宏进行指定是执行nsh_main还是user_start。
启动脚本分析
pixhawk PX4FMU和PX4IO最底层启动过程分析相关推荐
- 嵌入式linux启动过程分析,嵌入式Linux裸机开发(二)——S5PV210启动过程分析
嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介 友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅 ...
- OpenWrt启动过程分析+添加自启动脚本【转】
一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107 总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/p ...
- linux 重定位arm,Arm linxu启动过程分析(一)
本文着重分析 FS2410 平台 linux-2.6.14 内核启动的详细过程,主要包括: zImage 解压缩阶段. vmlinux 启动汇编阶段. startkernel 到创建第一个进程阶段三个 ...
- linxu 启动过程分析
linxu 启动过程分析 Linux启动过程如下:当用户打开PC的电源,BIOS开机自检,按BIOS中设置的启动设备(通常是硬盘)启动,接着启动设备上安装的引导程序lilo或grub开始引导Linux ...
- 开机SystemServer到ActivityManagerService启动过程分析
开机SystemServer到ActivityManagerService启动过程 一 从Systemserver到AMS zygote-> systemserver:java入层口: /*** ...
- AliOS Things的启动过程分析(一)
AliOS Things的启动过程分析(一) 在本篇文章中,我们以developerkit开发板为例,介绍AliOS Things的启动过程.AliOS Things支持多种工具链进行编译链接的方式生 ...
- Chromium的GPU进程启动过程分析
Chromium除了有Browser进程和Render进程,还有GPU进程.GPU进程负责Chromium的GPU操作,例如Render进程通过GPU进程离屏渲染网页,Browser进程也是通过GPU ...
- Android开发入门教程2-Android init 启动过程分析
Android init 启动过程分析 分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linu ...
- 嵌入式linux s5pv210,嵌入式Linux裸机开发(二)——S5PV210启动过程分析
嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅三 ...
最新文章
- 在数据框中采样随机行
- Linux零基础初级教程
- 数据库记录的添加、修改、删除(DataAdapter、DataTable 、DataRow )
- SeqGAN——对抗思想与增强学习的碰撞
- mysql高并发下主键冲突
- Python datetime isocalendar()方法与示例
- crawler_微信采集方案
- jquery name选择器_jquery笔记
- Java面向对象知识总结
- 智能会议系统(17)--- Linphone用户注册
- 项目管理笔记(观念)
- 学生食堂信息管理系统
- 德语翻译器在线翻译中文-德语翻译器支持各大语言翻译
- win10找回自带的windows照片查看器——打开jpg、png、gif、psd其他格式的图片
- nltk 句子结构分析
- 阿里飞冰(Iceworks)入门和飞冰是干什么的
- 静下心来,无欲则刚——源自内心的骄傲
- 重构机器学习算法的知识体系 - 《终极算法》读书笔记
- vue cli3 配置sass全局变量设置不生效,sass混合器文件全局引入
- Cortex-M3处理器系统框图
热门文章
- PHP通过__call实现简单的AOP(主事务后的其他操作)比如前置通知,后置通知
- rest模式get,post,put,delete简单讲解
- 【php学习笔记】ticks篇
- javascript基础07
- 编写你的第一个 Django 应用,第 6 部分
- Plugin [id: 'org.jetbrains.kotlin.jvm'] was not found in any of the following sources:
- Spring_mvc ioc/DI 控制反转与依赖注入
- 操作ROS松灵机器人步骤及遇到的问题
- 【MFC】工具栏按钮追加显示文本
- 【STM32】中断相关函数和类型