BetaFlight开源代码框架简介

  • 1. 框架设计分析考量
  • 2. 框架分析前提条件
  • 3. 主程序框架
  • 4. 调度框架
  • 5. 模块方法
  • 6. 典型任务&模块
    • 6.1 典型任务
    • 6.2 典型模块
    • 6.3 传感模块
  • 7. 回顾
  • 8. 分析模板

1. 框架设计分析考量

框架设计重点要做到各切分模块的业务融合,分析的主要考量点:

  1. 突出业务框架逻辑
  2. 从框架引入模块概念
  3. 功能模块化实现方法
  4. 性能及优化实现方法

2. 框架分析前提条件

  1. 【打开】所有功能代码宏定义,以便有全局性了解
  2. 【忽略】UNIT_TEST等测试代码,暂不考虑自测
  3. 【侧重】框架代码逻辑实现,突出业务框架逻辑
  4. 【忽略】框架算法逻辑伪代码处理,强调概念
  5. 【举例】模块分析方法(配典型模块入门分析)

3. 主程序框架

C语言工程代码函数入口为main,之前启动及C环境初始化代码不做介绍,启动文件代码文件(lib\main\STM32H7\Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\arm\startup_stm32h745xx.s)。业务逻辑方面主要是从main来分析框架代码,这里也不会对HAL(Hardware Adapter Layer)做分析,对底层感兴趣的朋友可以从STM官网或者其他网站得到更多的STM32开发方面的资讯。

这里着重飞控业务&功能方面的学习和简介,所以回归话题,从main入口进入后,主程序框架分为两部分:初始化(init)和调度执行(schedule)。

main├──> init│   ├──> ... // module initialization code here│   └──> tasksInit└──> run├──> scheduler  // NOT normal OS scheduler, quite special related to flight control task prioirty└──> SIMULATOR_BUILD // if simulation enabled, baremetal loop for max rate 20kHz NOT full CPU└──> delayMicroseconds_real(50)└──>  microsleep└──>  nanosleep

4. 调度框架

这里为什么说调度框架,主要是由于这个schedule和操作系统常规的OS调度不太一样,它有业务相关的特殊处理部分。因此,从概念上来说,调度器和业务是紧耦合。

目前其他的一些开源飞控代码用到OS的有nuttx,chibios等。后续我们如果介绍Paparazzi项目就会用到chibios。这里BetaFlight可能由于其发展历史,沿用了目前裸奔+业务调度的方式。

scheduler├──> <陀螺仪使能>│   ├──> <修正调度异常剩余时间> //其他耗时任务导致任务调度时间不足,比如USB任务│   ├──> <修正调度触发阈值时间> //调度代码耗散时间,控制接近边界 schedLoopStartMinCycles,调整粒度schedLoopStartDeltaUpCycles│   └──> <触发调度> // schedLoopRemainingCycles < schedLoopStartCycles│       ├──> <修正调度触发阈值时间> //控制接近边界 schedLoopStartMinCycles,调整粒度schedLoopStartDeltaDownCycles│       ├──> [精准对齐调度触发时间]│       ├──> schedulerExecuteTask(gyroTask, currentTimeUs); //执行陀螺仪传感任务│       ├──> schedulerExecuteTask(getTask(TASK_FILTER), currentTimeUs); //按比例执行过滤任务│       ├──> schedulerExecuteTask(getTask(TASK_PID), currentTimeUs); //按比例执行PID任务│       ├──> rxFrameCheck //检查接收机数据│       ├──> [故障保护模式检查]│       └──> <使用陀螺仪外部中断模式锁定调度器时间>├──> [更新调度器剩余时间,schedLoopRemainingCycles]└──> <陀螺仪不使能 或者 调度剩余时间大于非实时任务检查时间>├──> [更新所有非实时任务的任务动态优先级]│   ├──> <事件驱动任务>│   │   ├──> <执行任务checkFunc,并更新任务动态优先级>│   │   └──> <已执行checkFunc,未调度执行任务,继续提升任务动态优先级>│   ├──> <时间驱动任务>│   │   └──> [更新基于上次调度与当前时间间隔的任务动态优先级]│   └──> <挑选最高优先级任务,并计算剩余执行时间>  //TASK_SERIAL只要优先级够,就直接执行不进行阻塞├──> [更新checkCycles,所有非实时任务最优任务选择本次计算时间]└──> <有高优先级任务选中>├──> [更新taskRequiredTimeCycles和schedLoopRemainingCycles数据]├──> <陀螺仪不使能 或者  (taskRequiredTimeCycles < schedLoopRemainingCycles)>│   ├──> schedulerExecuteTask(selectedTask, currentTimeUs); //执行选中高优先级任务│   ├──> [TASK_OSD/TASK_RX, skippedRxAttempts/skippedOSDAttempts清零]│   └──> [修正taskGuardCycles,以便下次更精确的预估执行时间]└──> <TASK_OSD/TASK_RX 或者 (taskAgePeriods > TASK_AGE_EXPEDITE_COUNT)>└──> [能找TASK_AGE_EXPEDITE_SCALE比率缩短任务预计时间]

注:目前4.3代码只有3个实时任务:GYRO、FILTER、PID。

5. 模块方法

基于主程序框架和调度框架,一个模块涉及以下几部分:

  1. 初始化
  • 硬件初始化
  • 业务初始化
  1. 任务
  • 实时任务
  • 事件任务
  • 时间任务
  1. 驱动
  • 查询
  • 中断
  1. 接口

6. 典型任务&模块

6.1 典型任务

  1. BetaFlight模块设计之一:系统任务模块分析
  2. BetaFlight模块设计之二:SERIAL任务分析
  3. BetaFlight模块设计之三:芯片温度&参考电压和电池监测模块分析
  4. BetaFlight模块设计之四:ESC传感任务分析
  5. BetaFlight模块设计之五:最大栈使用量监测
  6. BetaFlight模块设计之六:Beeper任务分析
  7. BetaFlight模块设计之七:LEDSTRIP任务分析
  8. BetaFlight模块设计之八:GPS任务分析
  9. BetaFlight模块设计之九:气压计任务分析
  10. BetaFlight模块设计之十:磁力计任务分析
  11. BetaFlight模块设计之十一:Gyro&Acc任务分析
  12. BetaFlight模块设计之十二:电传任务分析
  13. BetaFlight模块设计之十三:Gyro过滤任务分析
  14. BetaFlight模块设计之十四:高度计算任务分析
  15. BetaFlight模块设计之十五:RunCam设备任务分析
  16. BetaFlight模块设计之十六:OSD更新任务分析
  17. BetaFlight模块设计之十七:pinioBox任务分析
  18. BetaFlight模块设计之十八:图传模块同步任务分析
  19. BetaFlight模块设计之十九:摄像头按键控制模拟任务分析
  20. BetaFlight模块设计之二十:CMS菜单模块分析
  21. BetaFlight模块设计之二十一:dashboard任务分析
  22. BetaFlight模块设计之二十二:地面测距任务分析
  23. BetaFlight模块设计之二十三:CRSF V3串口速率协商任务分析
  24. BetaFlight模块设计之二十四:transponder任务分析
  25. BetaFlight模块设计之二十五:dispatch任务分析
  26. BetaFlight模块设计之二十六:接收机任务分析
  27. BetaFlight模块设计之二十七:姿态更新任务分析
  28. BetaFlight模块设计之二十八:MainPidLoop任务分析

任务相关的分析基本结束,因为看的节奏比较快,时间也仓促,所以肯定存在诸多问题,希望能通过交流,大家多留言给出错误的批示,以便我尽快纠正。

6.2 典型模块

关于软件模块,会尽量一点点的补充详细起来,以便对飞控的具体细节方面更加透彻的理解。

  1. BetaFlight模块设计之二十九:滤波模块分析
  2. BetaFlight模块设计之三十:Cli模块分析
  3. BetaFlight模块设计之三十一:blackbox模块分析
  4. BetaFlight模块设计之三十二:MSP协议模块分析
  5. BetaFlight模块设计之三十三:Pid模块分析
  6. BetaFlight模块设计之三十四:OSD模块分析
  7. BetaFlight模块设计之三十五:RSSI信号强度&链路稳定性分析

6.3 传感模块

深入传感数据,挖掘物理特性与飞控之间的关系,请查阅:BetaFlight深入传感设计:传感模块设计框架

7. 回顾

基于上述代码框架,BetaFlight从大块任务切分的角度看,需要深入分析和理解下面的各个任务模块。这也为后续分析代码提供了方向。

注:后续有时间将会深入每个任务和模块进行分析。

// Task ID data in .data (initialised data)
task_attribute_t task_attributes[TASK_COUNT] = {[TASK_SYSTEM] = DEFINE_TASK("SYSTEM", "LOAD", NULL, taskSystemLoad, TASK_PERIOD_HZ(10), TASK_PRIORITY_MEDIUM_HIGH),[TASK_MAIN] = DEFINE_TASK("SYSTEM", "UPDATE", NULL, taskMain, TASK_PERIOD_HZ(1000), TASK_PRIORITY_MEDIUM_HIGH),[TASK_SERIAL] = DEFINE_TASK("SERIAL", NULL, NULL, taskHandleSerial, TASK_PERIOD_HZ(100), TASK_PRIORITY_LOW), // 100 Hz should be enough to flush up to 115 bytes @ 115200 baud[TASK_BATTERY_ALERTS] = DEFINE_TASK("BATTERY_ALERTS", NULL, NULL, taskBatteryAlerts, TASK_PERIOD_HZ(5), TASK_PRIORITY_MEDIUM),[TASK_BATTERY_VOLTAGE] = DEFINE_TASK("BATTERY_VOLTAGE", NULL, NULL, batteryUpdateVoltage, TASK_PERIOD_HZ(SLOW_VOLTAGE_TASK_FREQ_HZ), TASK_PRIORITY_MEDIUM), // Freq may be updated in tasksInit[TASK_BATTERY_CURRENT] = DEFINE_TASK("BATTERY_CURRENT", NULL, NULL, batteryUpdateCurrentMeter, TASK_PERIOD_HZ(50), TASK_PRIORITY_MEDIUM),#ifdef USE_TRANSPONDER[TASK_TRANSPONDER] = DEFINE_TASK("TRANSPONDER", NULL, NULL, transponderUpdate, TASK_PERIOD_HZ(250), TASK_PRIORITY_LOW),
#endif#ifdef USE_STACK_CHECK[TASK_STACK_CHECK] = DEFINE_TASK("STACKCHECK", NULL, NULL, taskStackCheck, TASK_PERIOD_HZ(10), TASK_PRIORITY_LOWEST),
#endif[TASK_GYRO] = DEFINE_TASK("GYRO", NULL, NULL, taskGyroSample, TASK_GYROPID_DESIRED_PERIOD, TASK_PRIORITY_REALTIME),[TASK_FILTER] = DEFINE_TASK("FILTER", NULL, NULL, taskFiltering, TASK_GYROPID_DESIRED_PERIOD, TASK_PRIORITY_REALTIME),[TASK_PID] = DEFINE_TASK("PID", NULL, NULL, taskMainPidLoop, TASK_GYROPID_DESIRED_PERIOD, TASK_PRIORITY_REALTIME),
#ifdef USE_ACC[TASK_ACCEL] = DEFINE_TASK("ACC", NULL, NULL, taskUpdateAccelerometer, TASK_PERIOD_HZ(1000), TASK_PRIORITY_MEDIUM),[TASK_ATTITUDE] = DEFINE_TASK("ATTITUDE", NULL, NULL, imuUpdateAttitude, TASK_PERIOD_HZ(100), TASK_PRIORITY_MEDIUM),
#endif[TASK_RX] = DEFINE_TASK("RX", NULL, rxUpdateCheck, taskUpdateRxMain, TASK_PERIOD_HZ(33), TASK_PRIORITY_HIGH), // If event-based scheduling doesn't work, fallback to periodic scheduling[TASK_DISPATCH] = DEFINE_TASK("DISPATCH", NULL, NULL, dispatchProcess, TASK_PERIOD_HZ(1000), TASK_PRIORITY_HIGH),#ifdef USE_BEEPER[TASK_BEEPER] = DEFINE_TASK("BEEPER", NULL, NULL, beeperUpdate, TASK_PERIOD_HZ(100), TASK_PRIORITY_LOW),
#endif#ifdef USE_GPS[TASK_GPS] = DEFINE_TASK("GPS", NULL, NULL, gpsUpdate, TASK_PERIOD_HZ(TASK_GPS_RATE), TASK_PRIORITY_MEDIUM), // Required to prevent buffer overruns if running at 115200 baud (115 bytes / period < 256 bytes buffer)
#endif#ifdef USE_MAG[TASK_COMPASS] = DEFINE_TASK("COMPASS", NULL, NULL, taskUpdateMag, TASK_PERIOD_HZ(10), TASK_PRIORITY_LOW),
#endif#ifdef USE_BARO[TASK_BARO] = DEFINE_TASK("BARO", NULL, NULL, taskUpdateBaro, TASK_PERIOD_HZ(20), TASK_PRIORITY_LOW),
#endif#if defined(USE_BARO) || defined(USE_GPS)[TASK_ALTITUDE] = DEFINE_TASK("ALTITUDE", NULL, NULL, taskCalculateAltitude, TASK_PERIOD_HZ(40), TASK_PRIORITY_LOW),
#endif#ifdef USE_DASHBOARD[TASK_DASHBOARD] = DEFINE_TASK("DASHBOARD", NULL, NULL, dashboardUpdate, TASK_PERIOD_HZ(10), TASK_PRIORITY_LOW),
#endif#ifdef USE_OSD[TASK_OSD] = DEFINE_TASK("OSD", NULL, osdUpdateCheck, osdUpdate, TASK_PERIOD_HZ(OSD_FRAMERATE_DEFAULT_HZ), TASK_PRIORITY_LOW),
#endif#ifdef USE_TELEMETRY[TASK_TELEMETRY] = DEFINE_TASK("TELEMETRY", NULL, NULL, taskTelemetry, TASK_PERIOD_HZ(250), TASK_PRIORITY_LOW),
#endif#ifdef USE_LED_STRIP[TASK_LEDSTRIP] = DEFINE_TASK("LEDSTRIP", NULL, NULL, ledStripUpdate, TASK_PERIOD_HZ(100), TASK_PRIORITY_LOW),
#endif#ifdef USE_BST[TASK_BST_MASTER_PROCESS] = DEFINE_TASK("BST_MASTER_PROCESS", NULL, NULL, taskBstMasterProcess, TASK_PERIOD_HZ(50), TASK_PRIORITY_LOWEST),
#endif#ifdef USE_ESC_SENSOR[TASK_ESC_SENSOR] = DEFINE_TASK("ESC_SENSOR", NULL, NULL, escSensorProcess, TASK_PERIOD_HZ(100), TASK_PRIORITY_LOW),
#endif#ifdef USE_CMS[TASK_CMS] = DEFINE_TASK("CMS", NULL, NULL, cmsHandler, TASK_PERIOD_HZ(20), TASK_PRIORITY_LOW),
#endif#ifdef USE_VTX_CONTROL[TASK_VTXCTRL] = DEFINE_TASK("VTXCTRL", NULL, NULL, vtxUpdate, TASK_PERIOD_HZ(5), TASK_PRIORITY_LOWEST),
#endif#ifdef USE_RCDEVICE[TASK_RCDEVICE] = DEFINE_TASK("RCDEVICE", NULL, NULL, rcdeviceUpdate, TASK_PERIOD_HZ(20), TASK_PRIORITY_MEDIUM),
#endif#ifdef USE_CAMERA_CONTROL[TASK_CAMCTRL] = DEFINE_TASK("CAMCTRL", NULL, NULL, taskCameraControl, TASK_PERIOD_HZ(5), TASK_PRIORITY_LOW),
#endif#ifdef USE_ADC_INTERNAL[TASK_ADC_INTERNAL] = DEFINE_TASK("ADCINTERNAL", NULL, NULL, adcInternalProcess, TASK_PERIOD_HZ(1), TASK_PRIORITY_LOWEST),
#endif#ifdef USE_PINIOBOX[TASK_PINIOBOX] = DEFINE_TASK("PINIOBOX", NULL, NULL, pinioBoxUpdate, TASK_PERIOD_HZ(20), TASK_PRIORITY_LOWEST),
#endif#ifdef USE_RANGEFINDER[TASK_RANGEFINDER] = DEFINE_TASK("RANGEFINDER", NULL, NULL, taskUpdateRangefinder, TASK_PERIOD_HZ(10), TASK_PRIORITY_LOWEST),
#endif#ifdef USE_CRSF_V3[TASK_SPEED_NEGOTIATION] = DEFINE_TASK("SPEED_NEGOTIATION", NULL, NULL, speedNegotiationProcess, TASK_PERIOD_HZ(100), TASK_PRIORITY_LOW),
#endif
};

