mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-15 20:35:33 +03:00
Increase number of element groups and use peak hold task estimation for OSD
This commit is contained in:
parent
b6bc232a19
commit
28e596a500
1 changed files with 36 additions and 30 deletions
|
@ -188,16 +188,18 @@ const osd_stats_e osdStatsDisplayOrder[OSD_STAT_COUNT] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Group elements in a number of groups to reduce task scheduling overhead
|
// Group elements in a number of groups to reduce task scheduling overhead
|
||||||
#define OSD_GROUP_COUNT 20
|
#define OSD_GROUP_COUNT OSD_ITEM_COUNT
|
||||||
// Aim to render a group of elements within a target time
|
// Aim to render a group of elements within a target time
|
||||||
#define OSD_ELEMENT_RENDER_TARGET 40
|
#define OSD_ELEMENT_RENDER_TARGET 30
|
||||||
// Allow a margin by which a group render can exceed that of the sum of the elements before declaring insane
|
// Allow a margin by which a group render can exceed that of the sum of the elements before declaring insane
|
||||||
// This will most likely be violated by a USB interrupt whilst using the CLI
|
// This will most likely be violated by a USB interrupt whilst using the CLI
|
||||||
#define OSD_ELEMENT_RENDER_GROUP_MARGIN 5
|
#if defined(STM32F411xE)
|
||||||
// Safe margin when rendering elements
|
#define OSD_ELEMENT_RENDER_GROUP_MARGIN 7
|
||||||
#define OSD_ELEMENT_RENDER_MARGIN 5
|
#else
|
||||||
// Safe margin in other states
|
#define OSD_ELEMENT_RENDER_GROUP_MARGIN 2
|
||||||
#define OSD_MARGIN 2
|
#endif
|
||||||
|
// Decay the estimated max task duration by 1/(1 << OSD_EXEC_TIME_SHIFT) on every invocation
|
||||||
|
#define OSD_EXEC_TIME_SHIFT 8
|
||||||
|
|
||||||
// Format a float to the specified number of decimal places with optional rounding.
|
// Format a float to the specified number of decimal places with optional rounding.
|
||||||
// OSD symbols can optionally be placed before and after the formatted number (use SYM_NONE for no symbol).
|
// OSD symbols can optionally be placed before and after the formatted number (use SYM_NONE for no symbol).
|
||||||
|
@ -1162,14 +1164,16 @@ bool osdUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTimeUs)
|
||||||
return (osdState != OSD_STATE_IDLE);
|
return (osdState != OSD_STATE_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Called when there is OSD update work to be done
|
// Called when there is OSD update work to be done
|
||||||
void osdUpdate(timeUs_t currentTimeUs)
|
void osdUpdate(timeUs_t currentTimeUs)
|
||||||
{
|
{
|
||||||
static timeUs_t osdStateDurationUs[OSD_STATE_COUNT] = { 0 };
|
// Times are known to be short so use uint16_t rather than timeUs_t
|
||||||
static timeUs_t osdElementDurationUs[OSD_ITEM_COUNT] = { 0 };
|
static uint16_t osdStateDurationFracUs[OSD_STATE_COUNT] = { 0 };
|
||||||
static timeUs_t osdElementGroupMembership[OSD_ITEM_COUNT];
|
static uint16_t osdElementDurationUs[OSD_ITEM_COUNT] = { 0 };
|
||||||
static timeUs_t osdElementGroupTargetUs[OSD_GROUP_COUNT] = { 0 };
|
static uint16_t osdElementGroupMembership[OSD_ITEM_COUNT];
|
||||||
static timeUs_t osdElementGroupDurationUs[OSD_GROUP_COUNT] = { 0 };
|
static uint16_t osdElementGroupTargetFracUs[OSD_GROUP_COUNT] = { 0 };
|
||||||
|
static uint16_t osdElementGroupDurationFracUs[OSD_GROUP_COUNT] = { 0 };
|
||||||
static uint8_t osdElementGroup;
|
static uint8_t osdElementGroup;
|
||||||
static bool firstPass = true;
|
static bool firstPass = true;
|
||||||
uint8_t osdCurElementGroup = 0;
|
uint8_t osdCurElementGroup = 0;
|
||||||
|
@ -1213,7 +1217,7 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
case OSD_STATE_UPDATE_HEARTBEAT:
|
case OSD_STATE_UPDATE_HEARTBEAT:
|
||||||
if (displayHeartbeat(osdDisplayPort)) {
|
if (displayHeartbeat(osdDisplayPort)) {
|
||||||
// Extraordinary action was taken, so return without allowing osdStateDurationUs table to be updated
|
// Extraordinary action was taken, so return without allowing osdStateDurationFracUs table to be updated
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1305,23 +1309,23 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
// Reset groupings
|
// Reset groupings
|
||||||
for (elementGroup = 0; elementGroup < OSD_GROUP_COUNT; elementGroup++) {
|
for (elementGroup = 0; elementGroup < OSD_GROUP_COUNT; elementGroup++) {
|
||||||
if (osdElementGroupDurationUs[elementGroup] > (osdElementGroupTargetUs[elementGroup] + OSD_ELEMENT_RENDER_GROUP_MARGIN)) {
|
if (osdElementGroupDurationFracUs[elementGroup] > (OSD_ELEMENT_RENDER_TARGET << OSD_EXEC_TIME_SHIFT)) {
|
||||||
osdElementGroupDurationUs[elementGroup] = 0;
|
osdElementGroupDurationFracUs[elementGroup] = 0;
|
||||||
}
|
}
|
||||||
osdElementGroupTargetUs[elementGroup] = 0;
|
osdElementGroupTargetFracUs[elementGroup] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
elementGroup = 0;
|
elementGroup = 0;
|
||||||
|
|
||||||
// Based on the current element rendering, group to execute in approx 40us
|
// Based on the current element rendering, group to execute in approx 40us
|
||||||
for (uint8_t curElement = 0; curElement < activeElements; curElement++) {
|
for (uint8_t curElement = 0; curElement < activeElements; curElement++) {
|
||||||
if ((osdElementGroupTargetUs[elementGroup] == 0) ||
|
if ((osdElementGroupTargetFracUs[elementGroup] == 0) ||
|
||||||
((osdElementGroupTargetUs[elementGroup] + osdElementDurationUs[curElement]) <= OSD_ELEMENT_RENDER_TARGET) ||
|
(osdElementGroupTargetFracUs[elementGroup] + (osdElementDurationUs[curElement]) <= (OSD_ELEMENT_RENDER_TARGET << OSD_EXEC_TIME_SHIFT)) ||
|
||||||
(elementGroup == (OSD_GROUP_COUNT - 1))) {
|
(elementGroup == (OSD_GROUP_COUNT - 1))) {
|
||||||
osdElementGroupTargetUs[elementGroup] += osdElementDurationUs[curElement];
|
osdElementGroupTargetFracUs[elementGroup] += osdElementDurationUs[curElement];
|
||||||
// If group membership changes, reset the stats for the group
|
// If group membership changes, reset the stats for the group
|
||||||
if (osdElementGroupMembership[curElement] != elementGroup) {
|
if (osdElementGroupMembership[curElement] != elementGroup) {
|
||||||
osdElementGroupDurationUs[elementGroup] = 0;
|
osdElementGroupDurationFracUs[elementGroup] = osdElementGroupTargetFracUs[elementGroup];
|
||||||
}
|
}
|
||||||
osdElementGroupMembership[curElement] = elementGroup;
|
osdElementGroupMembership[curElement] = elementGroup;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1360,8 +1364,11 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
executeTimeUs = micros() - startElementTime;
|
executeTimeUs = micros() - startElementTime;
|
||||||
|
|
||||||
if (executeTimeUs > osdElementDurationUs[osdCurElement]) {
|
if (executeTimeUs > (osdElementDurationUs[osdCurElement] >> OSD_EXEC_TIME_SHIFT)) {
|
||||||
osdElementDurationUs[osdCurElement] = executeTimeUs;
|
osdElementDurationUs[osdCurElement] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||||
|
} else if (osdElementDurationUs[osdCurElement] > 0) {
|
||||||
|
// Slowly decay the max time
|
||||||
|
osdElementDurationUs[osdCurElement]--;
|
||||||
}
|
}
|
||||||
} while (moreElements);
|
} while (moreElements);
|
||||||
|
|
||||||
|
@ -1415,26 +1422,25 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
// rendered which is unrepresentative, so ignore
|
// rendered which is unrepresentative, so ignore
|
||||||
if (!firstPass) {
|
if (!firstPass) {
|
||||||
if (osdCurState == OSD_STATE_UPDATE_ELEMENTS) {
|
if (osdCurState == OSD_STATE_UPDATE_ELEMENTS) {
|
||||||
if (executeTimeUs > osdElementGroupDurationUs[osdCurElementGroup]) {
|
if (executeTimeUs > (osdElementGroupDurationFracUs[osdCurElementGroup] >> OSD_EXEC_TIME_SHIFT)) {
|
||||||
osdElementGroupDurationUs[osdCurElementGroup] = executeTimeUs;
|
osdElementGroupDurationFracUs[osdCurElementGroup] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (executeTimeUs > osdStateDurationUs[osdCurState]) {
|
if (executeTimeUs > (osdStateDurationFracUs[osdCurState] >> OSD_EXEC_TIME_SHIFT)) {
|
||||||
osdStateDurationUs[osdCurState] = executeTimeUs;
|
osdStateDurationFracUs[osdCurState] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (osdState == OSD_STATE_UPDATE_ELEMENTS) {
|
if (osdState == OSD_STATE_UPDATE_ELEMENTS) {
|
||||||
schedulerSetNextStateTime(osdElementGroupDurationUs[osdElementGroup] + OSD_ELEMENT_RENDER_MARGIN);
|
schedulerSetNextStateTime((osdElementGroupDurationFracUs[osdElementGroup] >> OSD_EXEC_TIME_SHIFT) + OSD_ELEMENT_RENDER_GROUP_MARGIN);
|
||||||
} else {
|
} else {
|
||||||
if (osdState == OSD_STATE_IDLE) {
|
if (osdState == OSD_STATE_IDLE) {
|
||||||
schedulerSetNextStateTime(osdStateDurationUs[OSD_STATE_CHECK] + OSD_MARGIN);
|
schedulerSetNextStateTime(osdStateDurationFracUs[OSD_STATE_CHECK] >> OSD_EXEC_TIME_SHIFT);
|
||||||
} else {
|
} else {
|
||||||
schedulerSetNextStateTime(osdStateDurationUs[osdState] + OSD_MARGIN);
|
schedulerSetNextStateTime(osdStateDurationFracUs[osdState] >> OSD_EXEC_TIME_SHIFT);
|
||||||
}
|
}
|
||||||
schedulerIgnoreTaskExecTime();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue