• 正文
    • 1、背景
    • 2、代碼結(jié)構(gòu)概述
    • 3、如何安裝?
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

用統(tǒng)計(jì)數(shù)據(jù)揭示BaseFlight開(kāi)源飛控代碼工程的全貌

03/13 15:03 來(lái)源:直觀解
639
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

1、背景

Baseflight是一款開(kāi)源的飛行控制軟件,最初是MultiWii項(xiàng)目的32位分支,旨在為多旋翼、固定翼和直升機(jī)等飛行器提供高效的飛行控制解決方案。Baseflight的發(fā)展歷程可以追溯到MultiWii項(xiàng)目,它在性能和功能上進(jìn)行了顯著的優(yōu)化和擴(kuò)展,特別是在移植到更強(qiáng)大的32位處理器(如STM32)后,解決了早期8位單片機(jī)的性能瓶頸問(wèn)題。

1.開(kāi)源與社區(qū)支持

Baseflight是一個(gè)完全開(kāi)源的項(xiàng)目,代碼托管在GitHub上(https://github.com/multiwii/baseflight,下載其實(shí)幾百k,純c代碼的空間都不大),獲得了全球眾多開(kāi)發(fā)者和愛(ài)好者的貢獻(xiàn)和支持。

2.兼容多種硬件平臺(tái):

Baseflight支持多種流行的飛行控制器硬件,例如NAZE32、SKYLINE32 Mini等,這些硬件具有高性價(jià)比和良好的性能表現(xiàn)(http://www.yinyanmodel.com/ch/ProductView.asp?ID=393)。

3.豐富的配置選項(xiàng):

通過(guò)Baseflight Configurator圖形用戶界面,用戶可以方便地調(diào)整飛控參數(shù),如PID值、傳感器校準(zhǔn)等,以滿足不同的飛行需求。

所謂調(diào)整飛控參數(shù),就是調(diào)整源碼中類(lèi)似這種的變量:

float magneticDeclination = 0.0f; ? ? ? // calculated at startup from config

4.命令行CLI(command line)接口:

除了圖形界面外,Baseflight還提供了命令行接口(CLI),允許用戶直接通過(guò)串口進(jìn)行高級(jí)設(shè)置和調(diào)試操作。

5.家族譜系:

Baseflight是Cleanflight和Betaflight等后續(xù)項(xiàng)目的前身。Cleanflight在其基礎(chǔ)上增加了更多特性,而B(niǎo)etaflight則進(jìn)一步提升了性能,成為目前FPV競(jìng)速無(wú)人機(jī)中最常用的固件之一https://oscarliang.com/baseflight-cleanflight-comparison/。

2、代碼結(jié)構(gòu)概述

三層架構(gòu):驅(qū)動(dòng)-計(jì)算-工具

BaseFlight代碼通常采用分層架構(gòu)。最上層是與硬件交互的驅(qū)動(dòng)層,負(fù)責(zé)采集傳感器數(shù)據(jù)(如加速度計(jì)、陀螺儀、磁力計(jì)等)并將控制信號(hào)輸出到電機(jī)驅(qū)動(dòng)模塊。中間層是核心控制算法層,包含姿態(tài)估計(jì)、導(dǎo)航和控制算法等。最下層是一些基礎(chǔ)的工具函數(shù)庫(kù)。

圖1 筆者用source insight閱讀baseflight全代碼

主要文件的統(tǒng)計(jì)和解釋

整個(gè)項(xiàng)目不過(guò)1.6w行,78個(gè)文件。最大的文件是cli.c超過(guò)一千行(包含大量的交互處理,所以代碼多一點(diǎn)),其余文件均小于1k行,符合良好的c語(yǔ)言代碼設(shè)計(jì)規(guī)范。數(shù)量最多的是drv_開(kāi)頭的驅(qū)動(dòng)層程序。

其次是各種計(jì)算和控制文件,比如fw_nav,是前向?qū)Ш降囊馑?,也就是控制無(wú)人機(jī)往前飛。比如mixer是混合器,混合器是混合操控命令環(huán)境感知等等渠道的信息,形成最終的每個(gè)旋翼的電動(dòng)機(jī)的控制命令。

最后是各種輔助文件,包含各種輔助函數(shù),比如utils.c.h,比如printf.c.h。

還有一個(gè)不屬于上面三類(lèi)的重要文件makefile,是把baseflight編譯成固件.bin的核心文件,一般不要去改。

圖2 baseflight的簡(jiǎn)明項(xiàng)目報(bào)告

文件名 類(lèi)型 大小 行數(shù) 解釋
board.h src 9197 - 包含與硬件板相關(guān)的定義和配置信息的頭文件
buzzer.c src 6377 113 用于控制蜂鳴器源代碼文件
buzzer.h src 1756 - 包含與控制蜂鳴器相關(guān)的定義和函數(shù)聲明的頭文件
cli.c src 48960 917 用于處理命令行界面的源代碼文件
cli.h src 158 - 包含與命令行界面相關(guān)的定義和函數(shù)聲明的頭文件
config.c src 12733 316 用于處理配置信息的源代碼文件
drv_adc.c src 3462 63 用于控制ADC模數(shù)轉(zhuǎn)換器)的源代碼文件
drv_adc.h src 570 - 包含與控制ADC相關(guān)的定義和函數(shù)聲明的頭文件
drv_adxl345.c src 3486 60 用于控制ADXL345加速度計(jì)的源代碼文件
drv_adxl345.h src 189 - 包含與控制ADXL345加速度計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_ak8975.c src 1546 30 用于控制AK8975磁力計(jì)的源代碼文件
drv_ak8975.h src 122 - 包含與控制AK8975磁力計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_bma280.c src 1332 27 用于控制BMA280加速度計(jì)的源代碼文件
drv_bma280.h src 51 - 包含與控制BMA280加速度計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_bmp085.c src 9395 149 用于控制BMP085氣壓計(jì)的源代碼文件
drv_bmp085.h src 50 - 包含與控制BMP085氣壓計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_bmp280.c src 7015 76 用于控制BMP280氣壓計(jì)的源代碼文件
drv_bmp280.h src 48 - 包含與控制BMP280氣壓計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_gpio.c src 2900 62 用于控制GPIO(通用輸入輸出)的源代碼文件
drv_gpio.h src 1179 - 包含與控制GPIO相關(guān)的定義和函數(shù)聲明的頭文件
drv_hcsr04.c src 4049 83 用于控制HCSR04超聲波傳感器的源代碼文件
drv_hcsr04.h src 185 - 包含與控制HCSR04超聲波傳感器相關(guān)的定義和函數(shù)聲明的頭文件
drv_hmc5883l.c src 8102 93 用于控制HMC5883L磁力計(jì)的源代碼文件
drv_hmc5883l.h src 133 - 包含與控制HMC5883L磁力計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_i2c.c src 16997 289 用于控制I2C總線的源代碼文件
drv_i2c.h src 546 - 包含與控制I2C總線相關(guān)的定義和函數(shù)聲明的頭文件
drv_i2c_soft.c src 4692 168 用于軟件模擬I2C總線的源代碼文件
drv_l3g4200d.c src 2709 48 用于控制L3G4200D陀螺儀的源代碼文件
drv_l3g4200d.h src 68 - 包含與控制L3G4200D陀螺儀相關(guān)的定義和函數(shù)聲明的頭文件
drv_ledring.c src 1214 40 用于控制LED環(huán)的源代碼文件
drv_ledring.h src 95 - 包含與控制LED環(huán)相關(guān)的定義和函數(shù)聲明的頭文件
drv_mma845x.c src 4010 41 用于控制MMA845X加速度計(jì)的源代碼文件
drv_mma845x.h src 52 - 包含與控制MMA845X加速度計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_mpu.c src 18305 353 用于控制MPU6050/6500/9250 ?IMU(慣性測(cè)量單元)的源代碼文件
drv_mpu.h src 605 - 包含與控制MPU6050/6500/9250 ?IMU相關(guān)的定義和函數(shù)聲明的頭文件
drv_ms5611.c src 5821 117 用于控制MS5611氣壓計(jì)的源代碼文件
drv_ms5611.h src 50 - 包含與控制MS5611氣壓計(jì)相關(guān)的定義和函數(shù)聲明的頭文件
drv_pwm.c src 14536 237 用于控制PWM脈沖寬度調(diào)制)輸出的源代碼文件
drv_pwm.h src 2090 - 包含與控制PWM輸出相關(guān)的定義和函數(shù)聲明的頭文件
drv_serial.c src 1019 27 用于控制串口通信的源代碼文件
drv_serial.h src 1644 - 包含與控制串口通信相關(guān)的定義和函數(shù)聲明的頭文件
drv_softserial.c src 14155 297 用于軟件模擬串口通信的源代碼文件
drv_softserial.h src 1619 - 包含與軟件模擬串口通信相關(guān)的定義和函數(shù)聲明的頭文件
drv_spi.c src 3091 93 用于控制SPI(串行外設(shè)接口)的源代碼文件
drv_spi.h src 260 - 包含與控制SPI相關(guān)的定義和函數(shù)聲明的頭文件
drv_system.c src 5970 79 用于系統(tǒng)級(jí)別控制的源代碼文件
drv_system.h src 564 - 包含與系統(tǒng)級(jí)別控制相關(guān)的定義和函數(shù)聲明的頭文件
drv_timer.c src 8105 104 用于控制定時(shí)器的源代碼文件
drv_timer.h src 856 - 包含與控制定時(shí)器相關(guān)的定義和函數(shù)聲明的頭文件
drv_uart.c src 14017 329 用于控制UART(通用異步收發(fā)器)通信的源代碼文件
drv_uart.h src 1231 - 包含與控制UART通信相關(guān)的定義和函數(shù)聲明的頭文件
flash.bat support 681 - 用于執(zhí)行閃存操作的批處理文件
fw_nav.c src 9207 176 包含導(dǎo)航相關(guān)功能的源代碼文件
gps.c src 57742 812 包含GPS相關(guān)功能的源代碼文件
ibus.c src 2178 49 用于處理i-Bus(Flysky接收機(jī)的信號(hào)協(xié)議)的源代碼文件
imu.c src 15173 294 包含IMU(慣性測(cè)量單元)相關(guān)功能的源代碼文件
JLinkSettings.ini - 573 - J-Link調(diào)試器的配置文件
main.c src 9069 202 程序的入口點(diǎn),包含主要的執(zhí)行邏輯
Makefile - 6751 - 用于管理項(xiàng)目編譯的Makefile文件
mixer.c src 24140 342 用于控制飛行器的混合器的源代碼文件
mw.c src 43199 832 主要的飛行控制代碼的源代碼文件
mw.h src 26858 - 包含與飛行控制相關(guān)的定義和函數(shù)聲明的頭文件
printf.c src 6704 167 實(shí)現(xiàn)了格式化輸出功能的源代碼文件
printf.h src 4923 - 包含與格式化輸出相關(guān)的定義和函數(shù)聲明的頭文件
rxmsp.c src 533 18 用于處理R-XSR接收機(jī)的源代碼文件
sbus.c src 3398 58 用于處理S.Bus(Futaba接收機(jī)的信號(hào)協(xié)議)的源代碼文件
sensors.c src 17656 406 用于處理各種傳感器的源代碼文件
serial.c src 37714 703 用于控制串口通信的源代碼文件
spektrum.c src 5512 116 用于處理Spektrum接收機(jī)的源代碼文件
sumd.c src 1950 47 用于處理SUMD(Graupner接收機(jī)的信號(hào)協(xié)議)的源代碼文件
telemetry_common.c src 3237 90 包含通用遙測(cè)功能的源代碼文件
telemetry_common.h src 288 - 包含與通用遙測(cè)功能相關(guān)的定義和函數(shù)聲明的頭文件
telemetry_frsky.c src 7648 172 用于處理FrSky遙測(cè)的源代碼文件
telemetry_frsky.h src 332 - 包含與FrSky遙測(cè)相關(guān)的定義和函數(shù)聲明的頭文件
telemetry_hott.c src 9205 126 用于處理HoTT遙測(cè)的源代碼文件
telemetry_hott.h src 8791 - 包含與HoTT遙測(cè)相關(guān)的定義和函數(shù)聲明的頭文件
utils.c src 3944 114 包含一些常用功能的實(shí)用函數(shù)的源代碼文件
utils.h src 211 - 包含與實(shí)用函數(shù)相關(guān)的定義和函數(shù)聲明的頭文件

