Skip to content

Generic Board STM32G031J6: Flash download fails (Linux, USART) #1659

Closed
@olikraus

Description

@olikraus

Desktop and Board

see #1637

grafik
USART connected to PA9/10

Arduino Core Version

Latest Arduino_Core_STM32, especially including PR #1653 (bootloader jump into application)

Bug Description

Overview

If a .ino file is downloaded to the STM32G031J6 device, then the download might be invalid, if the size of the flashfile has changed.
The demonstration will use two different files (difference actually is only a delay value). If one file overwrites the other, then the newly flashed file is invalid an will not work:

  1. Erase flash
  2. Upload first hex: stm32_g0_serial_blink_100_600.ino --> All ok
  3. Upload second hex: stm32_g0_serial_blink_600_600.hex --> Code hangs, download invalid

Flash will work successfully if the flash memory was erased fully before any of the two programs is uploaded.

  1. Erase flash
  2. Upload first hex: stm32_g0_serial_blink_100_600.ino --> All ok
  3. Erase flash
  4. Upload second hex: stm32_g0_serial_blink_600_600.hex --> All ok

The problem can be demonstrated inside Arduino IDE. The steps below however will demonstrated the bug by using CubeProgrammer only. This demonstrates, that the root problem (bug) is located in STM32CubeProgrammer, which does not flash correctly via USART.

Preparation

As a preparation I will create two HEX files

stm32_g0_serial_blink_100_600.ino:

#define MYPIN 6

void setup() {
  Serial.setRx(PA_10_R);
  Serial.setTx(PA_9_R);
  Serial.begin(9600);
  pinMode(MYPIN, OUTPUT);
  Serial.println("setup done");
}

void loop() {
  Serial.println(millis());
  digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);                       // wait for a second
  digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
  delay(600);                       // wait for a second
}

stm32_g0_serial_blink_600_600.ino:

#define MYPIN 6

void setup() {
  Serial.setRx(PA_10_R);
  Serial.setTx(PA_9_R);
  Serial.begin(9600);
  pinMode(MYPIN, OUTPUT);
  Serial.println("setup done");
}

void loop() {
  Serial.println(millis());
  digitalWrite(MYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(600);                       // wait for a second
  digitalWrite(MYPIN, LOW);    // turn the LED off by making the voltage LOW
  delay(600);                       // wait for a second
}

Compiled with Arduino IDE, the following two hex files can be obtained:

-rw-rw-r-- 1 kraus kraus 42869 Feb 14 20:44 stm32_g0_serial_blink_100_600.hex
-rw-rw-r-- 1 kraus kraus 42877 Feb 14 20:43 stm32_g0_serial_blink_600_600.hex

The size of the two hex files differs slightly.
For further testing both hex files are attached:
hex_files.zip

Reproducing the Bug

  1. ./STM32_Programmer.sh -c port=/dev/ttyUSB0 -e [0 31]: This will erase all flash end ensure a fixed starting point
  2. ./STM32_Programmer.sh -c port=/dev/ttyUSB0 -w stm32_g0_serial_blink_100_600.hex -g: This will download and start the first hex file. Thanks to Bootloader jump to application #1653, the code is started directly without further boot0 mode change and without reset event.
  3. Press reset button to bring the device back into bootloader
  4. ./STM32_Programmer.sh -c port=/dev/ttyUSB0 -w stm32_g0_serial_blink_600_600.hex -g: This will download and start the second hex file. Unfortunately the download fails and the start will not work.

Analysis of the Bug

STMCubeProgrammer also allows the verification of the uploaded data, which is disabled by default.
Let us repeat step 4 with verification:

./STM32_Programmer.sh -c port=/dev/ttyUSB0 -w stm32_g0_serial_blink_600_600.hex -v -g

The output will finally look like this:

Erasing internal memory sectors [0 7]
Download in Progress:
[==================================================] 100% 
File download complete
Time elapsed during download operation: 00:00:02.286
Verifying ...
Read progress:
[==================================================] 100% 
Error: Data mismatch found at address  0x08003800 (byte = 0x12 instead of 0x00)
Error: Download verification failed

Obviously CubeProgrammer was not able to flash correctly and as a consequence, the newly flash code is faulty, unable to start and execute.

Let us repeat the last step, but with flash erase before:

./STM32_Programmer.sh -c port=/dev/ttyUSB0 -e [0 31]
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -w stm32_g0_serial_blink_600_600.hex -v -g

The download now succeeds:

Verifying ...
Read progress:
[==================================================] 100% 
Download verified successfully 
RUNNING Program ... 
  Address:      : 0x8000000
Start operation achieved successfully

This means the verification error will vanish, if we have a fully erased flash memory.

Affected Devices

As described in #1637 also a STM32G031F8 is affected by the same bug, assuming that probably all STM32G devices are affected.

Assumed Root Cause

As analyzed in #1637 CubeProgrammer does not correctly erase the required target range. It probably erases too less due to a mismatch/confusion of the sector size (2k vs 1k).

Conclusion

Download via USART interface does not work reliable for STM32G devices. The problem is caused by STM32CubeProgrammer.
PR #1653 does NOT fix this problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    invalidThis doesn't seem right

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions