diff --git a/src/systemcmds/bl_update/bl_update.c b/src/systemcmds/bl_update/bl_update.c index 5e62fa1c4e..1266c6e45a 100644 --- a/src/systemcmds/bl_update/bl_update.c +++ b/src/systemcmds/bl_update/bl_update.c @@ -38,6 +38,8 @@ */ #include +#include +#include #include #include @@ -50,7 +52,6 @@ #include #include "systemlib/systemlib.h" -#include "systemlib/err.h" #include @@ -58,58 +59,84 @@ __EXPORT int bl_update_main(int argc, char *argv[]); +static void print_usage(const char *reason) +{ + if (reason) { + PX4_ERR("%s", reason); + } + + PRINT_MODULE_DESCRIPTION("Utility to flash the bootloader from a file"); + + PRINT_MODULE_USAGE_NAME_SIMPLE("bl_update", "command"); + PRINT_MODULE_USAGE_COMMAND_DESCR("setopt", "Set option bits to unlock the FLASH (only needed if in locked state)"); + + PRINT_MODULE_USAGE_COMMAND_DESCR("", "Bootloader bin file"); +} + #if defined (CONFIG_STM32_STM32F40XX) -static void setopt(void); +static int setopt(void); #endif int bl_update_main(int argc, char *argv[]) { #if !defined (CONFIG_STM32_STM32F40XX) - errx(1, "Not supportedon this HW"); + PX4_ERR("Not supported on this HW"); + return 1; } #else if (argc != 2) { - errx(1, "missing firmware filename or command"); + print_usage("missing firmware filename or command"); + return 1; } if (!strcmp(argv[1], "setopt")) { - setopt(); + return setopt(); } int fd = open(argv[1], O_RDONLY); if (fd < 0) { - err(1, "open %s", argv[1]); + PX4_ERR("open %s failed", argv[1]); + return 1; } struct stat s; if (stat(argv[1], &s) != 0) { - err(1, "stat %s", argv[1]); + PX4_ERR("stat %s failed", argv[1]); + close(fd); + return 1; } /* sanity-check file size */ if (s.st_size > BL_FILE_SIZE_LIMIT) { - errx(1, "%s: file too large (limit: %u, actual: %d)", argv[1], BL_FILE_SIZE_LIMIT, s.st_size); + PX4_ERR("%s: file too large (limit: %u, actual: %d)", argv[1], BL_FILE_SIZE_LIMIT, s.st_size); + close(fd); + return 1; } uint8_t *buf = malloc(s.st_size); if (buf == NULL) { - errx(1, "failed to allocate %u bytes for firmware buffer", s.st_size); + PX4_ERR("failed to allocate %u bytes for firmware buffer", s.st_size); + close(fd); + return 1; } if (read(fd, buf, s.st_size) != s.st_size) { - err(1, "firmware read error"); + PX4_ERR("firmware read error"); + close(fd); + free(buf); + return 1; } close(fd); @@ -122,10 +149,11 @@ bl_update_main(int argc, char *argv[]) ((hdr[1] - PX4_FLASH_BASE) > BL_FILE_SIZE_LIMIT)) /* entrypoint not outside bootloader */ { free(buf); - errx(1, "not a bootloader image"); + PX4_ERR("not a bootloader image"); + return 1; } - warnx("image validated, erasing bootloader..."); + PX4_INFO("image validated, erasing bootloader..."); usleep(10000); /* prevent other tasks from running while we do this */ @@ -138,10 +166,10 @@ bl_update_main(int argc, char *argv[]) if (size != BL_FILE_SIZE_LIMIT) { - warnx("WARNING: erase error at 0x%08x", &base[size]); + PX4_ERR("erase error at 0x%08x", &base[size]); } - warnx("flashing..."); + PX4_INFO("flashing..."); /* now program the bootloader - speed is not critical so use x8 mode */ @@ -149,7 +177,7 @@ bl_update_main(int argc, char *argv[]) if (size != s.st_size) { - warnx("WARNING: program error at 0x%0x8", &base[size]); + PX4_ERR("program error at 0x%0x8", &base[size]); goto flash_end; } @@ -157,18 +185,18 @@ bl_update_main(int argc, char *argv[]) stm32_flash_lock(); - warnx("verifying..."); + PX4_INFO("verifying..."); /* now run a verify pass */ for (int i = 0; i < s.st_size; i++) { if (base[i] != buf[i]) { - warnx("WARNING: verify failed at %u - retry update, DO NOT reboot", i); + PX4_WARN("verify failed at %u - retry update, DO NOT reboot", i); goto flash_end; } } - warnx("bootloader update complete"); + PX4_INFO("bootloader update complete"); flash_end: /* unlock the scheduler */ @@ -178,7 +206,7 @@ flash_end: exit(0); } -static void +static int setopt(void) { volatile uint32_t *optcr = (volatile uint32_t *)0x40023c14; @@ -187,7 +215,8 @@ setopt(void) const uint16_t opt_bits = (0 << 2); /* BOR = 0, setting for 2.7-3.6V operation */ if ((*optcr & opt_mask) == opt_bits) { - errx(0, "option bits are already set as required"); + PX4_INFO("option bits are already set as required"); + return 0; } /* unlock the control register */ @@ -196,7 +225,8 @@ setopt(void) *optkeyr = 0x4c5d6e7fU; if (*optcr & 1) { - errx(1, "option control register unlock failed"); + PX4_ERR("option control register unlock failed"); + return 1; } /* program the new option value */ @@ -205,10 +235,11 @@ setopt(void) usleep(1000); if ((*optcr & opt_mask) == opt_bits) { - errx(0, "option bits set"); + PX4_INFO("option bits set"); + return 0; } - errx(1, "option bits setting failed; readback 0x%04x", *optcr); - + PX4_ERR("option bits setting failed; readback 0x%04x", *optcr); + return 1; } #endif // CONFIG_STM32_STM32F40XX