1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-18 22:05:10 +03:00

Projectkk2glider/flash savings (#4199)

* Flash savings: getFileExtension() de-templated, saves 160 bytes

* Flash savings: several variables moved to rodata, RGB macro optimization (speed and can now be used to initialize rodata)

Result for Horus:
   text	   data	    bss	    dec
1261182	 808603	  42020	2111805   before
1267149	 803335	  42124	2112608   after (data size also counts .sram section)

5kB saved in .data section (RAM and FLASH)

* Removed compiler warnings

* RGB() and ARGB() gtests added

* ARGB() optimized
This commit is contained in:
Damjan Adamic 2017-01-05 21:44:59 +01:00 committed by Bertrand Songis
parent 3b58ee8d3c
commit 82dce3ee60
14 changed files with 120 additions and 67 deletions

View file

@ -66,7 +66,7 @@ uint16_t crc16(const uint8_t * buf, uint32_t len)
} }
// CRC8 implementation with polynom = x^8+x^7+x^6+x^4+x^2+1 (0xD5) // CRC8 implementation with polynom = x^8+x^7+x^6+x^4+x^2+1 (0xD5)
unsigned char crc8tab[256] = { const unsigned char crc8tab[256] = {
0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, 0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54,
0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D, 0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D,
0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, 0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06,

View file

@ -106,7 +106,7 @@ void dumpTraceBuffer()
#if defined(DEBUG_INTERRUPTS) #if defined(DEBUG_INTERRUPTS)
#if defined(PCBHORUS) #if defined(PCBHORUS)
const char * interruptNames[INT_LAST] = { const char * const interruptNames[INT_LAST] = {
"Tick ", // INT_TICK, "Tick ", // INT_TICK,
"1ms ", // INT_1MS, "1ms ", // INT_1MS,
"Ser2 ", // INT_SER2, "Ser2 ", // INT_SER2,
@ -139,7 +139,7 @@ void dumpTraceBuffer()
#endif // #if defined(DEBUG_USB_INTERRUPTS) #endif // #if defined(DEBUG_USB_INTERRUPTS)
}; };
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
const char * interruptNames[INT_LAST] = { const char * const interruptNames[INT_LAST] = {
"Tick ", // INT_TICK, "Tick ", // INT_TICK,
"5ms ", // INT_5MS, "5ms ", // INT_5MS,
"Audio", // INT_AUDIO, "Audio", // INT_AUDIO,
@ -231,7 +231,7 @@ void DebugTimer::stop()
DebugTimer debugTimers[DEBUG_TIMERS_COUNT]; DebugTimer debugTimers[DEBUG_TIMERS_COUNT];
const char * debugTimerNames[DEBUG_TIMERS_COUNT] = { const char * const debugTimerNames[DEBUG_TIMERS_COUNT] = {
"Pulses int." // debugTimerIntPulses, "Pulses int." // debugTimerIntPulses,
,"Pulses dur." // debugTimerIntPulsesDuration, ,"Pulses dur." // debugTimerIntPulsesDuration,
,"10ms dur. " // debugTimerPer10ms, ,"10ms dur. " // debugTimerPer10ms,

View file

@ -273,7 +273,7 @@ struct InterruptCounters
uint32_t resetTime; uint32_t resetTime;
}; };
extern const char * interruptNames[INT_LAST]; extern const char * const interruptNames[INT_LAST];
extern struct InterruptCounters interruptCounters; extern struct InterruptCounters interruptCounters;
#define DEBUG_INTERRUPT(int) (++interruptCounters.cnt[int]) #define DEBUG_INTERRUPT(int) (++interruptCounters.cnt[int])
@ -388,7 +388,7 @@ enum DebugTimers {
}; };
extern DebugTimer debugTimers[DEBUG_TIMERS_COUNT]; extern DebugTimer debugTimers[DEBUG_TIMERS_COUNT];
extern const char * debugTimerNames[DEBUG_TIMERS_COUNT]; extern const char * const debugTimerNames[DEBUG_TIMERS_COUNT];
#endif // #if defined(__cplusplus) #endif // #if defined(__cplusplus)

View file

@ -25,11 +25,9 @@
#undef OPAQUE #undef OPAQUE
#undef RGB #undef RGB
#define TO4BITS(x) (uint32_t(limit<int>(0, x, 255)) >> 4) #define RGB(r, g, b) (uint16_t)((((r) & 0xF8) << 8) + (((g) & 0xFC) << 3) + (((b) & 0xF8) >> 3))
#define TO5BITS(x) (uint32_t(limit<int>(0, x, 255)) >> 3) #define ARGB(a, r, g, b) (uint16_t)((((a) & 0xF0) << 8) + (((r) & 0xF0) << 4) + (((g) & 0xF0) << 0) + (((b) & 0xF0) >> 4))
#define TO6BITS(x) (uint32_t(limit<int>(0, x, 255)) >> 2)
#define RGB(r, g, b) ((TO5BITS(r) << 11) + (TO6BITS(g) << 5) + (TO5BITS(b) << 0))
#define ARGB(a, r, g, b) ((TO4BITS(a) << 12) + (TO4BITS(r) << 8) + (TO4BITS(g) << 4) + (TO4BITS(b) << 0))
#define WHITE RGB(0xFF, 0xFF, 0xFF) #define WHITE RGB(0xFF, 0xFF, 0xFF)
#define BLACK RGB(0, 0, 0) #define BLACK RGB(0, 0, 0)
#define YELLOW RGB(0xF0, 0xD0, 0x10) #define YELLOW RGB(0xF0, 0xD0, 0x10)

View file

@ -20,59 +20,59 @@
#include "opentx.h" #include "opentx.h"
uint16_t font_tinsize_specs[] = { const uint16_t font_tinsize_specs[] = {
#include "font_tinsize.specs" #include "font_tinsize.specs"
}; };
pm_uchar font_tinsize[] = { const pm_uchar font_tinsize[] = {
#include "font_tinsize.lbm" #include "font_tinsize.lbm"
}; };
uint16_t font_smlsize_specs[] = { const uint16_t font_smlsize_specs[] = {
#include "font_smlsize.specs" #include "font_smlsize.specs"
}; };
pm_uchar font_smlsize[] = { const pm_uchar font_smlsize[] = {
#include "font_smlsize.lbm" #include "font_smlsize.lbm"
}; };
uint16_t font_stdsize_specs[] = { const uint16_t font_stdsize_specs[] = {
#include "font_stdsize.specs" #include "font_stdsize.specs"
}; };
pm_uchar font_stdsize[] = { const pm_uchar font_stdsize[] = {
#include "font_stdsize.lbm" #include "font_stdsize.lbm"
}; };
uint16_t font_midsize_specs[] = { const uint16_t font_midsize_specs[] = {
#include "font_midsize.specs" #include "font_midsize.specs"
}; };
pm_uchar font_midsize[] = { const pm_uchar font_midsize[] = {
#include "font_midsize.lbm" #include "font_midsize.lbm"
}; };
uint16_t font_dblsize_specs[] = { const uint16_t font_dblsize_specs[] = {
#include "font_dblsize.specs" #include "font_dblsize.specs"
}; };
pm_uchar font_dblsize[] = { const pm_uchar font_dblsize[] = {
#include "font_dblsize.lbm" #include "font_dblsize.lbm"
}; };
uint16_t font_xxlsize_specs[] = { const uint16_t font_xxlsize_specs[] = {
#include "font_xxlsize.specs" #include "font_xxlsize.specs"
}; };
pm_uchar font_xxlsize[] = { const pm_uchar font_xxlsize[] = {
#include "font_xxlsize.lbm" #include "font_xxlsize.lbm"
}; };
uint16_t font_stdsizebold_specs[] = { const uint16_t font_stdsizebold_specs[] = {
#include "font_stdsizebold.specs" #include "font_stdsizebold.specs"
}; };
pm_uchar font_stdsizebold[] = { const pm_uchar font_stdsizebold[] = {
#include "font_stdsizebold.lbm" #include "font_stdsizebold.lbm"
}; };

View file

@ -216,7 +216,7 @@ bool menuRadioSdManager(event_t _event)
if (!strcmp(line, "..")) { if (!strcmp(line, "..")) {
break; // no menu for parent dir break; // no menu for parent dir
} }
char * ext = getFileExtension(line); const char * ext = getFileExtension(line);
if (ext) { if (ext) {
if (!strcasecmp(ext, SOUNDS_EXT)) { if (!strcasecmp(ext, SOUNDS_EXT)) {
POPUP_MENU_ADD_ITEM(STR_PLAY_FILE); POPUP_MENU_ADD_ITEM(STR_PLAY_FILE);
@ -337,7 +337,7 @@ bool menuRadioSdManager(event_t _event)
if (reusableBuffer.sdmanager.lines[i][0]) { if (reusableBuffer.sdmanager.lines[i][0]) {
if (s_editMode == EDIT_MODIFY_STRING && attr) { if (s_editMode == EDIT_MODIFY_STRING && attr) {
uint8_t extlen, efflen; uint8_t extlen, efflen;
char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen); const char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen);
editName(MENUS_MARGIN_LEFT, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen, _event, attr, 0); editName(MENUS_MARGIN_LEFT, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen, _event, attr, 0);
efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen); efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen);
if (s_editMode == 0) { if (s_editMode == 0) {
@ -366,7 +366,7 @@ bool menuRadioSdManager(event_t _event)
} }
} }
char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); const char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]);
if (ext && isExtensionMatching(ext, BITMAPS_EXT)) { if (ext && isExtensionMatching(ext, BITMAPS_EXT)) {
if (currentBitmapIndex != menuVerticalPosition) { if (currentBitmapIndex != menuVerticalPosition) {
currentBitmapIndex = menuVerticalPosition; currentBitmapIndex = menuVerticalPosition;

View file

@ -45,12 +45,12 @@ union ZoneOptionValue
#define OPTION_VALUE_UNSIGNED(x) uint32_t(x) #define OPTION_VALUE_UNSIGNED(x) uint32_t(x)
#define OPTION_VALUE_SIGNED(x) uint32_t(x) #define OPTION_VALUE_SIGNED(x) uint32_t(x)
#define OPTION_VALUE_BOOL(x) uint32_t(x) #define OPTION_VALUE_BOOL(x) uint32_t(x)
#define OPTION_VALUE_STRING(...) *(ZoneOptionValue *)(const char *)__VA_ARGS__ #define OPTION_VALUE_STRING(...) { .stringValue = {__VA_ARGS__} }
#else #else
#define OPTION_VALUE_UNSIGNED(x) { .unsignedValue = (x) } #define OPTION_VALUE_UNSIGNED(x) { .unsignedValue = (x) }
#define OPTION_VALUE_SIGNED(x) { .signedValue = (x) } #define OPTION_VALUE_SIGNED(x) { .signedValue = (x) }
#define OPTION_VALUE_BOOL(x) { .boolValue = (x) } #define OPTION_VALUE_BOOL(x) { .boolValue = (x) }
#define OPTION_VALUE_STRING(...) *(ZoneOptionValue *)(const char *)__VA_ARGS__ #define OPTION_VALUE_STRING(...) { .stringValue = {__VA_ARGS__} }
#endif #endif
struct ZoneOption struct ZoneOption

View file

@ -34,7 +34,7 @@ class TextWidget: public Widget
}; };
const ZoneOption TextWidget::options[] = { const ZoneOption TextWidget::options[] = {
{ "Text", ZoneOption::String, OPTION_VALUE_STRING("\015\347\0\14\377\376\373\364") }, { "Text", ZoneOption::String, OPTION_VALUE_STRING('\15', '\347', '\0', '\14', '\377', '\376', '\373', '\364') },
{ "Color", ZoneOption::Color, OPTION_VALUE_UNSIGNED(RED) }, { "Color", ZoneOption::Color, OPTION_VALUE_UNSIGNED(RED) },
{ "Size", ZoneOption::TextSize, OPTION_VALUE_UNSIGNED(0) }, { "Size", ZoneOption::TextSize, OPTION_VALUE_UNSIGNED(0) },
{ NULL, ZoneOption::Bool } { NULL, ZoneOption::Bool }

View file

@ -258,7 +258,7 @@ void menuRadioSdManager(event_t _event)
break; // no menu for parent dir break; // no menu for parent dir
} }
#if defined(CPUARM) #if defined(CPUARM)
char * ext = getFileExtension(line); const char * ext = getFileExtension(line);
if (ext) { if (ext) {
if (!strcasecmp(ext, SOUNDS_EXT)) { if (!strcasecmp(ext, SOUNDS_EXT)) {
POPUP_MENU_ADD_ITEM(STR_PLAY_FILE); POPUP_MENU_ADD_ITEM(STR_PLAY_FILE);
@ -401,7 +401,7 @@ void menuRadioSdManager(event_t _event)
#if defined(CPUARM) #if defined(CPUARM)
if (s_editMode == EDIT_MODIFY_STRING && attr) { if (s_editMode == EDIT_MODIFY_STRING && attr) {
uint8_t extlen, efflen; uint8_t extlen, efflen;
char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen); const char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen);
editName(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen, _event, attr, 0); editName(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen, _event, attr, 0);
efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen); efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen);
if (s_editMode == 0) { if (s_editMode == 0) {
@ -428,7 +428,7 @@ void menuRadioSdManager(event_t _event)
} }
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); const char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]);
if (ext && isExtensionMatching(ext, BITMAPS_EXT)) { if (ext && isExtensionMatching(ext, BITMAPS_EXT)) {
if (lastPos != menuVerticalPosition) { if (lastPos != menuVerticalPosition) {
if (!lcdLoadBitmap(modelBitmap, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) { if (!lcdLoadBitmap(modelBitmap, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) {

View file

@ -38,9 +38,9 @@ extern "C" {
lua_State *lsScripts = NULL; lua_State *lsScripts = NULL;
uint8_t luaState = 0; uint8_t luaState = 0;
uint8_t luaScriptsCount = 0; uint8_t luaScriptsCount = 0;
ScriptInternalData scriptInternalData[MAX_SCRIPTS] = { { SCRIPT_NOFILE, 0 } }; ScriptInternalData scriptInternalData[MAX_SCRIPTS];
ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS] = { {0} }; ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS];
ScriptInternalData standaloneScript = { SCRIPT_NOFILE, 0 }; ScriptInternalData standaloneScript;
uint16_t maxLuaInterval = 0; uint16_t maxLuaInterval = 0;
uint16_t maxLuaDuration = 0; uint16_t maxLuaDuration = 0;
bool luaLcdAllowed; bool luaLcdAllowed;

View file

@ -114,7 +114,7 @@ bool isFilePatternAvailable(const char * path, const char * file, const char * p
char * getFileIndex(char * filename, unsigned int & value) char * getFileIndex(char * filename, unsigned int & value)
{ {
value = 0; value = 0;
char * pos = getFileExtension(filename); char * pos = (char *)getFileExtension(filename);
if (!pos || pos == filename) if (!pos || pos == filename)
return NULL; return NULL;
int multiplier = 1; int multiplier = 1;
@ -148,7 +148,7 @@ int findNextFileIndex(char * filename, uint8_t size, const char * directory)
uint8_t extlen; uint8_t extlen;
char * indexPos = getFileIndex(filename, index); char * indexPos = getFileIndex(filename, index);
char extension[LEN_FILE_EXTENSION_MAX+1] = "\0"; char extension[LEN_FILE_EXTENSION_MAX+1] = "\0";
char *p = getFileExtension(filename, 0, 0, NULL, &extlen); char * p = (char *)getFileExtension(filename, 0, 0, NULL, &extlen);
if (p) strncat(extension, p, sizeof(extension)-1); if (p) strncat(extension, p, sizeof(extension)-1);
while (1) { while (1) {
index++; index++;
@ -163,6 +163,32 @@ int findNextFileIndex(char * filename, uint8_t size, const char * directory)
} }
} }
const char * getFileExtension(const char * filename, uint8_t size, uint8_t extMaxLen, uint8_t *fnlen, uint8_t *extlen)
{
int len = size;
if (!size) {
len = strlen(filename);
}
if (!extMaxLen) {
extMaxLen = LEN_FILE_EXTENSION_MAX;
}
if (fnlen != NULL) {
*fnlen = (uint8_t)len;
}
for (int i=len-1; i >= 0 && len-i <= extMaxLen; --i) {
if (filename[i] == '.') {
if (extlen) {
*extlen = len-i;
}
return &filename[i];
}
}
if (extlen != NULL) {
*extlen = 0;
}
return NULL;
}
/** /**
Check if given extension exists in a list of extensions. Check if given extension exists in a list of extensions.
@param extension The extension to search for, including leading period. @param extension The extension to search for, including leading period.
@ -198,7 +224,7 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen
static uint16_t lastpopupMenuOffset = 0; static uint16_t lastpopupMenuOffset = 0;
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char *fnExt; const char * fnExt;
uint8_t fnLen, extLen; uint8_t fnLen, extLen;
char tmpExt[LEN_FILE_EXTENSION_MAX+1] = "\0"; char tmpExt[LEN_FILE_EXTENSION_MAX+1] = "\0";

View file

@ -111,32 +111,7 @@ inline const pm_char * SDCARD_ERROR(FRESULT result)
#endif #endif
// NOTE: 'size' must = 0 or be a valid character position within 'filename' array -- it is NOT validated // NOTE: 'size' must = 0 or be a valid character position within 'filename' array -- it is NOT validated
template<class T> const char * getFileExtension(const char * filename, uint8_t size=0, uint8_t extMaxLen=0, uint8_t *fnlen=NULL, uint8_t *extlen=NULL);
T * getFileExtension(T * filename, uint8_t size=0, uint8_t extMaxLen=0, uint8_t *fnlen=NULL, uint8_t *extlen=NULL)
{
int len = size;
if (!size) {
len = strlen(filename);
}
if (!extMaxLen) {
extMaxLen = LEN_FILE_EXTENSION_MAX;
}
if (fnlen != NULL) {
*fnlen = (uint8_t)len;
}
for (int i=len-1; i >= 0 && len-i <= extMaxLen; --i) {
if (filename[i] == '.') {
if (extlen) {
*extlen = len-i;
}
return &filename[i];
}
}
if (extlen != NULL) {
*extlen = 0;
}
return NULL;
}
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
#define O9X_FOURCC 0x3378396F // o9x for Taranis #define O9X_FOURCC 0x3378396F // o9x for Taranis

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "gtests.h"
#if defined(COLORLCD)
#include "colors.h"
TEST(color, RGB)
{
// test conversion from RGB to RGB565 (5 bits for R, 6 bits for G, 5 bits for B)
EXPECT_EQ(RGB(0, 0, 0), (uint16_t)0x0000);
EXPECT_EQ(RGB(255, 255, 255), (uint16_t)0xFFFF);
EXPECT_EQ(RGB(255, 0, 0), (uint16_t)0xF800);
EXPECT_EQ(RGB(0, 255, 0), (uint16_t)0x07E0);
EXPECT_EQ(RGB(0, 0, 255), (uint16_t)0x001F);
EXPECT_EQ(RGB(30, 40, 150), (uint16_t)0x1952);
}
TEST(color, ARGB)
{
// test conversion from RGB to ARGB4444 (4 bits for alpha, 4 bits for R, 4 bits for G, 4 bits for B)
EXPECT_EQ(ARGB(0, 0, 0, 0), (uint16_t)0x0000);
EXPECT_EQ(ARGB(255, 255, 255, 255), (uint16_t)0xFFFF);
EXPECT_EQ(ARGB(255, 0, 0, 0), (uint16_t)0xF000);
EXPECT_EQ(ARGB(0, 255, 0, 0), (uint16_t)0x0F00);
EXPECT_EQ(ARGB(0, 0, 255, 0), (uint16_t)0x00F0);
EXPECT_EQ(ARGB(0, 0, 0, 255), (uint16_t)0x000F);
EXPECT_EQ(ARGB(128, 30, 40, 150), (uint16_t)0x8129);
}
#endif

View file

@ -138,7 +138,7 @@
/* Private macro -------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; static const __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/ /* Private functions ---------------------------------------------------------*/