autodetect first working version
Hi @spth @vdudouyt, For your consideration, this proposal for a STM8 device auto-detection. For the moment only device reads are performed for the auto-detection. Based on the device table provided with STVP, it is possible to auto-detect STM8 families, sufficiently, to identify the flash block size, eeprom base address, read-out-protection (S or L), and regs (S or L). In proposed code the auto-detection is currently added under the -a option, and works instead of the -p option. For instance, this command to perform autodetection only (on STM8S105):
./stm8flash -c stlinkv2 -a
STLink: v2, JTAG: v37, SWIM: v7, VID: 8304, PID: 4837
found SP = 0x7ff, assuming ram size = 2K
bootrom is present
found PC = 0x6000 : mcu currently stalled in bootrom
possible match! found STM8S105 with 2048 bytes RAM, flash size between 16384 and 32768, eeprom at 0x4000 with size between 1024 and 1024, flash block size = 128
auto-detection successful
Determine FLASH area
No action has been specified
-a option can be combined with existing actions in stm8flash, for example read from flash below on STM8S103. For now it reads/writes the smallest size detected.
$ ./stm8flash -c stlinkv2 -a -s flash -r autodetect_flash.bin
STLink: v2, JTAG: v37, SWIM: v7, VID: 8304, PID: 4837
found SP = 0x3ff, assuming ram size = 1K
bootrom not present
found PC = 0x8000 : mcu currently stalled in flash
possible match! found STM8Sx03 with 1024 bytes RAM, flash size between 4096 and 8192, eeprom at 0x4000 with size between 640 and 640, flash block size = 64
auto-detection successful
Determine FLASH area
STLink: v2, JTAG: v37, SWIM: v7, VID: 8304, PID: 4837
Due to its file extension (or lack thereof), "autodetect_flash.bin" is considered as RAW BINARY format!
Reading 4096 bytes at 0x8000... OK
Bytes received: 4096
The changes are essentially in autodetect.* in main.c the auto-detection stage is added. in stlinkv2.c the open() function was modified to effectively stall the CPU (there was a comment that CPU was stalled, but in reality only SWIM_DM was activated). For the auto-detection it was more convenient to have the CPU stalled immediately after reset, because then SP points to the top of RAM, and ram size can be deduced. In stm8.c I adapted the ROP_UNKNOWN read_out_protection_mode values based on the datasheets/reference manuals. For instance there is a single reference manual for STM8AF and STM8S, so obviously these devices have the same handling for ROP. The other changed files are cosmetic changes.
PR is not ready for merging yet, but I'm interested to know your results on other devices, and happy to take comments. Thanks for testing & reviewing!
I'll try to find a bit of time for testing next week or the week after.
I tried with an STM8AF5288:
root@notebook6:/tmp/stm8flash# ./stm8flash -c stlinkv2 -a
STLink: v2, JTAG: v0, SWIM: v4, VID: 8304, PID: 4837
found SP = 0x17ff, assuming ram size = 6K
bootrom is present
found PC = 0x6000 : mcu currently stalled in bootrom
auto-detection failed with code -2
No part has been specified
With a STM8S003K3 I get a segfault:
root@notebook6:/tmp/stm8flash# gdb --args ./stm8flash -c stlink -a
GNU gdb (Debian 10.1-2) 10.1.90.20210103-git
[…]
Reading symbols from ./stm8flash...
(gdb) run
Starting program: /tmp/stm8flash/stm8flash -c stlink -a
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7d6f640 (LWP 39929)]
Thread 1 "stm8flash" received signal SIGSEGV, Segmentation fault.
0x00005555555578a9 in stlink_swim_read_range (pgm=0x555555564220 <pgms>, device=0x0, buffer=0x555555564aa0 <buffer> "", start=32768, length=4) at stlink.c:403
403 stlink_swim_write_byte(pgm, 0x00, device->regs.CLK_CKDIVR); // mov 0x00, CLK_DIVR
(gdb) bt
#0 0x00005555555578a9 in stlink_swim_read_range (pgm=0x555555564220 <pgms>, device=0x0, buffer=0x555555564aa0 <buffer> "", start=32768, length=4) at stlink.c:403
#1 0x000055555555d0e0 in autodetect (pgm=0x555555564220 <pgms>, autodetect_device=0x7fffffffdeb0) at autodetect.c:400
#2 0x000055555555a874 in main (argc=4, argv=0x7fffffffe1f8) at main.c:415
P.S.: Same with STM8S105C6. Maybe the segfault is triggered by the use of stlink instead of stlinkv2?
I tried with an STM8AF5288:
root@notebook6:/tmp/stm8flash# ./stm8flash -c stlinkv2 -a STLink: v2, JTAG: v0, SWIM: v4, VID: 8304, PID: 4837 found SP = 0x17ff, assuming ram size = 6K bootrom is present found PC = 0x6000 : mcu currently stalled in bootrom auto-detection failed with code -2 No part has been specified
not good. it means no part was autodetected. do you mind activating and sharing debug output? It will indicate if there is just a bug in the algorithm, or just that the autodetect approach isn't going to work at all. As a side note, I have a bit lost interest in this PR, so if you don't see real advantage in proceeding, I don't mind to close it straight away.
With a STM8S003K3 I get a segfault:
root@notebook6:/tmp/stm8flash# gdb --args ./stm8flash -c stlink -a GNU gdb (Debian 10.1-2) 10.1.90.20210103-git […] Reading symbols from ./stm8flash... (gdb) run Starting program: /tmp/stm8flash/stm8flash -c stlink -a [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff7d6f640 (LWP 39929)] Thread 1 "stm8flash" received signal SIGSEGV, Segmentation fault. 0x00005555555578a9 in stlink_swim_read_range (pgm=0x555555564220 <pgms>, device=0x0, buffer=0x555555564aa0 <buffer> "", start=32768, length=4) at stlink.c:403 403 stlink_swim_write_byte(pgm, 0x00, device->regs.CLK_CKDIVR); // mov 0x00, CLK_DIVR (gdb) bt #0 0x00005555555578a9 in stlink_swim_read_range (pgm=0x555555564220 <pgms>, device=0x0, buffer=0x555555564aa0 <buffer> "", start=32768, length=4) at stlink.c:403 #1 0x000055555555d0e0 in autodetect (pgm=0x555555564220 <pgms>, autodetect_device=0x7fffffffdeb0) at autodetect.c:400 #2 0x000055555555a874 in main (argc=4, argv=0x7fffffffe1f8) at main.c:415P.S.: Same with STM8S105C6. Maybe the segfault is triggered by the use of stlink instead of stlinkv2?
Yes, it is linked to the use of stlink; the stlinkv2 driver code was updated, but not stlink. current autodetect will only work with the updated stlinkv2 segfault here is because read_range tries to access the device structure, which is uninitialized (we're trying to initialize it by autodetect instead of by '-p'). Sorry, but current code is in proof of concept stage.
The STM8AF5288 debug output:
root@notebook6:/tmp/stm8flash# ./stm8flash -c stlinkv2 -a
GET_VERSION
STLink: v2, JTAG: v0, SWIM: v4, VID: 8304, PID: 4837
GET_CURRENT_MODE
-> 03 00
SWIM READBUFSIZE
-> 0x1800
SWIM READ_CAP 01
-> 00 01 02 04 00 00 00 00
SWIM ASSERT_RESET
status 00 00 00 00
SWIM ENTER_SEQ
status 01 00 00 00
status 00 00 00 00
SWIM WRITEMEM 00 01 00 00 7f 80 a1
status 01 00 00 00
status 00 01 00 00
SWIM WRITEMEM 00 01 00 00 7f 99 09
status 01 00 00 00
status 00 01 00 00
SWIM DEASSERT_RESET
status 00 00 00 00
SWIM READMEM 00 01 00 00 7f 80
status 01 00 00 00
status 00 01 00 00
SWIM READBUF
-> 0xa3
SWIM RESET
status 00 00 00 00
SWIM WRITEMEM 00 01 00 00 7f 80 b3
status 01 00 00 00
status 00 01 00 00
SWIM SPEED 01
status 00 00 00 00
continuing in high speed swim
starting autodetection
read range
read 0x8000 to 0x8004
SWIM READMEM 00 04 00 00 80 00
status 01 00 00 00
status 00 04 00 00
SWIM READBUF
reading 0x82008007 at flast start address : no read-out protection active. proceeding with autodetection
read range
read 0x7f08 to 0x7f0a
SWIM READMEM 00 02 00 00 7f 08
status 01 00 00 00
status 00 02 00 00
SWIM READBUF
found SP = 0x17ff, assuming ram size = 6K
read range
read 0x6000 to 0x6004
SWIM READMEM 00 04 00 00 60 00
status 01 00 00 00
status 00 04 00 00
SWIM READBUF
reading 0x9bad0c25 at bootrom start address : bootrom is present
read range
read 0x7f01 to 0x7f04
SWIM READMEM 00 03 00 00 7f 01
status 01 00 00 00
status 00 03 00 00
SWIM READBUF
found PC = 0x6000 : mcu currently stalled in bootrom
read range
read 0x4ffc to 0x5000
SWIM READMEM 00 04 00 00 4f fc
status 01 00 00 00
status 00 04 00 00
SWIM READBUF
id @ 4ffc = 0x0
read range
read 0x67f0 to 0x67f4
SWIM READMEM 00 04 00 00 67 f0
status 01 00 00 00
status 00 04 00 00
SWIM READBUF
id @ 67f0 = 0x37394142
1 potential matches left
checking type STNRG
read range
read 0x0030 to 0x0034
SWIM READMEM 00 04 00 00 00 30
status 01 00 00 00
status 00 04 00 00
SWIM READBUF
uniqueID initial 4 bytes = 0x0
-> no valid unique ID
read range
read 0x67f1 to 0x67f5
SWIM READMEM 00 04 00 00 67 f1
status 01 00 00 00
status 00 04 00 00
SWIM READBUF
id @ 67f1 = 0x39414246
autodetection completed
SWIM READMEM 00 01 00 00 7f 80
status 01 00 00 00
status 00 01 00 00
SWIM READBUF
-> 0xb3
SWIM WRITEMEM 00 01 00 00 7f 80 b7
status 01 00 00 00
status 00 01 00 00
SWIM GEN_RST
status 00 00 00 00
SWIM EXIT
auto-detection failed with code -2
No part has been specified
Well, I was assuming the tables in STVP were correct. STM8AF5288 should read 0x55576588 at address 0x67F1, but it doesn't. That makes this whole approach rather useless.