8. 分析模板

这里补充一个模板用于后续模块分析使用,后续会逐步一个个一起与大家分享每个模块的设计和实现。

【模板】模块 & 任务├──> 初始化│   ├──> [x]硬件初始化│   └──> [V]业务初始化├──> 任务│   ├──> [x]实时任务│   ├──> [x]事件任务│   └──> [V]时间任务bla...bla...├──> 驱动│   ├──> [x]查询│   └──> [x]中断└──> 接口├──> bla...bla...└──> bla...bla...函数分析:
bla...bla...

BetaFlight开源代码框架简介相关推荐

  1. 最大开源代码sourceforge 简介 及视音频方面常用的开源代码

    所有的音视频凯源代码在这里:http://sourceforge.net/directory/audio-video/os:windows/,你可以下载分析,视频不懂请发邮件给我,帮你分析. 0.视频 ...

  2. ArduPilot之开源代码LibrarySketches设计

    ArduPilot之开源代码Library&Sketches设计 1. 简介 1.1 Core libraries 1.2 Sensor libraries 1.3 Other librari ...

  3. ArduPilot之开源代码基础知识Threading概念

    ArduPilot之开源代码基础知识&Threading概念 1. 源由 2. 基础知识 2.1 The timer callbacks 2.2 HAL specific threads 2. ...

  4. ArduPilot之开源代码Sensor Drivers设计

    ArduPilot之开源代码Sensor Drivers设计 1. 源由 2. Sensor Drivers设计 2.1 front-end / back-end分层 2.2 设计思想分析 3 实例理 ...

  5. Java开源——常见J2EE框架简介

    Java开源--常见J2EE框架简介 Spring Framework Spring是一个解决了许多在J2EE开发中常见的问题的强大框架. Spring提供了管理业务对象的一致方法并且鼓励了注入对接口 ...

  6. 流量回放开源代码Java_流量回放框架 jvm-sandbox-repeater 的实践

    一. 前言 你是否和我一样遇到过以下的问题? 1)服务重构,一堆接口需要回归,让人头疼 2)每次迭代,都要花很多精力来进行回归测试 3)线上 bug,线下复现不了 4)接口自动化用例写辛苦,维护更辛苦 ...

  7. 六款值得推荐的Android开源框架简介

    六款值得推荐的Android开源框架简介 技术不再多,知道一些常用的.不错的就够了.下面就是最近整理的"性价比"比较高的Android开源框架,应该是相对实用的. 1.volley ...

  8. [转载]Zookeeper开源客户端框架Curator简介

    转载声明:http://macrochen.iteye.com/blog/1366136 Zookeeper开源客户端框架Curator简介 博客分类: Distributed Open Source ...

  9. 开源推荐 | 携程 Foxpage 前端低代码框架

    作者简介 Jason Wang,携程研发经理,目前主要负责低代码类产品的设计和研发,关注低代码行业的发展及相关解决方案在企业内部的落地. 大厂技术  高级前端  Node进阶 点击上方 程序员成长指北 ...

  10. 开源 | 携程 Foxpage 前端低代码框架

    作者简介 Jason Wang,携程研发经理,目前主要负责低代码类产品的设计和研发,关注低代码行业的发展及相关解决方案在企业内部的落地. 一.背景 随着低代码开发方式被越来越多的人接受和认可,低代码得 ...

