1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-23 16:25:31 +03:00

On-board custom defaults take 2 (#8707)

On-board custom defaults take 2
This commit is contained in:
Michael Keller 2019-08-13 08:54:31 +12:00 committed by GitHub
commit 814caa638f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 447 additions and 223 deletions

View file

@ -30,6 +30,9 @@ EXST ?= no
# compile for target loaded into RAM # compile for target loaded into RAM
RAM_BASED ?= no RAM_BASED ?= no
# reserve space for custom defaults
CUSTOM_DEFAULTS_EXTENDED ?= no
# Debugger optons: # Debugger optons:
# empty - ordinary build with all optimizations enabled # empty - ordinary build with all optimizations enabled
# RELWITHDEBINFO - ordinary build with debug symbols and all optimizations enabled # RELWITHDEBINFO - ordinary build with debug symbols and all optimizations enabled
@ -123,7 +126,8 @@ FATFS_SRC = $(notdir $(wildcard $(FATFS_DIR)/*.c))
CSOURCES := $(shell find $(SRC_DIR) -name '*.c') CSOURCES := $(shell find $(SRC_DIR) -name '*.c')
LD_FLAGS := LD_FLAGS :=
EXTRA_LD_FLAGS :=
# #
# Default Tool options - can be overridden in {mcu}.mk files. # Default Tool options - can be overridden in {mcu}.mk files.
@ -185,6 +189,11 @@ else
.DEFAULT_GOAL := hex .DEFAULT_GOAL := hex
endif endif
ifeq ($(CUSTOM_DEFAULTS_EXTENDED),yes)
TARGET_FLAGS += -DUSE_CUSTOM_DEFAULTS=
EXTRA_LD_FLAGS += -Wl,--defsym=USE_CUSTOM_DEFAULTS_EXTENDED=1
endif
INCLUDE_DIRS := $(INCLUDE_DIRS) \ INCLUDE_DIRS := $(INCLUDE_DIRS) \
$(ROOT)/lib/main/MAVLink $(ROOT)/lib/main/MAVLink
@ -266,7 +275,8 @@ LD_FLAGS = -lm \
-Wl,--cref \ -Wl,--cref \
-Wl,--no-wchar-size-warning \ -Wl,--no-wchar-size-warning \
-Wl,--print-memory-usage \ -Wl,--print-memory-usage \
-T$(LD_SCRIPT) -T$(LD_SCRIPT) \
$(EXTRA_LD_FLAGS)
endif endif
############################################################################### ###############################################################################

View file

@ -9,9 +9,6 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x08000000 to 0x080FFFFF 1024K full flash, 0x08000000 to 0x080FFFFF 1024K full flash,
0x08000000 to 0x08003FFF 16K isr vector, startup code, 0x08000000 to 0x08003FFF 16K isr vector, startup code,
@ -22,9 +19,11 @@ ENTRY(Reset_Handler)
/* Specify the memory areas */ /* Specify the memory areas */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 10K
FLASH_CUSTOM_DEFAULTS (r) : ORIGIN = 0x08002800, LENGTH = 6K
FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K
FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = 992K FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS) ? 976K : 992K
FLASH_CUSTOM_DEFAULTS_EXTENDED (r): ORIGIN = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 0x080FC000 : 0x08100000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 16K : 0K
SYSTEM_MEMORY (rx): ORIGIN = 0x1FFF0000, LENGTH = 29K SYSTEM_MEMORY (rx): ORIGIN = 0x1FFF0000, LENGTH = 29K

View file

@ -9,9 +9,6 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x08000000 to 0x080FFFFF 1024K full flash, 0x08000000 to 0x080FFFFF 1024K full flash,
0x08000000 to 0x08003FFF 16K OPBL, 0x08000000 to 0x08003FFF 16K OPBL,

View file

@ -9,12 +9,10 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x08000000 to 0x0807FFFF 512K full flash, 0x08000000 to 0x0807FFFF 512K full flash,
0x08000000 to 0x08003FFF 16K isr vector, startup code, 0x08000000 to 0x08003FFF 16K isr vector, startup code,
0x08004000 to 0x08007FFF 16K config, // FLASH_Sector_1 0x08004000 to 0x08007FFF 16K config, // FLASH_Sector_1
0x08008000 to 0x0807FFFF 480K firmware, 0x08008000 to 0x0807FFFF 480K firmware,
*/ */
@ -22,9 +20,11 @@ ENTRY(Reset_Handler)
/* Specify the memory areas */ /* Specify the memory areas */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 10K
FLASH_CUSTOM_DEFAULTS (r) : ORIGIN = 0x08002800, LENGTH = 6K
FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K
FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = 480K FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS) ? 464K : 480K
FLASH_CUSTOM_DEFAULTS_EXTENDED (r): ORIGIN = DEFINED(USE_CUSTOM_DEFAULTS) ? 0x0807C000 : 0x08080000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 16K : 0K
SYSTEM_MEMORY (rx): ORIGIN = 0x1FFF0000, LENGTH = 29K SYSTEM_MEMORY (rx): ORIGIN = 0x1FFF0000, LENGTH = 29K

View file

@ -9,9 +9,6 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x08000000 to 0x0807FFFF 512K full flash, 0x08000000 to 0x0807FFFF 512K full flash,
0x08000000 to 0x08003FFF 16K OPBL, 0x08000000 to 0x08003FFF 16K OPBL,

View file

@ -9,9 +9,6 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x08000000 to 0x0807FFFF 512K full flash, 0x08000000 to 0x0807FFFF 512K full flash,
0x08000000 to 0x08003FFF 16K isr vector, startup code, 0x08000000 to 0x08003FFF 16K isr vector, startup code,
@ -22,7 +19,8 @@ ENTRY(Reset_Handler)
/* Specify the memory areas */ /* Specify the memory areas */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 10K
FLASH_CUSTOM_DEFAULTS (r) : ORIGIN = 0x08002800, LENGTH = 6K
FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K
FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = 480K FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = 480K

View file

@ -9,9 +9,6 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x08000000 to 0x0807FFFF 512K full flash 0x08000000 to 0x0807FFFF 512K full flash
0x08000000 to 0x08003FFF 16K ISR vector 0x08000000 to 0x08003FFF 16K ISR vector
@ -29,9 +26,11 @@ MEMORY
ITCM_FLASH_CONFIG (r) : ORIGIN = 0x00204000, LENGTH = 16K ITCM_FLASH_CONFIG (r) : ORIGIN = 0x00204000, LENGTH = 16K
ITCM_FLASH1 (rx) : ORIGIN = 0x00208000, LENGTH = 480K ITCM_FLASH1 (rx) : ORIGIN = 0x00208000, LENGTH = 480K
AXIM_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K AXIM_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 10K
AXIM_FLASH_CUSTOM_DEFAULTS (r) : ORIGIN = 0x08002800, LENGTH = 6K
AXIM_FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K AXIM_FLASH_CONFIG (r) : ORIGIN = 0x08004000, LENGTH = 16K
AXIM_FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = 480K AXIM_FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 464K : 480K
AXIM_FLASH_CUSTOM_DEFAULTS_EXTENDED (r) : ORIGIN = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 0x0807C000 : 0x08080000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 16K : 0K
DTCM_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K DTCM_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
SRAM1 (rwx) : ORIGIN = 0x20010000, LENGTH = 176K SRAM1 (rwx) : ORIGIN = 0x20010000, LENGTH = 176K
@ -40,8 +39,10 @@ MEMORY
} }
REGION_ALIAS("FLASH", AXIM_FLASH) REGION_ALIAS("FLASH", AXIM_FLASH)
REGION_ALIAS("FLASH_CUSTOM_DEFAULTS", AXIM_FLASH_CUSTOM_DEFAULTS)
REGION_ALIAS("FLASH_CONFIG", AXIM_FLASH_CONFIG) REGION_ALIAS("FLASH_CONFIG", AXIM_FLASH_CONFIG)
REGION_ALIAS("FLASH1", AXIM_FLASH1) REGION_ALIAS("FLASH1", AXIM_FLASH1)
REGION_ALIAS("FLASH_CUSTOM_DEFAULTS_EXTENDED", AXIM_FLASH_CUSTOM_DEFAULTS_EXTENDED)
REGION_ALIAS("STACKRAM", DTCM_RAM) REGION_ALIAS("STACKRAM", DTCM_RAM)
REGION_ALIAS("FASTRAM", DTCM_RAM) REGION_ALIAS("FASTRAM", DTCM_RAM)

