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)
{
SET_BIT(RCC->GCR, RCC_GCR_BOOT_C2);
}

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.

https://docs.micropython.org/en/latest/pyboard/tutorial/assembler.html

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

OMV_ENABLE_CM4=1

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.

envie_m4.upload.address=0x08100000
envie_m7.upload.address=0x08040000

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.