Special thanks to these projects, nim-platformio and svd2nim, I've been able to get an LED to blink on a ST Nucleo F446RE board (details). I've had a brief chat with @auxym regarding svd2nim since he's the most recent developer for svd2nim. But I also wanted to open up the discussion to the wider audience.
I made this analysis of the assembly code generated using the output of svd2nim. TL;DR: simple read() and write() work great with one modification. But the write() that accepts values for each field needs work.
Hi! Could you let me know how you produced the assembly output (for a specific proc?). I'll play around with different (nim) codegen options and see how that ends up compiled by gcc.
Are you compiling with -d:danger --opt:size?
I am not using those options. I will give them a try after this.
I just created a repo, nucleo_blink, that might help you recreate my work. It's a VSCode project that will recommend the PlatformIO extension. Then there's also a platformio.ini file that will set the (platform, board and framework) so that PlatformIO will install the arm-none-eabi-gcc toolchain, proper linker scripts and then fetch the nim-platformio dependency (the one that I mod'd to support STM32 processors). I don't know if that will all happen automatically in one sequence; it may need some retries.
Assuming you can get that working, then perform a PlatformIO Build via VSCode command. It should compile main.nim and do all the .c and .o cross-compiling behind the scenes and give you output in the Terminal window.
Assuming you have a successful build, then find your output .elf file, <project dir>/.pio/build/nucleo_f446re/firmware.elf. Run command line objdump on that file to get the disassembly:
> path/to/arm-none-eabi-objdump.exe -D path/to/firmware.elf > path/to/firmware.elf.txt
My path to objdump is: C:\Users\dwhall\.platformio\packages\toolchain-gccarmnoneeabi\bin\arm-none-eabi-objdump.exe.
Are you compiling with -d:danger --opt:size?
I tried them and did not see much difference, though I have not tried all Items from the analysis. My nim.cfg has checks:off which I find more calming than d:danger. I will leave opt:size in my nim.cfg.
The case I want to fix first is Item 5, the multi-line modifyIt(). This is the pattern I would use the most in my projects and I estimate that since the single-item is working so well, there's a good chance of figuring out why multi-item blows up.
Progress! I focused on the multi-line modifyIt proc and found that the svd2nim code generator passes a variable value to some bitops. I rewrote a proc by hand using constant values and the resulting assembly was much more compact. Here's the writeup. Using constants, of course, gives the nim and C optimizers a greater chance of success.
So now I think we need to dream up some bitops like code that either handles the 1-bit sized field better (as a special case of the general set-field procs) or can perform the multi-bit masking and setting with constant values.