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);
配置分析
- dashboard需要用到oled_ug2864hsweg01设备。
- ug2864hsweg01规格书,官网没有找到datasheet。
- 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模块设计之二十八:MainPidLoop任务分析