From bbc14c0979abe50349c223d2717ca8e5be6a9a96 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Fri, 16 Oct 2020 10:52:35 -0700 Subject: [PATCH] Use 32b loads to set print strings (#7545) 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 for #6538 to work with. --- bootloaders/eboot/eboot.c | 37 ++++++++++++++++++++++-------------- bootloaders/eboot/eboot.elf | Bin 44900 -> 44892 bytes 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index bf8a53115..1ca64a16a 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; } @@ -234,26 +234,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; @@ -268,8 +274,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 48b3543892c439817ed8ffa358333cf48937c4ef..e7e1fc543975fb3e53c36801db8004e63a9ef4aa 100755 GIT binary patch delta 12248 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 ND%?8~EzI7V_CMBv0{s90 delta 12359 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