cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H755: HSEM HAL_HSEM_Take() Not Blocking in FreeRTOS Task

Daniel_Ismail
Associate III

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.

 

Debugging Steps I Have Already Taken

  1. 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.

  2. 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.

  3. Isolated the Issue: The problem persists even when all other tasks and logic are simplified. The HAL_HSEM_Take() call simply does not block.


Application Code

 

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) {}
}

 

My Question

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.

 

0 REPLIES 0