日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

pixhawk PX4FMU和PX4IO最底层启动过程分析

發(fā)布時(shí)間:2024/4/18 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pixhawk PX4FMU和PX4IO最底层启动过程分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
摘要: pixhawk PX4FMU和PX4IO最底層啟動(dòng)過(guò)程分析1.1 主處理器和協(xié)處理器的固件燒寫和運(yùn)行流程首先,大體了解PX4IO 與PX4FMU各自的任務(wù)。PX4IO(STM32F100)為PIXHAWK 中專用于處理輸入輸出的部分,輸入為支持的各類遙控器(PPM ...

pixhawk PX4FMU和PX4IO最底層啟動(dòng)過(guò)程分析

1.1 主處理器和協(xié)處理器的固件燒寫和運(yùn)行流程

首先,大體了解PX4IO 與PX4FMU各自的任務(wù)。


PX4IO(STM32F100)為PIXHAWK 中專用于處理輸入輸出的部分,輸入為支持的各類遙控器(PPM,SPKT/DSM,SBUS), 輸出為電調(diào)的PWM 驅(qū)動(dòng)信號(hào), 它與PX4FMU(STM32F427)通過(guò)串口進(jìn)行通信。

PX4FMU :各種傳感器數(shù)據(jù)讀取、姿態(tài)解算、PWM控制量的計(jì)算、與PX4IO通信。負(fù)責(zé)飛控最主要的工作。

其中這兩處理器的固件燒寫運(yùn)行流程如下(也可以搜索相應(yīng)的文章):

主處理器和協(xié)處理器,固件下載到固件運(yùn)行的流程圖。值得說(shuō)明的一點(diǎn)是分別給兩個(gè)處理器下載blootloader以后,主處理器等待下載飛控固件,用地面站通過(guò)USB向飛控固件下載完以后,主處理器的飛控固件啟動(dòng),這時(shí)候通過(guò)串口給協(xié)處理器下載固件(固件只是下載一次)。這個(gè)工作完成之后,主處理器和協(xié)處理器同時(shí)開(kāi)始工作。

詳細(xì)可以看到如下代碼

#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]);//向協(xié)處理器下載固件

delete up;

這段代碼在px4io.cpp中,隨著px4io.cpp進(jìn)程啟動(dòng)而啟動(dòng)。功能就是由主處理器向協(xié)處理器燒寫代碼。

其中協(xié)處理器的固件源代碼在:

E:\Firmware-master\Firmware\src\modules\px4iofirmware?這里面主要是是一些,IO口的操作和安全開(kāi)關(guān)的操作。他會(huì)在編譯飛控固件的時(shí)候,一起被編譯成為px4io-v2.bin,放在NUTTX文件系統(tǒng)中,在主處理器運(yùn)行的時(shí)候把這個(gè)固件燒寫進(jìn)入?yún)f(xié)處理器。具體的燒寫到單片機(jī)的FLASH那個(gè)位置可以在px4io.cpp相關(guān)代碼找到。

在軟件層面的詳細(xì)流程圖如下:

1.2 Bootloader和NUTTX啟動(dòng)詳解

?????在嵌入式操作系統(tǒng)中,BootLoader是在操作系統(tǒng)內(nèi)核運(yùn)行之前運(yùn)行。可以初始化硬件設(shè)備、建立內(nèi)存空間映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個(gè)合適狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準(zhǔn)備好正確的環(huán)境。在嵌入式系統(tǒng)中,通常并沒(méi)有像BIOS那樣的固件程序(注,有的嵌入式CPU也會(huì)內(nèi)嵌一段短小的啟動(dòng)程序),因此整個(gè)系統(tǒng)的加載啟動(dòng)任務(wù)就完全由BootLoader來(lái)完成。Bootloader是嵌入式系統(tǒng)在加電后執(zhí)行的第一段代碼,在它完成CPU和相關(guān)硬件的初始化之后,再將操作系統(tǒng)映像或固化的嵌入式應(yīng)用程序裝在到內(nèi)存中然后跳轉(zhuǎn)到操作系統(tǒng)所在的空間,啟動(dòng)操作系統(tǒng)運(yùn)行.

? ?進(jìn)入px4/Bootloader可以看到main_f1、main_f4,分別對(duì)應(yīng)著PX4IO、PX4FMU的Bootloader.

值得注意的是單片機(jī)的二進(jìn)制代碼在單片機(jī)的啟動(dòng)位置

我們知道Pixhawk硬件使用STM32的芯片,

Cortex M3的內(nèi)核有三種啟動(dòng)方式,其分別是:

? ? ? A.通過(guò)boot引腳設(shè)置可以將中斷向量表定位于SRAM區(qū),即起始地址為0x2000000,同時(shí)復(fù)位后PC指針位于0x2000000處;
? ? ? B.通過(guò)boot引腳設(shè)置可以將中斷向量表定位于FLASH區(qū),即起始地址為0x8000000,同時(shí)復(fù)位后PC指針位于0x8000000處;
? ? ? C.通過(guò)boot引腳設(shè)置可以將中斷向量表定位于內(nèi)置Bootloader區(qū),
M3單片機(jī)復(fù)位后,從0x00000000取棧指針(SP),從0x00000004取復(fù)位向量(PC),有了棧指針和復(fù)位向量后,單片機(jī)就按照正常流程運(yùn)行了,單片機(jī)啟動(dòng)默認(rèn)先運(yùn)行BootLoader,所以默認(rèn)的中斷向量表位置是BootLoader的中斷向量表。我們知道
Bootloader是上電執(zhí)行的第一個(gè)代碼, Pixhawk的啟動(dòng)是通過(guò)B的方式來(lái)啟動(dòng)的,所以我們?cè)谙?/span>Bootloader的時(shí)候也是向FLASH這0x8000000地址燒寫的固件(具體可以看固件燒寫這篇文章),Bootloader燒寫成功以后每次上電就會(huì)啟動(dòng),啟動(dòng)的起始地址就是FLASH的0x8000000。Bootloader啟動(dòng)執(zhí)行到最后,會(huì)用匯編語(yǔ)句,自動(dòng)跳轉(zhuǎn)到FLASH中固件下載的位置,開(kāi)始執(zhí)行固件代碼。

NUTTX啟動(dòng)(也就是上面的固件代碼,匯編語(yǔ)句就是跳轉(zhuǎn)到這個(gè)位置來(lái)執(zhí)行stm32_start.c):

此部分摘自于pixhawk自學(xué)筆記之px4程序啟動(dòng)順序

代碼位置:Firmware/build_px4fmu-v2_default/px4fmu-v2/Nuttx/nuttx/arch/arm/src/stm32/stm32_start.c

__start-- #處理器執(zhí)行的第一條指令(px4使用的是stm32,入口在stm32_start.c中)

???stm32_clockconfig() ? #初始化時(shí)鐘

? ? rcc_reset() ? ? ? ?#復(fù)位rcc

? ? stm32_stdclockconfig() #初始化標(biāo)準(zhǔn)時(shí)鐘

? ? rcc_enableperipherals()#使能外設(shè)時(shí)鐘

------------------------------------------------------------------

? ? stm32_fpuconfig() ? ? ? ?#配置fpu

? ? stm32_lowsetup() ? ? ? ? #基本初始化串口,之后可以使用up_lowputc()

? ? stm32_gpioinit() ? ? ? ? #初始化gpio,只是調(diào)用stm32_gpioremap()設(shè)置重映射

? ? up_earlyserialinit() ? ? ?#初始化串口,之后可以使用up_putc()

? ? stm32_boardinitialize() ??

? ? stm32_spiinitialize() ? ? #初始化spi,只是調(diào)用stm32_configgpio()設(shè)置gpio

? ? stm32_usbinitialize() ? ? #初始化usb,只是調(diào)用stm32_configgpio()設(shè)置gpio

? ? up_ledinit(); ? ? ? ? ?#初始化led,只是調(diào)用stm32_configgpio()設(shè)置gpio

???----------------------------------------------------------------------------------------------

???stm32_start.c文件中我們會(huì)看到這么一句話:

? ??? /* Then start NuttX */

? ? showprogress('\r');

? ? showprogress('\n');

? ? os_start();系統(tǒng)開(kāi)始啟動(dòng)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

一下是?os_start()內(nèi)容:

? ? dq_init()? ? ? ? ? ? ? ????? ?? ??? ?????#初始化各種狀態(tài)的任務(wù)列表(置為null)

? ? ? ? g_pidhash[i]= ? ? ? ? ?????? ?? ???? #初始化唯一可以確定的元素--進(jìn)程ID

? ? ? ? g_pidhash[PIDHASH(0)]= ? ? ?#分配空閑任務(wù)的進(jìn)程ID為0

? ? ? ? g_idletcb=? ? ? ? ? ? ? ? ? ? ?? ? ? ?#初始化空閑任務(wù)的任務(wù)控制塊

? ? ? ? sem_initialize()-- ? ? ? ? ? ? ?? ? ?#初始化信號(hào)量 ? ? ? ? ? ? ? ?

? ? ? ? dq_init() ? ? ? ? ? ? ? ?? ? ? ? ? ?#將信號(hào)量隊(duì)列置為null

? ? ? ? sem_initholders() ? ? ? ? ? ? #初始化持有者結(jié)構(gòu)以支持優(yōu)先級(jí)繼承

? ? ? ? up_allocate_heap() ? ? ? ? #分配用戶模式的堆(設(shè)置堆的起點(diǎn)和大小)

? ? ? ? kumm_initialize() ? ? ? ? ? ?#初始化用戶模式的堆

? ? ? ? up_allocate_kheap() ? ? ? ?#分配內(nèi)核模式的堆

? ? ? ? kmm_initialize() ? ? ? ? ? ? ? #初始化內(nèi)核模式的堆

? ? ? ? task_initialize() ? ? ? ? ? ? ? ?#初始化任務(wù)數(shù)據(jù)結(jié)構(gòu)

? ? ? ? irq_initialize() ? ? ? ? ? ? ? ?? #將所有中斷向量都指向同一個(gè)異常中斷處理程序

