From 46b221d491b405a4ee92e341c136454df48971b8 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sun, 23 Aug 2020 15:32:06 -0700 Subject: [PATCH] Use 32b loads to set print strings Instead of using either a series of etc_putc or setting a series of bytes one by one, use a simple macro to define 32b constants to build up strings. Saves ~30 bytes of program code in eboot --- bootloaders/eboot/eboot.c | 37 ++++++++++++++++++++++-------------- bootloaders/eboot/eboot.elf | Bin 44468 -> 44944 bytes 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index 6b3b316341..ed8a49d712 100644 --- a/bootloaders/eboot/eboot.c +++ b/bootloaders/eboot/eboot.c @@ -21,20 +21,20 @@ extern unsigned char _gzip_dict; extern void ets_wdt_enable(void); extern void ets_wdt_disable(void); +// Converts bit of a string into a uint32 +#define S(a,b,c,d) ( (((uint32_t)a) & 0xff) | (((uint32_t)b) << 8) | (((uint32_t)c) << 16) | (((uint32_t)d)<<24) ) + int print_version(const uint32_t flash_addr) { uint32_t ver; if (SPIRead(flash_addr + APP_START_OFFSET + sizeof(image_header_t) + sizeof(section_header_t), &ver, sizeof(ver))) { return 1; } - char fmt[7]; - fmt[0] = 'v'; - fmt[1] = '%'; - fmt[2] = '0'; - fmt[3] = '8'; - fmt[4] = 'x'; - fmt[5] = '\n'; - fmt[6] = 0; + // We don't have BSS and can't print from flash, so build up string + // 4 chars at a time. Smaller code than byte-wise assignment. + uint32_t fmt[2]; + fmt[0] = S('v', '%', '0', '8'); + fmt[1] = S('x', '\n', 0, 0); ets_printf((const char*) fmt, ver); return 0; } @@ -222,26 +222,32 @@ int main() } if (cmd.action == ACTION_COPY_RAW) { - ets_putc('c'); ets_putc('p'); ets_putc(':'); + uint32_t cp = S('c', 'p', ':', 0); + ets_printf((const char *)cp); ets_wdt_disable(); res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], false); ets_wdt_enable(); - ets_putc('0'+res); ets_putc('\n'); + cp = S('0' + res, '\n', 0, 0 ); + ets_printf((const char *)cp); #if 0 //devyte: this verify step below (cmp:) only works when the end of copy operation above does not overwrite the //beginning of the image in the empty area, see #7458. Disabling for now. //TODO: replace the below verify with hash type, crc, or similar. // Verify the copy - ets_putc('c'); ets_putc('m'); ets_putc('p'); ets_putc(':'); + uint32_t v[2]; + v[0] = S('c', 'm', 'p', ':'); + v[1] = 0; + ets_printf(const char *)v); if (res == 0) { ets_wdt_disable(); res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], true); ets_wdt_enable(); } - ets_putc('0'+res); ets_putc('\n'); + cp = S('0' + res, '\n', 0, 0 ); + ets_printf((const char *)cp); #endif if (res == 0) { cmd.action = ACTION_LOAD_APP; @@ -256,8 +262,11 @@ int main() if (cmd.action == ACTION_LOAD_APP) { ets_putc('l'); ets_putc('d'); ets_putc('\n'); res = load_app_from_flash_raw(cmd.args[0]); - //we will get to this only on load fail - ets_putc('e'); ets_putc(':'); ets_putc('0'+res); ets_putc('\n'); + // We will get to this only on load fail + uint32_t e[2]; + e[0] = S('e', ':', '0' + res, '\n' ); + e[1] = 0; + ets_printf((const char*)e); } if (res) { diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf index 8c235c2087a1b2e72ba0ebb58ca69d24c202d202..f74afaa512229d5d92d9ba40425590ff64365bec 100755 GIT binary patch delta 15763 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 delta 15380 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 F{tG;n1QP%N