I use dual-core STM32H747 for math processing and periodic output via QuadSPI on M7 processor, and the rest of hardware control with I2C on M4. Apparently I reserved the same port PB, for QSPI and I2C:
Two cores will randomly access it, more correctly M7 periodically 48kHz (QSPI) accesses PB10 and M4 randomly (I2C for user interface) accesses PB6 PB7.
Does it mean that when they both access GPIOB the race condition will happen which means the second one will fail ? Is it possible to dedicate PB10 pin for M7 exclusively, and PB6 PB7 pins to M4 ? or the smallest granularity is port not pin? Do I have to lock the whole port before accessing it, or I can do that on per-pin level?
If the I2C is done by an I2C module on the chip, then you need to do nothing.
The granularity of the GPIO is indeed port-width. However, when a pin is assigned an alternate function, its driver is disconnected from the GPIO and connected to whatever module its alternate function selects.
The various modules do not control the pins through the GPIO. In fact, the GPIO is just another module, to which the pin is connected by default (the GPIO is function 0, which is the reset value, that's all).
Therefore, if PB6 and PB7 are assigned their I2C function, then those two pins are disconnected from the GPIO module and connected to the I2C module. You can still actually read the state of those pins through the GPIO, but when the I2C module changes the state of those pins it doesn't touch the GPIO.
Of course, if you realise the I2C with software bit-banging, that's a completely different problem and in that case yes, you need locking.
Hi! What do you mean by "need to do nothing"?
What happens when two cores (M7/M4) are accessing two peripherals (QSPI/I2C) that shares the same pins (or port)?
Don't you need to define priorities and stop/postpone the lower priority process?
I mean, you don't need to do anything.
The peripherals don't share pins. Each pin can be used by one and only one peripheral at the time, including the GPIO. When you configure the alternate function registers for the pins so that your PB6-7 are assigned as I2C SCL and SDL, then those pins will be disconnected from the GPIO and connected to the I2C. When you set the alternate function register so that PB10 is QSPI CS then that pin is disconnected from the GPIO and connected to the QSPI.
If a pin is assigned to some module other than the GPIO, then you can write to the GPIO port data register whatever you want, whenever you want and it won't affect the level of that pin. It is physically internally disconnected from the GPIO and connected to whatever module you selected in the alternate function register and only that module has any effect on that pin. If a pin is assigned to the I2C, then only the I2C can modify that pin. If the pin is assigned to the QSPI, then only the QSPI can change the level on that pin. For all intents and purposes the alternate function register re-wires the chip and connects the pin to a unit other than the GPIO. Once that connection is set, no other module can affect the pin in any way.
Take a look at the chip's User Manual, the GPIO section explains all the details, explaining where the multiplexers are and how the whole pin circuitry is organised.
Furthermore, even when pins are connected to the GPIO, you only need to worry about multi-core access on the GPIO if you use read-modify-write. If you set and clear pins via the set and clear registers of the GPIO, then there is no race condition. The peripheral buses all have bus arbiters that guarantee that only one core can access the bus at any given time; simultaneous accesses are serialised by the hardware. Then, since the bit set and bit clear registers operate atomically, no race condition can occur.
@Kocsonya: is everything you said about I2C module, valid for QSPI module as well ? 6 QSPI pins are located across 2 GPIOs PB PF (PF is also used for ADC). So I don't have to lock them, when working with QSPI module?
Yes, it is true for all pins and all peripheral modules.