From 4337408e0413e61b74be90fe46f9b0336acc7215 Mon Sep 17 00:00:00 2001 From: rutgerhendriks <3134550+rutgerhendriks@users.noreply.github.com> Date: Wed, 27 May 2020 15:59:44 +0200 Subject: [PATCH 01/10] Create ccpp.yml --- .github/workflows/ccpp.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/ccpp.yml diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml new file mode 100644 index 000000000..23aa0bfc5 --- /dev/null +++ b/.github/workflows/ccpp.yml @@ -0,0 +1,17 @@ +name: C/C++ CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: make + run: make From c1ea72d842702160173504f4e5869b55b8e986d7 Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 10:48:51 +0200 Subject: [PATCH 02/10] Add support for writing option bytes to the Nucleo 144 STM32F767ZI. This adds --area=option_boot_add, --area=optcr and --area=optcr1 --- include/stlink.h | 14 +- include/stlink/tools/flash.h | 2 +- include/stm32.h | 1 + src/chipid.c | 14 +- src/common.c | 560 +++++++++++++++++++++++++++++++++-- src/flash_loader.c | 20 +- src/tools/flash.c | 131 +++++--- src/tools/flash_opts.c | 110 +++++-- src/usb.c | 1 + 9 files changed, 750 insertions(+), 103 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index c87c6b173..c96cf2ef9 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -120,7 +120,8 @@ enum stlink_flash_type { STLINK_FLASH_TYPE_UNKNOWN = 0, STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank, apparently */ - STLINK_FLASH_TYPE_F4, // used by f2, f4, f7 */ + STLINK_FLASH_TYPE_F4, // used by f2, f4 */ + STLINK_FLASH_TYPE_F7, STLINK_FLASH_TYPE_L0, // l0, l1 */ STLINK_FLASH_TYPE_L4, // l4, l4+ */ STLINK_FLASH_TYPE_G0, @@ -146,8 +147,8 @@ struct stlink_reg { typedef uint32_t stm32_addr_t; typedef struct flash_loader { -stm32_addr_t loader_addr; // loader sram addr -stm32_addr_t buf_addr; // buffer sram address + stm32_addr_t loader_addr; // loader sram addr + stm32_addr_t buf_addr; // buffer sram address } flash_loader_t; typedef struct _cortex_m3_cpuid_ { @@ -288,7 +289,14 @@ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr int stlink_load_device_params(stlink_t *sl); int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte); + int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); +int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); +int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control_register); +int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_control_register1); int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index a912a14aa..e5b4d2572 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -11,7 +11,7 @@ enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; -enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1,FLASH_OTP = 2, FLASH_OPTION_BYTES = 3}; +enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3, FLASH_OPTION_BYTES_BOOT_ADD = 4, FLASH_OPTCR = 5, FLASH_OPTCR1 = 6}; struct flash_opts { enum flash_cmd cmd; diff --git a/include/stm32.h b/include/stm32.h index c71718653..be5bb5bc7 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -20,5 +20,6 @@ #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) #endif /* STM32_H */ diff --git a/src/chipid.c b/src/chipid.c index fcc1c55eb..abddb7dc5 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -6,12 +6,14 @@ static const struct stlink_chipid_params devices[] = { //RM0410 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7XXXX, .description = "F76xxx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, //! "System memory" starting address from - .bootrom_size = 0xEDC0 //! @todo "System memory" byte size in hex from + .flash_type = STLINK_FLASH_TYPE_F7, + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, //! "System memory" starting address from + .bootrom_size = 0xEDC0, //! @todo "System memory" byte size in hex from + .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 + .option_size = 0x20 }, { //RM0385 and DS10916 document was used to find these paramaters diff --git a/src/common.c b/src/common.c index e8f7cebc6..0c3b0fe69 100644 --- a/src/common.c +++ b/src/common.c @@ -236,6 +236,33 @@ #define FLASH_OBR_OFF ((uint32_t) 0x1c) #define FLASH_WRPR_OFF ((uint32_t) 0x20) +//STM32F7 +#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) +#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) +#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) +#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) +#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) +#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) +#define FLASH_F7_OPTCR_LOCK 0 +#define FLASH_F7_OPTCR_START 1 +#define FLASH_F7_CR_STRT 16 +#define FLASH_F7_CR_LOCK 31 +#define FLASH_F7_CR_SER 1 +#define FLASH_F7_CR_SNB 3 +#define FLASH_F7_CR_SNB_MASK 0xf8 +#define FLASH_F7_SR_BSY 16 +#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ +#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ +#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ +#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_OPTCR1_BOOT_ADD0 0 +#define FLASH_F7_OPTCR1_BOOT_ADD1 16 + +#define FLASH_F7_SR_ERROR_MASK ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | (1 << FLASH_F7_SR_OP_ERR)) + //STM32F4 #define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) @@ -337,6 +364,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) reg = FLASH_F4_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_F7) + reg = FLASH_F7_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -377,6 +406,9 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; @@ -414,6 +446,8 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { key_reg = FLASH_F4_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + key_reg = FLASH_F7_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; flash_key1 = FLASH_L0_PEKEY1; @@ -462,6 +496,9 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; @@ -506,6 +543,10 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; case STLINK_FLASH_TYPE_L0: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -551,6 +592,10 @@ static int lock_flash_option(stlink_t *sl) { optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; case STLINK_FLASH_TYPE_L0: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -599,6 +644,9 @@ static int unlock_flash_option(stlink_t *sl) case STLINK_FLASH_TYPE_F4: optkey_reg = FLASH_F4_OPT_KEYR; break; + case STLINK_FLASH_TYPE_F7: + optkey_reg = FLASH_F7_OPT_KEYR; + break; case STLINK_FLASH_TYPE_L0: optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; optkey1 = FLASH_L0_OPTKEY1; @@ -649,6 +697,9 @@ static void set_flash_cr_pg(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + x |= 1 << FLASH_CR_PG; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; @@ -673,6 +724,8 @@ static void clear_flash_cr_pg(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) cr_reg = FLASH_F4_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_F7) + cr_reg = FLASH_F7_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_reg = STM32L4_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -730,6 +783,10 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); @@ -786,6 +843,9 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); @@ -805,6 +865,9 @@ static void set_flash_cr_strt(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_strt = 1 << FLASH_F7_CR_STRT; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = 1 << STM32L4_FLASH_CR_STRT; @@ -842,6 +905,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -873,6 +938,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_busy_shift = FLASH_F4_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_busy_shift = FLASH_F7_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_busy_shift = STM32L4_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -919,17 +986,20 @@ static int check_flash_error(stlink_t *sl) { uint32_t res = 0; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; - break; - case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; - default: - break; + case STLINK_FLASH_TYPE_F0: + res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_F7: + res = read_flash_sr(sl) & FLASH_F7_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; + default: + break; } if (res) { @@ -1311,13 +1381,13 @@ int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ret = sl->backend->read_debug32(sl, addr, data); if (!ret) - DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); + DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); return ret; } int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { - DLOG("*** stlink_write_debug32 %x to %#x\n", data, addr); + DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); return sl->backend->write_debug32(sl, addr, data); } @@ -1522,9 +1592,11 @@ void stlink_print_data(stlink_t * sl) { fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); */ } - DLOG(" %02x", (unsigned int) sl->q_buf[i]); + //DLOG(" %02x", (unsigned int) sl->q_buf[i]); + fprintf(stderr, " %02x", (unsigned int) sl->q_buf[i]); } - DLOG("\n\n"); + //DLOG("\n\n"); + fprintf(stderr, "\n"); } /* memory mapped file */ @@ -1913,7 +1985,7 @@ static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size) { /* read size bytes from addr to file */ - + ILOG("read from address %#010x size %d\n", addr, size); int error; int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); @@ -2044,6 +2116,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STLINK_FLASH_TYPE_F4 || + sl->flash_type == STLINK_FLASH_TYPE_F7 || sl->flash_type == STLINK_FLASH_TYPE_L4) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -2487,10 +2560,12 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (eraseonly) return 0; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { /* todo: check write operation */ - ILOG("Starting Flash write for F2/F4/L4\n"); + ILOG("Starting Flash write for F2/F4/F7/L4\n"); /* flash loader initialization */ if (stlink_flash_loader_init(sl, &fl) == -1) { ELOG("stlink_flash_loader_init() == -1\n"); @@ -3117,13 +3192,62 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ return ret; } +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + + //(void) addr; + //(void) len; + + ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t*) (base), addr); + write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); + ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + if ( addr == 0 ) { + addr = FLASH_F7_OPTCR; + ILOG("No address provided, using %#10x\n", addr); + } + + if ( addr == FLASH_F7_OPTCR ) { + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + } else if ( addr == FLASH_F7_OPTCR1 ) { + // Read FLASH_F7_OPTCR + uint32_t oldvalue; + stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); + // Write FLASH_F7_OPTCR lock and start address + stlink_write_debug32(sl, FLASH_F7_OPTCR, (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + } else { + WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); + stlink_write_debug32(sl, addr, option_byte); + } + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t*) base, addr); + + /* option bytes are reloaded at reset only, no obl. */ + + return ret; +} + /** * Read option bytes * @param sl * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { +int stlink_read_option_control_register_Gx(stlink_t *sl, uint32_t* option_byte) { return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); } @@ -3133,19 +3257,106 @@ int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_option_control_register_Gx(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t* option_byte) { return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_option_control_register_f2(sl, option_byte); +} + /** * Read option bytes * @param sl * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { +int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t* option_byte) { return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); } + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_option_control_register_f4(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); + return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option control register 1 byte from %#10x\n", FLASH_F7_OPTCR1); + return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option byte boot address\n"); + return stlink_read_option_control_register1_f7(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + * + * Since multiple bytes can be read, we read and print all but one here + * and then return the last one just like other devices + */ +int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { + int err = -1; + for (uint8_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), option_byte); + if (err == -1) { + return err; + } else { + printf("%08x\n", *option_byte); + } + } + + return stlink_read_debug32(sl, sl->option_base + (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); +} + /** * Read first option bytes * @param sl @@ -3153,9 +3364,43 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); return stlink_read_debug32(sl, sl->option_base, option_byte); } +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +//int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* option_byte) { +// DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); +// return stlink_read_debug32(sl, sl->option_base, option_byte); +//} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +//int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* option_byte) { +// DLOG("@@@@ Read option control register byte from %#10x\n", sl->option_base); +// return stlink_read_debug32(sl, sl->option_base, option_byte); +//} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +//int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* option_byte) { +// DLOG("@@@@ Read option control register 1 byte from %#10x\n", sl->option_base); +// return stlink_read_debug32(sl, sl->option_base, option_byte); +//} + /** * Read option bytes * @param sl @@ -3174,6 +3419,8 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) return stlink_read_option_bytes_f2(sl, option_byte); case STLINK_CHIPID_STM32_F446: return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_f7(sl, option_byte); case STLINK_CHIPID_STM32_G0_CAT1: case STLINK_CHIPID_STM32_G0_CAT2: case STLINK_CHIPID_STM32_G4_CAT2: @@ -3184,6 +3431,72 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) } } +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes boot address read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_boot_add_f7(sl, option_byte); + default: + return -1; + //return stlink_read_option_bytes_boot_add_generic(sl, option_byte); + } +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register_f7(sl, option_byte); + default: + return -1; + //return stlink_read_option_control_register_generic(sl, option_byte); + } +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register1_f7(sl, option_byte); + default: + return -1; + //return stlink_read_option_control_register1_generic(sl, option_byte); + } +} + /** * Write option bytes * @param sl @@ -3192,7 +3505,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) */ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { - WLOG("About to write option byte %#10x to target.\n", option_byte); + WLOG("About to write option byte %#10x to %#10x.\n", option_byte, sl->option_base); return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); } @@ -3212,6 +3525,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return -1; } + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { ELOG("Option bytes start address out of Option bytes range\n"); return -1; @@ -3238,6 +3552,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui case STLINK_FLASH_TYPE_F4: ret = stlink_write_option_bytes_f4(sl, base, addr, len); break; + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_f7(sl, base, addr, len); + break; case STLINK_FLASH_TYPE_L0: ret = stlink_write_option_bytes_l0(sl, base, addr, len); break; @@ -3255,8 +3572,203 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui if (ret) ELOG("Flash option write failed!\n"); - else - ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + else + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_control_register) { + int ret = 0; + + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", option_control_register, FLASH_F7_OPTCR); + //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); + //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR1); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_control_register1) { + int ret = 0; + + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", option_control_register1, FLASH_F7_OPTCR1); + //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); + //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + uint32_t current_control_register_value; + stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); + stlink_write_debug32(sl, FLASH_F7_OPTCR, (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, FLASH_F7_OPTCR1); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add) { + ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); + return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add) +{ + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + break; + default: + ELOG("Option bytes boot address writing is currently not implemented for connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control_register) +{ + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_control_register_f7(sl, option_control_register); + break; + default: + ELOG("Option control register writing is currently not implemented for connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register %#010x!\n", option_control_register); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_control_register1) +{ + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_control_register1_f7(sl, option_control_register1); + break; + default: + ELOG("Option control register 1 writing is currently not implemented for connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); /* Re-lock flash. */ lock_flash_option(sl); diff --git a/src/flash_loader.c b/src/flash_loader.c index a2c5879ce..b6058cd0e 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -176,19 +176,19 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { - size_t size = 0; + size_t size = 0; - /* allocate the loader in sram */ - if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { - WLOG("Failed to write flash loader to sram!\n"); - return -1; - } + /* allocate the loader in sram */ + if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { + WLOG("Failed to write flash loader to sram!\n"); + return -1; + } - /* allocate a one page buffer in sram right after loader */ - fl->buf_addr = fl->loader_addr + (uint32_t) size; - ILOG("Successfully loaded flash loader in sram\n"); + /* allocate a one page buffer in sram right after loader */ + fl->buf_addr = fl->loader_addr + (uint32_t) size; + ILOG("Successfully loaded flash loader in sram\n"); - return 0; + return 0; } static int loader_v_dependent_assignment(stlink_t *sl, diff --git a/src/tools/flash.c b/src/tools/flash.c index 3a83daf8a..9c4e20dff 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -28,15 +28,23 @@ static void cleanup(int signum) { static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] {read|write} [addr] [size]"); + puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); + puts(" : Can be 'main' (default), 'system', 'otp', 'optcr', 'optcr1', 'option' or 'option_boot_add'"); puts("print tool version info: ./st-flash [--version]"); - puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX"); - puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); + puts("example read option byte: ./st-flash --area=option read [path] [size]"); + puts("example write option byte: ./st-flash --area=option write 0xXXXXXXXX"); + puts("On selected targets:"); + puts("example read boot_add option byte: ./st-flash --area=option_boot_add read"); + puts("example write boot_add option byte: ./st-flash --area=option_boot_add write 0xXXXXXXXX"); + puts("example read option control register byte: ./st-flash --area=optcr read"); + puts("example write option control register1 byte: ./st-flash --area=optcr write 0xXXXXXXXX"); + puts("example read option control register1 byte: ./st-flash --area=optcr1 read"); + puts("example write option control register1 byte: ./st-flash --area=optcr1 write 0xXXXXXXXX"); } int main(int ac, char** av) @@ -54,7 +62,7 @@ int main(int ac, char** av) return -1; } - printf("st-flash %s\n", STLINK_VERSION); + ILOG("st-flash %s\n", STLINK_VERSION); sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); @@ -62,7 +70,7 @@ int main(int ac, char** av) return -1; } - if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + if (STLINK_FLASH_TYPE_UNKNOWN == sl->flash_type) { printf("Failed to connect to target\n"); return -1; } @@ -80,14 +88,14 @@ int main(int ac, char** av) signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + if (STLINK_DEV_DFU_MODE == stlink_current_mode(sl)) { if (stlink_exit_dfu_mode(sl)) { printf("Failed to exit DFU mode\n"); goto on_error; } } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + if (STLINK_DEV_DEBUG_MODE != stlink_current_mode(sl)) { if (stlink_enter_swd_mode(sl)) { printf("Failed to enter SWD mode\n"); goto on_error; @@ -109,7 +117,7 @@ int main(int ac, char** av) } // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STLINK_CHIPID_STM32_F4) + if (STLINK_CHIPID_STM32_F4 == sl->chip_id) { memset(sl->q_buf,0,4); for (int i=0;i<8;i++) { @@ -131,19 +139,20 @@ int main(int ac, char** av) goto on_error; } - if (o.cmd == FLASH_CMD_WRITE) /* write */ + if (FLASH_CMD_WRITE == o.cmd) // write { size_t size = 0; - if (o.format == FLASH_FORMAT_IHEX) { + if (FLASH_FORMAT_IHEX == o.format) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { printf("Cannot parse %s as Intel-HEX file\n", o.filename); goto on_error; } } + if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if (o.format == FLASH_FORMAT_IHEX) + if (FLASH_FORMAT_IHEX == o.format) err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -155,7 +164,7 @@ int main(int ac, char** av) } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if (o.format == FLASH_FORMAT_IHEX) + if (FLASH_FORMAT_IHEX == o.format) err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_sram(sl, o.filename, o.addr); @@ -174,25 +183,39 @@ int main(int ac, char** av) goto on_error; } } - else if (o.area == FLASH_OPTION_BYTES){ + else if (FLASH_OPTION_BYTES == o.area) { if (o.val == 0) { printf("attempting to set option byte to 0, abort.\n"); goto on_error; - } + } err = stlink_write_option_bytes32(sl, o.val); - if (err == -1) - { + if (err == -1) { printf("stlink_write_option_bytes32() == -1\n"); goto on_error; } } - else { + else if (FLASH_OPTCR == o.area) { + DLOG("@@@@ Write %d (%0#10x) to option control register\n", o.val, o.val); + + err = stlink_write_option_control_register32(sl, o.val); + } + else if (FLASH_OPTCR1 == o.area) { + DLOG("@@@@ Write %d (%0#10x) to option control register 1\n", o.val, o.val); + + err = stlink_write_option_control_register1_32(sl, o.val); + } + else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + DLOG("@@@@ Write %d (%0#10x) to option bytes boot address\n", o.val, o.val); + + err = stlink_write_option_bytes_boot_add32(sl, o.val); + } + else { err = -1; printf("Unknown memory region\n"); goto on_error; } - } else if (o.cmd == FLASH_CMD_ERASE) + } else if (FLASH_CMD_ERASE == o.cmd) { err = stlink_erase_flash_mass(sl); if (err == -1) @@ -200,7 +223,7 @@ int main(int ac, char** av) printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } - } else if (o.cmd == CMD_RESET) + } else if (CMD_RESET == o.cmd) { if (sl->version.stlink_v > 1) { if (stlink_jtag_reset(sl, 2)) { @@ -216,35 +239,69 @@ int main(int ac, char** av) } else /* read */ { - if(o.area == FLASH_OPTION_BYTES){ - uint32_t option_byte; - err = stlink_read_option_bytes32(sl, &option_byte); - if (err == -1) { - printf("could not read option bytes (%d)\n", err); - goto on_error; - } else { - printf("%x\n",option_byte); - } - }else{ - if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)){ + if ((FLASH_MAIN_MEMORY == o.area) || (FLASH_SYSTEM_MEMORY == o.area)) { + if ((o.size == 0) && (o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { o.size = sl->flash_size; } - else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)){ + else if ((o.size == 0) && (o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { o.size = sl->sram_size; } - err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, o.addr, o.size); - if (err == -1) - { + if (err == -1) { printf("stlink_fread() == -1\n"); goto on_error; } + } else if (FLASH_OPTION_BYTES == o.area) { + uint8_t remaining_option_length = sl->option_size / 4; + DLOG("@@@@ Read %d (%#x) option bytes from %#10x\n", remaining_option_length, remaining_option_length, sl->option_base); + + if (NULL != o.filename) { + if (0 == o.size) { + o.size = sl->option_size; + } + err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, sl->option_base, o.size); + } else { + uint32_t option_byte = 0; + err = stlink_read_option_bytes32(sl, &option_byte); + if (err == -1) { + printf("could not read option bytes (%d)\n", err); + goto on_error; + } else { + printf("%08x\n", option_byte); + } + } + } else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + uint32_t option_byte = 0; + err = stlink_read_option_bytes_boot_add32(sl, &option_byte); + if (err == -1) { + printf("could not read option bytes boot address (%d)\n", err); + goto on_error; + } else { + printf("%08x\n",option_byte); + } + } else if (FLASH_OPTCR == o.area) { + uint32_t option_byte = 0; + err = stlink_read_option_control_register32(sl, &option_byte); + if (err == -1) { + printf("could not read option control register (%d)\n", err); + goto on_error; + } else { + printf("%08x\n",option_byte); + } + } else if (FLASH_OPTCR1 == o.area) { + uint32_t option_byte = 0; + err = stlink_read_option_control_register1_32(sl, &option_byte); + if (err == -1) { + printf("could not read option control register (%d)\n", err); + goto on_error; + } else { + printf("%08x\n",option_byte); + } } } - if (o.reset){ + if (o.reset) { if (sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); stlink_reset(sl); } diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index a5c9d287f..8557445e0 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -145,6 +145,12 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->area = FLASH_OTP; else if (strcmp(area, "option") == 0) o->area = FLASH_OPTION_BYTES; + else if (strcmp(area, "option_boot_add") == 0) + o->area = FLASH_OPTION_BYTES_BOOT_ADD; + else if (strcmp(area, "optcr") == 0) + o->area = FLASH_OPTCR; + else if (strcmp(area, "optcr1") == 0) + o->area = FLASH_OPTCR1; else return -1; @@ -236,19 +242,19 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_ERASE; } else if (strcmp(av[0], "read") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_READ; } else if (strcmp(av[0], "write") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_WRITE; } else if (strcmp(av[0], "reset") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = CMD_RESET; } else { @@ -268,33 +274,93 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { break; case FLASH_CMD_READ: // expect filename, addr and size - if ((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; - if (ac != 3) return invalid_args("read "); - if (ac != 3) return -1; - o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) address; + if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if (ac != 3) return invalid_args("read "); + o->filename = av[0]; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) address; - uint32_t size; - result = get_integer_from_char_array(av[2], &size); - if (result != 0) return bad_arg ("size"); - else o->size = (size_t) size; + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) return bad_arg ("size"); + else o->size = (size_t) size; + break; + } + else if ((FLASH_OTP == o->area)) { + return bad_arg("TODO: otp not implemented yet"); + if (ac > 1) return invalid_args("otp read: [path]"); + if (ac > 0) o->filename = av[0]; + break; + } + else if ((FLASH_OPTION_BYTES == o->area)) { + if (ac > 2) return invalid_args("option bytes read: [path] [size]"); + if (ac > 0) o->filename = av[0]; + if (ac > 1) { + uint32_t size; + result = get_integer_from_char_array(av[1], &size); + if (result != 0) return bad_arg("option bytes read: invalid size"); + else o->size = (size_t) size; + } + break; + } + else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + if (ac > 0) return invalid_args("option bytes boot_add read"); + break; + } + else if ((FLASH_OPTCR == o->area)) { + if (ac > 0) return invalid_args("option control register read"); + break; + } + else if ((FLASH_OPTCR1 == o->area)) { + if (ac > 0) return invalid_args("option control register 1 read"); + break; + } break; case FLASH_CMD_WRITE: - if (o->area == FLASH_OPTION_BYTES){ - if (ac != 1) return -1; - + // TODO: should be boot add 0 and boot add 1 uint32 + if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (ac >=1 && ac <= 2) { + o->filename = av[0]; + } + else + return invalid_args("write [addr]"); + + if (ac == 2) { + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) addr; + } + } + else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + if (ac != 1) return invalid_args("option bytes boot_add write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR == o->area) { // expect option control register value + if (ac != 1) return invalid_args("option control register write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + if (ac != 1) return invalid_args("option control register 1 write "); + uint32_t val; result = get_integer_from_char_array(av[0], &val); if (result != 0) return bad_arg ("val"); else o->val = (uint32_t) val; - } - else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr + else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr if (ac != 2) return invalid_args("write "); o->filename = av[0]; uint32_t addr; @@ -302,7 +368,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (result != 0) return bad_arg ("addr"); else o->addr = (stm32_addr_t) addr; } - else if (o->format == FLASH_FORMAT_IHEX) { // expect filename + else if (FLASH_FORMAT_IHEX == o->format) { // expect filename if (ac != 1) return invalid_args("write "); o->filename = av[0]; } diff --git a/src/usb.c b/src/usb.c index b986aed57..b492afed7 100644 --- a/src/usb.c +++ b/src/usb.c @@ -655,6 +655,7 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_READMEM_32BIT; + DLOG("using address %#010x\n", addr); write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); From 972ecf8d960919d0c9433c73b809ddcc701f847b Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 12:40:15 +0200 Subject: [PATCH 03/10] Continue merging upstream --- src/common.c | 3 +- src/st-flash/flash.c | 5 +- src/st-flash/flash_opts.c | 417 ++++++++++++++++------------- src/stlink-lib/chipid.c | 2 +- src/stlink-lib/flash_loader.c | 486 +++++++++++++++++----------------- 5 files changed, 481 insertions(+), 432 deletions(-) diff --git a/src/common.c b/src/common.c index 1703dee76..58e67d447 100644 --- a/src/common.c +++ b/src/common.c @@ -3637,8 +3637,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui if (ret) { ELOG("Flash option write failed!\n"); - else + } else { ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } /* Re-lock flash. */ lock_flash_option(sl); diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 6d70fc5e6..128b8acc0 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -140,7 +140,6 @@ int main(int ac, char** av) { { size_t size = 0; if (FLASH_FORMAT_IHEX == o.format) { - if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { @@ -150,7 +149,7 @@ int main(int ac, char** av) { } if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if (FLASH_FORMAT_IHEX == o.format) + if (FLASH_FORMAT_IHEX == o.format) { err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -162,7 +161,7 @@ int main(int ac, char** av) { } } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if (FLASH_FORMAT_IHEX == o.format) + if (FLASH_FORMAT_IHEX == o.format) { err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_sram(sl, o.filename, o.addr); diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 6d1940675..8557445e0 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -2,12 +2,11 @@ #include #include -#include "flash.h" +#include static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); - - if (strlen(str) < n) { return(false); } + if (strlen(str) < n) return false; return (0 == strncmp(str, prefix, n)); } @@ -20,28 +19,37 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re uint64_t value; char *tail; - if (starts_with (str, "0x") || starts_with (str, "0X")) { // hexadecimal + // hexadecimal + if (starts_with (str, "0x") || starts_with (str, "0X")) { value = strtoul (str + 2, &tail, 16); - } else if (starts_with (str, "0b") || starts_with (str, "0B")) { // binary + } + // binary + else if (starts_with (str, "0b") || starts_with (str, "0B")) { value = strtoul (str + 2, &tail, 2); - } else if (starts_with (str, "0")) { // octal + } + // octal + else if (starts_with (str, "0")) { value = strtoul (str + 1, &tail, 8); - } else { // decimal + } + // decimal + else { value = strtoul (str, &tail, 10); } if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { value = value * 1024; - } else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { + } + else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { value = value * 1024 * 1024; - } else if (tail[0] == '\0') { - /* value not changed */ - } else { - return(-1); } - + else if (tail[0] == '\0') { + // value not change + } + else { + return -1; + } *read_value = value; - return(0); + return 0; } // support positive integer from 0 to UINT32_MAX @@ -51,26 +59,28 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { uint64_t value; int result = get_long_integer_from_char_array (str, &value); - if (result != 0) { - return(result); - } else if (value > UINT32_MAX) { - fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); - return(-1); - } else { + return result; + } + else if (value > UINT32_MAX) { + fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, \ +cannot convert to int32_t\n"); + return -1; + } + else { *read_value = (uint32_t)value; - return(0); + return 0; } } static int invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); - return(-1); + return -1; } static int bad_arg(const char *arg) { fprintf(stderr, "*** Error: Invalid value for %s\n", arg); - return(-1); + return -1; } int flash_get_opts(struct flash_opts* o, int ac, char** av) { @@ -81,177 +91,173 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // options int result; - while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); - } else if (strcmp(av[0], "--debug") == 0) { + } + else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; - } else if (strcmp(av[0], "--opt") == 0) { + } + else if (strcmp(av[0], "--opt") == 0) { o->opt = ENABLE_OPT; - } else if (strcmp(av[0], "--reset") == 0) { + } + else if (strcmp(av[0], "--reset") == 0) { o->reset = 1; - } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { + } + else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { const char * serial; - if (strcmp(av[0], "--serial") == 0) { ac--; av++; - - if (ac < 1) { return(-1); } - + if (ac < 1) return -1; serial = av[0]; - } else { + } + else { serial = av[0] + strlen("--serial="); } - - /** @todo This is not really portable, as strlen really returns size_t we need to obey - and not cast it to a signed type. */ + /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array - - if (j % 2 != 0) { return(-1); } - + int length = j / 2; // the length of the destination-array + if (j % 2 != 0) return -1; for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { + } + else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; - if (strcmp(av[0], "--area") == 0) { ac--; av++; - - if (ac < 1) { return(-1); } - + if (ac < 1) return -1; area = av[0]; - } else { + } + else { area = av[0] + strlen("--area="); } - - if (strcmp(area, "main") == 0) { + if (strcmp(area, "main") == 0) o->area = FLASH_MAIN_MEMORY; - } else if (strcmp(area, "system") == 0) { + else if (strcmp(area, "system") == 0) o->area = FLASH_SYSTEM_MEMORY; - } else if (strcmp(area, "otp") == 0) { + else if (strcmp(area, "otp") == 0) o->area = FLASH_OTP; - } else if (strcmp(area, "option") == 0) { + else if (strcmp(area, "option") == 0) o->area = FLASH_OPTION_BYTES; - } else { - return(-1); - } + else if (strcmp(area, "option_boot_add") == 0) + o->area = FLASH_OPTION_BYTES_BOOT_ADD; + else if (strcmp(area, "optcr") == 0) + o->area = FLASH_OPTCR; + else if (strcmp(area, "optcr1") == 0) + o->area = FLASH_OPTCR1; + else + return -1; - } else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + } + else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { const char* freq; - if (strcmp(av[0], "--freq") == 0) { ac--; av++; - - if (ac < 1) { - return(-1); - } - + if (ac < 1) return -1; freq = av[0]; - } else { + } + else { freq = av[0] + strlen("--freq="); } - if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { o->freq = 5; - } else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + } + else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { o->freq = 15; - } else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + } + else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { o->freq = 25; - } else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + } + else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { o->freq = 50; - } else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + } + else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { o->freq = 100; - } else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + } + else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { o->freq = 125; - } else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + } + else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { o->freq = 240; - } else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + } + else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { o->freq = 480; - } else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + } + else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { o->freq = 950; - } else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || - strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + } + else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { o->freq = 1200; - } else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || - strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + } + else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { o->freq = 1800; - } else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || - strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + } + else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { o->freq = 4000; - } else { - return(-1); } - } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { + else + return -1; + } + else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; - if (strcmp(av[0], "--format") == 0) { ac--; av++; - - if (ac < 1) { return(-1); } - + if (ac < 1) return -1; format = av[0]; - } else { + } + else { format = av[0] + strlen("--format="); } - - if (strcmp(format, "binary") == 0) { + if (strcmp(format, "binary") == 0) o->format = FLASH_FORMAT_BINARY; - } else if (strcmp(format, "ihex") == 0) { + else if (strcmp(format, "ihex") == 0) o->format = FLASH_FORMAT_IHEX; - } else { - return(bad_arg("format")); - } - } else if ( starts_with(av[0], "--flash=")) { + else + return bad_arg("format"); + } + else if ( starts_with(av[0], "--flash=") ) { const char *arg = av[0] + strlen("--flash="); uint32_t flash_size; result = get_integer_from_char_array(arg, &flash_size); - - if (result != 0) { - return(bad_arg ("--flash")); - } else { - o->flash_size = (size_t)flash_size; - } - } else if (strcmp(av[0], "--connect-under-reset") == 0) { - o->connect_under_reset = true; - } else { - break; // non-option found - + if (result != 0) return bad_arg ("--flash"); + else o->flash_size = (size_t) flash_size; + } + else { + break; // non-option found } ac--; av++; } - /* command and (optional) device name */ + // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_ERASE; - } else if (strcmp(av[0], "read") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + } + else if (strcmp(av[0], "read") == 0) { + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_READ; - } else if (strcmp(av[0], "write") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + } + else if (strcmp(av[0], "write") == 0) { + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_WRITE; - } else if (strcmp(av[0], "reset") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + } + else if (strcmp(av[0], "reset") == 0) { + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = CMD_RESET; - } else { + } + else { break; } @@ -259,83 +265,120 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { av++; } - switch (o->cmd) { - case FLASH_CMD_NONE: // no command found - return(-1); - - case FLASH_CMD_ERASE: // no more arguments expected - - if (ac != 0) { return(-1); } - - break; - - case FLASH_CMD_READ: // expect filename, addr and size - - if ((o->area == FLASH_OPTION_BYTES) && (ac == 0)) { break; } - - if (ac != 3) { return(invalid_args("read ")); } - - if (ac != 3) { return(-1); } - - o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - - if (result != 0) { - return(bad_arg ("addr")); - } else { - o->addr = (stm32_addr_t)address; - } - - uint32_t size; - result = get_integer_from_char_array(av[2], &size); - - if (result != 0) { - return(bad_arg ("size")); - } else { - o->size = (size_t)size; - } - - break; - - case FLASH_CMD_WRITE: - - if (o->area == FLASH_OPTION_BYTES) { - if (ac != 1) { return(-1); } + switch(o->cmd) { + case FLASH_CMD_NONE: // no command found + return -1; - uint32_t val; - result = get_integer_from_char_array(av[0], &val); + case FLASH_CMD_ERASE: // no more arguments expected + if (ac != 0) return -1; + break; - if (result != 0) { - return(bad_arg ("val")); - } else { - o->val = (uint32_t)val; + case FLASH_CMD_READ: // expect filename, addr and size + if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if (ac != 3) return invalid_args("read "); + o->filename = av[0]; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) address; + + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) return bad_arg ("size"); + else o->size = (size_t) size; + + break; } - - } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr - if (ac != 2) { return(invalid_args("write ")); } - - o->filename = av[0]; - uint32_t addr; - result = get_integer_from_char_array(av[1], &addr); - - if (result != 0) { - return(bad_arg ("addr")); - } else { - o->addr = (stm32_addr_t)addr; + else if ((FLASH_OTP == o->area)) { + return bad_arg("TODO: otp not implemented yet"); + if (ac > 1) return invalid_args("otp read: [path]"); + if (ac > 0) o->filename = av[0]; + break; } - } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename - if (ac != 1) { return(invalid_args("write ")); } - - o->filename = av[0]; - } else { - return(-1); // should have been caught during format parsing - } + else if ((FLASH_OPTION_BYTES == o->area)) { + if (ac > 2) return invalid_args("option bytes read: [path] [size]"); + if (ac > 0) o->filename = av[0]; + if (ac > 1) { + uint32_t size; + result = get_integer_from_char_array(av[1], &size); + if (result != 0) return bad_arg("option bytes read: invalid size"); + else o->size = (size_t) size; + } + break; + } + else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + if (ac > 0) return invalid_args("option bytes boot_add read"); + break; + } + else if ((FLASH_OPTCR == o->area)) { + if (ac > 0) return invalid_args("option control register read"); + break; + } + else if ((FLASH_OPTCR1 == o->area)) { + if (ac > 0) return invalid_args("option control register 1 read"); + break; + } + break; - break; + case FLASH_CMD_WRITE: + // TODO: should be boot add 0 and boot add 1 uint32 + if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (ac >=1 && ac <= 2) { + o->filename = av[0]; + } + else + return invalid_args("write [addr]"); + + if (ac == 2) { + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) addr; + } + } + else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + if (ac != 1) return invalid_args("option bytes boot_add write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR == o->area) { // expect option control register value + if (ac != 1) return invalid_args("option control register write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + if (ac != 1) return invalid_args("option control register 1 write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr + if (ac != 2) return invalid_args("write "); + o->filename = av[0]; + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) addr; + } + else if (FLASH_FORMAT_IHEX == o->format) { // expect filename + if (ac != 1) return invalid_args("write "); + o->filename = av[0]; + } + else { + return -1; // should have been caught during format parsing + } + break; - default: break; + default: break ; } - return(0); + return 0; } diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 147b0e74e..3763587e1 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -11,7 +11,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // No flash pages .sram_size = 0x80000, // "SRAM" byte size in hex from .bootrom_base = 0x00200000, // ! "System memory" starting address from - .bootrom_size = 0xEDC0 // ! @todo "System memory" byte size in hex from + .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 .option_size = 0x20 }, diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0e79c3c0a..b6058cd0e 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -3,210 +3,213 @@ #include #include -#include "flash_loader.h" #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 /* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ -/* flashloaders/stm32f0.s -- compiled with thumb2 */ -static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, - 0x58, 0x00, 0x00, 0x20 -}; - -/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ -static const uint8_t loader_code_stm32f0[] = { - 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32l[] = { - // flashloaders/stm32lx.s - - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, -}; - -static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s - - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32f4_lv[] = { - // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32l4[] = { - // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, - 0x4c, 0x60, 0x00, 0xf1, - 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x12, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32f7[] = { - // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32f7_lv[] = { - // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - - -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { + /* flashloaders/stm32f0.s -- compiled with thumb2 */ + static const uint8_t loader_code_stm32vl[] = { + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd1, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, + 0x58, 0x00, 0x00, 0x20 + }; + + /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ + static const uint8_t loader_code_stm32f0[] = { + 0xc0, 0x46, 0xc0, 0x46, + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd1, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32l[] = { + // flashloaders/stm32lx.s + + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xf4, 0xd1, 0x00, 0xbe, + }; + + static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32f4_lv[] = { + // flashloaders/stm32f4lv.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32l4[] = { + // flashloaders/stm32l4.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x12, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32f7[] = { + // flashloaders/stm32f7.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32f7_lv[] = { + // flashloaders/stm32f7lv.s + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) +{ size_t size = 0; - // allocate the loader in SRAM + /* allocate the loader in sram */ if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { WLOG("Failed to write flash loader to sram!\n"); - return(-1); + return -1; } - // allocate a one page buffer in SRAM right after loader - fl->buf_addr = fl->loader_addr + (uint32_t)size; + /* allocate a one page buffer in sram right after loader */ + fl->buf_addr = fl->loader_addr + (uint32_t) size; ILOG("Successfully loaded flash loader in sram\n"); - return(0); + return 0; } static int loader_v_dependent_assignment(stlink_t *sl, const uint8_t **loader_code, size_t *loader_size, const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size) { + const uint8_t *low_v_loader, size_t low_v_loader_size) +{ int retval = 0; - if ( sl->version.stlink_v == 1) { + if ( sl->version.stlink_v == 1){ printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; - } else { + } + else { int voltage = stlink_target_voltage(sl); - if (voltage == -1) { retval = -1; printf("Failed to read Target voltage\n"); - } else { + } + else { if (voltage > 2700) { *loader_code = high_v_loader; *loader_size = high_v_loader_size; @@ -216,11 +219,11 @@ static int loader_v_dependent_assignment(stlink_t *sl, } } } - - return(retval); + return retval; } -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) +{ const uint8_t* loader_code; size_t loader_size; @@ -232,7 +235,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || @@ -245,34 +248,38 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || - sl->chip_id == STLINK_CHIPID_STM32_F412 || - sl->chip_id == STLINK_CHIPID_STM32_F413 || - sl->chip_id == STLINK_CHIPID_STM32_F446) { + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F412 || + sl->chip_id == STLINK_CHIPID_STM32_F413 || + sl->chip_id == STLINK_CHIPID_STM32_F446 + ) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f4, sizeof(loader_code_stm32f4), loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); - - if (retval == -1) { return(retval); } + if (retval == -1) { + return retval; + } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || - sl->chip_id == STLINK_CHIPID_STM32_F72XXX) { + sl->chip_id == STLINK_CHIPID_STM32_F72XXX + ) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f7, sizeof(loader_code_stm32f7), loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); - - if (retval == -1) { return(retval); } + if (retval == -1) { + return retval; + } } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || @@ -285,102 +292,101 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) + { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { - ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", - sl->core_id, sl->chip_id); - return(-1); + ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", sl->core_id, sl->chip_id); + return -1; } memcpy(sl->q_buf, loader_code, loader_size); int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); - - if (ret) { return(ret); } + if (ret) + return ret; *addr = sl->sram_base; *size = loader_size; - return(0); // success + /* success */ + return 0; } -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) +{ struct stlink_reg rr; int i = 0; size_t count = 0; uint32_t flash_base = 0; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); - - // TODO: This can never return -1 + // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { // IMPOSSIBLE! ELOG("write_buffer_to_sram() == -1\n"); - return(-1); + return -1; } if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { count = size / sizeof(uint16_t); - - if (size % sizeof(uint16_t)) { ++count; } + if (size % sizeof(uint16_t)) + ++count; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) { count = size / sizeof(uint32_t); - - if (size % sizeof(uint32_t)) { ++count; } + if (size % sizeof(uint32_t)) + ++count; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { count = size / sizeof(uint64_t); - - if (size % sizeof(uint64_t)) { ++count; } + if (size % sizeof(uint64_t)) + ++count; } if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } - /* Setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); // source - stlink_write_reg(sl, target, 1); // target - stlink_write_reg(sl, (uint32_t)count, 2); // count - stlink_write_reg(sl, flash_base, 3); // flash register base - // only used on VL/F1_XL, but harmless for others - stlink_write_reg(sl, fl->loader_addr, 15); // pc register + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, (uint32_t) count, 2); /* count */ + stlink_write_reg(sl, flash_base, 3); /* flash register base, only used on VL/F1_XL, but harmless for others */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - /* Run loader */ + /* run loader */ stlink_run(sl); -/* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. - * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" - * (actually almost two ticks) of the system. 1 ms. Thus, the ten thousand attempts, when - * "something goes wrong" that requires the error message "flash loader run error" would wait - * for something like 20 seconds before coming up with the error. - * By increasing the sleep-per-round to the same order-of-magnitude as the tick-rounding that - * the OS uses, the wait until the error message is reduced to the same order of magnitude - * as what was intended. -- REW. - */ -#define WAIT_ROUNDS 30 - - // wait until done (reaches breakpoint) +// This piece of code used to try to spin for .1 second by waiting +// doing 10000 rounds of 10 microseconds. But because this usually runs +// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" +// (actually almost two ticks) of the system. 1 milisecond. Thus, the +// ten thousand attempts, when "something goes wrong" that requires +// the error message "flash loader run error" would wait for something +// like 20 seconds before coming up with the error. +// by increasing the sleep-per-round to the same order-of-magnitude as +// the tick-rounding that the OS uses, the wait until the error message is +// reduced to the same order of magnitude as what was intended. -- REW. +#define WAIT_ROUNDS 100 + /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(10000); - - if (stlink_is_core_halted(sl)) { break; } + usleep(1000); + if (stlink_is_core_halted(sl)) + break; } if (i >= WAIT_ROUNDS) { ELOG("flash loader run error\n"); - return(-1); + return -1; } - // check written byte count + /* check written byte count */ stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { ELOG("write error, count == %u\n", rr.r[2]); - return(-1); + return -1; } - return(0); + return 0; } From 77c58f054e091f9c2c4c2db7cdb44e242901b24b Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 14:55:34 +0200 Subject: [PATCH 04/10] re-applied the changes to the original files --- src/st-flash/flash_opts.c | 455 ++++++++++++++++--------------- src/stlink-lib/flash_loader.c | 486 +++++++++++++++++----------------- 2 files changed, 478 insertions(+), 463 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 8557445e0..6653c6e62 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -2,11 +2,12 @@ #include #include -#include +#include "flash.h" static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); - if (strlen(str) < n) return false; + + if (strlen(str) < n) { return(false); } return (0 == strncmp(str, prefix, n)); } @@ -19,37 +20,28 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re uint64_t value; char *tail; - // hexadecimal - if (starts_with (str, "0x") || starts_with (str, "0X")) { + if (starts_with (str, "0x") || starts_with (str, "0X")) { // hexadecimal value = strtoul (str + 2, &tail, 16); - } - // binary - else if (starts_with (str, "0b") || starts_with (str, "0B")) { + } else if (starts_with (str, "0b") || starts_with (str, "0B")) { // binary value = strtoul (str + 2, &tail, 2); - } - // octal - else if (starts_with (str, "0")) { + } else if (starts_with (str, "0")) { // octal value = strtoul (str + 1, &tail, 8); - } - // decimal - else { + } else { // decimal value = strtoul (str, &tail, 10); } if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { value = value * 1024; - } - else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { + } else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { value = value * 1024 * 1024; + } else if (tail[0] == '\0') { + /* value not changed */ + } else { + return(-1); } - else if (tail[0] == '\0') { - // value not change - } - else { - return -1; - } + *read_value = value; - return 0; + return(0); } // support positive integer from 0 to UINT32_MAX @@ -59,28 +51,26 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { uint64_t value; int result = get_long_integer_from_char_array (str, &value); + if (result != 0) { - return result; - } - else if (value > UINT32_MAX) { - fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, \ -cannot convert to int32_t\n"); - return -1; - } - else { + return(result); + } else if (value > UINT32_MAX) { + fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); + return(-1); + } else { *read_value = (uint32_t)value; - return 0; + return(0); } } static int invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); - return -1; + return(-1); } static int bad_arg(const char *arg) { fprintf(stderr, "*** Error: Invalid value for %s\n", arg); - return -1; + return(-1); } int flash_get_opts(struct flash_opts* o, int ac, char** av) { @@ -91,148 +81,158 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // options int result; + while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); - } - else if (strcmp(av[0], "--debug") == 0) { + } else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; - } - else if (strcmp(av[0], "--opt") == 0) { + } else if (strcmp(av[0], "--opt") == 0) { o->opt = ENABLE_OPT; - } - else if (strcmp(av[0], "--reset") == 0) { + } else if (strcmp(av[0], "--reset") == 0) { o->reset = 1; - } - else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { + } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { const char * serial; + if (strcmp(av[0], "--serial") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + serial = av[0]; - } - else { + } else { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ + + /** @todo This is not really portable, as strlen really returns size_t we need to obey + and not cast it to a signed type. */ int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array - if (j % 2 != 0) return -1; + int length = j / 2; // the length of the destination-array + + if (j % 2 != 0) { return(-1); } + for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - } - else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { + } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; + if (strcmp(av[0], "--area") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + area = av[0]; - } - else { + } else { area = av[0] + strlen("--area="); } - if (strcmp(area, "main") == 0) + + if (strcmp(area, "main") == 0) { o->area = FLASH_MAIN_MEMORY; - else if (strcmp(area, "system") == 0) + } else if (strcmp(area, "system") == 0) { o->area = FLASH_SYSTEM_MEMORY; - else if (strcmp(area, "otp") == 0) + } else if (strcmp(area, "otp") == 0) { o->area = FLASH_OTP; - else if (strcmp(area, "option") == 0) + } else if (strcmp(area, "option") == 0) { o->area = FLASH_OPTION_BYTES; - else if (strcmp(area, "option_boot_add") == 0) + } else if (strcmp(area, "option_boot_add") == 0) { o->area = FLASH_OPTION_BYTES_BOOT_ADD; - else if (strcmp(area, "optcr") == 0) + } else if (strcmp(area, "optcr") == 0) { o->area = FLASH_OPTCR; - else if (strcmp(area, "optcr1") == 0) + } else if (strcmp(area, "optcr1") == 0) { o->area = FLASH_OPTCR1; - else - return -1; + } else { + return(-1); + } - } - else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + } else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { const char* freq; + if (strcmp(av[0], "--freq") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { + return(-1); + } + freq = av[0]; - } - else { + } else { freq = av[0] + strlen("--freq="); } + if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { o->freq = 5; - } - else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + } else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { o->freq = 15; - } - else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + } else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { o->freq = 25; - } - else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + } else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { o->freq = 50; - } - else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + } else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { o->freq = 100; - } - else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + } else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { o->freq = 125; - } - else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + } else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { o->freq = 240; - } - else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + } else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { o->freq = 480; - } - else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + } else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { o->freq = 950; - } - else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + } else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || + strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { o->freq = 1200; - } - else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + } else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || + strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { o->freq = 1800; - } - else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + } else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || + strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { o->freq = 4000; + } else { + return(-1); } - else - return -1; - } - else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { + } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; + if (strcmp(av[0], "--format") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + format = av[0]; - } - else { + } else { format = av[0] + strlen("--format="); } - if (strcmp(format, "binary") == 0) + + if (strcmp(format, "binary") == 0) { o->format = FLASH_FORMAT_BINARY; - else if (strcmp(format, "ihex") == 0) + } else if (strcmp(format, "ihex") == 0) { o->format = FLASH_FORMAT_IHEX; - else - return bad_arg("format"); - } - else if ( starts_with(av[0], "--flash=") ) { + } else { + return(bad_arg("format")); + } + } else if ( starts_with(av[0], "--flash=")) { const char *arg = av[0] + strlen("--flash="); uint32_t flash_size; result = get_integer_from_char_array(arg, &flash_size); - if (result != 0) return bad_arg ("--flash"); - else o->flash_size = (size_t) flash_size; - } - else { - break; // non-option found + + if (result != 0) { + return(bad_arg ("--flash")); + } else { + o->flash_size = (size_t)flash_size; + } + } else if (strcmp(av[0], "--connect-under-reset") == 0) { + o->connect_under_reset = true; + } else { + break; // non-option found + } ac--; @@ -242,22 +242,21 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + if (FLASH_CMD_NONE != o->cmd) { return(-1); } o->cmd = FLASH_CMD_ERASE; - } - else if (strcmp(av[0], "read") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + } else if (strcmp(av[0], "read") == 0) { + if (FLASH_CMD_NONE != o->cmd) { return(-1); } + o->cmd = FLASH_CMD_READ; - } - else if (strcmp(av[0], "write") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + } else if (strcmp(av[0], "write") == 0) { + if (FLASH_CMD_NONE != o->cmd) { return(-1); } + o->cmd = FLASH_CMD_WRITE; - } - else if (strcmp(av[0], "reset") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + } else if (strcmp(av[0], "reset") == 0) { + if (FLASH_CMD_NONE != o->cmd) { return(-1); } + o->cmd = CMD_RESET; - } - else { + } else { break; } @@ -265,120 +264,142 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { av++; } - switch(o->cmd) { - case FLASH_CMD_NONE: // no command found - return -1; - - case FLASH_CMD_ERASE: // no more arguments expected - if (ac != 0) return -1; - break; + switch (o->cmd) { + case FLASH_CMD_NONE: // no command found + return(-1); - case FLASH_CMD_READ: // expect filename, addr and size - if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { - if (ac != 3) return invalid_args("read "); - o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) address; + case FLASH_CMD_ERASE: // no more arguments expected + if (ac != 0) { return(-1); } - uint32_t size; - result = get_integer_from_char_array(av[2], &size); - if (result != 0) return bad_arg ("size"); - else o->size = (size_t) size; + break; - break; + case FLASH_CMD_READ: // expect filename, addr and size + if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if (ac != 3) { return invalid_args("read "); } + + o->filename = av[0]; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) { + return bad_arg ("addr"); + } else { + o->addr = (stm32_addr_t) address; } - else if ((FLASH_OTP == o->area)) { - return bad_arg("TODO: otp not implemented yet"); - if (ac > 1) return invalid_args("otp read: [path]"); - if (ac > 0) o->filename = av[0]; - break; + + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) { + return bad_arg ("size"); + } else { + o->size = (size_t) size; } - else if ((FLASH_OPTION_BYTES == o->area)) { - if (ac > 2) return invalid_args("option bytes read: [path] [size]"); - if (ac > 0) o->filename = av[0]; - if (ac > 1) { - uint32_t size; - result = get_integer_from_char_array(av[1], &size); - if (result != 0) return bad_arg("option bytes read: invalid size"); - else o->size = (size_t) size; + + break; + } else if ((FLASH_OTP == o->area)) { + return bad_arg("TODO: otp not implemented yet"); + if (ac > 1) { return invalid_args("otp read: [path]"); } + if (ac > 0) { o->filename = av[0]; } + break; + } else if ((FLASH_OPTION_BYTES == o->area)) { + if (ac > 2) { return invalid_args("option bytes read: [path] [size]"); } + if (ac > 0) { o->filename = av[0]; } + if (ac > 1) { + uint32_t size; + result = get_integer_from_char_array(av[1], &size); + if (result != 0) { + return bad_arg("option bytes read: invalid size"); + } else { + o->size = (size_t) size; } - break; - } - else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { - if (ac > 0) return invalid_args("option bytes boot_add read"); - break; - } - else if ((FLASH_OPTCR == o->area)) { - if (ac > 0) return invalid_args("option control register read"); - break; - } - else if ((FLASH_OPTCR1 == o->area)) { - if (ac > 0) return invalid_args("option control register 1 read"); - break; } break; + } else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + if (ac > 0) { return invalid_args("option bytes boot_add read"); } + break; + } else if ((FLASH_OPTCR == o->area)) { + if (ac > 0) { return invalid_args("option control register read"); } + break; + } else if ((FLASH_OPTCR1 == o->area)) { + if (ac > 0) { return invalid_args("option control register 1 read"); } + break; + } - case FLASH_CMD_WRITE: - // TODO: should be boot add 0 and boot add 1 uint32 - if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address - if (ac >=1 && ac <= 2) { - o->filename = av[0]; - } - else - return invalid_args("write [addr]"); - - if (ac == 2) { - uint32_t addr; - result = get_integer_from_char_array(av[1], &addr); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) addr; - } - } - else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address - if (ac != 1) return invalid_args("option bytes boot_add write "); - - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) return bad_arg ("val"); - else o->val = (uint32_t) val; - } - else if (FLASH_OPTCR == o->area) { // expect option control register value - if (ac != 1) return invalid_args("option control register write "); - - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) return bad_arg ("val"); - else o->val = (uint32_t) val; - } - else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value - if (ac != 1) return invalid_args("option control register 1 write "); - - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) return bad_arg ("val"); - else o->val = (uint32_t) val; - } - else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr - if (ac != 2) return invalid_args("write "); + break; + + case FLASH_CMD_WRITE: + // TODO: should be boot add 0 and boot add 1 uint32 + if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (ac >=1 && ac <= 2) { o->filename = av[0]; + } else { + return invalid_args("write [addr]"); + } + + if (ac == 2) { uint32_t addr; result = get_integer_from_char_array(av[1], &addr); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) addr; - } - else if (FLASH_FORMAT_IHEX == o->format) { // expect filename - if (ac != 1) return invalid_args("write "); - o->filename = av[0]; + if (result != 0) { + return bad_arg ("addr"); + } else { + o->addr = (stm32_addr_t) addr; + } } - else { - return -1; // should have been caught during format parsing + } else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + if (ac != 1) { return invalid_args("option bytes boot_add write "); } + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + + if (result != 0) { + return(bad_arg ("val")); + } else { + o->val = (uint32_t)val; + } + } else if (FLASH_OPTCR == o->area) { // expect option control register value + if (ac != 1) { return invalid_args("option control register write "); } + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } + } else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + if (ac != 1) { return invalid_args("option control register 1 write "); } + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } + } else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr + if (ac != 2) { return invalid_args("write "); } + + o->filename = av[0]; + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + + if (result != 0) { + return(bad_arg ("addr")); + } else { + o->addr = (stm32_addr_t)addr; } - break; + } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename + if (ac != 1) { return(invalid_args("write ")); } + + o->filename = av[0]; + } else { + return(-1); // should have been caught during format parsing + } + + break; - default: break ; + default: break; } - return 0; + return(0); } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index b6058cd0e..0e79c3c0a 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -3,213 +3,210 @@ #include #include +#include "flash_loader.h" #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 /* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ - /* flashloaders/stm32f0.s -- compiled with thumb2 */ - static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, - 0x58, 0x00, 0x00, 0x20 - }; - - /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ - static const uint8_t loader_code_stm32f0[] = { - 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32l[] = { - // flashloaders/stm32lx.s - - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, - }; - - static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s - - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f4_lv[] = { - // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32l4[] = { - // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, - 0x4c, 0x60, 0x00, 0xf1, - 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x12, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f7[] = { - // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f7_lv[] = { - // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - - -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) -{ +/* flashloaders/stm32f0.s -- compiled with thumb2 */ +static const uint8_t loader_code_stm32vl[] = { + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd1, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, + 0x58, 0x00, 0x00, 0x20 +}; + +/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ +static const uint8_t loader_code_stm32f0[] = { + 0xc0, 0x46, 0xc0, 0x46, + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd1, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32l[] = { + // flashloaders/stm32lx.s + + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xf4, 0xd1, 0x00, 0xbe, +}; + +static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f4_lv[] = { + // flashloaders/stm32f4lv.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32l4[] = { + // flashloaders/stm32l4.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x12, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f7[] = { + // flashloaders/stm32f7.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f7_lv[] = { + // flashloaders/stm32f7lv.s + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; - /* allocate the loader in sram */ + // allocate the loader in SRAM if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { WLOG("Failed to write flash loader to sram!\n"); - return -1; + return(-1); } - /* allocate a one page buffer in sram right after loader */ - fl->buf_addr = fl->loader_addr + (uint32_t) size; + // allocate a one page buffer in SRAM right after loader + fl->buf_addr = fl->loader_addr + (uint32_t)size; ILOG("Successfully loaded flash loader in sram\n"); - return 0; + return(0); } static int loader_v_dependent_assignment(stlink_t *sl, const uint8_t **loader_code, size_t *loader_size, const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size) -{ + const uint8_t *low_v_loader, size_t low_v_loader_size) { int retval = 0; - if ( sl->version.stlink_v == 1){ + if ( sl->version.stlink_v == 1) { printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; - } - else { + } else { int voltage = stlink_target_voltage(sl); + if (voltage == -1) { retval = -1; printf("Failed to read Target voltage\n"); - } - else { + } else { if (voltage > 2700) { *loader_code = high_v_loader; *loader_size = high_v_loader_size; @@ -219,11 +216,11 @@ static int loader_v_dependent_assignment(stlink_t *sl, } } } - return retval; + + return(retval); } -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) -{ +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; @@ -235,7 +232,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || @@ -248,38 +245,34 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || - sl->chip_id == STLINK_CHIPID_STM32_F412 || - sl->chip_id == STLINK_CHIPID_STM32_F413 || - sl->chip_id == STLINK_CHIPID_STM32_F446 - ) { + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F412 || + sl->chip_id == STLINK_CHIPID_STM32_F413 || + sl->chip_id == STLINK_CHIPID_STM32_F446) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f4, sizeof(loader_code_stm32f4), loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); - if (retval == -1) { - return retval; - } + + if (retval == -1) { return(retval); } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || - sl->chip_id == STLINK_CHIPID_STM32_F72XXX - ) { + sl->chip_id == STLINK_CHIPID_STM32_F72XXX) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f7, sizeof(loader_code_stm32f7), loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); - if (retval == -1) { - return retval; - } + + if (retval == -1) { return(retval); } } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || @@ -292,101 +285,102 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) - { + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { - ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", sl->core_id, sl->chip_id); - return -1; + ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", + sl->core_id, sl->chip_id); + return(-1); } memcpy(sl->q_buf, loader_code, loader_size); int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); - if (ret) - return ret; + + if (ret) { return(ret); } *addr = sl->sram_base; *size = loader_size; - /* success */ - return 0; + return(0); // success } -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) -{ +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; int i = 0; size_t count = 0; uint32_t flash_base = 0; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); - // FIXME This can never return -1 + + // TODO: This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { // IMPOSSIBLE! ELOG("write_buffer_to_sram() == -1\n"); - return -1; + return(-1); } if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { count = size / sizeof(uint16_t); - if (size % sizeof(uint16_t)) - ++count; + + if (size % sizeof(uint16_t)) { ++count; } } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) { count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) - ++count; + + if (size % sizeof(uint32_t)) { ++count; } } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { count = size / sizeof(uint64_t); - if (size % sizeof(uint64_t)) - ++count; + + if (size % sizeof(uint64_t)) { ++count; } } if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, (uint32_t) count, 2); /* count */ - stlink_write_reg(sl, flash_base, 3); /* flash register base, only used on VL/F1_XL, but harmless for others */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + /* Setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); // source + stlink_write_reg(sl, target, 1); // target + stlink_write_reg(sl, (uint32_t)count, 2); // count + stlink_write_reg(sl, flash_base, 3); // flash register base + // only used on VL/F1_XL, but harmless for others + stlink_write_reg(sl, fl->loader_addr, 15); // pc register - /* run loader */ + /* Run loader */ stlink_run(sl); -// This piece of code used to try to spin for .1 second by waiting -// doing 10000 rounds of 10 microseconds. But because this usually runs -// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" -// (actually almost two ticks) of the system. 1 milisecond. Thus, the -// ten thousand attempts, when "something goes wrong" that requires -// the error message "flash loader run error" would wait for something -// like 20 seconds before coming up with the error. -// by increasing the sleep-per-round to the same order-of-magnitude as -// the tick-rounding that the OS uses, the wait until the error message is -// reduced to the same order of magnitude as what was intended. -- REW. -#define WAIT_ROUNDS 100 - /* wait until done (reaches breakpoint) */ +/* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. + * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" + * (actually almost two ticks) of the system. 1 ms. Thus, the ten thousand attempts, when + * "something goes wrong" that requires the error message "flash loader run error" would wait + * for something like 20 seconds before coming up with the error. + * By increasing the sleep-per-round to the same order-of-magnitude as the tick-rounding that + * the OS uses, the wait until the error message is reduced to the same order of magnitude + * as what was intended. -- REW. + */ +#define WAIT_ROUNDS 30 + + // wait until done (reaches breakpoint) for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(1000); - if (stlink_is_core_halted(sl)) - break; + usleep(10000); + + if (stlink_is_core_halted(sl)) { break; } } if (i >= WAIT_ROUNDS) { ELOG("flash loader run error\n"); - return -1; + return(-1); } - /* check written byte count */ + // check written byte count stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { ELOG("write error, count == %u\n", rr.r[2]); - return -1; + return(-1); } - return 0; + return(0); } From a5b98f58756b6a1414ca8175c578e07998a59061 Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 15:00:53 +0200 Subject: [PATCH 05/10] Fix compiler warning implicit cast --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 58e67d447..86d2ca8ea 100644 --- a/src/common.c +++ b/src/common.c @@ -3421,7 +3421,7 @@ int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { } } - return stlink_read_debug32(sl, sl->option_base + (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); + return stlink_read_debug32(sl, sl->option_base + (uint32_t) (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); } /** From 77652688f21253f94e23a7d1c02d5a5bf0008295 Mon Sep 17 00:00:00 2001 From: rutgerhendriks <3134550+rutgerhendriks@users.noreply.github.com> Date: Mon, 6 Jul 2020 09:37:32 +0200 Subject: [PATCH 06/10] Delete ccpp.yml Remove ccpp.yml from workflows --- .github/workflows/ccpp.yml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .github/workflows/ccpp.yml diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml deleted file mode 100644 index 23aa0bfc5..000000000 --- a/.github/workflows/ccpp.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: C/C++ CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: make - run: make From e273ec53e8cf2d3df68ada1095f39232f3d7b14f Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Mon, 6 Jul 2020 09:55:19 +0200 Subject: [PATCH 07/10] Revert changing all compiler warning preventions --- src/st-flash/flash.c | 48 +++++++++++++++++++-------------------- src/st-flash/flash_opts.c | 22 +++++++++--------- src/stlink-lib/usb.c | 1 - 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 128b8acc0..4bdc20a16 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -25,8 +25,7 @@ static void cleanup(int signum) { exit(1); } -static void usage(void) -{ +static void usage(void) { puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); @@ -60,13 +59,13 @@ int main(int ac, char** av) { return(-1); } - ILOG("st-flash %s\n", STLINK_VERSION); + printf("st-flash %s\n", STLINK_VERSION); sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); if (sl == NULL) { return(-1); } - if (STLINK_FLASH_TYPE_UNKNOWN == sl->flash_type) { + if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { printf("Failed to connect to target\n"); return(-1); } @@ -84,14 +83,14 @@ int main(int ac, char** av) { signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (STLINK_DEV_DFU_MODE == stlink_current_mode(sl)) { + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { if (stlink_exit_dfu_mode(sl)) { printf("Failed to exit DFU mode\n"); goto on_error; } } - if (STLINK_DEV_DEBUG_MODE != stlink_current_mode(sl)) { + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { if (stlink_enter_swd_mode(sl)) { printf("Failed to enter SWD mode\n"); goto on_error; @@ -113,7 +112,7 @@ int main(int ac, char** av) { } // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (STLINK_CHIPID_STM32_F4 == sl->chip_id) { + if (sl->chip_id == STLINK_CHIPID_STM32_F4) { memset(sl->q_buf, 0, 4); for (int i = 0; i < 8; i++) { @@ -136,10 +135,9 @@ int main(int ac, char** av) { goto on_error; } - if (FLASH_CMD_WRITE == o.cmd) // write - { + if (o.cmd == FLASH_CMD_WRITE) { // write size_t size = 0; - if (FLASH_FORMAT_IHEX == o.format) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { @@ -149,7 +147,7 @@ int main(int ac, char** av) { } if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if (FLASH_FORMAT_IHEX == o.format) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -161,7 +159,7 @@ int main(int ac, char** av) { } } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if (FLASH_FORMAT_IHEX == o.format) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_sram(sl, o.filename, o.addr); @@ -179,7 +177,7 @@ int main(int ac, char** av) { printf("stlink_fwrite_option_bytes() == -1\n"); goto on_error; } - } else if (FLASH_OPTION_BYTES == o.area) { + } else if (o.area == FLASH_OPTION_BYTES) { if (o.val == 0) { printf("attempting to set option byte to 0, abort.\n"); goto on_error; @@ -191,15 +189,15 @@ int main(int ac, char** av) { printf("stlink_write_option_bytes32() == -1\n"); goto on_error; } - } else if (FLASH_OPTCR == o.area) { + } else if (o.area == FLASH_OPTCR) { DLOG("@@@@ Write %d (%0#10x) to option control register\n", o.val, o.val); err = stlink_write_option_control_register32(sl, o.val); - } else if (FLASH_OPTCR1 == o.area) { + } else if (o.area == FLASH_OPTCR1) { DLOG("@@@@ Write %d (%0#10x) to option control register 1\n", o.val, o.val); err = stlink_write_option_control_register1_32(sl, o.val); - } else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) { DLOG("@@@@ Write %d (%0#10x) to option bytes boot address\n", o.val, o.val); err = stlink_write_option_bytes_boot_add32(sl, o.val); @@ -208,14 +206,14 @@ int main(int ac, char** av) { printf("Unknown memory region\n"); goto on_error; } - } else if (FLASH_CMD_ERASE == o.cmd) { + } else if (o.cmd == FLASH_CMD_ERASE) { err = stlink_erase_flash_mass(sl); if (err == -1) { printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } - } else if (CMD_RESET == o.cmd) { + } else if (o.cmd == CMD_RESET) { if (sl->version.stlink_v > 1) { if (stlink_jtag_reset(sl, 2)) { printf("Failed to reset JTAG\n"); @@ -228,20 +226,20 @@ int main(int ac, char** av) { goto on_error; } } else { // read - if ((FLASH_MAIN_MEMORY == o.area) || (FLASH_SYSTEM_MEMORY == o.area)) { + if ((o.area == FLASH_MAIN_MEMORY) || (o.area == FLASH_SYSTEM_MEMORY)) { if ((o.size == 0) && (o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { o.size = sl->flash_size; } else if ((o.size == 0) && (o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { o.size = sl->sram_size; } - err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, o.addr, o.size); + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); if (err == -1) { printf("stlink_fread() == -1\n"); goto on_error; } - } else if (FLASH_OPTION_BYTES == o.area) { + } else if (o.area == FLASH_OPTION_BYTES) { uint8_t remaining_option_length = sl->option_size / 4; DLOG("@@@@ Read %d (%#x) option bytes from %#10x\n", remaining_option_length, remaining_option_length, sl->option_base); @@ -249,7 +247,7 @@ int main(int ac, char** av) { if (0 == o.size) { o.size = sl->option_size; } - err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, sl->option_base, o.size); + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, sl->option_base, o.size); } else { uint32_t option_byte = 0; err = stlink_read_option_bytes32(sl, &option_byte); @@ -260,7 +258,7 @@ int main(int ac, char** av) { printf("%08x\n", option_byte); } } - } else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) { uint32_t option_byte = 0; err = stlink_read_option_bytes_boot_add32(sl, &option_byte); if (err == -1) { @@ -269,7 +267,7 @@ int main(int ac, char** av) { } else { printf("%08x\n",option_byte); } - } else if (FLASH_OPTCR == o.area) { + } else if (o.area == FLASH_OPTCR) { uint32_t option_byte = 0; err = stlink_read_option_control_register32(sl, &option_byte); if (err == -1) { @@ -278,7 +276,7 @@ int main(int ac, char** av) { } else { printf("%08x\n",option_byte); } - } else if (FLASH_OPTCR1 == o.area) { + } else if (o.area == FLASH_OPTCR1) { uint32_t option_byte = 0; err = stlink_read_option_control_register1_32(sl, &option_byte); if (err == -1) { diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 6653c6e62..1cfd6fe89 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -274,7 +274,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { break; case FLASH_CMD_READ: // expect filename, addr and size - if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if ((o->area == FLASH_MAIN_MEMORY) || (o->area == FLASH_SYSTEM_MEMORY)) { if (ac != 3) { return invalid_args("read "); } o->filename = av[0]; @@ -295,12 +295,12 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } break; - } else if ((FLASH_OTP == o->area)) { + } else if ((o->area == FLASH_OTP)) { return bad_arg("TODO: otp not implemented yet"); if (ac > 1) { return invalid_args("otp read: [path]"); } if (ac > 0) { o->filename = av[0]; } break; - } else if ((FLASH_OPTION_BYTES == o->area)) { + } else if ((o->area == FLASH_OPTION_BYTES)) { if (ac > 2) { return invalid_args("option bytes read: [path] [size]"); } if (ac > 0) { o->filename = av[0]; } if (ac > 1) { @@ -313,13 +313,13 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } } break; - } else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + } else if ((o->area == FLASH_OPTION_BYTES_BOOT_ADD)) { if (ac > 0) { return invalid_args("option bytes boot_add read"); } break; - } else if ((FLASH_OPTCR == o->area)) { + } else if ((o->area == FLASH_OPTCR)) { if (ac > 0) { return invalid_args("option control register read"); } break; - } else if ((FLASH_OPTCR1 == o->area)) { + } else if ((o->area == FLASH_OPTCR1)) { if (ac > 0) { return invalid_args("option control register 1 read"); } break; } @@ -328,7 +328,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { case FLASH_CMD_WRITE: // TODO: should be boot add 0 and boot add 1 uint32 - if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (o->area == FLASH_OPTION_BYTES) { // expect filename and optional address if (ac >=1 && ac <= 2) { o->filename = av[0]; } else { @@ -344,7 +344,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->addr = (stm32_addr_t) addr; } } - } else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { // expect option bytes boot address if (ac != 1) { return invalid_args("option bytes boot_add write "); } uint32_t val; @@ -355,7 +355,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else { o->val = (uint32_t)val; } - } else if (FLASH_OPTCR == o->area) { // expect option control register value + } else if (o->area == FLASH_OPTCR) { // expect option control register value if (ac != 1) { return invalid_args("option control register write "); } uint32_t val; @@ -366,7 +366,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else { o->val = (uint32_t) val; } - } else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + } else if (o->area == FLASH_OPTCR1) { // expect option control register 1 value if (ac != 1) { return invalid_args("option control register 1 write "); } uint32_t val; @@ -376,7 +376,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else { o->val = (uint32_t) val; } - } else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr + } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) { return invalid_args("write "); } o->filename = av[0]; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index a7875eb57..f9b4775f3 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -710,7 +710,6 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_READMEM_32BIT; - DLOG("using address %#010x\n", addr); write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); From ca02a8d507430e2a45e5c6fa9b019ab042c91770 Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Mon, 6 Jul 2020 10:07:26 +0200 Subject: [PATCH 08/10] src/st-flash/flash.c: improved error message --- src/st-flash/flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 4bdc20a16..9116f9c80 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -236,7 +236,7 @@ int main(int ac, char** av) { err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); if (err == -1) { - printf("stlink_fread() == -1\n"); + printf("could not read main memory (%d)\n", err); goto on_error; } } else if (o.area == FLASH_OPTION_BYTES) { From f57ae0c7142dd86b2dd5b0c298f7105ab65d574e Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Sun, 19 Jul 2020 16:55:02 +0200 Subject: [PATCH 09/10] Remove double parantheses --- src/st-flash/flash_opts.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 1cfd6fe89..ab716bb31 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -295,12 +295,12 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } break; - } else if ((o->area == FLASH_OTP)) { + } else if (o->area == FLASH_OTP) { return bad_arg("TODO: otp not implemented yet"); if (ac > 1) { return invalid_args("otp read: [path]"); } if (ac > 0) { o->filename = av[0]; } break; - } else if ((o->area == FLASH_OPTION_BYTES)) { + } else if (o->area == FLASH_OPTION_BYTES) { if (ac > 2) { return invalid_args("option bytes read: [path] [size]"); } if (ac > 0) { o->filename = av[0]; } if (ac > 1) { @@ -313,13 +313,13 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } } break; - } else if ((o->area == FLASH_OPTION_BYTES_BOOT_ADD)) { + } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { if (ac > 0) { return invalid_args("option bytes boot_add read"); } break; - } else if ((o->area == FLASH_OPTCR)) { + } else if (o->area == FLASH_OPTCR) { if (ac > 0) { return invalid_args("option control register read"); } break; - } else if ((o->area == FLASH_OPTCR1)) { + } else if (o->area == FLASH_OPTCR1) { if (ac > 0) { return invalid_args("option control register 1 read"); } break; } From 2dd47a432710c77f9dfd9a661212643a9667361f Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Sun, 19 Jul 2020 17:35:38 +0200 Subject: [PATCH 10/10] Reverted the last comparison changes --- src/st-flash/flash_opts.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index ab716bb31..e74ecc1ce 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -242,18 +242,18 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = FLASH_CMD_ERASE; } else if (strcmp(av[0], "read") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = FLASH_CMD_READ; } else if (strcmp(av[0], "write") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = FLASH_CMD_WRITE; } else if (strcmp(av[0], "reset") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = CMD_RESET; } else {