Description
Desktop and Board
see #1637
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:
- Erase flash
- Upload first hex: stm32_g0_serial_blink_100_600.ino --> All ok
- 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.
- Erase flash
- Upload first hex: stm32_g0_serial_blink_100_600.ino --> All ok
- Erase flash
- 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
./STM32_Programmer.sh -c port=/dev/ttyUSB0 -e [0 31]
: This will erase all flash end ensure a fixed starting point./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.- Press reset button to bring the device back into bootloader
./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.