tinygo
tinygo copied to clipboard
board: Add support for Arduino Portenta H7
Description
This PR implements the bare essentials for a functioning LED blinky on the Arduino Portenta H7. However, it is composed of two different target ports, one for each core of the STM32H747, a Cortex-M7 (stm32h7x7_cm7
) and a Cortex-M4 (stm32h7x7_cm4
).
A new blinky example was added blinky-dual-core
to demonstrate dual-core functionality, where each core blinks a different on-board LED at different intervals. The machine
package's GPIO implementation transparently handles the synchronization between cores when configuring pin modes and setting pin levels, so the user doesn't have to be aware of this in their application code.
Limitations
Unfortunately, when changing SVD providers for STM32 (154c7c691bc5c25ba31b84d2583e833ede881de4), the register definitions are no longer generated for these targets. To test this board, you will need to generate register definitions (make gen-device
) on a revision prior to that commit. Need advice on how to correct this.
Details
Board
Microcontroller
- STMicroelectronics STM32H747XI
Configuration
Core | Frequency | Flash | RAM (Total) | Bootloader |
---|---|---|---|---|
Cortex-M7 | 480 MHz | 768 KiB | 1 MiB | DFU (USB) |
Cortex-M4 | 240 MHz | 1024 KiB | 1 MiB | DFU (USB) |
I haven't looked at the PR itself. What I do want to note, is that there are may things that need to be fixed before multi-core can work correctly. Perhaps it's best to do that separately from this PR (for example, with an already supported chip).
Some things I can think of right away:
- The memory allocator doesn't lock the heap when it does a memory allocation. Doing this from multiple cores is therefore racy.
- The primitives in
sync/atomic
rely on disabling interrupts to operate atomically. This works on a single core chip but won't work on a multi core chip. See the__sync_*
primitives in https://github.com/tinygo-org/tinygo/blob/release/src/runtime/arch_cortexm.go. - There are many other places that need atomicity where this is done by disabling interrupts, for example channels and the scheduler itself. These need some other way of locking.
I haven't looked into how this can be done in a reliable way. I believe most big CPUs do this by locking specific memory locations but I have no idea how this is done on these microcontrollers.
Perhaps you need to rebase against the dev
branch to get the tests passing?
@deadprogram There is actually a bug in gen-device-svd
, preventing the register descriptions from compiling