1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-17 21:35:27 +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)
unsigned char crc8tab[256] = {
const unsigned char crc8tab[256] = {
0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54,
0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D,
0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06,

View file

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

View file

@ -273,7 +273,7 @@ struct InterruptCounters
uint32_t resetTime;
};
extern const char * interruptNames[INT_LAST];
extern const char * const interruptNames[INT_LAST];
extern struct InterruptCounters interruptCounters;
#define DEBUG_INTERRUPT(int) (++interruptCounters.cnt[int])
@ -388,7 +388,7 @@ enum DebugTimers {
};
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)

View file

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

View file

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

View file

@ -216,7 +216,7 @@ bool menuRadioSdManager(event_t _event)
if (!strcmp(line, "..")) {
break; // no menu for parent dir
}
char * ext = getFileExtension(line);
const char * ext = getFileExtension(line);
if (ext) {
if (!strcasecmp(ext, SOUNDS_EXT)) {
POPUP_MENU_ADD_ITEM(STR_PLAY_FILE);
@ -337,7 +337,7 @@ bool menuRadioSdManager(event_t _event)
if (reusableBuffer.sdmanager.lines[i][0]) {
if (s_editMode == EDIT_MODIFY_STRING && attr) {
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);
efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen);
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 (currentBitmapIndex != menuVerticalPosition) {
currentBitmapIndex = menuVerticalPosition;

View file

@ -45,12 +45,12 @@ union ZoneOptionValue
#define OPTION_VALUE_UNSIGNED(x) uint32_t(x)
#define OPTION_VALUE_SIGNED(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
#define OPTION_VALUE_UNSIGNED(x) { .unsignedValue = (x) }
#define OPTION_VALUE_SIGNED(x) { .signedValue = (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
struct ZoneOption

View file

@ -34,7 +34,7 @@ class TextWidget: public Widget
};
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) },
{ "Size", ZoneOption::TextSize, OPTION_VALUE_UNSIGNED(0) },
{ NULL, ZoneOption::Bool }

View file

@ -258,7 +258,7 @@ void menuRadioSdManager(event_t _event)
break; // no menu for parent dir
}
#if defined(CPUARM)
char * ext = getFileExtension(line);
const char * ext = getFileExtension(line);
if (ext) {
if (!strcasecmp(ext, SOUNDS_EXT)) {
POPUP_MENU_ADD_ITEM(STR_PLAY_FILE);
@ -401,7 +401,7 @@ void menuRadioSdManager(event_t _event)
#if defined(CPUARM)
if (s_editMode == EDIT_MODIFY_STRING && attr) {
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);
efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen);
if (s_editMode == 0) {
@ -428,7 +428,7 @@ void menuRadioSdManager(event_t _event)
}
#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 (lastPos != menuVerticalPosition) {
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;
uint8_t luaState = 0;
uint8_t luaScriptsCount = 0;
ScriptInternalData scriptInternalData[MAX_SCRIPTS] = { { SCRIPT_NOFILE, 0 } };
ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS] = { {0} };
ScriptInternalData standaloneScript = { SCRIPT_NOFILE, 0 };
ScriptInternalData scriptInternalData[MAX_SCRIPTS];
ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS];
ScriptInternalData standaloneScript;
uint16_t maxLuaInterval = 0;
uint16_t maxLuaDuration = 0;
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)
{
value = 0;
char * pos = getFileExtension(filename);
char * pos = (char *)getFileExtension(filename);
if (!pos || pos == filename)
return NULL;
int multiplier = 1;
@ -148,7 +148,7 @@ int findNextFileIndex(char * filename, uint8_t size, const char * directory)
uint8_t extlen;
char * indexPos = getFileIndex(filename, index);
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);
while (1) {
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.
@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;
FILINFO fno;
DIR dir;
char *fnExt;
const char * fnExt;
uint8_t fnLen, extLen;
char tmpExt[LEN_FILE_EXTENSION_MAX+1] = "\0";

View file

@ -111,32 +111,7 @@ inline const pm_char * SDCARD_ERROR(FRESULT result)
#endif
// NOTE: 'size' must = 0 or be a valid character position within 'filename' array -- it is NOT validated
template<class T>
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;
}
const char * getFileExtension(const char * filename, uint8_t size=0, uint8_t extMaxLen=0, uint8_t *fnlen=NULL, uint8_t *extlen=NULL);
#if defined(PCBTARANIS)
#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 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 functions ---------------------------------------------------------*/