stlink-org / stlink

Open source STM32 MCU programming toolset
BSD 3-Clause "New" or "Revised" License
4.28k stars 1.22k forks source link

STM32L051: Problem writing half pages #1203

Closed mattgbio closed 10 months ago

mattgbio commented 2 years ago

Hi everyone,

I'm having a problem when flashing a new firmware to an STM32L051 on a Raspberry Pi 4. While reading from flash as well as writing small chunks of data to flash works very well, I cannot write a complete firmware image to flash.

In particular, ./st-flash --connect-under-reset --freq=8M write ~/firmware-accel_V5_Release.bin 0x08000000

results in the following (shortened) output:

2021-12-06T11:09:54 INFO common.c: Flash page at addr: 0x0800b080 erased 2021-12-06T11:09:54 INFO common.c: Flash page at addr: 0x0800b100 erased 2021-12-06T11:09:54 INFO common.c: Finished erasing 355 pages of 128 (0x80) bytes 2021-12-06T11:09:54 INFO common.c: Starting Flash write for L0 2021-12-06T11:09:54 INFO common.c: Starting Half page flash write for STM32L core id 2021-12-06T11:09:54 INFO flash_loader.c: Successfully loaded flash loader in sram 2021-12-06T11:09:54 INFO flash_loader.c: Clear DFSR 2021-12-06T11:09:54 ERROR flash_loader.c: Write error 2021-12-06T11:09:54 WARN flash_loader.c: Loader state: R2 0x40 R15 0xFFFFFFFE 2021-12-06T11:09:54 WARN flash_loader.c: MCU state: DHCSR 0x3000B DFSR 0x8 CFSR 0x0 HFSR 0x0 2021-12-06T11:09:54 WARN common.c: l1_stlink_flash_loader_run(0x8000000) failed! == -1 2021-12-06T11:09:54 WARN common.c: write_half_pages failed == -1

As writing small chunks of data is working, I have disabled writing half pages by removing the following lines in src/common.c:3346:

if (len > pagesize) {
  if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) {
    // this may happen on a blank device!
    WLOG("\nwrite_half_pages failed == -1\n");
  } else {
    off = (size_t)(len / pagesize) * pagesize;
  }
}

With this fix, writing the firmware to flash is working:

2021-12-06T11:07:54 INFO common.c: Flash page at addr: 0x0800b080 erased 2021-12-06T11:07:54 INFO common.c: Flash page at addr: 0x0800b100 erased 2021-12-06T11:07:54 INFO common.c: Finished erasing 355 pages of 128 (0x80) bytes 2021-12-06T11:07:54 INFO common.c: Starting Flash write for L0 353/354 pages written 2021-12-06T11:08:35 INFO common.c: Starting verification of write complete 2021-12-06T11:08:36 INFO common.c: Flash written and verified! jolly good!

Obviously, not using half-page writing is very slow, but this is fine with me for the moment. Does anyone see any other downside of this workaround? Does it significantly reduce the number of available write cycles of the flash?

My setup:

Best, Matt

Ant-ON commented 2 years ago

@mattgbio Could you try https://github.com/stlink-org/stlink/tree/develop branch? I find it difficult to navigate in the commit you are using.

mattgbio commented 2 years ago

@Ant-ON Unfortunately, I can't. When using the develop-branch, I'm running into a problem with reading the flash size, similar as in https://github.com/stlink-org/stlink/issues/1199. That's why I'm using the most recent commit in the master-branch.

