Skip to content

Commit fe28ee2

Browse files
committed
Serialize the config via confparser for storing in EEPROM
Reduces the size of the data by about 40%.
1 parent 1f7cee4 commit fe28ee2

2 files changed

Lines changed: 39 additions & 29 deletions

File tree

src/main.c

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -976,20 +976,37 @@ static void refloat_thd(void *arg) {
976976
}
977977
}
978978

979+
// TODO: The required buffer size is not provided by the confparser. Until it's
980+
// added, use a number that should always be bigger. On a config write, we
981+
// check if we've written past the buffer end and crash. On a config read,
982+
// there's no way to check and the trailing end of the config will have bogus
983+
// numbers read from the EEPROM.
984+
#ifndef SERIALIZED_CONFIG_LENGTH
985+
#define SERIALIZED_CONFIG_LENGTH 400
986+
#endif
987+
979988
static void write_cfg_to_eeprom(Data *d) {
980-
uint32_t ints = sizeof(RefloatConfig) / 4 + 1;
981-
uint32_t *buffer = VESC_IF->malloc(ints * sizeof(uint32_t));
989+
uint32_t words = (SERIALIZED_CONFIG_LENGTH - 1) / 4 + 1;
990+
uint32_t *buffer = VESC_IF->malloc(words * sizeof(uint32_t));
982991
if (!buffer) {
983992
log_error("Failed to write config to EEPROM: Out of memory.");
984993
return;
985994
}
986995

987996
bool write_ok = true;
988-
memcpy(buffer, &(d->float_conf), sizeof(RefloatConfig));
989-
for (uint32_t i = 0; i < ints; i++) {
997+
uint32_t written_bytes = confparser_serialize_refloatconfig((uint8_t *) buffer, &d->float_conf);
998+
if (written_bytes > words * sizeof(uint32_t)) {
999+
log_error("Config write buffer overflow.");
1000+
fatal_error_terminate();
1001+
}
1002+
1003+
const uint32_t real_words = (written_bytes - 1) / 4 + 1;
1004+
// The confparser stores the signature at the beginning of the buffer.
1005+
// Write from the back so that the signature gets written last.
1006+
for (int32_t i = real_words - 1; i >= 0; --i) {
9901007
eeprom_var v;
9911008
v.as_u32 = buffer[i];
992-
if (!VESC_IF->store_eeprom_var(&v, i + 1)) {
1009+
if (!VESC_IF->store_eeprom_var(&v, i)) {
9931010
write_ok = false;
9941011
break;
9951012
}
@@ -998,10 +1015,7 @@ static void write_cfg_to_eeprom(Data *d) {
9981015
VESC_IF->free(buffer);
9991016

10001017
if (write_ok) {
1001-
eeprom_var v;
1002-
v.as_u32 = REFLOATCONFIG_SIGNATURE;
1003-
VESC_IF->store_eeprom_var(&v, 0);
1004-
1018+
log_msg("Config written: %uB", written_bytes);
10051019
beep_alert(d, 1, 0);
10061020
leds_status_confirm(&d->leds);
10071021
} else {
@@ -1026,33 +1040,29 @@ static void aux_thd(void *arg) {
10261040
}
10271041

10281042
static void read_cfg_from_eeprom(Data *d) {
1029-
uint32_t ints = sizeof(RefloatConfig) / 4 + 1;
1030-
uint32_t *buffer = VESC_IF->malloc(ints * sizeof(uint32_t));
1043+
uint32_t words = (SERIALIZED_CONFIG_LENGTH - 1) / 4 + 1;
1044+
uint32_t *buffer = VESC_IF->malloc(words * sizeof(uint32_t));
10311045
if (!buffer) {
10321046
log_error("Failed to read config from EEPROM: Out of memory.");
10331047
return;
10341048
}
10351049

10361050
eeprom_var v;
1037-
bool read_ok = VESC_IF->read_eeprom_var(&v, 0);
1038-
if (read_ok) {
1039-
if (v.as_u32 == REFLOATCONFIG_SIGNATURE) {
1040-
for (uint32_t i = 0; i < ints; i++) {
1041-
if (!VESC_IF->read_eeprom_var(&v, i + 1)) {
1042-
read_ok = false;
1043-
break;
1044-
}
1045-
buffer[i] = v.as_u32;
1046-
}
1047-
} else {
1048-
log_error("Failed signature check while reading config from EEPROM, using defaults.");
1049-
confparser_set_defaults_refloatconfig(&d->float_conf);
1050-
return;
1051+
bool read_ok = true;
1052+
for (uint32_t i = 0; i < words; ++i) {
1053+
if (!VESC_IF->read_eeprom_var(&v, i)) {
1054+
read_ok = false;
1055+
break;
10511056
}
1057+
buffer[i] = v.as_u32;
10521058
}
10531059

10541060
if (read_ok) {
1055-
memcpy(&d->float_conf, buffer, sizeof(RefloatConfig));
1061+
read_ok = confparser_deserialize_refloatconfig((uint8_t *) buffer, &d->float_conf);
1062+
if (!read_ok) {
1063+
log_error("Failed signature check while reading config from EEPROM, using defaults.");
1064+
confparser_set_defaults_refloatconfig(&d->float_conf);
1065+
}
10561066
} else {
10571067
log_error("Failed to read config from EEPROM, using defaults.");
10581068
confparser_set_defaults_refloatconfig(&d->float_conf);
@@ -2258,6 +2268,6 @@ INIT_FUN(lib_info *info) {
22582268
return true;
22592269
}
22602270

2261-
void send_app_data_overflow_terminate() {
2271+
void fatal_error_terminate() {
22622272
stop(ARG);
22632273
}

src/utils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
#endif
5858

5959
// Declaration for the SEMD_APP_DATA macro, definition needs to be in main.c.
60-
void send_app_data_overflow_terminate();
60+
void fatal_error_terminate();
6161

6262
#define SEND_BUF_MAX_SIZE 511
6363

@@ -77,7 +77,7 @@ void send_app_data_overflow_terminate();
7777
ind \
7878
); \
7979
/* terminate the main thread, the memory has just been corrupted by buffer overflow */ \
80-
send_app_data_overflow_terminate(); \
80+
fatal_error_terminate(); \
8181
} \
8282
VESC_IF->send_app_data(buffer, ind); \
8383
} while (0)

0 commit comments

Comments
 (0)