View file

@ -9,9 +9,6 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x00000000 to 0x00003FFF 16K TCM RAM, 0x00000000 to 0x00003FFF 16K TCM RAM,
@ -31,9 +28,11 @@ MEMORY
ITCM_FLASH_CONFIG (r) : ORIGIN = 0x00208000, LENGTH = 32K ITCM_FLASH_CONFIG (r) : ORIGIN = 0x00208000, LENGTH = 32K
ITCM_FLASH1 (rx) : ORIGIN = 0x00210000, LENGTH = 960K ITCM_FLASH1 (rx) : ORIGIN = 0x00210000, LENGTH = 960K
AXIM_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K AXIM_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 10K
AXIM_FLASH_CUSTOM_DEFAULTS (r) : ORIGIN = 0x08002800, LENGTH = 22K
AXIM_FLASH_CONFIG (r) : ORIGIN = 0x08008000, LENGTH = 32K AXIM_FLASH_CONFIG (r) : ORIGIN = 0x08008000, LENGTH = 32K
AXIM_FLASH1 (rx) : ORIGIN = 0x08010000, LENGTH = 960K AXIM_FLASH1 (rx) : ORIGIN = 0x08010000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS) ? 928K : 960K
AXIM_FLASH_CUSTOM_DEFAULTS_EXTENDED (r) : ORIGIN = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 0x080F8000 : 0x08100000, LENGTH = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? 32K : 0K
DTCM_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K DTCM_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
SRAM1 (rwx) : ORIGIN = 0x20010000, LENGTH = 240K SRAM1 (rwx) : ORIGIN = 0x20010000, LENGTH = 240K
@ -42,8 +41,10 @@ MEMORY
} }
REGION_ALIAS("FLASH", ITCM_FLASH) REGION_ALIAS("FLASH", ITCM_FLASH)
REGION_ALIAS("FLASH_CUSTOM_DEFAULTS", AXIM_FLASH_CUSTOM_DEFAULTS)
REGION_ALIAS("FLASH_CONFIG", AXIM_FLASH_CONFIG) REGION_ALIAS("FLASH_CONFIG", AXIM_FLASH_CONFIG)
REGION_ALIAS("FLASH1", ITCM_FLASH1) REGION_ALIAS("FLASH1", ITCM_FLASH1)
REGION_ALIAS("FLASH_CUSTOM_DEFAULTS_EXTENDED", AXIM_FLASH_CUSTOM_DEFAULTS_EXTENDED)
REGION_ALIAS("STACKRAM", DTCM_RAM) REGION_ALIAS("STACKRAM", DTCM_RAM)
REGION_ALIAS("FASTRAM", DTCM_RAM) REGION_ALIAS("FASTRAM", DTCM_RAM)

View file

@ -9,9 +9,6 @@
***************************************************************************** *****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* /*
0x00000000 to 0x00003FFF 16K TCM RAM, 0x00000000 to 0x00003FFF 16K TCM RAM,
@ -30,7 +27,8 @@ MEMORY
ITCM_FLASH_CONFIG (r) : ORIGIN = 0x00208000, LENGTH = 32K ITCM_FLASH_CONFIG (r) : ORIGIN = 0x00208000, LENGTH = 32K
ITCM_FLASH1 (rx) : ORIGIN = 0x00210000, LENGTH = 1984K ITCM_FLASH1 (rx) : ORIGIN = 0x00210000, LENGTH = 1984K
AXIM_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K AXIM_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 10K
AXIM_FLASH_CUSTOM_DEFAULTS (r) : ORIGIN = 0x08002800, LENGTH = 22K
AXIM_FLASH_CONFIG (r) : ORIGIN = 0x08008000, LENGTH = 32K AXIM_FLASH_CONFIG (r) : ORIGIN = 0x08008000, LENGTH = 32K
AXIM_FLASH1 (rx) : ORIGIN = 0x08010000, LENGTH = 1984K AXIM_FLASH1 (rx) : ORIGIN = 0x08010000, LENGTH = 1984K
@ -41,6 +39,7 @@ MEMORY
} }
REGION_ALIAS("FLASH", AXIM_FLASH) REGION_ALIAS("FLASH", AXIM_FLASH)
REGION_ALIAS("FLASH_CUSTOM_DEFAULTS", AXIM_FLASH_CUSTOM_DEFAULTS)
REGION_ALIAS("FLASH_CONFIG", AXIM_FLASH_CONFIG) REGION_ALIAS("FLASH_CONFIG", AXIM_FLASH_CONFIG)
REGION_ALIAS("FLASH1", AXIM_FLASH1) REGION_ALIAS("FLASH1", AXIM_FLASH1)

View file

@ -34,6 +34,13 @@ SECTIONS
. = ALIGN(4); . = ALIGN(4);
} >FLASH AT >AXIM_FLASH } >FLASH AT >AXIM_FLASH
/* Storage for the address for the configuration section so we can grab it out of the hex file */
.custom_defaults :
{
. = ALIGN(4);
*(.custom_defaults_address)
} >FLASH1 AT >AXIM_FLASH1
/* The program code and other data goes into FLASH */ /* The program code and other data goes into FLASH */
.text : .text :
{ {
@ -92,6 +99,19 @@ SECTIONS
PROVIDE_HIDDEN (__pg_resetdata_end = .); PROVIDE_HIDDEN (__pg_resetdata_end = .);
} >FLASH AT >AXIM_FLASH } >FLASH AT >AXIM_FLASH
/* Storage for the address for the configuration section so we can grab it out of the hex file */
.custom_defaults :
{
. = ALIGN(4);
KEEP (*(.custom_defaults_address))
. = ALIGN(4);
__custom_defaults_internal_start = .;
*(.custom_defaults);
} >FLASH_CUSTOM_DEFAULTS
PROVIDE_HIDDEN (__custom_defaults_start = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? ORIGIN(FLASH_CUSTOM_DEFAULTS_EXTENDED) : __custom_defaults_internal_start);
PROVIDE_HIDDEN (__custom_defaults_end = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? ORIGIN(FLASH_CUSTOM_DEFAULTS_EXTENDED) + LENGTH(FLASH_CUSTOM_DEFAULTS_EXTENDED) : ORIGIN(FLASH_CUSTOM_DEFAULTS) + LENGTH(FLASH_CUSTOM_DEFAULTS));
/* used by the startup to initialize data */ /* used by the startup to initialize data */
_sidata = LOADADDR(.data); _sidata = LOADADDR(.data);

View file

