vdudouyt / stm8flash

program your stm8 devices with SWIM/stlinkv(1,2)
GNU General Public License v2.0
401 stars 182 forks source link

autodetect first working version #147

Open stefaandesmet2003 opened 2 years ago

stefaandesmet2003 commented 2 years ago

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!

spth commented 2 years ago

I'll try to find a bit of time for testing next week or the week after.

spth commented 2 years ago

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
spth commented 2 years ago

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?

stefaandesmet2003 commented 2 years ago

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.

stefaandesmet2003 commented 2 years ago

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?

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.

spth commented 2 years ago

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
stefaandesmet2003 commented 2 years ago

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.