cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 - Handling with 2 MPUs

PButc.1
Associate II

Hello, the STM32H7 (dual core) has two dedicated memory protection units. If I configure one MPU to make a memory region only accessable as readonly, does the memory protection unit from the other core inherit those configuration or is it bypassing this configuration as it is following its own MPU configuration.

As all periphericals are theroteically accessible by both cores, can one core call the MPU API from the other core in order to configure it? In the end, one core could start a routine in order to configure both MPUs? If yes , how can I do that (example, description, etc.)?

If I have global variables within the scope of a file which is controlled and accessed by one core, can the other core read/modify the global data directly? Or do I get some compilation errors when I try to do that? Can I solve that with a "extern" attribute for those variables which are "in the hands" of the other core? Or do I need to use specific compiler pragmas in order to force the placement into a specific RAM location - in order to know the starting address of the data which is accessed than by the other core?

For example, if I have a global buffer array g_i32arr[100] filled with valid values by one core, can I directly access g_i32arr[] by the other core? If not, how can I do it ?

Does ST provide some example code in order to evaluate that mechanism with two MPUs? Especially for the use case if several peripherical resources should never be touched or executed by one core. Are there some examples around?

6 REPLIES 6

Each core is separate, so writing the MPU in one is not visible to the other, the memory maps are slightly different. Memory regions they have in-common can be used to share data, although the addresses might be different.

The M4 core doesn't cache, whilst the M7 does. You'll need to manage coherency and ownership/responsibilities.

Generally you'd pick one core to manage a given peripheral and use a semaphore or mutex if you need to "own" control of it.

The M4 is on a bus with memory and peripheral, it is designed to manage the IO on those. ie APB1, APB2, AHB1, AHB2, Ethernet, SDMMC2, USBHS1/2

You'd generally tell the linker where you want things placed, this typically isn't communicated between the builds between cores. Best you put all your shared stuff in a struct, have that in an include file, and place it in a common view memory ie mainly SRAM1,2 or 3, further away SRAM4, and not in memory that's not visible, ie ITCM, DTCM, AXI SRAM.

You're going to have to manage the floor-planning task.

Aren't there loads of examples under the CubeH7 trees?

STM32Cube_FW_H7_V1.7.0\Projects\STM32H745I-DISCO\Examples\HSEM\HSEM_ResourceSharing

0693W000004IihpQAC.jpg

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

The MPU is not a peripheral, it is a feature of the Cortex core. It's not shared between cores, and one core can't modify the MPU in the other core.

Sharing data between cores is a common question. Here are a few threads:

https://community.st.com/s/question/0D50X0000BVpPAqSQN/besteasiest-way-to-share-data-between-cores-in-stm32h745

https://community.st.com/s/question/0D50X0000CDoWaH/i-am-looking-for-an-example-for-stm32h747-dual-cpu-mcu-best-way-to-share-data-between-processors

https://community.st.com/s/question/0D53W000005piokSAA/stm32h745-inter-core-data-transfer

If you feel a post has answered your question, please click "Accept as Solution".

If coming from a Intel/x86 SMP world, the multiprocessing is not symmetrical between cores, and ARM does it without safety nets/barriers.

Not sure how much multi-core / multi-thread stuff is taught these days, but I think some background in computer/cpu architecture would be helpful, and a review of the plumbing as described in the reference manual.

ARM really pushes the "attention to detail" stuff on to the developer, both in their approach to the software/hardware, and driving their development tools.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
PButc.1
Associate II

Thanks for your reply. What does that mean for the initialization of common peripherals. Imagine one core initializes one peripheral e.g. SPI, GPIO. After some time the other core does an inititalization as well but it changes one GPIO from input to output mode. According to the CubeMx, the API for the GPIO initialization is provided on both cores. Doesn't that sound like a race condition as one core can overwrite the configuration of the previous one when both of the cores initializes a peripheral ? Do i need to initialize the peripheral e.g GPIO,SPI on both cores via the Init_API in order to use it or is it enough that just one core does the initialization. Isn't there any mechanism to check that one peripheral has been already initilaized?

TDK
Guru

> Doesn't that sound like a race condition as one core can overwrite the configuration of the previous one when both of the cores initializes a peripheral ? 

If both cores are trying to do different things with the same peripheral, clearly that's an issue. It's up to the programmer not to do things like this.

You can use hardware semaphores for locking access to peripherals, or better yet just have a single core interface with the peripheral as suggested above.

If you feel a post has answered your question, please click "Accept as Solution".
PButc.1
Associate II

Hello TDK,

thanks for your reply. I know about this embedded feature. This question was referring more from an initialization point of view as it looks, at least for me, a bit venturesome, when one core could directly read/modify/write to an GPIO output although its corresponding initialization was never called in this core context but by the different core instead. I was expecting that you need to call the initialization at least once. As you said, the integrator is responsilbe to ensure that the configuration is coherent, etc.