@ -116,6 +116,19 @@ SECTIONS
PROVIDE_HIDDEN (__pg_resetdata_end = .); PROVIDE_HIDDEN (__pg_resetdata_end = .);
} >FLASH } >FLASH
/* Storage for the address for the configuration section so we can grab it out of the hex file */
.custom_defaults :
{
. = ALIGN(4);
KEEP (*(.custom_defaults_address))
. = ALIGN(4);
__custom_defaults_internal_start = .;
*(.custom_defaults);
} >FLASH_CUSTOM_DEFAULTS
PROVIDE_HIDDEN (__custom_defaults_start = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? ORIGIN(FLASH_CUSTOM_DEFAULTS_EXTENDED) : __custom_defaults_internal_start);
PROVIDE_HIDDEN (__custom_defaults_end = DEFINED(USE_CUSTOM_DEFAULTS_EXTENDED) ? ORIGIN(FLASH_CUSTOM_DEFAULTS_EXTENDED) + LENGTH(FLASH_CUSTOM_DEFAULTS_EXTENDED) : ORIGIN(FLASH_CUSTOM_DEFAULTS) + LENGTH(FLASH_CUSTOM_DEFAULTS));
/* used by the startup to initialize data */ /* used by the startup to initialize data */
_sidata = LOADADDR(.data); _sidata = LOADADDR(.data);

View file