最新文章

  1. 解决Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile
  2. 【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( JNI 传递 Bitmap | 获取位图信息 | 获取图像数据 | 图像数据过滤 | 释放资源 )
  3. Linux学习之创建子进程
  4. 如何设计区块链项目的通证(token)模型
  5. 申请补办 CET(纸笔考试)成绩证明的方法
  6. ClickHouse:人群圈选业务的大杀器
  7. 《ext江湖》第8章继承-代码片段
  8. python中forward函数的引用_pytorch 调用forward 的具体流程
  9. 局域网查看计算机慢,局域网内的电脑访问共享文件夹速度很慢如何解决
  10. ASP.NET Core 处理 404 Not Found
  11. 安全,从写第一行代码开始!
  12. 用java制作心理测试软件_Java 程序员必备的10款开源工具
  13. 如何 tune spark jobs
  14. 11-23-day05-python入门-字典与集合及文件
  15. 地下城php补丁怎么用,dnf技能补丁怎么用到WeGame(附其使用教程)
  16. 操作系统之调度 (十) --- 处理机调度、高级调度、中级调度、低级调度...
  17. oracle 验证 lob 坏块,Oracle LOB坏块处理
  18. SDL库的安装,spca5xx的安装,spcaview 的安装,摄像头的查看,及常见问题的解决方法。
  19. Ubuntu 14.04 LTS 安装配置搜狗拼音输入法
  20. matlab julia分形图,Three.js 朱丽亚集(Julia set)分形图案

热门文章

  1. python打印网页成pdf_html – 在chrome-python 2.7中自动打印/保存网页为pdf
  2. origin拟合曲线方法
  3. x58服务器主板装win7系统,技嘉Z390主板重装win7方法|Z390主板Bios设置及安装win7图文教程...
  4. cpolar内网穿透工具
  5. idea中自动生成Java类图和时序图
  6. Java IO流知识点总结
  7. html点击图片可以放全屏,html:点击图片放大到全屏,再次点击缩回
  8. python之父去面试-Django面试题
  9. 二进制原码一位乘法运算
  10. 人脸识别技术软件测试测什么,人脸识别这么火,你知道它是什么吗?