1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-26 09:45:33 +03:00

Reduce RAM usage in CMS

Add support for direct pointers to readonly values rather than using
intermediate OSD_XXX_t types.
Use direct pointers on all readonly values.
Make sure all intermediate value/step holders are in flash rather
than ram, since they're never modified.

This saves another 352 bytes of RAM (mostly on data, a few on bss).
This commit is contained in:
Alberto García Hierro 2018-03-06 10:11:15 +00:00
parent 2095c64789
commit 0c14331305
6 changed files with 95 additions and 65 deletions

View file

@ -87,6 +87,7 @@ static uint8_t entry_flags[32];
#define CLR_PRINTLABEL(p, row) { entry_flags[row] &= ~PRINT_LABEL; }
#define IS_DYNAMIC(p) ((p)->flags & DYNAMIC)
#define IS_READONLY(p) ((p)->flags & READONLY)
static displayPort_t *pCurrentDisplay;
@ -339,7 +340,7 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_TAB:
if (IS_PRINTVALUE(p, screenRow)) {
OSD_TAB_t *ptr = p->data;
const OSD_TAB_t *ptr = p->data;
char * str = (char *)ptr->names[*ptr->val];
memcpy(buff, str, MAX(CMS_DRAW_BUFFER_LEN, strlen(str)));
cmsPadToSize(buff, CMS_DRAW_BUFFER_LEN);
@ -365,8 +366,14 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_UINT8:
if (IS_PRINTVALUE(p, screenRow) && p->data) {
OSD_UINT8_t *ptr = p->data;
itoa(*ptr->val, buff, 10);
const uint8_t *val;
if (IS_READONLY(p)) {
val = p->data;
} else {
const OSD_UINT8_t *ptr = p->data;
val = ptr->val;
}
itoa(*val, buff, 10);
cmsPadToSize(buff, 5);
cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay), row, buff);
CLR_PRINTVALUE(p, screenRow);
@ -375,8 +382,14 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_INT8:
if (IS_PRINTVALUE(p, screenRow) && p->data) {
OSD_INT8_t *ptr = p->data;
itoa(*ptr->val, buff, 10);
const int8_t *val;
if (IS_READONLY(p)) {
val = p->data;
} else {
const OSD_INT8_t *ptr = p->data;
val = ptr->val;
}
itoa(*val, buff, 10);
cmsPadToSize(buff, 5);
cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay), row, buff);
CLR_PRINTVALUE(p, screenRow);
@ -385,8 +398,14 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_UINT16:
if (IS_PRINTVALUE(p, screenRow) && p->data) {
OSD_UINT16_t *ptr = p->data;
itoa(*ptr->val, buff, 10);
const uint16_t *val;
if (IS_READONLY(p)) {
val = p->data;
} else {
const OSD_UINT16_t *ptr = p->data;
val = ptr->val;
}
itoa(*val, buff, 10);
cmsPadToSize(buff, 5);
cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay), row, buff);
CLR_PRINTVALUE(p, screenRow);
@ -395,8 +414,14 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_INT16:
if (IS_PRINTVALUE(p, screenRow) && p->data) {
OSD_UINT16_t *ptr = p->data;
itoa(*ptr->val, buff, 10);
const int16_t *val;
if (IS_READONLY(p)) {
val = p->data;
} else {
const OSD_INT16_t *ptr = p->data;
val = ptr->val;
}
itoa(*val, buff, 10);
cmsPadToSize(buff, 5);
cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay), row, buff);
CLR_PRINTVALUE(p, screenRow);
@ -405,7 +430,7 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_FLOAT:
if (IS_PRINTVALUE(p, screenRow) && p->data) {
OSD_FLOAT_t *ptr = p->data;
const OSD_FLOAT_t *ptr = p->data;
cmsFormatFloat(*ptr->val * ptr->multipler, buff);
cmsPadToSize(buff, 5);
cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay) - 1, row, buff); // XXX One char left ???
@ -416,7 +441,7 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_Setting:
if (IS_PRINTVALUE(p, screenRow) && p->data) {
buff[0] = '\0';
OSD_SETTING_t *ptr = p->data;
const OSD_SETTING_t *ptr = p->data;
const setting_t *var = &settingsTable[ptr->val];
int32_t value;
const void *valuePointer = setting_get_value_pointer(var);
@ -858,7 +883,7 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
case OME_Bool:
if (p->data) {
uint8_t *val = p->data;
uint8_t *val = (uint8_t *)p->data;
if (key == KEY_RIGHT)
*val = 1;
else
@ -892,8 +917,11 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
case OME_UINT8:
case OME_FLOAT:
if (IS_READONLY(p)) {
break;
}
if (p->data) {
OSD_UINT8_t *ptr = p->data;
const OSD_UINT8_t *ptr = p->data;
if (key == KEY_RIGHT) {
if (*ptr->val < ptr->max)
*ptr->val += ptr->step;
@ -911,7 +939,7 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
case OME_TAB:
if (p->type == OME_TAB) {
OSD_TAB_t *ptr = p->data;
const OSD_TAB_t *ptr = p->data;
if (key == KEY_RIGHT) {
if (*ptr->val < ptr->max)
@ -928,8 +956,11 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
break;
case OME_INT8:
if (IS_READONLY(p)) {
break;
}
if (p->data) {
OSD_INT8_t *ptr = p->data;
const OSD_INT8_t *ptr = p->data;
if (key == KEY_RIGHT) {
if (*ptr->val < ptr->max)
*ptr->val += ptr->step;
@ -946,8 +977,11 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
break;
case OME_UINT16:
if (IS_READONLY(p)) {
break;
}
if (p->data) {
OSD_UINT16_t *ptr = p->data;
const OSD_UINT16_t *ptr = p->data;
if (key == KEY_RIGHT) {
if (*ptr->val < ptr->max)
*ptr->val += ptr->step;
@ -964,8 +998,11 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
break;
case OME_INT16:
if (IS_READONLY(p)) {
break;
}
if (p->data) {
OSD_INT16_t *ptr = p->data;
const OSD_INT16_t *ptr = p->data;
if (key == KEY_RIGHT) {
if (*ptr->val < ptr->max)
*ptr->val += ptr->step;
@ -983,7 +1020,7 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
case OME_Setting:
if (p->data) {
OSD_SETTING_t *ptr = p->data;
const OSD_SETTING_t *ptr = p->data;
const setting_t *var = &settingsTable[ptr->val];
setting_min_t min = setting_get_min(var);
setting_max_t max = setting_get_max(var);

View file

@ -56,15 +56,15 @@ static const OSD_Entry cmsx_menuRcEntries[] =
{
OSD_LABEL_ENTRY("-- RC PREV --"),
OSD_INT16_DYN_ENTRY("ROLL", (&(OSD_INT16_t){ &rcData[ROLL], 1, 2500, 0 })),
OSD_INT16_DYN_ENTRY("PITCH", (&(OSD_INT16_t){ &rcData[PITCH], 1, 2500, 0 })),
OSD_INT16_DYN_ENTRY("THR", (&(OSD_INT16_t){ &rcData[THROTTLE], 1, 2500, 0 })),
OSD_INT16_DYN_ENTRY("YAW", (&(OSD_INT16_t){ &rcData[YAW], 1, 2500, 0 })),
OSD_INT16_RO_ENTRY("ROLL", &rcData[ROLL]),
OSD_INT16_RO_ENTRY("PITCH", &rcData[PITCH]),
OSD_INT16_RO_ENTRY("THR", &rcData[THROTTLE]),
OSD_INT16_RO_ENTRY("YAW", &rcData[YAW]),
OSD_INT16_DYN_ENTRY("AUX1", (&(OSD_INT16_t){ &rcData[AUX1], 1, 2500, 0 })),
OSD_INT16_DYN_ENTRY("AUX2", (&(OSD_INT16_t){ &rcData[AUX2], 1, 2500, 0 })),
OSD_INT16_DYN_ENTRY("AUX3", (&(OSD_INT16_t){ &rcData[AUX3], 1, 2500, 0 })),
OSD_INT16_DYN_ENTRY("AUX4", (&(OSD_INT16_t){ &rcData[AUX4], 1, 2500, 0 })),
OSD_INT16_RO_ENTRY("AUX1", &rcData[AUX1]),
OSD_INT16_RO_ENTRY("AUX2", &rcData[AUX2]),
OSD_INT16_RO_ENTRY("AUX3", &rcData[AUX3]),
OSD_INT16_RO_ENTRY("AUX4", &rcData[AUX4]),
OSD_BACK_ENTRY,
OSD_END_ENTRY,

View file

@ -64,8 +64,8 @@ static const char * const vtxBandNames[] = {
"RACEBAND",
};
static OSD_TAB_t entryVtxBand = {&cmsx_vtxBand,4,&vtxBandNames[0]};
static OSD_UINT8_t entryVtxChannel = {&cmsx_vtxChannel, 1, 8, 1};
static const OSD_TAB_t entryVtxBand = {&cmsx_vtxBand,4,&vtxBandNames[0]};
static const OSD_UINT8_t entryVtxChannel = {&cmsx_vtxChannel, 1, 8, 1};
static void cmsx_Vtx_ConfigRead(void)
{
@ -110,8 +110,8 @@ static long cmsx_Vtx_onExit(const OSD_Entry *self)
}
#ifdef VTX
static OSD_UINT8_t entryVtxMode = {&masterConfig.vtx_mode, 0, 2, 1};
static OSD_UINT16_t entryVtxMhz = {&masterConfig.vtx_mhz, 5600, 5950, 1};
static const OSD_UINT8_t entryVtxMode = {&masterConfig.vtx_mode, 0, 2, 1};
static const OSD_UINT16_t entryVtxMhz = {&masterConfig.vtx_mhz, 5600, 5950, 1};
#endif // VTX
static const OSD_Entry cmsx_menuVtxEntries[] =

View file

@ -304,19 +304,19 @@ static const char * const saCmsDeviceStatusNames[] = {
"ONL V2",
};
static OSD_TAB_t saCmsEntOnline = { &saCmsDeviceStatus, 2, saCmsDeviceStatusNames };
static const OSD_TAB_t saCmsEntOnline = { &saCmsDeviceStatus, 2, saCmsDeviceStatusNames };
static const OSD_Entry saCmsMenuStatsEntries[] = {
OSD_LABEL_ENTRY("- SA STATS -"),
OSD_TAB_DYN_ENTRY("STATUS", &saCmsEntOnline),
OSD_UINT16_DYN_ENTRY("BAUDRATE", (&(OSD_UINT16_t){ &sa_smartbaud, 0, 0, 0 })),
OSD_UINT16_DYN_ENTRY("SENT", (&(OSD_UINT16_t){ &saStat.pktsent, 0, 0, 0 })),
OSD_UINT16_DYN_ENTRY("RCVD", (&(OSD_UINT16_t){ &saStat.pktrcvd, 0, 0, 0 })),
OSD_UINT16_DYN_ENTRY("BADPRE", (&(OSD_UINT16_t){ &saStat.badpre, 0, 0, 0 })),
OSD_UINT16_DYN_ENTRY("BADLEN", (&(OSD_UINT16_t){ &saStat.badlen, 0, 0, 0 })),
OSD_UINT16_DYN_ENTRY("CRCERR", (&(OSD_UINT16_t){ &saStat.crc, 0, 0, 0 })),
OSD_UINT16_DYN_ENTRY("OOOERR", (&(OSD_UINT16_t){ &saStat.ooopresp, 0, 0, 0 })),
OSD_UINT16_RO_ENTRY("BAUDRATE", &sa_smartbaud),
OSD_UINT16_RO_ENTRY("SENT", &saStat.pktsent),
OSD_UINT16_RO_ENTRY("RCVD", &saStat.pktrcvd),
OSD_UINT16_RO_ENTRY("BADPRE", &saStat.badpre),
OSD_UINT16_RO_ENTRY("BADLEN", &saStat.badlen),
OSD_UINT16_RO_ENTRY("CRCERR", &saStat.crc),
OSD_UINT16_RO_ENTRY("OOOERR", &saStat.ooopresp),
OSD_BACK_ENTRY,
OSD_END_ENTRY,
@ -333,9 +333,9 @@ static const CMS_Menu saCmsMenuStats = {
.entries = saCmsMenuStatsEntries
};
static OSD_TAB_t saCmsEntBand = { &saCmsBand, 5, vtx58BandNames };
static const OSD_TAB_t saCmsEntBand = { &saCmsBand, 5, vtx58BandNames };
static OSD_TAB_t saCmsEntChan = { &saCmsChan, 8, vtx58ChannelNames };
static const OSD_TAB_t saCmsEntChan = { &saCmsChan, 8, vtx58ChannelNames };
static const char * const saCmsPowerNames[] = {
"---",
@ -345,9 +345,7 @@ static const char * const saCmsPowerNames[] = {
"800",
};
static OSD_TAB_t saCmsEntPower = { &saCmsPower, 4, saCmsPowerNames};
static OSD_UINT16_t saCmsEntFreqRef = { &saCmsFreqRef, 5600, 5900, 0 };
static const OSD_TAB_t saCmsEntPower = { &saCmsPower, 4, saCmsPowerNames};
static const char * const saCmsOpmodelNames[] = {
"----",
@ -365,7 +363,7 @@ static const char * const saCmsPitFModeNames[] = {
"POR"
};
static OSD_TAB_t saCmsEntPitFMode = { &saCmsPitFMode, 1, saCmsPitFModeNames };
static const OSD_TAB_t saCmsEntPitFMode = { &saCmsPitFMode, 1, saCmsPitFModeNames };
static long sacms_SetupTopMenu(void); // Forward
@ -480,7 +478,7 @@ static const OSD_Entry saCmsMenuPORFreqEntries[] =
{
OSD_LABEL_ENTRY("- POR FREQ -"),
OSD_UINT16_DYN_ENTRY("CUR FREQ", (&(OSD_UINT16_t){ &saCmsORFreq, 5000, 5900, 0 })),
OSD_UINT16_RO_ENTRY("CUR FREQ", &saCmsORFreq),
OSD_UINT16_ENTRY("NEW FREQ", (&(OSD_UINT16_t){ &saCmsORFreqNew, 5000, 5900, 1 })),
OSD_FUNC_CALL_ENTRY("SET", saCmsSetPORFreq),
@ -504,7 +502,7 @@ static const OSD_Entry saCmsMenuUserFreqEntries[] =
{
OSD_LABEL_ENTRY("- USER FREQ -"),
OSD_UINT16_DYN_ENTRY("CUR FREQ", (&(OSD_UINT16_t){ &saCmsUserFreq, 5000, 5900, 0 })),
OSD_UINT16_RO_ENTRY("CUR FREQ", &saCmsUserFreq),
OSD_UINT16_ENTRY("NEW FREQ", (&(OSD_UINT16_t){ &saCmsUserFreqNew, 5000, 5900, 1 })),
OSD_FUNC_CALL_ENTRY("SET", saCmsConfigUserFreq),
@ -524,7 +522,7 @@ static const CMS_Menu saCmsMenuUserFreq =
.entries = saCmsMenuUserFreqEntries,
};
static OSD_TAB_t saCmsEntFselMode = { &saCmsFselMode, 1, saCmsFselModeNames };
static const OSD_TAB_t saCmsEntFselMode = { &saCmsFselMode, 1, saCmsFselModeNames };
static const OSD_Entry saCmsMenuConfigEntries[] =
{
@ -592,7 +590,7 @@ static const OSD_Entry saCmsMenuChanModeEntries[] =
OSD_LABEL_FUNC_DYN_ENTRY("", saCmsDrawStatusString),
OSD_TAB_CALLBACK_ENTRY("BAND", saCmsConfigBandByGvar, &saCmsEntBand),
OSD_TAB_CALLBACK_ENTRY("CHAN", saCmsConfigChanByGvar, &saCmsEntChan),
OSD_UINT16_DYN_ENTRY("(FREQ)", &saCmsEntFreqRef),
OSD_UINT16_RO_ENTRY("(FREQ)", &saCmsFreqRef),
OSD_TAB_CALLBACK_ENTRY("POWER", saCmsConfigPowerByGvar, &saCmsEntPower),
OSD_SUBMENU_ENTRY("SET", &saCmsMenuCommence),
OSD_SUBMENU_ENTRY("CONFIG", &saCmsMenuConfig),

View file

@ -78,15 +78,13 @@ uint8_t trampCmsBand = 1;
uint8_t trampCmsChan = 1;
uint16_t trampCmsFreqRef;
OSD_TAB_t trampCmsEntBand = { &trampCmsBand, 5, vtx58BandNames };
static const OSD_TAB_t trampCmsEntBand = { &trampCmsBand, 5, vtx58BandNames };
OSD_TAB_t trampCmsEntChan = { &trampCmsChan, 8, vtx58ChannelNames };
static OSD_UINT16_t trampCmsEntFreqRef = { &trampCmsFreqRef, 5600, 5900, 0 };
static const OSD_TAB_t trampCmsEntChan = { &trampCmsChan, 8, vtx58ChannelNames };
static uint8_t trampCmsPower = 1;
OSD_TAB_t trampCmsEntPower = { &trampCmsPower, 5, trampPowerNames };
static const OSD_TAB_t trampCmsEntPower = { &trampCmsPower, 5, trampPowerNames };
static void trampCmsUpdateFreqRef(void)
{
@ -134,13 +132,11 @@ static long trampCmsConfigPower(displayPort_t *pDisp, const void *self)
return 0;
}
static OSD_INT16_t trampCmsEntTemp = { &trampData.temperature, -100, 300, 0 };
static const char * const trampCmsPitModeNames[] = {
"---", "OFF", "ON "
};
static OSD_TAB_t trampCmsEntPitMode = { &trampCmsPitMode, 2, trampCmsPitModeNames };
static const OSD_TAB_t trampCmsEntPitMode = { &trampCmsPitMode, 2, trampCmsPitModeNames };
static long trampCmsSetPitMode(displayPort_t *pDisp, const void *self)
{
@ -223,9 +219,9 @@ static const OSD_Entry trampMenuEntries[] =
OSD_TAB_CALLBACK_ENTRY("PIT", trampCmsSetPitMode, &trampCmsEntPitMode),
OSD_TAB_CALLBACK_ENTRY("BAND", trampCmsConfigBand, &trampCmsEntBand),
OSD_TAB_CALLBACK_ENTRY("CHAN", trampCmsConfigChan, &trampCmsEntChan),
OSD_UINT16_DYN_ENTRY("(FREQ)", &trampCmsEntFreqRef),
OSD_UINT16_RO_ENTRY("(FREQ)", &trampCmsFreqRef),
OSD_TAB_CALLBACK_ENTRY("POWER", trampCmsConfigPower, &trampCmsEntPower),
OSD_INT16_DYN_ENTRY("T(C)", &trampCmsEntTemp),
OSD_INT16_RO_ENTRY("T(C)", &trampData.temperature),
OSD_SUBMENU_ENTRY("SET", &trampCmsMenuCommence),
OSD_BACK_ENTRY,

View file

@ -65,7 +65,7 @@ typedef struct
const char * const text;
const OSD_MenuElement type;
const CMSEntryFuncPtr func;
void *data;
const void * const data;
uint8_t flags;
} OSD_Entry;
@ -74,17 +74,14 @@ typedef struct
#define PRINT_LABEL (1 << 1) // Text label should be printed
#define DYNAMIC (1 << 2) // Value should be updated dynamically
#define OPTSTRING (1 << 3) // (Temporary) Flag for OME_Submenu, indicating func should be called to get a string to display.
#define READONLY (1 << 4) // Indicates that the value is read-only and p->data points directly to it - applies to [U]INT(8|16)
#define OSD_LABEL_ENTRY(label) ((OSD_Entry){ label, OME_Label, NULL, NULL, 0 })
#define OSD_LABEL_DATA_ENTRY(label, data) ((OSD_Entry){ label, OME_Label, NULL, data, 0 })
#define OSD_LABEL_DATA_DYN_ENTRY(label, data) ((OSD_Entry){ label, OME_Label, NULL, data, DYNAMIC })
#define OSD_LABEL_FUNC_DYN_ENTRY(label, fn) ((OSD_Entry){ label, OME_LabelFunc, NULL, fn, DYNAMIC })
#define OSD_BACK_ENTRY ((OSD_Entry){ "BACK", OME_Back, NULL, NULL, 0 })
// Cast menus to (void *), since they should be declared as const to
// be able to save them in FLASH. Of course, this means that changing
// a entry->data pointer for a menu declared as const will result in
// UB.
#define OSD_SUBMENU_ENTRY(label, menu) ((OSD_Entry){ label, OME_Submenu, cmsMenuChange, (void *)menu, 0 })
#define OSD_SUBMENU_ENTRY(label, menu) ((OSD_Entry){ label, OME_Submenu, cmsMenuChange, menu, 0 })
#define OSD_FUNC_CALL_ENTRY(label, fn) ((OSD_Entry){ label, OME_Funcall, fn, NULL, 0 })
#define OSD_BOOL_ENTRY(label, val) ((OSD_Entry){ label, OME_Bool, NULL, val, 0 })
#define OSD_BOOL_FUNC_ENTRY(label, fn) ((OSD_Entry){ label, OME_BoolFunc, NULL, fn, 0 })
@ -92,7 +89,9 @@ typedef struct
#define OSD_UINT8_CALLBACK_ENTRY(label, cb, val)((OSD_Entry){ label, OME_UINT8, cb, val, 0 })
#define OSD_UINT16_ENTRY(label, val) ((OSD_Entry){ label, OME_UINT16, NULL, val, 0 })
#define OSD_UINT16_DYN_ENTRY(label, val) ((OSD_Entry){ label, OME_UINT16, NULL, val, DYNAMIC })
#define OSD_UINT16_RO_ENTRY(label, val) ((OSD_Entry){ label, OME_UINT16, NULL, val, DYNAMIC | READONLY })
#define OSD_INT16_DYN_ENTRY(label, val) ((OSD_Entry){ label, OME_INT16, NULL, val, DYNAMIC })
#define OSD_INT16_RO_ENTRY(label, val) ((OSD_Entry){ label, OME_INT16, NULL, val, DYNAMIC | READONLY })
#define OSD_STRING_ENTRY(label, str) ((OSD_Entry){ label, OME_String, NULL, str, 0 })
#define OSD_TAB_ENTRY(label, val) ((OSD_Entry){ label, OME_TAB, NULL, val, 0 })
#define OSD_TAB_DYN_ENTRY(label, val) ((OSD_Entry){ label, OME_TAB, NULL, val, DYNAMIC })