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

Posted lida2003

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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. 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

target-config

\\src\\main\\target\\KAKUTEF7\\target.h
#define USE_I2C

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

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,
);

显示页面种类

目前代码支持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;
\\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
;

函数分析

任务每隔大约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进展动态图标

以上是关于BetaFlight模块设计之二十一:dashboard任务分析的主要内容,如果未能解决你的问题,请参考以下文章

BetaFlight模块设计之二十六:接收机任务分析

BetaFlight模块设计之二十八:MainPidLoop任务分析

BetaFlight模块设计之二十二:地面测距任务分析

BetaFlight模块设计之二十九:滤波模块分析

BetaFlight模块设计之二十五:dispatch任务分析

BetaFlight模块设计之二十四:transponder任务分析