当前位置:   article > 正文

BetaFlight模块设计之二十一:dashboard任务分析_betaflight dashboard

betaflight dashboard

基于BetaFlight开源代码框架简介的框架设计,逐步分析内部模块功能设计。

dashboard任务

描述:主要用于FC上OLED显示屏信息更新。

 ├──> 初始化
 │   ├──> [v]硬件初始化displayPortOledInit/resetDisplay/ug2864hsweg01InitI2C
 │   └──> [v]业务初始化dashboardInit
 ├──> 任务
 │   ├──> [x]实时任务
 │   ├──> [x]事件任务
 │   └──> [v]时间任务[TASK_DASHBOARD] = DEFINE_TASK("DASHBOARD", NULL, NULL, dashboardUpdate, TASK_PERIOD_HZ(10), TASK_PRIORITY_LOW),
 ├──> 驱动
 │   ├──> [x]查询
 │   └──> [x]中断
 └──> 接口
     ├──> void dashboardShowFixedPage(pageId_e pageId);
     ├──> void dashboardEnablePageCycling(void);
     └──> void dashboardDisablePageCycling(void);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

配置分析

  1. dashboard需要用到oled_ug2864hsweg01设备
  2. ug2864hsweg01规格书,官网没有找到datasheet。
  3. CMS菜单模块,分别使用displayPortOledInit来初始化oled设备和cmsDisplayPortRegister向CMS菜单模块进行注册。

pre-config

\src\main\target\common_pre.h
#if (TARGET_FLASH_SIZE > 512)
#define USE_ESCSERIAL_SIMONK
#define USE_SERIAL_4WAY_SK_BOOTLOADER
#define USE_DASHBOARD
#define USE_EMFAT_AUTORUN
#define USE_EMFAT_ICON
#define USE_GPS_PLUS_CODES
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

target-config

\src\main\target\KAKUTEF7\target.h
#define USE_I2C
  • 1
  • 2

post-config

\src\main\target\common_post.h
// XXX Followup implicit dependencies among DASHBOARD, display_xxx and USE_I2C.
// XXX This should eventually be cleaned up.
#ifndef USE_I2C
#undef USE_I2C_OLED_DISPLAY
#undef USE_DASHBOARD
#else
#ifdef USE_DASHBOARD
#define USE_I2C_OLED_DISPLAY
#endif
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

default-config

\src\main\pg\dashboard.c
PG_REGISTER_WITH_RESET_TEMPLATE(dashboardConfig_t, dashboardConfig, PG_DASHBOARD_CONFIG, 0);

PG_RESET_TEMPLATE(dashboardConfig_t, dashboardConfig,
    .device = I2C_DEV_TO_CFG(DASHBOARD_I2C_INSTANCE),
    .address = DASHBOARD_I2C_ADDRESS,
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

显示页面种类

目前代码支持11种类型信息显示。

\src\main\io\dashboard.h
typedef enum {
    PAGE_WELCOME,
    PAGE_ARMED,
    PAGE_BATTERY,
    PAGE_SENSORS,
    PAGE_RX,
    PAGE_PROFILE,
    PAGE_RPROF,
    PAGE_TASKS,
#ifdef USE_GPS
    PAGE_GPS,
#endif
#ifdef ENABLE_DEBUG_DASHBOARD_PAGE
    PAGE_DEBUG,
#endif
#ifdef USE_BLACKBOX
    PAGE_BB,
#endif
    PAGE_COUNT
} pageId_e;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
\src\main\io\dashboard.c
static const pageEntry_t pages[PAGE_COUNT] = {
    { PAGE_WELCOME, FC_FIRMWARE_NAME,  showWelcomePage,    PAGE_FLAGS_SKIP_CYCLING },
    { PAGE_ARMED,   "ARMED",           showArmedPage,      PAGE_FLAGS_SKIP_CYCLING },
    { PAGE_PROFILE, "PROFILE",         showProfilePage,    PAGE_FLAGS_NONE },
    { PAGE_RPROF,   "RATE PROFILE",    showRateProfilePage,PAGE_FLAGS_NONE },
#ifdef USE_GPS
    { PAGE_GPS,     "GPS",             showGpsPage,        PAGE_FLAGS_NONE },
#endif
    { PAGE_RX,      "RX",              showRxPage,         PAGE_FLAGS_NONE },
    { PAGE_BATTERY, "BATTERY",         showBatteryPage,    PAGE_FLAGS_NONE },
    { PAGE_SENSORS, "SENSORS",         showSensorsPage,    PAGE_FLAGS_NONE },
    { PAGE_TASKS,   "TASKS",           showTasksPage,      PAGE_FLAGS_NONE },
#ifdef USE_BLACKBOX
    { PAGE_BB,      "BLACK BOX",       showBBPage,         PAGE_FLAGS_NONE },
#endif
#ifdef ENABLE_DEBUG_DASHBOARD_PAGE
    { PAGE_DEBUG,   "DEBUG",           showDebugPage,      PAGE_FLAGS_NONE },
#endif
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

函数分析

任务每隔大约200ms检查一次,而实际显示屏幕每5秒更换一次(在循环显示模式下)。

dashboardUpdate
 ├──> <USE_CMS><displayIsGrabbed(displayPort)>  // 设备未初始化完成,直接返回
 │   └──> return
 ├──> <!updateNow = (int32_t)(currentTimeUs - nextDisplayUpdateAt) >= 0L;> //更新未到计划指定时间,暂不更新
 │   └──> return
 ├──> nextDisplayUpdateAt = currentTimeUs + DISPLAY_UPDATE_FREQUENCY; // 200ms refresh,计划下次更新指定时间
 ├──> <armedState><armedStateChanged>
 │   ├──> dashboardSetPage(PAGE_ARMED);  //上锁动作发生,dashboard显示锁定页面
 │   └──> pageState.pageChanging = true;
 ├──> <!armedState>
 │   ├──> <armedStateChanged>
 │   │   └──> pageState.pageFlags |= PAGE_STATE_FLAG_FORCE_PAGE_CHANGE;  //解锁后,强制进行dashboard页面刷新
 │   ├──> pageState.pageChanging = (pageState.pageFlags & PAGE_STATE_FLAG_FORCE_PAGE_CHANGE) ||          (((int32_t)(currentTimeUs - pageState.nextPageAt) >= 0L && (pageState.pageFlags & PAGE_STATE_FLAG_CYCLE_ENABLED)));
 │   └──> <pageState.pageChanging>
 │       ├──> do pageState.cycleIndex++;pageState.cycleIndex = pageState.cycleIndex % PAGE_COUNT;pageState.page = &pages[pageState.cycleIndex];  //寻找不是跳过循环显示的页面
 │       └──> while (pageState.page->flags & PAGE_FLAGS_SKIP_CYCLING);
 ├──> <pageState.pageChanging> //需要刷新页面,先清空强制刷新标记位;下一页需要刷新时间更新
 │   ├──> pageState.pageFlags &= ~PAGE_STATE_FLAG_FORCE_PAGE_CHANGE;  
 │   ├──> pageState.nextPageAt = currentTimeUs + PAGE_CYCLE_FREQUENCY;
 │   ├──> resetDisplay 
 │   ├──> <!dashboardPresent> //设备不存在
 │   │   └──> return
 │   └──> handlePageChange
 ├──> <!dashboardPresent> //设备不存在
 │   └──> return
 ├──> pageState.page->drawFn(); //Page页面更新
 └──> <!armedState>
     ├──> updateFailsafeStatus  //failsafe状态
     ├──> updateRxStatus   //接收机状态
     └──> updateTicker  //发送类似progress进展动态图标
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/454413
推荐阅读
相关标签
  

闽ICP备14008679号