@ -30,7 +30,7 @@
// FIXME remove this for targets that don't need a CLI. Perhaps use a no-op macro when USE_CLI is not enabled // FIXME remove this for targets that don't need a CLI. Perhaps use a no-op macro when USE_CLI is not enabled
// signal that we're in cli mode // signal that we're in cli mode
uint8_t cliMode = 0; bool cliMode = false;
#ifdef USE_CLI #ifdef USE_CLI
@ -172,14 +172,7 @@ uint8_t cliMode = 0;
#include "cli.h" #include "cli.h"
typedef struct serialPassthroughPort_e { static serialPort_t *cliPort = NULL;
int id;
uint32_t baud;
unsigned mode;
serialPort_t *port;
} serialPassthroughPort_t;
static serialPort_t *cliPort;
#ifdef STM32F1 #ifdef STM32F1
#define CLI_IN_BUFFER_SIZE 128 #define CLI_IN_BUFFER_SIZE 128
@ -189,7 +182,7 @@ static serialPort_t *cliPort;
#endif #endif
#define CLI_OUT_BUFFER_SIZE 64 #define CLI_OUT_BUFFER_SIZE 64
static bufWriter_t *cliWriter; static bufWriter_t *cliWriter = NULL;
static uint8_t cliWriteBuffer[sizeof(*cliWriter) + CLI_OUT_BUFFER_SIZE]; static uint8_t cliWriteBuffer[sizeof(*cliWriter) + CLI_OUT_BUFFER_SIZE];
static char cliBuffer[CLI_IN_BUFFER_SIZE]; static char cliBuffer[CLI_IN_BUFFER_SIZE];
@ -219,6 +212,24 @@ static bool signatureUpdated = false;
static const char* const emptyName = "-"; static const char* const emptyName = "-";
static const char* const emptyString = ""; static const char* const emptyString = "";
#if !defined(USE_CUSTOM_DEFAULTS)
#define CUSTOM_DEFAULTS_START ((char*)0)
#define CUSTOM_DEFAULTS_END ((char *)0)
#else
extern char __custom_defaults_start;
extern char __custom_defaults_end;
#define CUSTOM_DEFAULTS_START (&__custom_defaults_start)
#define CUSTOM_DEFAULTS_END (&__custom_defaults_end)
static bool processingCustomDefaults = false;
static char cliBufferTemp[CLI_IN_BUFFER_SIZE];
#endif
#if defined(USE_CUSTOM_DEFAULTS_ADDRESS)
static char __attribute__ ((section(".custom_defaults_address"))) *customDefaultsStart = CUSTOM_DEFAULTS_START;
static char __attribute__ ((section(".custom_defaults_address"))) *customDefaultsEnd = CUSTOM_DEFAULTS_END;
#endif
#ifndef USE_QUAD_MIXER_ONLY #ifndef USE_QUAD_MIXER_ONLY
// sync this with mixerMode_e // sync this with mixerMode_e
static const char * const mixerNames[] = { static const char * const mixerNames[] = {
@ -288,6 +299,13 @@ typedef enum {
REBOOT_TARGET_BOOTLOADER_FLASH, REBOOT_TARGET_BOOTLOADER_FLASH,
} rebootTarget_e; } rebootTarget_e;
typedef struct serialPassthroughPort_e {
int id;
uint32_t baud;
unsigned mode;
serialPort_t *port;
} serialPassthroughPort_t;
static void backupPgConfig(const pgRegistry_t *pg) static void backupPgConfig(const pgRegistry_t *pg)
{ {
memcpy(pg->copy, pg->address, pg->size); memcpy(pg->copy, pg->address, pg->size);
@ -300,6 +318,10 @@ static void restorePgConfig(const pgRegistry_t *pg)
static void backupConfigs(void) static void backupConfigs(void)
{ {
if (configIsInCopy) {
return;
}
// make copies of configs to do differencing // make copies of configs to do differencing
PG_FOREACH(pg) { PG_FOREACH(pg) {
backupPgConfig(pg); backupPgConfig(pg);
@ -310,6 +332,10 @@ static void backupConfigs(void)
static void restoreConfigs(void) static void restoreConfigs(void)
{ {
if (!configIsInCopy) {
return;
}
PG_FOREACH(pg) { PG_FOREACH(pg) {
restorePgConfig(pg); restorePgConfig(pg);
} }
@ -317,19 +343,54 @@ static void restoreConfigs(void)
configIsInCopy = false; configIsInCopy = false;
} }
static void backupAndResetConfigs(void) #if defined(USE_RESOURCE_MGMT) || defined(USE_TIMER_MGMT)
static bool isReadingConfigFromCopy()
{
return configIsInCopy;
}
#endif
static bool isWritingConfigToCopy()
{
return configIsInCopy
#if defined(USE_CUSTOM_DEFAULTS)
&& !processingCustomDefaults
#endif
;
}
static void backupAndResetConfigs(const bool useCustomDefaults)
{ {
backupConfigs(); backupConfigs();
// reset all configs to defaults to do differencing // reset all configs to defaults to do differencing
resetConfigs(); resetConfigs();
#if defined(USE_CUSTOM_DEFAULTS)
if (useCustomDefaults) {
cliProcessCustomDefaults();
}
#else
UNUSED(useCustomDefaults);
#endif
} }
static void cliWriterFlush()
{
if (cliWriter) {
bufWriterFlush(cliWriter);
}
}
static void cliPrint(const char *str) static void cliPrint(const char *str)
{ {
while (*str) { if (cliWriter) {
bufWriterAppend(cliWriter, *str++); while (*str) {
bufWriterAppend(cliWriter, *str++);
}
cliWriterFlush();
} }
bufWriterFlush(cliWriter);
} }
static void cliPrintLinefeed(void) static void cliPrintLinefeed(void)
@ -360,8 +421,10 @@ static void cliPutp(void *p, char ch)
static void cliPrintfva(const char *format, va_list va) static void cliPrintfva(const char *format, va_list va)
{ {
tfp_format(cliWriter, cliPutp, format, va); if (cliWriter) {
bufWriterFlush(cliWriter); tfp_format(cliWriter, cliPutp, format, va);
cliWriterFlush();
}
} }
static bool cliDumpPrintLinef(dumpFlags_t dumpMask, bool equalsDefault, const char *format, ...) static bool cliDumpPrintLinef(dumpFlags_t dumpMask, bool equalsDefault, const char *format, ...)
@ -380,7 +443,9 @@ static bool cliDumpPrintLinef(dumpFlags_t dumpMask, bool equalsDefault, const ch
static void cliWrite(uint8_t ch) static void cliWrite(uint8_t ch)
{ {
bufWriterAppend(cliWriter, ch); if (cliWriter) {
bufWriterAppend(cliWriter, ch);
}
} }
static bool cliDefaultPrintLinef(dumpFlags_t dumpMask, bool equalsDefault, const char *format, ...) static bool cliDefaultPrintLinef(dumpFlags_t dumpMask, bool equalsDefault, const char *format, ...)
@ -647,22 +712,16 @@ static uint16_t getValueOffset(const clivalue_t *value)
return 0; return 0;
} }
void *cliGetValuePointer(const clivalue_t *value) STATIC_UNIT_TESTED void *cliGetValuePointer(const clivalue_t *value)
{ {
const pgRegistry_t* rec = pgFind(value->pgn); const pgRegistry_t* rec = pgFind(value->pgn);
if (configIsInCopy) { if (isWritingConfigToCopy()) {
return CONST_CAST(void *, rec->copy + getValueOffset(value)); return CONST_CAST(void *, rec->copy + getValueOffset(value));
} else { } else {
return CONST_CAST(void *, rec->address + getValueOffset(value)); return CONST_CAST(void *, rec->address + getValueOffset(value));
} }
} }
const void *cliGetDefaultPointer(const clivalue_t *value)
{
const pgRegistry_t* rec = pgFind(value->pgn);
return rec->address + getValueOffset(value);
}
static const char *dumpPgValue(const clivalue_t *value, dumpFlags_t dumpMask, const char *headingStr) static const char *dumpPgValue(const clivalue_t *value, dumpFlags_t dumpMask, const char *headingStr)
{ {
const pgRegistry_t *pg = pgFind(value->pgn); const pgRegistry_t *pg = pgFind(value->pgn);
@ -698,7 +757,7 @@ static void dumpAllValues(uint16_t valueSection, dumpFlags_t dumpMask, const cha
for (uint32_t i = 0; i < valueTableEntryCount; i++) { for (uint32_t i = 0; i < valueTableEntryCount; i++) {
const clivalue_t *value = &valueTable[i]; const clivalue_t *value = &valueTable[i];
bufWriterFlush(cliWriter); cliWriterFlush();
if ((value->type & VALUE_SECTION_MASK) == valueSection || ((valueSection == MASTER_VALUE) && (value->type & VALUE_SECTION_MASK) == HARDWARE_VALUE)) { if ((value->type & VALUE_SECTION_MASK) == valueSection || ((valueSection == MASTER_VALUE) && (value->type & VALUE_SECTION_MASK) == HARDWARE_VALUE)) {
headingStr = dumpPgValue(value, dumpMask, headingStr); headingStr = dumpPgValue(value, dumpMask, headingStr);
} }
@ -826,16 +885,25 @@ static void cliSetVar(const clivalue_t *var, const uint32_t value)
#if defined(USE_RESOURCE_MGMT) && !defined(MINIMAL_CLI) #if defined(USE_RESOURCE_MGMT) && !defined(MINIMAL_CLI)
static void cliRepeat(char ch, uint8_t len) static void cliRepeat(char ch, uint8_t len)
{ {
for (int i = 0; i < len; i++) { if (cliWriter) {
bufWriterAppend(cliWriter, ch); for (int i = 0; i < len; i++) {
bufWriterAppend(cliWriter, ch);
}
cliPrintLinefeed();
} }
cliPrintLinefeed();
} }
#endif #endif
static void cliPrompt(void) static void cliPrompt(void)
{ {
cliPrint("\r\n# "); #if defined(USE_CUSTOM_DEFAULTS) && defined(DEBUG_CUSTOM_DEFAULTS)
if (processingCustomDefaults) {
cliPrint("\r\nd: #");
} else
#endif
{
cliPrint("\r\n# ");
}
} }
static void cliShowParseError(void) static void cliShowParseError(void)
@ -2352,7 +2420,7 @@ static void cliFlashErase(char *cmdline)
cliPrintLine("Erasing,"); cliPrintLine("Erasing,");
#endif #endif
bufWriterFlush(cliWriter); cliWriterFlush();
flashfsEraseCompletely(); flashfsEraseCompletely();
while (!flashfsIsReady()) { while (!flashfsIsReady()) {
@ -2363,7 +2431,7 @@ static void cliFlashErase(char *cmdline)
cliPrintLinefeed(); cliPrintLinefeed();
} }
bufWriterFlush(cliWriter); cliWriterFlush();
#endif #endif
delay(100); delay(100);
} }
@ -3048,19 +3116,17 @@ static void cliMcuId(char *cmdline)
cliPrintLinef("mcu_id %08x%08x%08x", U_ID_0, U_ID_1, U_ID_2); cliPrintLinef("mcu_id %08x%08x%08x", U_ID_0, U_ID_1, U_ID_2);
} }
static uint32_t getFeatureMask(const uint32_t featureMask) static uint32_t *getFeatureMask(void)
{ {
if (featureMaskIsCopied) { if (featureMaskIsCopied) {
return featureMaskCopy; return &featureMaskCopy;
} else { } else {
return featureMask; return &featureConfigMutable()->enabledFeatures;
} }
} }
static void printFeature(dumpFlags_t dumpMask, const featureConfig_t *featureConfig, const featureConfig_t *featureConfigDefault, const char *headingStr) static void printFeature(dumpFlags_t dumpMask, const uint32_t mask, const uint32_t defaultMask, const char *headingStr)
{ {
const uint32_t mask = getFeatureMask(featureConfig->enabledFeatures);
const uint32_t defaultMask = featureConfigDefault->enabledFeatures;
headingStr = cliPrintSectionHeading(dumpMask, false, headingStr); headingStr = cliPrintSectionHeading(dumpMask, false, headingStr);
for (uint32_t i = 0; featureNames[i]; i++) { // disabled features first for (uint32_t i = 0; featureNames[i]; i++) { // disabled features first
if (strcmp(featureNames[i], emptyString) != 0) { //Skip unused if (strcmp(featureNames[i], emptyString) != 0) { //Skip unused
@ -3089,7 +3155,7 @@ static void printFeature(dumpFlags_t dumpMask, const featureConfig_t *featureCon
static void cliFeature(char *cmdline) static void cliFeature(char *cmdline)
{ {
uint32_t len = strlen(cmdline); uint32_t len = strlen(cmdline);
const uint32_t mask = getFeatureMask(featureMask()); const uint32_t mask = *getFeatureMask();
if (len == 0) { if (len == 0) {
cliPrint("Enabled: "); cliPrint("Enabled: ");
for (uint32_t i = 0; ; i++) { for (uint32_t i = 0; ; i++) {
@ -3112,8 +3178,8 @@ static void cliFeature(char *cmdline)
cliPrintLinefeed(); cliPrintLinefeed();
return; return;
} else { } else {
if (!featureMaskIsCopied) { if (!featureMaskIsCopied && !configIsInCopy) {
featureMaskCopy = featureMask(); featureMaskCopy = featureConfig()->enabledFeatures;
featureMaskIsCopied = true; featureMaskIsCopied = true;
} }
uint32_t feature; uint32_t feature;
@ -3147,10 +3213,10 @@ static void cliFeature(char *cmdline)
} }
#endif #endif
if (remove) { if (remove) {
featureClear(feature, &featureMaskCopy); featureClear(feature, getFeatureMask());
cliPrint("Disabled"); cliPrint("Disabled");
} else { } else {
featureSet(feature, &featureMaskCopy); featureSet(feature, getFeatureMask());
cliPrint("Enabled"); cliPrint("Enabled");
} }
cliPrintLinef(" %s", featureNames[i]); cliPrintLinef(" %s", featureNames[i]);
@ -3392,7 +3458,7 @@ static char *checkCommand(char *cmdline, const char *command)
static void cliRebootEx(rebootTarget_e rebootTarget) static void cliRebootEx(rebootTarget_e rebootTarget)
{ {
cliPrint("\r\nRebooting"); cliPrint("\r\nRebooting");
bufWriterFlush(cliWriter); cliWriterFlush();
waitForSerialPortToFinishTransmitting(cliPort); waitForSerialPortToFinishTransmitting(cliPort);
motorShutdown(); motorShutdown();
@ -3451,16 +3517,14 @@ static void cliExit(char *cmdline)
UNUSED(cmdline); UNUSED(cmdline);
cliPrintHashLine("leaving CLI mode, unsaved changes lost"); cliPrintHashLine("leaving CLI mode, unsaved changes lost");
bufWriterFlush(cliWriter); cliWriterFlush();
*cliBuffer = '\0'; *cliBuffer = '\0';
bufferIndex = 0; bufferIndex = 0;
cliMode = 0; cliMode = false;
// incase a motor was left running during motortest, clear it here // incase a motor was left running during motortest, clear it here
mixerResetDisarmedMotors(); mixerResetDisarmedMotors();
cliReboot(); cliReboot();
cliWriter = NULL;
} }
#ifdef USE_GPS #ifdef USE_GPS
@ -4074,6 +4138,12 @@ static void cliSave(char *cmdline)
{ {
UNUSED(cmdline); UNUSED(cmdline);
#if defined(USE_CUSTOM_DEFAULTS)
if (processingCustomDefaults) {
return;
}
#endif
#ifdef USE_CLI_BATCH #ifdef USE_CLI_BATCH
if (commandBatchActive && commandBatchError) { if (commandBatchActive && commandBatchError) {
cliPrintCommandBatchWarning("PLEASE FIX ERRORS THEN 'SAVE'"); cliPrintCommandBatchWarning("PLEASE FIX ERRORS THEN 'SAVE'");
@ -4104,15 +4174,51 @@ static void cliSave(char *cmdline)
cliReboot(); cliReboot();
} }
#if defined(USE_CUSTOM_DEFAULTS)
static bool isDefaults(char *ptr)
{
return strncmp(ptr, "# " FC_FIRMWARE_NAME, 12) == 0;
}
#endif
static void cliDefaults(char *cmdline) static void cliDefaults(char *cmdline)
{ {
bool saveConfigs; bool saveConfigs = true;
#if defined(USE_CUSTOM_DEFAULTS)
bool useCustomDefaults = true;
#elif defined(USE_CUSTOM_DEFAULTS_ADDRESS)
// Required to keep the linker from eliminating these
if (customDefaultsStart != customDefaultsEnd) {
delay(0);
}
#endif
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
saveConfigs = true;
} else if (strncasecmp(cmdline, "nosave", 6) == 0) { } else if (strncasecmp(cmdline, "nosave", 6) == 0) {
saveConfigs = false; saveConfigs = false;
#if defined(USE_CUSTOM_DEFAULTS)
} else if (strncasecmp(cmdline, "bare", 4) == 0) {
useCustomDefaults = false;
} else if (strncasecmp(cmdline, "show", 4) == 0) {
char *customDefaultsPtr = customDefaultsStart;
if (isDefaults(customDefaultsPtr)) {
while (*customDefaultsPtr && *customDefaultsPtr != 0xFF && customDefaultsPtr < customDefaultsEnd) {
if (*customDefaultsPtr != '\n') {
cliPrintf("%c", *customDefaultsPtr++);
} else {
cliPrintLinefeed();
customDefaultsPtr++;
}
}
} else {
cliPrintError("NO DEFAULTS FOUND");
}
return;
#endif
} else { } else {
cliPrintError("INVALID OPTION");
return; return;
} }
@ -4128,6 +4234,12 @@ static void cliDefaults(char *cmdline)
commandBatchError = false; commandBatchError = false;
#endif #endif
#if defined(USE_CUSTOM_DEFAULTS)
if (useCustomDefaults) {
cliProcessCustomDefaults();
}
#endif
if (saveConfigs) { if (saveConfigs) {
cliSave(NULL); cliSave(NULL);
} }
@ -4156,7 +4268,7 @@ STATIC_UNIT_TESTED void cliGet(char *cmdline)
pidProfileIndexToUse = getCurrentPidProfileIndex(); pidProfileIndexToUse = getCurrentPidProfileIndex();
rateProfileIndexToUse = getCurrentControlRateProfileIndex(); rateProfileIndexToUse = getCurrentControlRateProfileIndex();
backupAndResetConfigs(); backupAndResetConfigs(true);
for (uint32_t i = 0; i < valueTableEntryCount; i++) { for (uint32_t i = 0; i < valueTableEntryCount; i++) {
if (strcasestr(valueTable[i].name, cmdline)) { if (strcasestr(valueTable[i].name, cmdline)) {
@ -4192,11 +4304,9 @@ STATIC_UNIT_TESTED void cliGet(char *cmdline)
pidProfileIndexToUse = CURRENT_PROFILE_INDEX; pidProfileIndexToUse = CURRENT_PROFILE_INDEX;
rateProfileIndexToUse = CURRENT_PROFILE_INDEX; rateProfileIndexToUse = CURRENT_PROFILE_INDEX;
if (matchedCommands) { if (!matchedCommands) {
return; cliPrintErrorLinef("INVALID NAME");
} }
cliPrintErrorLinef("INVALID NAME");
} }
static uint8_t getWordLength(char *bufBegin, char *bufEnd) static uint8_t getWordLength(char *bufBegin, char *bufEnd)
@ -4813,7 +4923,7 @@ static void printResource(dumpFlags_t dumpMask, const char *headingStr)
const pgRegistry_t* pg = pgFind(resourceTable[i].pgn); const pgRegistry_t* pg = pgFind(resourceTable[i].pgn);
const void *currentConfig; const void *currentConfig;
const void *defaultConfig; const void *defaultConfig;
if (configIsInCopy) { if (isReadingConfigFromCopy()) {
currentConfig = pg->copy; currentConfig = pg->copy;
defaultConfig = pg->address; defaultConfig = pg->address;
} else { } else {
@ -5028,7 +5138,7 @@ static const char *printPeripheralDmaopt(dmaoptEntry_t *entry, int index, dumpFl
const void *currentConfig; const void *currentConfig;
const void *defaultConfig; const void *defaultConfig;
if (configIsInCopy) { if (isReadingConfigFromCopy()) {
currentConfig = pg->copy; currentConfig = pg->copy;
defaultConfig = pg->address; defaultConfig = pg->address;
} else { } else {
@ -5141,7 +5251,7 @@ static void printDmaopt(dumpFlags_t dumpMask, const char *headingStr)
const timerIOConfig_t *currentConfig; const timerIOConfig_t *currentConfig;
const timerIOConfig_t *defaultConfig; const timerIOConfig_t *defaultConfig;
if (configIsInCopy) { if (isReadingConfigFromCopy()) {
currentConfig = (timerIOConfig_t *)pg->copy; currentConfig = (timerIOConfig_t *)pg->copy;
defaultConfig = (timerIOConfig_t *)pg->address; defaultConfig = (timerIOConfig_t *)pg->address;
} else { } else {
@ -5218,7 +5328,7 @@ static void cliDmaopt(char *cmdline)
const pgRegistry_t* pg = pgFind(entry->pgn); const pgRegistry_t* pg = pgFind(entry->pgn);
const void *currentConfig; const void *currentConfig;
if (configIsInCopy) { if (isWritingConfigToCopy()) {
currentConfig = pg->copy; currentConfig = pg->copy;
} else { } else {
currentConfig = pg->address; currentConfig = pg->address;
@ -5375,7 +5485,7 @@ static void printTimer(dumpFlags_t dumpMask, const char *headingStr)
const timerIOConfig_t *defaultConfig; const timerIOConfig_t *defaultConfig;
headingStr = cliPrintSectionHeading(dumpMask, false, headingStr); headingStr = cliPrintSectionHeading(dumpMask, false, headingStr);
if (configIsInCopy) { if (isReadingConfigFromCopy()) {
currentConfig = (timerIOConfig_t *)pg->copy; currentConfig = (timerIOConfig_t *)pg->copy;
defaultConfig = (timerIOConfig_t *)pg->address; defaultConfig = (timerIOConfig_t *)pg->address;
} else { } else {
@ -5784,7 +5894,7 @@ static void printConfig(char *cmdline, bool doDiff)
dumpMask = dumpMask | BARE; // show the diff / dump without extra commands and board specific data dumpMask = dumpMask | BARE; // show the diff / dump without extra commands and board specific data
} }
backupAndResetConfigs(); backupAndResetConfigs((dumpMask & BARE) == 0);
#ifdef USE_CLI_BATCH #ifdef USE_CLI_BATCH
bool batchModeEnabled = false; bool batchModeEnabled = false;
@ -5859,7 +5969,7 @@ static void printConfig(char *cmdline, bool doDiff)
#endif #endif
#endif #endif
printFeature(dumpMask, &featureConfig_Copy, featureConfig(), "feature"); printFeature(dumpMask, featureConfig_Copy.enabledFeatures, *getFeatureMask(), "feature");
#if defined(USE_BEEPER) #if defined(USE_BEEPER)
printBeeper(dumpMask, beeperConfig_Copy.beeper_off_flags, beeperConfig()->beeper_off_flags, "beeper", BEEPER_ALLOWED_MODES, "beeper"); printBeeper(dumpMask, beeperConfig_Copy.beeper_off_flags, beeperConfig()->beeper_off_flags, "beeper", BEEPER_ALLOWED_MODES, "beeper");
@ -5989,7 +6099,7 @@ static void cliMsc(char *cmdline)
#endif #endif
cliPrintHashLine("Restarting in mass storage mode"); cliPrintHashLine("Restarting in mass storage mode");
cliPrint("\r\nRebooting"); cliPrint("\r\nRebooting");
bufWriterFlush(cliWriter); cliWriterFlush();
waitForSerialPortToFinishTransmitting(cliPort); waitForSerialPortToFinishTransmitting(cliPort);
motorShutdown(); motorShutdown();
@ -6057,7 +6167,11 @@ const clicmd_t cmdTable[] = {
#ifdef USE_LED_STRIP_STATUS_MODE #ifdef USE_LED_STRIP_STATUS_MODE
CLI_COMMAND_DEF("color", "configure colors", NULL, cliColor), CLI_COMMAND_DEF("color", "configure colors", NULL, cliColor),
#endif #endif
CLI_COMMAND_DEF("defaults", "reset to defaults and reboot", "[nosave]", cliDefaults), #if defined(USE_CUSTOM_DEFAULTS)
CLI_COMMAND_DEF("defaults", "reset to defaults and reboot", "[nosave|bare|show]", cliDefaults),
#else
CLI_COMMAND_DEF("defaults", "reset to defaults and reboot", "[nosave|show]", cliDefaults),
#endif
CLI_COMMAND_DEF("diff", "list configuration changes from default", "[master|profile|rates|hardware|all] {defaults|bare}", cliDiff), CLI_COMMAND_DEF("diff", "list configuration changes from default", "[master|profile|rates|hardware|all] {defaults|bare}", cliDiff),
#ifdef USE_RESOURCE_MGMT #ifdef USE_RESOURCE_MGMT
@ -6202,120 +6316,176 @@ static void cliHelp(char *cmdline)
} }
} }
static void processCharacter(const char c)
{
if (bufferIndex && (c == '\n' || c == '\r')) {
// enter pressed
cliPrintLinefeed();
#if defined(USE_CUSTOM_DEFAULTS) && defined(DEBUG_CUSTOM_DEFAULTS)
if (processingCustomDefaults) {
cliPrint("d: ");
}
#endif
// Strip comment starting with # from line
char *p = cliBuffer;
p = strchr(p, '#');
if (NULL != p) {
bufferIndex = (uint32_t)(p - cliBuffer);
}
// Strip trailing whitespace
while (bufferIndex > 0 && cliBuffer[bufferIndex - 1] == ' ') {
bufferIndex--;
}
// Process non-empty lines
if (bufferIndex > 0) {
cliBuffer[bufferIndex] = 0; // null terminate
const clicmd_t *cmd;
char *options;
for (cmd = cmdTable; cmd < cmdTable + ARRAYLEN(cmdTable); cmd++) {
if ((options = checkCommand(cliBuffer, cmd->name))) {
break;
}
}
if (cmd < cmdTable + ARRAYLEN(cmdTable)) {
cmd->func(options);
} else {
cliPrintError("UNKNOWN COMMAND, TRY 'HELP'");
}
bufferIndex = 0;
}
memset(cliBuffer, 0, sizeof(cliBuffer));
// 'exit' will reset this flag, so we don't need to print prompt again
if (!cliMode) {
return;
}
cliPrompt();
} else if (bufferIndex < sizeof(cliBuffer) && c >= 32 && c <= 126) {
if (!bufferIndex && c == ' ')
return; // Ignore leading spaces
cliBuffer[bufferIndex++] = c;
cliWrite(c);
}
}
static void processCharacterInteractive(const char c)
{
if (c == '\t' || c == '?') {
// do tab completion
const clicmd_t *cmd, *pstart = NULL, *pend = NULL;
uint32_t i = bufferIndex;
for (cmd = cmdTable; cmd < cmdTable + ARRAYLEN(cmdTable); cmd++) {
if (bufferIndex && (strncasecmp(cliBuffer, cmd->name, bufferIndex) != 0)) {
continue;
}
if (!pstart) {
pstart = cmd;
}
pend = cmd;
}
if (pstart) { /* Buffer matches one or more commands */
for (; ; bufferIndex++) {
if (pstart->name[bufferIndex] != pend->name[bufferIndex])
break;
if (!pstart->name[bufferIndex] && bufferIndex < sizeof(cliBuffer) - 2) {
/* Unambiguous -- append a space */
cliBuffer[bufferIndex++] = ' ';
cliBuffer[bufferIndex] = '\0';
break;
}
cliBuffer[bufferIndex] = pstart->name[bufferIndex];
}
}
if (!bufferIndex || pstart != pend) {
/* Print list of ambiguous matches */
cliPrint("\r\033[K");
for (cmd = pstart; cmd <= pend; cmd++) {
cliPrint(cmd->name);
cliWrite('\t');
}
cliPrompt();
i = 0; /* Redraw prompt */
}
for (; i < bufferIndex; i++)
cliWrite(cliBuffer[i]);
} else if (!bufferIndex && c == 4) { // CTRL-D
cliExit(cliBuffer);
return;
} else if (c == 12) { // NewPage / CTRL-L
// clear screen
cliPrint("\033[2J\033[1;1H");
cliPrompt();
} else if (c == 127) {
// backspace
if (bufferIndex) {
cliBuffer[--bufferIndex] = 0;
cliPrint("\010 \010");
}
} else {
processCharacter(c);
}
}
void cliProcess(void) void cliProcess(void)
{ {
if (!cliWriter) { if (!cliWriter) {
return; return;
} }
// Be a little bit tricky. Flush the last inputs buffer, if any. // Flush the buffer to get rid of any MSP data polls sent by configurator after CLI was invoked
bufWriterFlush(cliWriter); cliWriterFlush();
while (serialRxBytesWaiting(cliPort)) { while (serialRxBytesWaiting(cliPort)) {
uint8_t c = serialRead(cliPort); uint8_t c = serialRead(cliPort);
if (c == '\t' || c == '?') {
// do tab completion
const clicmd_t *cmd, *pstart = NULL, *pend = NULL;
uint32_t i = bufferIndex;
for (cmd = cmdTable; cmd < cmdTable + ARRAYLEN(cmdTable); cmd++) {
if (bufferIndex && (strncasecmp(cliBuffer, cmd->name, bufferIndex) != 0))
continue;
if (!pstart)
pstart = cmd;
pend = cmd;
}
if (pstart) { /* Buffer matches one or more commands */
for (; ; bufferIndex++) {
if (pstart->name[bufferIndex] != pend->name[bufferIndex])
break;
if (!pstart->name[bufferIndex] && bufferIndex < sizeof(cliBuffer) - 2) {
/* Unambiguous -- append a space */
cliBuffer[bufferIndex++] = ' ';
cliBuffer[bufferIndex] = '\0';
break;
}
cliBuffer[bufferIndex] = pstart->name[bufferIndex];
}
}
if (!bufferIndex || pstart != pend) {
/* Print list of ambiguous matches */
cliPrint("\r\033[K");
for (cmd = pstart; cmd <= pend; cmd++) {
cliPrint(cmd->name);
cliWrite('\t');
}
cliPrompt();
i = 0; /* Redraw prompt */
}
for (; i < bufferIndex; i++)
cliWrite(cliBuffer[i]);
} else if (!bufferIndex && c == 4) { // CTRL-D
cliExit(cliBuffer);
return;
} else if (c == 12) { // NewPage / CTRL-L
// clear screen
cliPrint("\033[2J\033[1;1H");
cliPrompt();
} else if (bufferIndex && (c == '\n' || c == '\r')) {
// enter pressed
cliPrintLinefeed();
// Strip comment starting with # from line processCharacterInteractive(c);
char *p = cliBuffer;
p = strchr(p, '#');
if (NULL != p) {
bufferIndex = (uint32_t)(p - cliBuffer);
}
// Strip trailing whitespace
while (bufferIndex > 0 && cliBuffer[bufferIndex - 1] == ' ') {
bufferIndex--;
}
// Process non-empty lines
if (bufferIndex > 0) {
cliBuffer[bufferIndex] = 0; // null terminate
const clicmd_t *cmd;
char *options;
for (cmd = cmdTable; cmd < cmdTable + ARRAYLEN(cmdTable); cmd++) {
if ((options = checkCommand(cliBuffer, cmd->name))) {
break;
}
}
if (cmd < cmdTable + ARRAYLEN(cmdTable)) {
cmd->func(options);
} else {
cliPrintError("UNKNOWN COMMAND, TRY 'HELP'");
}
bufferIndex = 0;
}
memset(cliBuffer, 0, sizeof(cliBuffer));
// 'exit' will reset this flag, so we don't need to print prompt again
if (!cliMode)
return;
cliPrompt();
} else if (c == 127) {
// backspace
if (bufferIndex) {
cliBuffer[--bufferIndex] = 0;
cliPrint("\010 \010");
}
} else if (bufferIndex < sizeof(cliBuffer) && c >= 32 && c <= 126) {
if (!bufferIndex && c == ' ')
continue; // Ignore leading spaces
cliBuffer[bufferIndex++] = c;
cliWrite(c);
}
} }
} }
#if defined(USE_CUSTOM_DEFAULTS)
void cliProcessCustomDefaults(void)
{
if (processingCustomDefaults) {
return;
}
char *customDefaultsPtr = customDefaultsStart;
if (isDefaults(customDefaultsPtr)) {
#if !defined(DEBUG_CUSTOM_DEFAULTS)
bufWriter_t *cliWriterTemp = cliWriter;
cliWriter = NULL;
#endif
memcpy(cliBufferTemp, cliBuffer, sizeof(cliBuffer));
uint32_t bufferIndexTemp = bufferIndex;
bufferIndex = 0;
processingCustomDefaults = true;
while (*customDefaultsPtr && *customDefaultsPtr != 0xFF && customDefaultsPtr < customDefaultsEnd) {
processCharacter(*customDefaultsPtr++);
}
processingCustomDefaults = false;
#if !defined(DEBUG_CUSTOM_DEFAULTS)
cliWriter = cliWriterTemp;
#endif
memcpy(cliBuffer, cliBufferTemp, sizeof(cliBuffer));
bufferIndex = bufferIndexTemp;
} else {
cliPrintError("NO DEFAULTS FOUND");
}
}
#endif
void cliEnter(serialPort_t *serialPort) void cliEnter(serialPort_t *serialPort)
{ {
cliMode = 1; cliMode = true;
cliPort = serialPort; cliPort = serialPort;
setPrintfSerialPort(cliPort); setPrintfSerialPort(cliPort);
cliWriter = bufWriterInit(cliWriteBuffer, sizeof(cliWriteBuffer), (bufWrite_t)serialWriteBufShim, serialPort); cliWriter = bufWriterInit(cliWriteBuffer, sizeof(cliWriteBuffer), (bufWrite_t)serialWriteBufShim, serialPort);
@ -6335,9 +6505,4 @@ void cliEnter(serialPort_t *serialPort)
resetCommandBatch(); resetCommandBatch();
#endif #endif
} }
void cliInit(const serialConfig_t *serialConfig)
{
UNUSED(serialConfig);
}
#endif // USE_CLI #endif // USE_CLI

View file

@ -20,14 +20,11 @@
#pragma once #pragma once
extern uint8_t cliMode; #include <stdbool.h>
struct clivalue_s; extern bool cliMode;
void *cliGetValuePointer(const struct clivalue_s *value);
const void *cliGetDefaultPointer(const struct clivalue_s *value);
struct serialConfig_s;
void cliInit(const struct serialConfig_s *serialConfig);
void cliProcess(void); void cliProcess(void);
void cliProcessCustomDefaults(void);
struct serialPort_s; struct serialPort_s;
void cliEnter(struct serialPort_s *serialPort); void cliEnter(struct serialPort_s *serialPort);

View file

@ -64,8 +64,3 @@ void featureDisableAll(void)
{ {
featureConfigMutable()->enabledFeatures = 0; featureConfigMutable()->enabledFeatures = 0;
} }
uint32_t featureMask(void)
{
return featureConfig()->enabledFeatures;
}

View file

@ -66,7 +66,6 @@ bool featureIsEnabled(const uint32_t mask);
void featureEnable(const uint32_t mask); void featureEnable(const uint32_t mask);
void featureDisable(const uint32_t mask); void featureDisable(const uint32_t mask);
void featureDisableAll(void); void featureDisableAll(void);
uint32_t featureMask(void);
void featureSet(const uint32_t mask, uint32_t *features); void featureSet(const uint32_t mask, uint32_t *features);
void featureClear(const uint32_t mask, uint32_t *features); void featureClear(const uint32_t mask, uint32_t *features);

View file

@ -30,8 +30,6 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "build/debug.h" #include "build/debug.h"
#include "cli/cli.h"
#include "cms/cms.h" #include "cms/cms.h"
#include "cms/cms_types.h" #include "cms/cms_types.h"
@ -725,10 +723,6 @@ void init(void)
mspInit(); mspInit();
mspSerialInit(); mspSerialInit();
#ifdef USE_CLI
cliInit(serialConfig());
#endif
failsafeInit(); failsafeInit();
rxInit(); rxInit();

View file

@ -177,7 +177,7 @@ static uint32_t getFeatureMask(void)
if (featureMaskIsCopied) { if (featureMaskIsCopied) {
return featureMaskCopy; return featureMaskCopy;
} else { } else {
return featureMask(); return featureConfig()->enabledFeatures;
} }
} }

View file

@ -26,6 +26,8 @@
#define USBD_PRODUCT_STRING "KISSFCV2F7" #define USBD_PRODUCT_STRING "KISSFCV2F7"
#undef USE_CUSTOM_DEFAULTS_ADDRESS
#define LED0_PIN PA8 // blue #define LED0_PIN PA8 // blue
#define LED1_PIN PC8 // blingbling #define LED1_PIN PC8 // blingbling
#define LED1_INVERTED #define LED1_INVERTED

View file

@ -56,6 +56,8 @@
#define USBD_PRODUCT_STRING "OmnibusF4" #define USBD_PRODUCT_STRING "OmnibusF4"
#endif #endif
#define USE_CUSTOM_DEFAULTS
#define LED0_PIN PB5 #define LED0_PIN PB5
#define USE_BEEPER #define USE_BEEPER
#define BEEPER_PIN PB4 #define BEEPER_PIN PB4

View file

@ -1,6 +1,9 @@
F405_TARGETS += $(TARGET) F405_TARGETS += $(TARGET)
FEATURES += SDCARD_SPI VCP ONBOARDFLASH FEATURES += SDCARD_SPI VCP ONBOARDFLASH
CUSTOM_DEFAULTS_EXTENDED = yes
TARGET_SRC = \ TARGET_SRC = \
$(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \ $(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \
$(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \ $(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \

View file

@ -2,6 +2,8 @@ F411_TARGETS += $(TARGET)
FEATURES += SDCARD_SPI VCP ONBOARDFLASH FEATURES += SDCARD_SPI VCP ONBOARDFLASH
CUSTOM_DEFAULTS_EXTENDED = yes
TARGET_SRC = \ TARGET_SRC = \
$(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \ $(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \
$(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \ $(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \

View file

@ -1,4 +1,5 @@
F411_TARGETS += $(TARGET) F411_TARGETS += $(TARGET)
FEATURES += VCP SDCARD_SPI ONBOARDFLASH FEATURES += VCP SDCARD_SPI ONBOARDFLASH
TARGET_SRC = \ TARGET_SRC = \

View file

@ -1,4 +1,5 @@
F405_TARGETS += $(TARGET) F405_TARGETS += $(TARGET)
FEATURES += VCP SDCARD_SPI MSC FEATURES += VCP SDCARD_SPI MSC
TARGET_SRC = \ TARGET_SRC = \

View file

@ -1,6 +1,9 @@
F7X5XG_TARGETS += $(TARGET) F7X5XG_TARGETS += $(TARGET)
FEATURES += SDCARD_SPI VCP ONBOARDFLASH FEATURES += SDCARD_SPI VCP ONBOARDFLASH
CUSTOM_DEFAULTS_EXTENDED = yes
TARGET_SRC = \ TARGET_SRC = \
$(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \ $(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \
$(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \ $(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \

View file

@ -1,6 +1,9 @@
F7X2RE_TARGETS += $(TARGET) F7X2RE_TARGETS += $(TARGET)
FEATURES += SDCARD_SPI VCP ONBOARDFLASH FEATURES += SDCARD_SPI VCP ONBOARDFLASH
CUSTOM_DEFAULTS_EXTENDED = yes
TARGET_SRC = \ TARGET_SRC = \
$(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \ $(addprefix drivers/accgyro/,$(notdir $(wildcard $(SRC_DIR)/drivers/accgyro/*.c))) \
$(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \ $(addprefix drivers/barometer/,$(notdir $(wildcard $(SRC_DIR)/drivers/barometer/*.c))) \

View file

@ -372,3 +372,7 @@ extern uint8_t __config_end;
#ifndef USE_ITERM_RELAX #ifndef USE_ITERM_RELAX
#undef USE_ABSOLUTE_CONTROL #undef USE_ABSOLUTE_CONTROL
#endif #endif
#if defined(USE_CUSTOM_DEFAULTS)
#define USE_CUSTOM_DEFAULTS_ADDRESS
#endif

View file

@ -67,6 +67,7 @@
#define USE_DMA_SPEC #define USE_DMA_SPEC
#define USE_TIMER_MGMT #define USE_TIMER_MGMT
#define USE_PERSISTENT_OBJECTS #define USE_PERSISTENT_OBJECTS
#define USE_CUSTOM_DEFAULTS_ADDRESS
// Re-enable this after 4.0 has been released, and remove the define from STM32F4DISCOVERY // Re-enable this after 4.0 has been released, and remove the define from STM32F4DISCOVERY
//#define USE_SPI_TRANSACTION //#define USE_SPI_TRANSACTION
@ -97,6 +98,7 @@
#define USE_DMA_SPEC #define USE_DMA_SPEC
#define USE_TIMER_MGMT #define USE_TIMER_MGMT
#define USE_PERSISTENT_OBJECTS #define USE_PERSISTENT_OBJECTS
#define USE_CUSTOM_DEFAULTS_ADDRESS
// Re-enable this after 4.0 has been released, and remove the define from STM32F4DISCOVERY // Re-enable this after 4.0 has been released, and remove the define from STM32F4DISCOVERY
//#define USE_SPI_TRANSACTION //#define USE_SPI_TRANSACTION
#endif // STM32F7 #endif // STM32F7

View file

@ -117,3 +117,5 @@
#define USE_RX_FLYSKY #define USE_RX_FLYSKY
#define USE_RX_FLYSKY_SPI_LED #define USE_RX_FLYSKY_SPI_LED
#define USE_CUSTOM_DEFAULTS

View file

@ -56,6 +56,7 @@ extern "C" {
void cliSet(char *cmdline); void cliSet(char *cmdline);
void cliGet(char *cmdline); void cliGet(char *cmdline);
int cliGetSettingIndex(char *name, uint8_t length); int cliGetSettingIndex(char *name, uint8_t length);
void *cliGetValuePointer(const clivalue_t *value);
const clivalue_t valueTable[] = { const clivalue_t valueTable[] = {
{ "array_unit_test", VAR_INT8 | MODE_ARRAY | MASTER_VALUE, .config.array.length = 3, PG_RESERVED_FOR_TESTING_1, 0 }, { "array_unit_test", VAR_INT8 | MODE_ARRAY | MASTER_VALUE, .config.array.length = 3, PG_RESERVED_FOR_TESTING_1, 0 },
@ -356,4 +357,6 @@ bool persistBoardInformation(void) { return true; };
void activeAdjustmentRangeReset(void) {} void activeAdjustmentRangeReset(void) {}
void analyzeModeActivationConditions(void) {} void analyzeModeActivationConditions(void) {}
bool isModeActivationConditionConfigured(const modeActivationCondition_t *, const modeActivationCondition_t *) { return false; } bool isModeActivationConditionConfigured(const modeActivationCondition_t *, const modeActivationCondition_t *) { return false; }
void delay(uint32_t) {}
} }

11
src/utils/make_config_hex.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
INPUT_FILE=$1
DESTINATION_DIR=$2
TARGET_ADDRESS=0x080FC000
srec_cat ${INPUT_FILE} -binary -offset ${TARGET_ADDRESS} \
-generate '(' -maximum-address ${INPUT_FILE} -binary -maximum-address ${INPUT_FILE} -binary -offset 1 ')' \
-constant 0x00 -offset ${TARGET_ADDRESS} \
-output ${DESTINATION_DIR}/$(basename ${INPUT_FILE}).hex -intel