Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugging not working with Arduino examples #48

Open
maxgerhardt opened this issue Mar 25, 2021 · 11 comments
Open

Debugging not working with Arduino examples #48

maxgerhardt opened this issue Mar 25, 2021 · 11 comments

Comments

@maxgerhardt
Copy link
Contributor

Issue is just for tracking what was said in #38.

However, debugging the Arduino framework code is currently not possible because of one freaking file failing compilation in --debug mode: WInterrupts.c. I've filed a bug at https://sourceforge.net/p/sdcc/bugs/3199/. Would be nice to get that resolved before release.

Hopefully there will be an update on that soon, so that debugging can be fully working in any framework :)

@valeros
Copy link
Member

valeros commented Mar 25, 2021

Does it make sense to submit an issue to Sduino repo as well? It seems that a perfectly valid SDCC keyword __naked here breaks the build process.

Found a similar report here so it indeed seems like a SDCC bug.

@maxgerhardt
Copy link
Contributor Author

maxgerhardt commented Mar 25, 2021

Oh, that's a good tip!

I've commented out the __naked in the C file, and then compiling that single file went through, but linking failed with

Unexpected character `\012' in asxxxx .rel file

Which is due to this bug: https://sourceforge.net/p/sdcc/bugs/2970/ (SDCC outputs a file with line-endings on Windows that it itself cannot read back later)

Which is also really strange because why would the linker fail now and not before?

So I added a workaround script to fixup all .rel files:

platform_packages = 
   toolchain-sdcc@~1.40100.0
extra_scripts = fix_debug_compile.py
import shutil
Import("env")
# convert \r\n (dos) to \n (unix)
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_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))
# for all source .rel files when building the lib and elf file
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)

And this got linking working. But for debugging, I'm hitting now the same issue as in #44 that the ELF DWARF symbols are broken. Debugging starts, and I can halt the chip, but it has no idea where it is in the C code.

grafik

But that's at least one step further in finding out the cause.

The firmware built in this debug mode works btw, removing __naked doesn't break it.

EDIT: Now that I think about the Dos2Unix workaround, it may only appear when the archiver sdar is invoked to build an intermediate library archive file.. It does not appear when directly linking 3 .rel files together in debug mode, because the blink-spl example does exactly that and linking works. It may be needed to include this workaround if it is not fixed in the next SDCC version..

@valeros
Copy link
Member

valeros commented Mar 25, 2021

I believe there is a hacky way to build the firmware, but I'm not sure whether it'll work. If sdar complains about .rel files, we can link all the sources as object files and avoid creating static libraries. Simply replace https://github.com/platformio/platform-ststm8/blob/develop/builder/frameworks/arduino.py#L110:L118 with the following code:

    env.BuildSources(
            os.path.join("$BUILD_DIR", "FrameworkArduinoVariant"),
           os.path.join(FRAMEWORK_DIR, "variants", env.BoardConfig().get("build.variant"))
    )

env.BuildSources(
    os.path.join("$BUILD_DIR", "FrameworkArduino"),
    os.path.join(FRAMEWORK_DIR, "cores", env.BoardConfig().get("build.core"))
)

Then we need to remove --out-fmt-elf only for WInterrupts in an extra script:

extra_scripts =
    pre:winterrupts_fix.py
Import("env")

def replace_node(node):
    if "WInterrupts" not in node.name:
        return node
    return env.Object(
        node,
        CFLAGS=[f for f in env["CFLAGS"] if f != "--out-fmt-elf"]
    )

env.AddBuildMiddleware(replace_node)

@maxgerhardt
Copy link
Contributor Author

maxgerhardt commented Mar 30, 2021

I've tested the above python code (with the code fix to remove __naked), and it indeed builds it differently without archives in debug mode successfully.

RAM:   [=         ]   8.2% (used 84 bytes from 1024 bytes)
Flash: [========= ]  93.8% (used 7680 bytes from 8192 bytes)
Building .pio\build\stm8sblue\firmware.hex
================ [SUCCESS] Took 3.29 seconds ================

However, the resulting ELF file still has the bug

Reading symbols from ..pio\build\stm8sblue\firmware.elf...Dwarf Error: Could not find abbrev number 117 in CU at offset 0x74 [in module C:\Users\Max\temp\TetrisThemeArduino.pio\build\stm8sblue\firmware.elf]

as per #44, so no debugging possible :(

Also, with using archives and with the dos2unix fix above, the resulting binary is much smaller

RAM:   [=         ]   7.4% (used 76 bytes from 1024 bytes)
Flash: [=====     ]  54.9% (used 4498 bytes from 8192 bytes)
Building .pio\build\stm8sblue\firmware.hex
================ [SUCCESS] Took 3.35 seconds ================

So we should rather stay archives. And maybe with the dos2unix fix for Windows in these cases where sdcc --debug outputs .rel files with line-endings that sdar can't read... if it doesn't get fixed along with the DWARF error in the next version, that is.

A different question: What are the plans for release? New boads were added, SDCC was updated, tools like stm8gal etc were updated, the Arduino core was update, debugging was added, it however just works on baremetal examples where SDCC bugs don't occur, like they do in SPL or Arduino builds. This is almost perfect. However sadly, the SDCC people seem slow (the line-ending bug for Windows has been known for a year, all it got was a comment saying 'maybe fixed in 4.1.0, which it didn't), so I'm not expecting an answer on the more critical DWARF generation bug anytime soon. Still the improvements from the last release are substantial. Release now with partly non-functional debugging features or wait for release later?

@valeros
Copy link
Member

valeros commented Mar 30, 2021

A different question: What are the plans for release?

I published it yesterday https://github.com/platformio/platform-ststm8/releases/tag/v2.0.0

@maxgerhardt
Copy link
Contributor Author

There have been new developments in this -- SDCC devs say that naked should not result in that error anymore, per linked bugreport. I still have to get the toolchain (I guess self-compiled) and test this.

@stefaandesmet2003
Copy link

Not sure if this helps, but in my setup debugging STM8 with arduino framework seems working.
I'm on Ubuntu 20.04, so I don't have the windows related SDCC issues.
in packages/framework-arduinoststm8 I modified WInterrrupts.c to remove the __naked keyword :

#define IMPLEMENT_ISR(vect, interrupt) \
 void vect(void) __interrupt((interrupt)>>8) { \
    intFunc[(interrupt)&0xff](); \
  }

And in packages/tool-stm8binutils I had to replace stm8-gdb with a fresh build, because of libpython2.7.so issue similar to platformio/platformio-vscode-ide#1792

platformio.ini is this :

[env:stm8sblack]
platform = ststm8
board = stm8sblack
framework = arduino
upload_protocol = stlinkv2
debug_tool = stlink
debug_build_flags = -D ENABLE_SWIM

the additional debug flag is needed because otherwise sduino disables SWIM during init in wiring_init.c :

void init()
{
#ifndef ENABLE_SWIM
	// free the SWIM pin to be used as a general I/O-Pin
	CFG->GCR = CFG_GCR_SWD;
#endif
...

If the target was still running a non-debug arduino build, SWIM is already disabled and openocd cannot connect. Therefore I press the reset button on the board to keep the target in reset while platformio starts openocd. After that openocd holds target in reset and gdb overwrites the flash with code that has 'ENABLE_SWIM'. So for subsequent debug uploads, no need to press the reset button.

Screenshot from 2021-08-24 14-38-19

@maxgerhardt
Copy link
Contributor Author

That's very interesting, for reference, what does PlatformIO show about the used SDCC version at the beginning of compilation ("PACKAGES:")? You've not overwritten the toolchain-sdcc folder with your own version right?

@stefaandesmet2003
Copy link

nothing changed in toolchain-sdcc.

~/.platformio/packages/toolchain-sdcc/bin$ ./sdcc --version
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/gbz80/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15 4.1.0 #12072 (Linux)
published under GNU General Public License (GPL)

Screenshot from 2021-08-24 15-45-55

@stefaandesmet2003
Copy link

@maxgerhardt @valeros why does platform.py force the use of an older sdcc version for arduino framework?
I've been using sduino with sdcc 4.1.0 without issues whatsoever.

Screenshot from 2021-08-31 09-30-07

@maxgerhardt
Copy link
Contributor Author

maxgerhardt commented Aug 31, 2021

If we don't use the same SDCC version the original SDuino core does (https://github.com/tenbaht/sduino/blob/development/package_sduino_stm8_index.json#L380-L388) there might be situations where the compiled result is different (and behaves different) than in the Arduino IDE, so for compatibility reasons they are kept the same. For SPL there is no "reference compiler", so we use the latest one.

The SDCC update should go through in the core first. tenbaht/sduino#121 has been long open on this, but no change yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants