-
Notifications
You must be signed in to change notification settings - Fork 913
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
Add RP2350 support #4459
base: dev
Are you sure you want to change the base?
Add RP2350 support #4459
Conversation
Size difference with the dev branch: Binary size differencenot the same command! tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650 go: downloading tinygo.org/x/tinyfont v0.3.0 drivers/sizes-dev.txt has more commands than drivers/sizes-pr.txt tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go flash ram before after diff before after diff 16736 16736 0 0.00% 4308 4308 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650 61012 61012 0 0.00% 6176 6176 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adt7410/main.go 9468 9468 0 0.00% 4740 4740 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adxl345/main.go 13424 13424 0 0.00% 6780 6780 0 0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/amg88xx 8580 8580 0 0.00% 4732 4732 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go 11584 11584 0 0.00% 6556 6556 0 0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/apds9960/proximity/main.go 9668 9668 0 0.00% 4752 4752 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go 8196 8196 0 0.00% 2304 2304 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go 138668 138668 0 0.00% 40348 40348 0 0.00% |
This is great @soypat thank you for getting going on it! Please see tinygo-org/cmsis-svd-data#1 for some related supporting work. |
Yes! I've looked at it and generated the device definitions. I just added a new commit with stubs for machine and runtime and am getting the following error during linking:
|
I'm not too sure that the |
OK, blinky1 now compiles. I am afraid of flashing the resulting .uf2 😅 |
I've noticed the bootloader is not included in the build pipeline. I can write invalid assembly in it and everything still compiles... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my main concerns:
absolutely, make sure serial out is functional
make sure panic works
empty functions should panic
make sure all that stuff in ldscript is right
#if should have no defaults, there should always be a value, and the default should be "something was not set that is expected to be set"
/* See Rust for a more complete reference: https://github.com/rp-rs/rp-hal/blob/main/rp235x-hal-examples/memory.x */ | ||
MEMORY | ||
{ | ||
/* 2MiB safe default. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these known to match the machine hardware? This is one of the places you really want to get it right, or you'll be in Debug Hell forever.
targets/rp2350_boot2_generic03h.s
Outdated
sw a0, QMI_M0_RCMD_OFFSET(a3) | ||
li a0, INIT_M0_RFMT | ||
sw a0, QMI_M0_RFMT_OFFSET(a3) | ||
#else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make the #else have an actual value, #elseif arm and have the fallthrough #else do a #error. Maybe that's too picky, but I've been burned by default behavior.
@rminnich I'll leave all functions so far in panic("unimplemented") state. We should focus on getting the bootloader working and setting the LED pin high/low. |
@deadprogram @aykevl I'm melding the RP2040 and RP2350 APIs... it's got some design decisions that some may consider questionable. I've managed to reuse a lot of logic between them at the cost of some magic constant weirdness. There are a few cases where code reuse was just not worth it though such as with the peripheral reset. Love to hear your input on how it is coming along. |
OK I feel like I've gotten the hang of writing Cortex assembler and understand what is going on with the linker scripts. I cannot however get to the point of flashing the RP2350 correctly- after I flash it the RP2350 enters bootoader mode and appears as a mass storage device ready to get flashed again. |
Working on a a pico binary encoder/decoder https://github.com/soypat/picobin. Raspberry Pi's picotool is missing lots of features to inspect binaries, which makes sense- it's not designed to reverse engineer their stuff. Also RP2350 documentation on pico binary layout is VERY lackluster compared to their hardware documentation so having code to describe the layout gives me confidence on what exactly is going on. |
OK. I've run into a limitation of the Note: @aykevl This PR would add aforementioned tinyboot as a dependency of tinygo compiler. I'm in favor of third partying build tools so that others can use the package and find bugs in parallel to the TinyGo compiler. Edit: progress here: https://github.com/soypat/tinyboot/tree/main/build/xelf |
Thanks for all you great work on this! I was able to bodge together enough fixes to build a working RP2350 GPIO out example here: Blinkinlabs@fbb5234 I cheated in several ways to get it to work so it isn't pullable as-is. The main changes were:
After disabling some other initialization bits which were causing the image to hang, I succeeded in running a very short that just turns the LED on and off repeatedly.
|
Here's also a very basic python tool for extracting IMAGE_BLOCKs from rp2350 ELF files: https://gist.github.com/cibomahto/790c1a34d6001a088de9bfba6e27ed23 |
@soypat What do you mean by this? It's generally not possible to move stuff in the firmware file after linking. |
Would it be possible to write binaries in a similar way that ESP8266/ESP32 binaries are created? So the ELF file is not modified, instead the ELF file is converted to a binary in a custom way that adds the special header. |
@aykevl Looking at the esp builder: I think not, because for the RP2350, the pico SDK generates a normal ELF image, just with some magic headers embedded in it. For RP2350 ELF output, the pico SDK generates a normal ELF file directly, with one info block tucked between the isr table and the start of program image, and another in a second ELF section, at the end of the program image. The first one needs to include an offset to the second one (which needs to be calculated after the program image size is determined), but the second one points back to the memory address of the first one, which should be fixed. If this is done as a post-processing step, it does require rewriting the ELF file in order to make those two changes. Perhaps the builder could insert a dummy section for the second block, and then patch it with elfpatch? At a glance, this seems like it should also allow UF2 files to be generated from the patched ELF. However, the datasheet also gives an example of a minimum implementation that doesn't need any post processing, just a simple header that needs to be placed in the first 4k of the image. I've chosen this approach to get a basic output working. The disadvantage of this is that it won't support any of the fancier validation options that the rp2350 boot rom offers, such as image signing or partition support. |
That looks like a much simpler way to do it!
This can probably also be done by the linker, with some special assembler magic. |
Correct. These 'blocks' each contain a pointer to the next block, in the form of an offset. The rp2350 bootrom uses the offsets to walk through the block chain, and to verify that they form a closed loop back to the first block. The trick is that if you only have one block, you can point it back to itself by specifying a zero offset, so no calculation needs to be done. For the proof of concept, I gave it an explicit position by modifying the arm linker file: Blinkinlabs@fbb5234#diff-2048f2f7e5dcd7f7efd321f90018d841b002168ec4aa103d33363f4f4f316171R12 . This is very straightforward, but seems a little invasive to add that for all ARM targets. Another straightforward option is to include a modified version of arm.ld just for the rp2350, but I don't see any other examples that do that and it's probably more difficult to maintain. Maybe there's an assembler directive to put something at the beginning of .text? |
Actually in my opinion it's fine, if the name is slightly different. Something more generic/descriptive. What about |
Seeks to solve #4452.
Notes:
gen-device-svd.go
Changed to support multiline Metadata descriptions such as the one found for the RP2350.rp2350.ld
takes rust version as reference. Ideally I'd like a minimal version, I've left it all in so people with more experience can note of what is required and what is "extra"