表1 全文件列表

里面的main.c,會(huì)把主循環(huán)拉起來(lái)。就像任何持續(xù)執(zhí)行的嵌入式系統(tǒng),都是靠一個(gè)無(wú)限循環(huán)來(lái)保證器件的無(wú)限執(zhí)行的。

 

?// loopy?while?(1) {?//這里,main啟動(dòng)無(wú)限循環(huán)? ??loop();?#ifdef?SOFTSERIAL_LOOPBACK? ??if?(loopbackPort1) {? ? ? ??while?(serialTotalBytesWaiting(loopbackPort1)) {? ? ? ? ? ??uint8_t?b =?serialRead(loopbackPort1);? ? ? ? ? ??serialWrite(loopbackPort1, b);? ? ? ? ? ??//serialWrite(core.mainport, 0x01);? ? ? ? ? ??//serialWrite(core.mainport, b);? ? ? ? };? ? }? ??if?(loopbackPort2) {? ? ? ??while?(serialTotalBytesWaiting(loopbackPort2)) {? ? ? ? ? ??serialRead(loopbackPort2);? ? ? ? };? ? }#endif}

區(qū)區(qū)幾行代碼,其內(nèi)容卻很豐富:

1. 無(wú)限循環(huán) (while (1))

while (1) 創(chuàng)建了一個(gè)無(wú)限循環(huán),使得代碼不斷重復(fù)執(zhí)行。后面會(huì)說(shuō)如何終止無(wú)限循環(huán)。

2. 調(diào)用 loop() 函數(shù)

這個(gè)loop() 就是飛行的主要函數(shù),不在main。c里面,而在mw.c里面。mw的意思就是main work。之所以分開(kāi)無(wú)非是軟件工程良好代碼規(guī)范的需要:不要讓單個(gè)文件太過(guò)龐大。

3. 條件編譯 (#ifdef SOFTSERIAL_LOOPBACK)

a. #ifdef SOFTSERIAL_LOOPBACK 是一個(gè)預(yù)處理器指令,表示只有在定義了 SOFTSERIAL_LOOPBACK 宏的情況下,才會(huì)編譯下面的代碼塊。

4. 處理 loopbackPort1

a. 如果 loopbackPort1 存在(即不為 NULL 或假值),則進(jìn)入一個(gè)內(nèi)部循環(huán)。

b. while (serialTotalBytesWaiting(loopbackPort1)):此循環(huán)將持續(xù)運(yùn)行,直到 loopbackPort1 上沒(méi)有任何數(shù)據(jù)等待讀取為止。

c. uint8_t b = serialRead(loopbackPort1);:從 loopbackPort1 讀取一個(gè)字節(jié)的數(shù)據(jù)并存儲(chǔ)在變量 b 中。

d. serialWrite(loopbackPort1, b);:將剛剛讀取到的數(shù)據(jù)再寫(xiě)回到 loopbackPort1,這實(shí)際上是在模擬一個(gè)回環(huán)(loopback)操作。

5. 處理 loopbackPort2

a. 如果 loopbackPort2 存在,則進(jìn)入另一個(gè)內(nèi)部循環(huán)。

b. while (serialTotalBytesWaiting(loopbackPort2)):此循環(huán)將持續(xù)運(yùn)行,直到 loopbackPort2 上沒(méi)有任何數(shù)據(jù)等待讀取為止。

c. serialRead(loopbackPort2);:從 loopbackPort2 讀取一個(gè)字節(jié)的數(shù)據(jù),但沒(méi)有將其存儲(chǔ)或重新發(fā)送出去,因此這似乎只是簡(jiǎn)單地丟棄數(shù)據(jù)。

其中值得注意的幾個(gè)點(diǎn):

● 死循環(huán):由于 while (1) 是一個(gè)死循環(huán),除非通過(guò)外部中斷或其他方式終止程序,否則這段代碼會(huì)一直運(yùn)行下去。

● 資源消耗:在沒(méi)有數(shù)據(jù)可讀的情況下,serialTotalBytesWaiting 函數(shù)會(huì)持續(xù)返回 false,導(dǎo)致循環(huán)快速結(jié)束。然而,如果端口上有大量數(shù)據(jù)等待讀取,這可能會(huì)導(dǎo)致 CPU 資源的高占用率。

● 調(diào)試和測(cè)試:#ifdef SOFTSERIAL_LOOPBACK 指令使得這部分代碼可以根據(jù)需要啟用或禁用。這對(duì)于調(diào)試和測(cè)試不同的功能場(chǎng)景非常有用。

3、如何安裝?

假設(shè)某一位讀者花了很大力氣根據(jù)自己的設(shè)備改寫(xiě)了baseflight的程序,而且這位讀者可能就是某個(gè)無(wú)人機(jī)廠商的創(chuàng)始人或者總師,需要把自己的產(chǎn)品(這些改進(jìn)就是你的產(chǎn)品)變現(xiàn)才能盈利,那么我們?cè)趺窗研薷暮蟮某绦颉白⑷搿憋w控里面。

