Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32L051: Problem writing half pages #1203

Closed
mattgbio opened this issue Dec 6, 2021 · 7 comments · Fixed by #1330
Closed

STM32L051: Problem writing half pages #1203

mattgbio opened this issue Dec 6, 2021 · 7 comments · Fixed by #1330

Comments

@mattgbio
Copy link

mattgbio commented Dec 6, 2021

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:

  • Programmer/board type: STLINK /V2
  • Operating system and version: Linux (Raspberry Pi OS 5.10.63-v8+)
  • stlink tools version and/or git commit hash: e662da0
  • stlink commandline tool name: st-flash
  • Target chip (and board, if applicable): STM32L051

Best,
Matt

@Ant-ON Ant-ON self-assigned this Dec 7, 2021
@Ant-ON
Copy link
Collaborator

Ant-ON commented Dec 7, 2021

@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
Copy link
Author

mattgbio commented Dec 7, 2021

@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 #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
Copy link
Collaborator

Ant-ON commented Dec 7, 2021

@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
Copy link
Author

mattgbio commented Dec 7, 2021

@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
Copy link

lglina commented Nov 30, 2022

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
Copy link
Member

Nightwalker-87 commented Dec 29, 2022

@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
Copy link
Member

Duplicate of #681.

@stlink-org stlink-org locked as resolved and limited conversation to collaborators Sep 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.