platformio / platform-ststm8

ST STM8: development platform for PlatformIO
https://registry.platformio.org/platforms/platformio/ststm8
Apache License 2.0
40 stars 26 forks source link

Add debug support using STLink(/V2) via OpenOCD #31

Closed cocus closed 3 years ago

cocus commented 3 years ago

Hi! I'm currently porting an existing project I have from IAR to SDCC and Platformio. One thing I really need is the debug feature using the STLink/V2 probe I have. I found out that this platform on platformio doesn't support being debugged, although the STM8S105 from the ST8Discovery kit does allow it (even if that one also has an STLink embedded on it). So I figured I could give that board a try, even if my MCU is different. It turns out that the openocd doesn't allow to use SWIM with the provided arguments, but it can use SWIM by changing the arguments you pass to it. Then I managed to run OpenOCD with custom parameters, with the following code added to platformio.ini:

; settings for the STM8S003, 8K flash, 1K ram
board_build.mcu = stm8s003f3p6
board_build.extra_flags = -DSTM8S003
board_upload.maximum_size = 8192
board_upload.maximum_ram_size = 1024

debug_tool = custom
debug_server =
  $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd
  -f interface/stlink-dap.cfg
  -f target/stm8s003.cfg
  -c "init"
  -c "reset halt"
upload_protocol = stlinkv2

It's actually able to communicate with the board I have, but I don't have a complete running code to validate it actually works. Moreover, OpenOCD complains that the provided image doesn't contain debug symbols and I should specify them with the "file" command. I thought platformio would be creating an .elf file with debug symbols, but might not be the case? Or am I missing something?

Thanks!

maxgerhardt commented 3 years ago

Ah, I was about to open this issue as well.

I've played around a long time with this circa a month ago and had a good fight with sdcc, stm8-gdb and openocd; the first two to make them generate an ELF file with debug symbols that stm8-gdb can read, and the last one to figure out the correct command to program the chip, since it wouldn't except the usually used program command (https://sourceforge.net/p/openocd/tickets/293/). In the end (see bottom) I managed to teach PlatformIO how to flash the binary via openocd.

I'll talk about what I've expiermented with / found out / having problems with so that maybe other people can gloss over it, too.

For SDCC to include debug information into the compiled files (or the .rel files), it must be given the --debug flag. However on Windows there's a nice bug (https://sourceforge.net/p/sdcc/bugs/2970/) that will make sdcc generate a file with Unix lineendings which then it itself cannot read at a later point since it's using the file-encoding of the OS, Windows in my case, and fails.

I've experimented quite a bit with it and used advanced scripting to work around this bug by last-minute fixing the line-endings before feeding into SDCC. This does allow it to compile correctly with --debug.

However, as a next blockade, reading the generated .elf file with stm8-gdb (which is a separate project from SDCC) still says that no debug information was found. At this point I'm not sure whether SDCC is still generating the ELF in a wrong way or if stm8-gdb has a bug.

In any case, I'm also able to connect to my chip using OpenOCD. Using simliar commands per your debug_x directives above, I'm able to connect to a separately started OpenOCD instance. It's a bit hacky (after connecting I have to type target remote :3333 to actually connect to OpenOCD) but there are signs of life: The registers of the STM8 core are being read out (PC, A, X, Y, SP, CC) and there's a callstack, albeit with all function addresses being unknown due to the ELF file or stm8-gdb.

grafik

I'll continue my journey to get this working further regarding:

And hopefully at the end, we have fully-featured development environment for STM8 chips with PlatformIO, beatiful and correctly working Intellisense for SDCC, and debugging with OpenOCD with the help of debug symbols generated by SDCC and read by stm8-gdb, plus register decoding as one can e.g. see here, as it already works for other PlatformIO platforms.


Addendum: I'm testing with a STM8S103F3P6 breakout board. My platformio.ini is

[env:stm8sblue]
;build_type = debug 
platform = ststm8
board = stm8sblue
framework = arduino
;upload_protocol = stlinkv2
upload_protocol = custom
upload_flags =
    -f
    interface\stlink-dap.cfg
    -c 
    transport select swim
    -f 
    target\stm8s103.cfg
upload_command = $PROJECT_PACKAGES_DIR/tool-openocd/bin/openocd $UPLOAD_FLAGS -c "init; reset halt; load_image {$SOURCE}; verify_image {$SOURCE}; reset; shutdown"
debug_tool = custom 
; empty. You need to start openocd yourself with
; openocd -f interface\stlink-dap.cfg -f target\stm8s103.cfg
debug_server =
;    $PROJECT_PACKAGES_DIR/tool-openocd/bin/openocd
;    -f
;    interface\stlink-dap.cfg
;    -f 
;    target\stm8s103.cfg
debug_port = localhost:3333
;debug_load_mode = manual
debug_init_break = 
;tbreak setup
debug_init_cmds =
    $INIT_BREAK
;    monitor init
;    monitor reset halt
debug_load_mode = manual
build_flags = --debug --fverbose-asm --verbose
debug_build_flags = --debug
extra_scripts = fix_debug_compile.py

and the fix_debug_compile.py script is

import shutil
Import("env")

def dos2unix(file_to_strip, output_file):
    content = ''
    outsize = 0
    with open(file_to_strip, 'rb') as infile:
        content = infile.read()
    with open(output_file, 'wb') as output:
        for line in content.splitlines():
            outsize += len(line) + 1
            output.write(line + b'\n')

def fix_elf(source, target, env):  
    # build our own 
    #print(env["LINKCOM"])
    #env.Execute([env["LINKCOM"]])
    pass

def fix_rel_file(source, target, env):

    for src in source:
        print("dos2unix fix: " + str(src))
        dos2unix(str(src), str(src)+".fixed")
        shutil.move(str(src)+".fixed", str(src))
# so that debug output ends up in the final ELF file
#env.Append(LINKFLAGS=["--debug"])
# hook pre-build actions of these files to workaround SDCC error: 
# if .rel files compiled in --debug mode have Windows line endings, linking will fail.
env.AddPreAction("$BUILD_DIR/libFrameworkArduino.lib", fix_rel_file)
env.AddPreAction("$BUILD_DIR/libFrameworkArduinoVariant.lib", fix_rel_file)
env.AddPreAction("$BUILD_DIR/${PROGNAME}.elf", fix_rel_file)
env.AddPostAction("$BUILD_DIR/${PROGNAME}.elf", fix_elf)

env.Append(LINKFLAGS = ["--verbose", "--debug", "--fverbose-asm", "--no-peep"])
#env["OBJSUFFIX"] = ".o"
#env.Replace(LD="sdld")
#env["LINK"] = "stm8-ld"
##env["LINKFLAGS"] =[]
cocus commented 3 years ago

Hi @maxgerhardt ! I've finally made it and it works :) you were on the right track, since I was there some weeks ago. However, I found out that the sdcc compiler doesn't emit debug symbols on the object code if you don't pass a specific flag. Also, I found out that "something" in the PIO is passing non-sdcc args to sdcc, like -O2. So my final solution was to add some args to make sdcc emit proper dwarf debug symbols (thanks to the SDCC forum, where they replied about my issue).

Following is my platformio.ini, and that's the only thing you need to change. I know, it'll be nice to have these on the python files, but it's a good starting point.

[env]
platform = ststm8
board = stm8sdisco
framework = spl

; settings for the STM8S003, 8K flash, 1K ram
board_build.mcu = stm8s003f3p6
board_build.extra_flags = -DSTM8S003
board_upload.maximum_size = 8192
board_upload.maximum_ram_size = 1024

[env:stm8sblue_debug]
build_type = debug
# add debug symbols, and in dwarf format on each object code. linker will pick them up
build_flags = --debug --out-fmt-elf
# not sure who's adding these?
build_unflags = -Og -ggdb2 -g2

debug_tool = custom
debug_server =
  $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd
  -f interface/stlink-dap.cfg
  -f target/stm8s003.cfg
  -c "init"
  -c "reset halt"

[env:stm8sblue_release]
upload_protocol = stlinkv2

I'm using an STM8S003, with an STLinkV2 on a generic volt/amp meter chinese board. image

maxgerhardt commented 3 years ago

Oh wow thank you, this actually works for me too! :)

grafik

I however wasn't able to even debug the spl-blink example since the flash size exploded in debug mode. But I've quickly extended https://github.com/maxgerhardt/stm8-headers-pio to have a baremetal project and used this as platformio.ini

[env:stm8sblue_debug]
platform = ststm8
board = stm8sblue
;framework = spl
build_type = debug
build_flags = --debug --out-fmt-elf
build_unflags = -Og -ggdb2 -g2
debug_tool = custom
debug_server =
  $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd
  -f interface/stlink-dap.cfg
  -f target/stm8s103.cfg
  -c "init"
  -c "reset halt"

for my STM8S103 chip, and it works per above.

# not sure who's adding these? build_unflags = -Og -ggdb2 -g2

These come from the core as the default debug flags that get applied when using build_type = debug (which is also used for compilation during the debugging phase)

https://github.com/platformio/platformio-core/blob/7f1f760645fa63f2ac874620b73d31ffbaf9a040/platformio/project/options.py#L626

