• 正文
    • 1、背景
    • 2、代碼結構概述
    • 3、如何安裝?
  • 相關推薦
申請入駐 產業(yè)圖譜

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

03/13 15:03 來源:直觀解
721
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

1、背景

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

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

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

2.兼容多種硬件平臺:

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

3.豐富的配置選項:

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

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

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

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

除了圖形界面外,Baseflight還提供了命令行接口(CLI),允許用戶直接通過串口進行高級設置和調試操作。

5.家族譜系:

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

2、代碼結構概述

三層架構:驅動-計算-工具

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

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

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

整個項目不過1.6w行,78個文件。最大的文件是cli.c超過一千行(包含大量的交互處理,所以代碼多一點),其余文件均小于1k行,符合良好的c語言代碼設計規(guī)范。數(shù)量最多的是drv_開頭的驅動層程序。

其次是各種計算和控制文件,比如fw_nav,是前向導航的意思,也就是控制無人機往前飛。比如mixer是混合器,混合器是混合操控命令環(huán)境感知等等渠道的信息,形成最終的每個旋翼的電動機的控制命令。

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

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

圖2 baseflight的簡明項目報告

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

表1 全文件列表

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

 

?// loopy?while?(1) {?//這里,main啟動無限循環(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ū)幾行代碼,其內容卻很豐富:

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

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

2. 調用 loop() 函數(shù)

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

3. 條件編譯 (#ifdef SOFTSERIAL_LOOPBACK)

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

4. 處理 loopbackPort1

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

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

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

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

5. 處理 loopbackPort2

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

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

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

其中值得注意的幾個點:

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

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

● 調試和測試:#ifdef SOFTSERIAL_LOOPBACK 指令使得這部分代碼可以根據需要啟用或禁用。這對于調試和測試不同的功能場景非常有用。

3、如何安裝?

假設某一位讀者花了很大力氣根據自己的設備改寫了baseflight的程序,而且這位讀者可能就是某個無人機廠商的創(chuàng)始人或者總師,需要把自己的產品(這些改進就是你的產品)變現(xiàn)才能盈利,那么我們怎么把修改后的程序“注入”飛控里面。

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

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

表2 安裝 Baseflight 固件到硬件中

那么固件哪來的?baseflight都是源文件啊。

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

表3 baseflight固件生成

特別注意,除非你改變了源工程的文件結構,否則不要改原先的makefile文件。

相關推薦