? ? ? ? wd_initialize() ? ? ? ? ? ? ? ?? #初始化看門狗數(shù)據(jù)結(jié)構(gòu)

? ? ? ? clock_initialize() ? ? ? ? ? ? ? #初始化rtc

? ? ? ? timer_initialize() ? ? ? ? ? ? ? #配置POSIX定時(shí)器

? ? ? ? sig_initialize() ? ? ? ? ? ? ? ?? #初始化信號(hào)

? ? ? ? mq_initialize() ? ? ? ? ? ? ? ?? #初始化命名消息隊(duì)列

? ? ? ? pthread_initialize() ? ? ? ? ? #初始化線程特定的數(shù)據(jù),空函數(shù)

? ? ? ? fs_initialize()---? ? ? ? ? ? ? ? #初始化文件系統(tǒng) ? ? ? ? ? ? ?

? ? ? ? sem_init() ? ? ? ? #初始化節(jié)點(diǎn)信號(hào)量為1

? ? ? ? files_initialize() #初始化文件數(shù)組,空函數(shù)

? ? ? ? net_initialize()-- ? ? ? #初始化網(wǎng)絡(luò)

? ? ? ? uip_initialize() ??? ??#初始化uIP層

? ? ? ? net_initroute() ??? ???#初始化路由表

? ? ? ? netdev_seminit() ? #初始化網(wǎng)絡(luò)設(shè)備信號(hào)量

? ? ? ? arptimer_init() ? ?? ??#初始化ARP定時(shí)器

? ? ? ? up_initialize()--- ? ? ? #處理器特定的初始化

? ? ? ? up_calibratedelay()? ??? ?????#校準(zhǔn)定時(shí)器

? ? ? ? up_addregion() ??? ?????? ? ?? #增加額外的內(nèi)存段

? ? ? ? up_irqinitialize()?? ?????? ??? ??#設(shè)置中斷優(yōu)先級(jí),關(guān)聯(lián)硬件異常處理函數(shù)

? ? ? ? up_pminitialize() ?? ?????? ????#初始化電源管理

? ? ? ? up_dmainitialize()?? ?????? ????#初始化DMA

? ? ? ? up_timerinit() ? ??? ?????? ??? ???#初始化定時(shí)器中斷

? ? ? ? devnull_register()?? ?????? ??? ?#注冊(cè)/dev/null

? ? ? ? devzero_register()?? ?????? ????#注冊(cè)/dev/zero

? ? ? ? up_serialinit() ? ?? ?????? ??? ??? ?#注冊(cè)串口控制臺(tái)/dev/console和串口/dev/ttyS0

? ? ? ? up_rnginitialize()?? ?????? ??? ??#初始化并注冊(cè)隨機(jī)數(shù)生成器

? ? ? ? up_netinitialize()?? ?????? ??? ???#初始化網(wǎng)絡(luò),是arch/arm/src/chip/stm32_eth.c中的

? ? ? ? up_usbinitialize()?? ?????? ??? ???#初始化usb驅(qū)動(dòng)

? ? ? ? board_led_on() ? ??? ?????? ??? ???#打開(kāi)中斷使能led,但很快會(huì)被其它地方的led操作改變狀態(tài)

? ? ? ? lib_initialize() ? ? ? ?????? ??? ? ?#初始化c庫(kù),空函數(shù)

? ? ? ? group_allocate() ? ? ? ?????? ??#分配空閑組

? ? ? ? group_setupidlefiles() ? ? ? ?#在空閑任務(wù)上創(chuàng)建stdout、stderr、stdin

? ? ? ? group_initialize() ? ? ? ? ? ? ??#完全初始化空閑組

? ? ? ? os_bringup()------ ? ? ? ? ? ? ?#創(chuàng)建初始任務(wù)

? ? ? ? KEKERNEL_THREAD() ? ?#啟動(dòng)內(nèi)核工作者線程

? ? ? ? board_initialize() ? ? ? ? ? #最后一刻的板級(jí)初始化

? ? ? ? TASK_CREATE() ? ? ? ? ? ? #啟動(dòng)默認(rèn)應(yīng)用程序

? ? ? ? forup_idle() ? ? ? ? ? ? ? ? ? ?? ? ?#空閑任務(wù)循環(huán)

? ? ? ? for(;;) ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ?#不應(yīng)該到達(dá)這里

__start 負(fù)責(zé)STM32 芯片的底層初始化,包括時(shí)鐘,FPU,GPIO 等單元的初始化

os_start 負(fù)責(zé)OS 的底層初始化,包括各種隊(duì)列和進(jìn)程結(jié)構(gòu)的初始化

os_bringup 負(fù)責(zé)OS 基本進(jìn)程的啟動(dòng)以及用戶進(jìn)程的啟動(dòng),用戶啟動(dòng)入口由(CONFIG_USER_ENTRYPOINT)宏進(jìn)行指定是執(zhí)行nsh_main還是user_start。? ??

啟動(dòng)腳本分析


總結(jié)

以上是生活随笔為你收集整理的pixhawk PX4FMU和PX4IO最底层启动过程分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。