Baseflight 主要運(yùn)行在基于 STM32 系列微控制器 (MCU) 的硬件平臺(tái)上。STM32 是一種廣泛應(yīng)用于無(wú)人機(jī)飛行控制器的 32 位 ARM Cortex-M 處理器,具有高性能和豐富的外設(shè)接口。具體來(lái)說(shuō),Baseflight 支持多種常見(jiàn)的飛控板,例如 Naze32、F3、CC3D 等 。

步驟 描述 操作
1 準(zhǔn)備工具和環(huán)境 下載并安裝 Betaflight Configurator 或 Baseflight Configurator。
確保電腦上已安裝相應(yīng)的驅(qū)動(dòng)程序。
2 連接飛控板 使用 ?USB 線將飛控板連接到電腦,確保連接穩(wěn)固,飛控板上的電源指示燈亮起。
3 進(jìn)入引導(dǎo)模式 某些飛控板需要按下并按住“Boot”按鈕,然后插入 USB 線。
具體操作請(qǐng)參考飛控板說(shuō)明書(shū)。
4 刷寫(xiě)固件 1.?打開(kāi) Betaflight Configurator 或 Baseflight ?Configurator。
2.?連接成功后,軟件會(huì)自動(dòng)檢測(cè)到飛控板。
3.?選擇最新的 ?Baseflight 固件文件(通常為 .bin 文件格式)。
4.?點(diǎn)擊“Flash ?Firmware”按鈕開(kāi)始刷寫(xiě)過(guò)程。
5.?刷寫(xiě)完成后,確保所有步驟都正確無(wú)誤,并等待提示確認(rèn)固件已成功安裝。
5 配置和校準(zhǔn) 通過(guò)配置工具對(duì)飛控板進(jìn)行必要的設(shè)置和校準(zhǔn)。
包括陀螺儀、加速度計(jì)、磁羅盤(pán)等傳感器校準(zhǔn)。
PID 參數(shù)調(diào)整。

表2 安裝 Baseflight 固件到硬件中

那么固件哪來(lái)的?baseflight都是源文件啊。

步驟 描述 操作
1 獲取源代碼,加入你自己的修改 從 Baseflight 的官方 GitHub 倉(cāng)庫(kù)獲取最新版本的源代碼。
確保使用的是最新的穩(wěn)定版本或開(kāi)發(fā)分支。
2 配置硬件目標(biāo) 根據(jù)使用的具體硬件平臺(tái)(例如 STM32F103C8),配置 Makefile 或其他構(gòu)建工具來(lái)指定目標(biāo)硬件。
確保生成的固件與硬件兼容。
3 編譯固件 使用 Makefile 或類(lèi)似的構(gòu)建工具來(lái)編譯源代碼。
通過(guò)命令行運(yùn)行 make 命令啟動(dòng)編譯過(guò)程。
Makefile 會(huì)調(diào)用編譯器、鏈接器等工具,生成 .bin ?文件。
4 生成二進(jìn)制文件 編譯完成后,生成的固件將以二進(jìn)制文件形式保存,通常是 ?.bin 文件格式。這個(gè)文件可以直接燒錄到 MCU 的閃存中運(yùn)行。
5 驗(yàn)證固件(避免把硬件燒成磚) 在燒錄之前,建議對(duì)生成的 .bin 文件進(jìn)行驗(yàn)證。
可以通過(guò)檢查文件大小、校驗(yàn)和等方式進(jìn)行初步驗(yàn)證。
一些開(kāi)發(fā)者還會(huì)在固件中嵌入版本信息,以便在燒錄前進(jìn)行進(jìn)一步驗(yàn)證。
6 燒錄固件 使用適當(dāng)?shù)墓ぞ撸ㄈ?ST-Link、JTAG 等)將生成的 .bin 文件燒錄到飛控板的閃存中。
確保在燒錄時(shí)選擇正確的啟動(dòng)模式(例如,STM32F103C8 ?板有引導(dǎo)模式開(kāi)關(guān)),以便正確加載新固件。

表3 baseflight固件生成

特別注意,除非你改變了源工程的文件結(jié)構(gòu),否則不要改原先的makefile文件。

相關(guān)推薦