Open maxgerhardt opened 3 years ago
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.
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..
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)
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?
A different question: What are the plans for release?
I published it yesterday https://github.com/platformio/platform-ststm8/releases/tag/v2.0.0
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.
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 https://github.com/platformio/platformio-vscode-ide/issues/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.
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?
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)
@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.
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. https://github.com/tenbaht/sduino/issues/121 has been long open on this, but no change yet.
Issue is just for tracking what was said in #38.
Hopefully there will be an update on that soon, so that debugging can be fully working in any framework :)