1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-23 08:15:30 +03:00

Track state execution time for OSD, baro, rx and GPS tasks and inform scheduler of next state execution time

This commit is contained in:
Steve Evans 2020-08-14 16:42:20 +01:00 committed by Steve Evans
parent a63172cc1f
commit ab1baccc66
44 changed files with 1392 additions and 721 deletions

View file

@ -63,7 +63,7 @@ extern "C" {
#include "rx/rx.h"
void osdRefresh(timeUs_t currentTimeUs);
void osdUpdate(timeUs_t currentTimeUs);
void osdFormatTime(char * buff, osd_timer_precision_e precision, timeUs_t time);
int osdConvertTemperatureToSelectedUnit(int tempInDegreesCelcius);
@ -120,6 +120,7 @@ void setDefaultSimulationState()
memset(osdElementConfigMutable(), 0, sizeof(osdElementConfig_t));
osdConfigMutable()->enabled_stats = 0;
osdConfigMutable()->framerate_hz = 12;
rssi = 1024;
@ -135,10 +136,19 @@ void setDefaultSimulationState()
rcData[PITCH] = 1500;
simulationTime = 0;
osdFlyTime = 0;
DISABLE_ARMING_FLAG(ARMED);
}
void osdRefresh()
{
while (osdUpdateCheck(simulationTime, 0)) {
osdUpdate(simulationTime);
simulationTime += 10;
}
simulationTime += 0.1e6;
}
/*
* Performs a test of the OSD actions on arming.
* (reused throughout the test suite)
@ -149,9 +159,10 @@ void doTestArm(bool testEmpty = true)
// craft has been armed
ENABLE_ARMING_FLAG(ARMED);
simulationTime += 5e6;
// when
// sufficient OSD updates have been called
osdRefresh(simulationTime);
osdRefresh();
// then
// arming alert displayed
@ -163,7 +174,7 @@ void doTestArm(bool testEmpty = true)
// when
// sufficient OSD updates have been called
osdRefresh(simulationTime);
osdRefresh();
// then
// arming alert disappears
@ -194,7 +205,7 @@ void doTestDisarm()
// when
// sufficient OSD updates have been called
osdRefresh(simulationTime);
osdRefresh();
// then
// post flight statistics displayed
@ -240,7 +251,10 @@ void simulateFlight(void)
simulationBatteryVoltage = 1580;
simulationAltitude = 100;
simulationTime += 1e6;
osdRefresh(simulationTime);
while (osdUpdateCheck(simulationTime, 0)) {
osdUpdate(simulationTime);
simulationTime += 10;
}
rssi = 512;
gpsSol.groundSpeed = 800;
@ -249,7 +263,10 @@ void simulateFlight(void)
simulationBatteryVoltage = 1470;
simulationAltitude = 150;
simulationTime += 1e6;
osdRefresh(simulationTime);
while (osdUpdateCheck(simulationTime, 0)) {
osdUpdate(simulationTime);
simulationTime += 10;
}
rssi = 256;
gpsSol.groundSpeed = 200;
@ -258,7 +275,10 @@ void simulateFlight(void)
simulationBatteryVoltage = 1520;
simulationAltitude = 200;
simulationTime += 1e6;
osdRefresh(simulationTime);
while (osdUpdateCheck(simulationTime, 0)) {
osdUpdate(simulationTime);
simulationTime += 10;
}
rssi = 256;
gpsSol.groundSpeed = 800;
@ -267,11 +287,17 @@ void simulateFlight(void)
simulationBatteryVoltage = 1470;
simulationAltitude = 200; // converts to 6.56168 feet which rounds to 6.6 in imperial units stats test
simulationTime += 1e6;
osdRefresh(simulationTime);
while (osdUpdateCheck(simulationTime, 0)) {
osdUpdate(simulationTime);
simulationTime += 10;
}
simulationBatteryVoltage = 1520;
simulationTime += 1e6;
osdRefresh(simulationTime);
while (osdUpdateCheck(simulationTime, 0)) {
osdUpdate(simulationTime);
simulationTime += 10;
}
rssi = 256;
gpsSol.groundSpeed = 800;
@ -280,11 +306,13 @@ void simulateFlight(void)
simulationBatteryVoltage = 1470;
simulationAltitude = 200;
simulationTime += 1e6;
osdRefresh(simulationTime);
while (osdUpdateCheck(simulationTime, 0)) {
osdUpdate(simulationTime);
simulationTime += 10;
}
simulationBatteryVoltage = 1520;
simulationTime += 1e6;
osdRefresh(simulationTime);
}
class OsdTest : public ::testing::Test
@ -312,6 +340,14 @@ protected:
TEST_F(OsdTest, TestInit)
{
// given
// display port is initialised
displayPortTestInit();
// and
// default state values are set
setDefaultSimulationState();
// and
// this battery configuration (used for battery voltage elements)
batteryConfigMutable()->vbatmincellvoltage = 330;
batteryConfigMutable()->vbatmaxcellvoltage = 430;
@ -320,6 +356,8 @@ TEST_F(OsdTest, TestInit)
// OSD is initialised
osdInit(&testDisplayPort, OSD_DISPLAYPORT_DEVICE_AUTO);
osdRefresh();
// then
// display buffer should contain splash screen
displayPortTestBufferSubstring(7, 8, "MENU:THR MID");
@ -329,7 +367,7 @@ TEST_F(OsdTest, TestInit)
// when
// splash screen timeout has elapsed
simulationTime += 4e6;
osdUpdate(simulationTime);
osdRefresh();
// then
// display buffer should be empty
@ -362,7 +400,7 @@ TEST_F(OsdTest, TestDisarm)
// when
// sufficient OSD updates have been called
osdRefresh(simulationTime);
osdRefresh();
// then
// post flight stats screen disappears
@ -399,7 +437,7 @@ TEST_F(OsdTest, TestDisarmWithDismissStats)
// when
// sufficient OSD updates have been called
osdRefresh(simulationTime);
osdRefresh();
// then
// post flight stats screen disappears
@ -446,7 +484,7 @@ TEST_F(OsdTest, TestStatsTiming)
// and
// these conditions occur during flight
simulationTime += 1e6;
osdRefresh(simulationTime);
osdRefresh();
// and
// the craft is disarmed
@ -459,7 +497,7 @@ TEST_F(OsdTest, TestStatsTiming)
// and
// these conditions occur during flight
simulationTime += 1e6;
osdRefresh(simulationTime);
osdRefresh();
// and
// the craft is disarmed
@ -469,7 +507,7 @@ TEST_F(OsdTest, TestStatsTiming)
// statistics screen should display the following
int row = 7;
displayPortTestBufferSubstring(2, row++, "2017-11-19 10:12:");
displayPortTestBufferSubstring(2, row++, "TOTAL ARM : 00:02.50");
displayPortTestBufferSubstring(2, row++, "TOTAL ARM : 00:13.61");
displayPortTestBufferSubstring(2, row++, "LAST ARM : 00:01");
}
@ -598,7 +636,7 @@ TEST_F(OsdTest, TestAlarms)
osdElementConfigMutable()->item_pos[OSD_MAIN_BATT_VOLTAGE] = OSD_POS(12, 1) | OSD_PROFILE_1_FLAG;
osdElementConfigMutable()->item_pos[OSD_ITEM_TIMER_1] = OSD_POS(20, 1) | OSD_PROFILE_1_FLAG;
osdElementConfigMutable()->item_pos[OSD_ITEM_TIMER_2] = OSD_POS(1, 1) | OSD_PROFILE_1_FLAG;
osdElementConfigMutable()->item_pos[OSD_REMAINING_TIME_ESTIMATE] = OSD_POS(1, 2) | OSD_PROFILE_1_FLAG;
osdElementConfigMutable()->item_pos[OSD_REMAINING_TIME_ESTIMATE] = OSD_POS(1, 2) | OSD_PROFILE_1_FLAG;
osdElementConfigMutable()->item_pos[OSD_ALTITUDE] = OSD_POS(23, 7) | OSD_PROFILE_1_FLAG;
// and
@ -611,10 +649,10 @@ TEST_F(OsdTest, TestAlarms)
// and
// this timer 1 configuration
osdConfigMutable()->timers[OSD_TIMER_1] = OSD_TIMER(OSD_TIMER_SRC_ON, OSD_TIMER_PREC_HUNDREDTHS, 3);
osdConfigMutable()->timers[OSD_TIMER_1] = OSD_TIMER(OSD_TIMER_SRC_ON, OSD_TIMER_PREC_HUNDREDTHS, 5);
EXPECT_EQ(OSD_TIMER_SRC_ON, OSD_TIMER_SRC(osdConfig()->timers[OSD_TIMER_1]));
EXPECT_EQ(OSD_TIMER_PREC_HUNDREDTHS, OSD_TIMER_PRECISION(osdConfig()->timers[OSD_TIMER_1]));
EXPECT_EQ(3, OSD_TIMER_ALARM(osdConfig()->timers[OSD_TIMER_1]));
EXPECT_EQ(5, OSD_TIMER_ALARM(osdConfig()->timers[OSD_TIMER_1]));
// and
// this timer 2 configuration
@ -630,21 +668,21 @@ TEST_F(OsdTest, TestAlarms)
// when
// time is passing by
simulationTime += 60e6;
osdRefresh(simulationTime);
osdRefresh();
// and
// the craft is armed
doTestArm(false);
simulationTime += 70e6;
osdRefresh(simulationTime);
osdRefresh();
// then
// no elements should flash as all values are out of alarm range
for (int i = 0; i < 30; i++) {
// Check for visibility every 100ms, elements should always be visible
simulationTime += 0.1e6;
osdRefresh(simulationTime);
osdRefresh();
#ifdef DEBUG_OSD
printf("%d\n", i);
@ -652,7 +690,7 @@ TEST_F(OsdTest, TestAlarms)
displayPortTestBufferSubstring(1, 1, "%c01:", SYM_FLY_M); // only test the minute part of the timer
displayPortTestBufferSubstring(8, 1, "%c99", SYM_RSSI);
displayPortTestBufferSubstring(12, 1, "%c16.8%c", SYM_BATT_FULL, SYM_VOLT);
displayPortTestBufferSubstring(20, 1, "%c02:", SYM_ON_M); // only test the minute part of the timer
displayPortTestBufferSubstring(20, 1, "%c04:", SYM_ON_M); // only test the minute part of the timer
displayPortTestBufferSubstring(23, 7, "%c0.0%c", SYM_ALTITUDE, SYM_M);
}
@ -665,14 +703,17 @@ TEST_F(OsdTest, TestAlarms)
simulationMahDrawn = 999999;
simulationTime += 60e6;
osdRefresh(simulationTime);
osdRefresh();
// then
// elements showing values in alarm range should flash
simulationTime += 1000000;
simulationTime -= simulationTime % 1000000;
timeUs_t startTime = simulationTime;
for (int i = 0; i < 15; i++) {
// Blinking should happen at 5Hz
simulationTime += 0.2e6;
osdRefresh(simulationTime);
// Blinking should happen at 2Hz
simulationTime = startTime + i*0.25e6;
osdRefresh();
#ifdef DEBUG_OSD
printf("%d\n", i);
@ -682,7 +723,7 @@ TEST_F(OsdTest, TestAlarms)
displayPortTestBufferSubstring(8, 1, "%c12", SYM_RSSI);
displayPortTestBufferSubstring(12, 1, "%c13.5%c", SYM_MAIN_BATT, SYM_VOLT);
displayPortTestBufferSubstring(1, 1, "%c02:", SYM_FLY_M); // only test the minute part of the timer
displayPortTestBufferSubstring(20, 1, "%c03:", SYM_ON_M); // only test the minute part of the timer
displayPortTestBufferSubstring(20, 1, "%c05:", SYM_ON_M); // only test the minute part of the timer
displayPortTestBufferSubstring(23, 7, "%c120.0%c", SYM_ALTITUDE, SYM_M);
} else {
displayPortTestBufferIsEmpty();
@ -704,7 +745,7 @@ TEST_F(OsdTest, TestElementRssi)
// when
rssi = 1024;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(8, 1, "%c99", SYM_RSSI);
@ -712,7 +753,7 @@ TEST_F(OsdTest, TestElementRssi)
// when
rssi = 0;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(8, 1, "%c 0", SYM_RSSI);
@ -720,7 +761,7 @@ TEST_F(OsdTest, TestElementRssi)
// when
rssi = 512;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(8, 1, "%c50", SYM_RSSI);
@ -739,7 +780,7 @@ TEST_F(OsdTest, TestElementAmperage)
// when
simulationBatteryAmperage = 0;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 12, " 0.00%c", SYM_AMP);
@ -747,7 +788,7 @@ TEST_F(OsdTest, TestElementAmperage)
// when
simulationBatteryAmperage = 2156;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 12, " 21.56%c", SYM_AMP);
@ -755,7 +796,7 @@ TEST_F(OsdTest, TestElementAmperage)
// when
simulationBatteryAmperage = 12345;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 12, "123.45%c", SYM_AMP);
@ -774,7 +815,7 @@ TEST_F(OsdTest, TestElementMahDrawn)
// when
simulationMahDrawn = 0;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 11, " 0%c", SYM_MAH);
@ -782,7 +823,7 @@ TEST_F(OsdTest, TestElementMahDrawn)
// when
simulationMahDrawn = 4;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 11, " 4%c", SYM_MAH);
@ -790,7 +831,7 @@ TEST_F(OsdTest, TestElementMahDrawn)
// when
simulationMahDrawn = 15;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 11, " 15%c", SYM_MAH);
@ -798,7 +839,7 @@ TEST_F(OsdTest, TestElementMahDrawn)
// when
simulationMahDrawn = 246;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 11, " 246%c", SYM_MAH);
@ -806,7 +847,7 @@ TEST_F(OsdTest, TestElementMahDrawn)
// when
simulationMahDrawn = 1042;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 11, "1042%c", SYM_MAH);
@ -830,7 +871,7 @@ TEST_F(OsdTest, TestElementPower)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 10, " 0W");
@ -840,7 +881,7 @@ TEST_F(OsdTest, TestElementPower)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 10, " 1W");
@ -850,7 +891,7 @@ TEST_F(OsdTest, TestElementPower)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 10, " 12W");
@ -860,7 +901,7 @@ TEST_F(OsdTest, TestElementPower)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 10, " 123W");
@ -870,7 +911,7 @@ TEST_F(OsdTest, TestElementPower)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 10, "1234W");
@ -893,7 +934,7 @@ TEST_F(OsdTest, TestElementAltitude)
// when
simulationAltitude = 0;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(23, 7, "%c-", SYM_ALTITUDE);
@ -901,7 +942,7 @@ TEST_F(OsdTest, TestElementAltitude)
// when
sensorsSet(SENSOR_GPS);
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(23, 7, "%c0.0%c", SYM_ALTITUDE, SYM_M);
@ -909,7 +950,7 @@ TEST_F(OsdTest, TestElementAltitude)
// when
simulationAltitude = 247; // rounds to 2.5m
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(23, 7, "%c2.5%c", SYM_ALTITUDE, SYM_M);
@ -917,7 +958,7 @@ TEST_F(OsdTest, TestElementAltitude)
// when
simulationAltitude = 4247; // rounds to 42.5m
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(23, 7, "%c42.5%c", SYM_ALTITUDE, SYM_M);
@ -925,7 +966,7 @@ TEST_F(OsdTest, TestElementAltitude)
// when
simulationAltitude = -247; // rounds to -2.5m
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(23, 7, "%c-2.5%c", SYM_ALTITUDE, SYM_M);
@ -933,7 +974,7 @@ TEST_F(OsdTest, TestElementAltitude)
// when
simulationAltitude = -70;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(23, 7, "%c-0.7%c", SYM_ALTITUDE, SYM_M);
@ -958,7 +999,7 @@ TEST_F(OsdTest, TestElementCoreTemperature)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 8, "C%c 0%c", SYM_TEMPERATURE, SYM_C);
@ -968,7 +1009,7 @@ TEST_F(OsdTest, TestElementCoreTemperature)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 8, "C%c 33%c", SYM_TEMPERATURE, SYM_C);
@ -978,7 +1019,7 @@ TEST_F(OsdTest, TestElementCoreTemperature)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(1, 8, "C%c 91%c", SYM_TEMPERATURE, SYM_F);
@ -1012,7 +1053,10 @@ TEST_F(OsdTest, TestElementWarningsBattery)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
// Delay as the warnings are flashing
simulationTime += 1000000;
simulationTime -= simulationTime % 1000000;
osdRefresh();
// then
displayPortTestBufferSubstring(9, 10, "BATT < FULL");
@ -1024,7 +1068,7 @@ TEST_F(OsdTest, TestElementWarningsBattery)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(9, 10, " ");
@ -1036,7 +1080,11 @@ TEST_F(OsdTest, TestElementWarningsBattery)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
// Delay as the warnings are flashing
simulationTime += 1000000;
simulationTime -= simulationTime % 1000000;
simulationTime += 0.25e6;
osdRefresh();
// then
displayPortTestBufferSubstring(9, 10, "LOW BATTERY ");
@ -1048,8 +1096,11 @@ TEST_F(OsdTest, TestElementWarningsBattery)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh(simulationTime);
// Delay as the warnings are flashing
simulationTime += 1000000;
simulationTime -= simulationTime % 1000000;
simulationTime += 0.25e6;
osdRefresh();
// then
displayPortTestBufferSubstring(9, 10, " LAND NOW ");
@ -1061,7 +1112,7 @@ TEST_F(OsdTest, TestElementWarningsBattery)
// when
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
displayPortTestBufferSubstring(9, 10, " ");
@ -1149,16 +1200,19 @@ TEST_F(OsdTest, TestGpsElements)
gpsSol.numSat = 0;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
// Sat indicator should blink and show "NC"
simulationTime += 1000000;
simulationTime -= simulationTime % 1000000;
timeUs_t startTime = simulationTime;
for (int i = 0; i < 15; i++) {
// Blinking should happen at 5Hz
simulationTime += 0.2e6;
osdRefresh(simulationTime);
// Blinking should happen at 2Hz
simulationTime = startTime + i*0.25e6;
osdRefresh();
if (i % 2 == 0) {
if (i % 2 == 1) {
displayPortTestBufferSubstring(2, 4, "%c%cNC", SYM_SAT_L, SYM_SAT_R);
} else {
displayPortTestBufferIsEmpty();
@ -1170,16 +1224,19 @@ TEST_F(OsdTest, TestGpsElements)
gpsSol.numSat = 0;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
// Sat indicator should blink and show "0"
simulationTime += 1000000;
simulationTime -= simulationTime % 1000000;
startTime = simulationTime;
for (int i = 0; i < 15; i++) {
// Blinking should happen at 5Hz
simulationTime += 0.2e6;
osdRefresh(simulationTime);
// Blinking should happen at 2Hz
simulationTime = startTime + i*0.25e6;
osdRefresh();
if (i % 2 == 0) {
if (i % 2 == 1) {
displayPortTestBufferSubstring(2, 4, "%c%c 0", SYM_SAT_L, SYM_SAT_R);
} else {
displayPortTestBufferIsEmpty();
@ -1191,14 +1248,14 @@ TEST_F(OsdTest, TestGpsElements)
gpsSol.numSat = 10;
displayClearScreen(&testDisplayPort);
osdRefresh(simulationTime);
osdRefresh();
// then
// Sat indicator should show "10" without flashing
for (int i = 0; i < 15; i++) {
// Blinking should happen at 5Hz
// Blinking should happen at 2Hz
simulationTime += 0.2e6;
osdRefresh(simulationTime);
osdRefresh();
displayPortTestBufferSubstring(2, 4, "%c%c10", SYM_SAT_L, SYM_SAT_R);
}
@ -1319,6 +1376,8 @@ extern "C" {
bool isUpright(void) { return true; }
float getMotorOutputLow(void) { return 1000.0; }
float getMotorOutputHigh(void) { return 2047.0; }
void ignoreTaskShortExecTime(void) {}
void ignoreTaskStateTime(void) {}
void ignoreTaskStateTime(void) { }
void ignoreTaskExecRate(void) { }
void ignoreTaskExecTime(void) { }
void schedulerSetNextStateTime(timeDelta_t) {}
}