./st-flash --connect-under-reset --freq=4M write ~/firmware-accel_V5_Release.bin 0x08000000 results in (I added the . in front of # for readability):

st-flash 1.7.0-126-gcb0f91a 2021-12-07T08:19:25 WARN common.c: NRST is not connected ---------- old ------------ .# Chip-ID file for L0xx Cat.3 .# chip_id 0x417 description L0xx Cat.3 flash_type 5 flash_size_reg 0x1ff8007c flash_pagesize 0x80 sram_size 0x2000 bootrom_base 0x1ff0000 bootrom_size 0x1000 option_base 0x1ff80000 option_size 0x14 flags 0

---------- new ------------ .# Chip-ID file for L0xx Cat.3 .# chip_id 0x417 description L0xx Cat.3 flash_type 5 flash_size_reg 0x0 flash_pagesize 0x80 sram_size 0x2000 bootrom_base 0x1ff0000 bootrom_size 0x1000 option_base 0x1ff80000 option_size 0x14 flags 0

2021-12-07T08:19:25 INFO common.c: L0xx Cat.3: 8 KiB SRAM, 0 KiB flash in at least 128 byte pages. Unknown memory region

Ant-ON commented 2 years ago

@mattgbio Unfortunately, there is a problem with the configs and it was not fixed... Could you try https://github.com/Ant-ON/stlink/tree/zf instead?

mattgbio commented 2 years ago

@Ant-ON Sure, this is the output:

st-flash 1.6.1-333-g5711a2c 2021-12-07T10:29:22 WARN common.c: NRST is not connected 2021-12-07T10:29:22 INFO common.c: L0xx Cat.3: 8 KiB SRAM, 64 KiB flash in at least 128 byte pages. file /home/pi/firmware-accel_V5_Release.bin md5 checksum: b064d5c6805a7788c03080a8ba7ee8f1, stlink checksum: 0x00405881 2021-12-07T10:29:22 INFO common.c: Attempting to write 45352 (0xb128) bytes to stm32 address: 134217728 (0x8000000) 2021-12-07T10:29:22 INFO common.c: Flash page at addr: 0x08000000 erased 2021-12-07T10:29:22 INFO common.c: Flash page at addr: 0x08000080 erased ... 2021-12-07T10:29:24 INFO common.c: Flash page at addr: 0x0800b080 erased 2021-12-07T10:29:24 INFO common.c: Flash page at addr: 0x0800b100 erased 2021-12-07T10:29:24 INFO common.c: Finished erasing 355 pages of 128 (0x80) bytes 2021-12-07T10:29:24 INFO common.c: Starting Flash write for L0 2021-12-07T10:29:24 INFO flash_loader.c: Successfully loaded flash loader in sram 2021-12-07T10:29:24 INFO flash_loader.c: Clear DFSR 2021-12-07T10:29:24 INFO common.c: Go to Thumb mode 2021-12-07T10:29:24 ERROR flash_loader.c: Write error 2021-12-07T10:29:24 WARN flash_loader.c: Loader state: R2 0x40 R15 0x0 2021-12-07T10:29:24 WARN flash_loader.c: MCU state: DHCSR 0x3000B DFSR 0x8 CFSR 0x0 HFSR 0x0 2021-12-07T10:29:24 WARN common.c: Failed to use flash loader, fallback to soft write 708/708 halfpages written 2021-12-07T10:29:25 ERROR common.c: Invalid flash address 2021-12-07T10:29:25 INFO common.c: Go to Thumb mode stlink_fwrite_flash() == -1

Even though it says that 708 halfpages have been written, the firmware image does not boot.

lglina commented 1 year ago

I can confirm this is still a problem programming the STM32L051K8 with st-flash under Linux with the ST-LINK/V2.

Per the above suggested temporary fix, here's a diff of my change that seems to work on the latest head version (pretty much just commenting out the broken bit!):

index b9c26bf..059a16f 100644
--- a/src/flashloader.c
+++ b/src/flashloader.c
@@ -346,13 +346,14 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl,
   } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) {
     uint32_t val;
     uint32_t flash_regs_base = get_stm32l0_flash_base(sl);
-    uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)?
-                                L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE;
+    //uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)?
+    //                            L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE;

     DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz));

     off = 0;

+       /*
     if (len > pagesize) {
       if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) {
         return (-1);
@@ -360,6 +361,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl,
         off = (size_t)(len / pagesize) * pagesize;
       }
     }
+       */

     // write remaining word in program memory
     for (; off < len; off += sizeof(uint32_t)) {

Would love to track this down and send a PR, but I'm pretty new to the STM32 :)

Nightwalker-87 commented 1 year ago

@Ant-ON: As you contributed to this issue previously - Can you give it another try? I've had a look at the source code based on the update from @lglina, but have no idea regarding the actual cause of this problem, apart from int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, which seems misplaced.

In the current HEAD of the develop branch the second part looks like this:

    if (len > pagesize) {
      if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) {
        return (-1);
      } else {
        off = (size_t)(len / pagesize) * pagesize;
      }
    }
Nightwalker-87 commented 1 year ago

Duplicate of #681.