Portenta Micropython on M7 core, C on M4 core?

I’ve been looking at the C examples and there is a special “bootM4” command to enable the second core. Looking at the init code, I see there’s something to sleep the M4 but not boot it.

the boot macro is defined as

#define bootM4() LL_RCC_ForceCM4Boot() // Provide a memorable alias

Which is in turn defined as

__STATIC_INLINE void LL_RCC_ForceCM4Boot(void)

And Set bit seems to be

#define SET_BIT(REG, BIT) ((REG) |= (BIT))

So I am guessing I should be able to do this with a simple bit of inline assembly.


I can’t seem to find and definition for those two constants RCC->GCR and RCC_GCR_BOOT_C2
and I’m not totally sure how to convert ((REG) |= (BIT)) into assembly.

Can anyone help me boot the M4 core? Or is there another reason this isn’t going to work?

Hi, which C examples are you referring to ? We don’t have any C examples. If you referring to Arduino’s code, you should ask on Arduino’s forums, if you mean ST HAL examples you should ask on ST’s forums. For what it’s worth, I don’t think what you’re trying to do will work because booting the CM4 alone is not enough, it needs a binary to run and that binary’s address needs to be set somewhere first.

That said I added very basic support for the CM4 in our code, but it’s not enabled by default. If you’re comfortable with building the firmware from source, and using command line tools on Linux you can test it and edit the M4 code if needed. Assuming you can do that, first you need to enable this option in omv/boards/PORTENTA/omv_boardconfig.mk


And then rebuild the firmware for TARGET=PORTENTA. This will generate two binaries one for the CM7 and CM4. You’ll need to upload the binaries manually with dfu-util… Reset the board to DFU bootloader (double tap reset) then execute the following commands in order:

../tools/dfu-util -w -d 2341:035b -a 1 -s 0x90F00000 -D drivers/cyw4343/firmware.bin
../tools/dfu-util -w -d 2341:035b -a 0 -s 0x8020000 -D build/bin/cm4.bin
../tools/dfu-util -w -d 2341:035b -a 0 -s 0x8040000:leave -D build/bin/firmware.bin

After reset, the CM4 should blink the green LED a few times and then it go to sleep. You can change the CM4 code/main.c here: cm4/src/main.c

NOTE: If you don’t want the CM4 running anymore just reupload the default firmware with the IDE.

Note: At some point we’ll add support for loading the CM4 binary from SD/flash from Python scripts and booting it, it’s just that this feature is not high priority right now. For now you’re on your own, so please don’t post further questions about this feature or building the firmware in general because it’s not something that we officially support.

Thanks for the update, yes you are correct in thinking I was referring to Arduino examples. I tried my question in the Arduino forum first. They of course don’t answer questions on Micropython.

From: https://docs.arduino.cc/tutorials/portenta-h7/por-ard-dcp
There is a comment “The bootloader of the H7 boards is configured in such a way that only M7 gets booted automatically.” hence why I perceived the need for a command to start the second core.

I’ve got working C code that runs on the M4 core and working Micropython for the M7 core. It is just that I’d like both of them to work together.

I think you’ve hit the nail on the head regarding the comment “that binary’s address needs to be set somewhere first”. It looks like the memory addresses used by the Micropython firmware and that of the Arduino based firmware are different, at least based on your commands posted above.


It is a one-off project so does not matter it won’t have long term support. I’ll experiment with your code so thanks for that and promise not to ask any more questions about the booting two cores.

Yes it seems they use the second bank I think, we use the second flash sector which is currently free, but this may change in the future.

If you use the same address that we use in our firmware (0x08020000) and rebuild the CM4 binary you can follow the procedure above it should work, or you can simply just replace the code in cm4/src/main.c.

Like I said in the future this should be a lot easier, we’ll add support for loading the CM4 fw to memory from Python and run it from there, it’s just wasn’t on the top of the list of things to support for the Portenta, you could try to ask Arduino about adding support for this feature and they will let us know if it needs to be done sooner.


Do you have any progress on this topic, it is not high priority but do you have a plan?
It will be great!

Basically our use case is fairly easy
We need to perform image recognition (M7 MicroPython) while acquiring some data from sensors via the M4, package the result and push it via Lora.

Today we have a system that is using R-PI + Coral + sensors + NB_Iot to achieve that and we are hoping to port everything on a Portenta H7 + Visionshield with Lora

We are also discussing with arduino as in their product page they say:
The Portenta H7 simultaneously runs high level code along with real time tasks. The design includes two processors that can run tasks in parallel. For example, is possible to execute Arduino compiled code along with MicroPython one, and have both cores to communicate with one another.

Happy to discuss in private message how we could speedup thing. thanks!
have a great day

We actually have something kinda working for this already. But, I don’t believe it’s very useful.

thanks for your answer.
If you can share or point to ressources it would be great. I believe any insight can be useful.

Here in this post, this reply documents how you can load a binary to the CM4: Portenta Micropython on M7 core, C on M4 core? - #2 by iabdalkader
You have to edit and build the firmware from source though. I’ll discuss this feature with Arduino soon and see if we can prioritize it.

great thanks!
I understand your firmware is taking the entire flash memory then definitely a way to go is using the SD to load binary and boot M4 (as you suggested it).
let me know if there is any update
again thank you!

No there’s a free sector (128KBs) but yes eventually we want to support loading binaries from Python from the SD to RAM.