2025-09-19 2:29 AM
Hello everyone,
I'm developing a dual-core FreeRTOS application on an STM32H755ZIT6 using STM32CubeIDE, and I'm facing an issue where the HSEM handshake is not working as expected.
My goal is to have a FreeRTOS task on the Cortex-M7 block and wait for a signal from the Cortex-M4.
Expected Behavior: The M7 task calls HAL_HSEM_Take() and should be blocked by the FreeRTOS scheduler until the M4 calls HAL_HSEM_Release() on the same semaphore.
Actual Behavior: The M7 task calls HAL_HSEM_Take() and it returns immediately, without blocking. This happens even when the corresponding HAL_HSEM_Release() call on the M4 is commented out for testing, causing the M7 task to loop continuously.
Verified Core IDs: I have confirmed in the project properties that the M4 project has the CORE_CM4 define and the M7 project has the CORE_CM7 define.
Implemented Handshake Logic: I have implemented the standard handshake where the M7 "primes" the lock by taking the semaphore once before the RTOS scheduler starts, and the task then calls HAL_HSEM_Take() in its main loop.
Isolated the Issue: The problem persists even when all other tasks and logic are simplified. The HAL_HSEM_Take() call simply does not block.
Here is the relevant code from my project.
shared_data.h (common to both cores)
#ifndef INC_SHARED_DATA_H_
#define INC_SHARED_DATA_H_
#include <stdint.h>
#define SHARED_MEM_ADDR 0x38000000
#define HSEM_ID_TOF_LOCK 1U
#define HSEM_ID_M7_NOTIFICATION 2U
typedef struct {
volatile uint32_t frame_count;
// ... other data members
} SharedTofData_t;
#define SHARED_TOF_DATA ((SharedTofData_t *)SHARED_MEM_ADDR)
#endif /* INC_SHARED_DATA_H_ */
Cortex-M4 main.c (Sender)
#include "main.h"
#include "shared_data.h"
// This function is called from the main while(1) loop when new sensor data is ready.
static void SEND_CMD_TOF_M7(void)
{
if (HAL_HSEM_FastTake(HSEM_ID_TOF_LOCK) == HAL_OK)
{
SHARED_TOF_DATA->frame_count++;
// Release the data lock
HAL_HSEM_Release(HSEM_ID_TOF_LOCK, 0);
// Send the notification signal to the CM7.
// NOTE: The M7 fails to block even when this line is commented out.
HAL_HSEM_Release(HSEM_ID_M7_NOTIFICATION, 0);
printf("-> Full dataset sent. Frame: %lu\r\n", SHARED_TOF_DATA->frame_count);
}
}
int main(void)
{
// ... Initialization ...
while (1)
{
// ... Logic to check for new sensor data ...
if (new_data_found)
{
SEND_CMD_TOF_M7();
}
}
}
Cortex-M7 main.c (Receiver)
#include "main.h"
#include "cmsis_os.h"
#include "shared_data.h"
// ... RTOS Task definitions ...
void StartHsemRxTask(void *argument)
{
for(;;)
{
// This call SHOULD block the task, but it returns immediately.
HAL_HSEM_Take(HSEM_ID_M7_NOTIFICATION, 0);
// This code is reached continuously, causing a stream of prints.
printf("Code shound't be reached until M4 notifies\r\n");
if (HAL_HSEM_FastTake(HSEM_ID_TOF_LOCK) == HAL_OK)
{
printf("--- [Direct Rx] Fetched Frame: %lu ---\r\n", SHARED_TOF_DATA->frame_count);
HAL_HSEM_Release(HSEM_ID_TOF_LOCK, 0);
}
}
}
int main(void)
{
// ... MCU and Peripheral Initialization ...
// Prime the notification semaphore by taking it once before the scheduler starts.
HAL_HSEM_FastTake(HSEM_ID_M7_NOTIFICATION);
/* Init scheduler */
osKernelInitialize();
// ... Create RTOS tasks (including HsemRxTask) ...
/* Start scheduler */
osKernelStart();
while (1) {}
}
Given that the issue occurs with this standard handshake logic and with confirmed Core ID settings, what could be the potential cause? Could this be a known issue with a specific HAL/CubeMX version, a toolchain problem, or is there another hardware configuration step I am missing for the HSEM to work correctly with FreeRTOS?
Thank you for your time and assistance.