Yes there are 16 Hw Gates called Sema4. You can read more about it in RM Chapter 24 IPS_Semaphores
A snip of the code will look like this
/** SEMA4 - Register Layout Typedef */
typedef struct {
__IO uint8_t Gate00; /**< Semaphores Gate 0 Register, offset: 0x0 */
__IO uint8_t Gate01; /**< Semaphores Gate 1 Register, offset: 0x1 */
__IO uint8_t Gate02; /**< Semaphores Gate 2 Register, offset: 0x2 */
__IO uint8_t Gate03; /**< Semaphores Gate 3 Register, offset: 0x3 */
__IO uint8_t Gate04; /**< Semaphores Gate 4 Register, offset: 0x4 */
__IO uint8_t Gate05; /**< Semaphores Gate 5 Register, offset: 0x5 */
__IO uint8_t Gate06; /**< Semaphores Gate 6 Register, offset: 0x6 */
__IO uint8_t Gate07; /**< Semaphores Gate 7 Register, offset: 0x7 */
__IO uint8_t Gate08; /**< Semaphores Gate 8 Register, offset: 0x8 */
__IO uint8_t Gate09; /**< Semaphores Gate 9 Register, offset: 0x9 */
__IO uint8_t Gate10; /**< Semaphores Gate 10 Register, offset: 0xA */
__IO uint8_t Gate11; /**< Semaphores Gate 11 Register, offset: 0xB */
__IO uint8_t Gate12; /**< Semaphores Gate 12 Register, offset: 0xC */
__IO uint8_t Gate13; /**< Semaphores Gate 13 Register, offset: 0xD */
__IO uint8_t Gate14; /**< Semaphores Gate 14 Register, offset: 0xE */
__IO uint8_t Gate15; /**< Semaphores Gate 15 Register, offset: 0xF */
} SEMA4_Type;
/* SEMA4 - Peripheral instance base addresses */
#define SEMA4_BASE (0x4001D000u)
#define SEMA4 ((SEMA4_Type *)SEMA4_BASE)
#define UNLOCK 0x00
#define CORE0_LOCK 0x01
#define CORE1_LOCK 0x02
void hello_M4()
{
/* Lock gate to write UART, then unlock */
SEMA4->Gate01 = CORE1_LOCK;
if(SEMA4->Gate01 == CORE1_LOCK) {
/* Output message from M4 */
printf("Hello M4!\n");
/* Unlock Semaphore */
SEMA4->Gate01 = UNLOCK;
}
}
Also is recommended used non cacheble section for the shared memory section to avoid coherency issues or make sure you are flushing the cache after writing