I might open an issue there to have this fixed.

But this is really good. Once the fix that that the debug mode builds with the --debug --out-fmt-elf flags by default, and OpenOCD as the builtin server is supported, it looks like STM8 debugging out-the-box is on its way.

CC @valeros for-your-interest.

cocus commented 3 years ago

Right, the flash usage is pretty high when you use SPL's code; hence I'm not using it. Also, in my example, the flash size and ram size are set for the stm8s003. If the s103 has more flash or ram, please change these values on platformio.ini. In any case, it'd not be a smart choice to use SPL if it uses half of your available flash!.

About the addition of the "core debug flags", amazing!

About OpenOCD, it should be already supported, it's just we're not passing the appropriate flags to the server on this particular platform. As you can see, everything that the package platform-ststm8 provides seems to be enough to debug any stm8 micro (that's supported by the shipped version of OpenOCD, which at least covers the s003 and s103).

maxgerhardt commented 3 years ago

Great stuff! With help from @gicking, even peripheral registers decoding (see "Peripherals" panel) is on the way after creating nearly the correct SVD files.

VSCode_Peripherals

vscode_iteration_2

I plan to create and PR the GDB debugging support and SVD files directly into this platform soon so that it becomes a built-in thing :)

valeros commented 3 years ago

Resolved in #38

anshchawla521 commented 5 months ago

Hi , I know the issue is closed and quite old but I am on platform io 6.1 and was trying to get debugging working for stm8s003f3p6 sadly i am getting a .pioinit:13 error. Any idea what could be causing this ?

I hv tried uploading the code and that works fine , the upload and debug also do work fine for stm8s103f

maxgerhardt commented 5 months ago

Well what's the log when you run pio debug --interface=gdb -- -x .pioinit in the core CLI?

anshchawla521 commented 5 months ago

I got the following output

Processing debug (platform: ststm8; board: stm8s003f3; framework: )
--------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm8/stm8s003f3.html
PLATFORM: ST STM8 (2.1.0) > ST STM8S003F3 chip
HARDWARE: STM8S003F3P6 16MHz, 1KB RAM, 8KB Flash       
DEBUG: Current (stlink) External (stlink)
PACKAGES:
 - tool-stm8binutils @ 0.230.0 (2.30)
 - toolchain-sdcc @ 1.40200.0 (4.2.0)
No dependencies
Building in debug mode
Checking size .pio\build\debug\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=====     ]  49.4% (used 506 bytes from 1024 bytes)
Flash: [========= ]  90.0% (used 7376 bytes from 8192 bytes)
============= [SUCCESS] Took 2.03 seconds =============\Reading symbols from C:\Users\HP\Documents\PlatformIO\Projects\b3603\.pio\build\debug\firmware.elf...done.

PlatformIO Unified Debugger -> https://bit.ly/pio-debugPlatformIO: debug_tool = stlink
PlatformIO: Initializing remote target...
\xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev-00378-ge5be992df (2020-06-26-09:29)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_gates_jtag srst_open_drain connect_deassert_srst

Info : tcl server disabled
Info : telnet server disabled
Info : STLINK V2J40S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.249304

.pioinit:13: Error in sourced command file:
(gdb) Remote communication error.  Target disconnected.: Success.

image

Weirdly enough . I wrote a basic code to test stms103f3 and when I ran the same code on stms003f3 the debugger worked(although I need to do a clean before it starts working)

image

now if I stop this debug session and retry to debug with old code it starts debugging although i dont think properly as none of the breakpoints are getting hit.

image

anshchawla521 commented 5 months ago

So I disabled the IO operations on the swim lines and tried to debug the code again , this time I have a new error.

image

and yes I hv read about DWARF error and how sdcc guys say they fixed it but it didn't actually get fixed and then this thread was a work around. BUT where do I stand now with this new error ?

maxgerhardt commented 5 months ago

Yes the problems with SDCC were notorious. Is it possibly for you to upload your exact project files into a repo and link it here? Or at least a minimal version which makes that error appear.

anshchawla521 commented 5 months ago

https://github.com/anshchawla521/b3603

I have the repo link here for now , but will try to put together a minimal version

maxgerhardt commented 5 months ago

Are you able to debug a simple blinky project with the stm8s003f3, like https://github.com/platformio/platform-ststm8/tree/develop/examples/spl-blink?

anshchawla521 commented 5 months ago

I cannot build the SPL blink example there was no entry to stm8s003f3 in platform.ini so I manually added it like I did in my project But this result in the compiled code to be 277% of the total memory.

image image

Also do i need to do #define STM8S003 so that only some files in stm8s.h get compiled or pio takes care of that ?