Skip to main content
Visitor II
May 9, 2025
Question

HSEM causes weird jitter

  • May 9, 2025
  • 1 reply
  • 452 views

Hello,

Has anybody experienced weird jittery like behaviour when using the HSEM between two cores on the STM32H755 or another dual core MCU? This is the logic right now:


The CM4 has a 1 kHz loop that toggles a GPIO on each successful reception of data on an communication bus. On each cycle (reception of data), the CM4 writes to shared memory at address 0x38000000 which is a shared memory region located in SRAM4. Afterward the CM4 reads data at address 0x38000400 which is also in SRAM4. On every read and write, the HSEM is taken and released accordingly.

The CM7 has a 160 kHz loop that toggles a GPIO, reads from address 0x38000000, then writes to address 0x38000400. Similarly, on the CM7 each read and write operation on shared memory uses HSEM to take and release the hardware semaphore accordingly.

 

The problem is that with this approach, I see data at 0x38000400 update non periodically. Sometimes I see valid data after 450 us up to 7 ms. It is quite random. Is there something I'm missing?

 

See attached ioc file as well as code snippets for both the CM4 and CM7 side

 

//CM4
void cm4_task(uint16_t *pDataCmd, uint16_t *pDataFbk) {
 /* Send commands */
 if (HAL_HSEM_FastTake(0) == HAL_OK) {
 memcpy((void*)0x38000000, pDataCmd, size);
 HAL_HSEM_Release(0, 0);
 }

 /* Receive feedbacks */
 if (HAL_HSEM_FastTake(1) == HAL_OK) {
 memcpy(pDataFbk, (void*)0x38000400, size);
 HAL_HSEM_Release(1, 0);
 }

 HAL_GPIO_TogglePin(Some_GPIO_Port, Some_Pin);
}

//CM7
extern struct command_t commands = {0};
extern struct feedback_t feedback = {0};
void cm7_task(void) {
 if (HAL_HSEM_FastTake(0) == HAL_OK) {
 memcpy(&commands, (void*)0x38000000, size);
 
 // commands processed in another context
 
 HAL_HSEM_Release(0, 0);
 }

 if (HAL_HSEM_FastTake(1) == HAL_OK) {
 memcpy((void*)0x38000400, &feedback, size); 
 HAL_HSEM_Release(1, 0);
 }

 HAL_GPIO_TogglePin(Another_GPIO_Port, Another_Pin);
}
    This topic has been closed for replies.

    1 reply

    Super User
    May 9, 2025

    Take out the HSEM stuff and see how regular the pin toggles are. You have so many interrupts happening, probably something else going on. Most priorities are set the same, so any one of them could be hogging the cpu.

    Visitor II
    May 9, 2025

    So removing the HSEM stuff, the pin toggles regularly which is good. Just not sure why we see valid data in 0x38000400 at irregular intervals up 7 ms which is odd. Does using a HSEM to mutex these regions even necessary if we're restricting ram access to single-reader-single-writer? Or partial reads still a chance?

    Super User
    May 10, 2025

    You can toggle the pin at the beginning and end of the interrupt. That way, the length of the pulse will show how long it's in the interrupt.

    Taking an HSEM is quick as is unlikely to be the root issue here.

     

    If you're only sending one way for a region, you can do this without a mutex. Use a flag that is 0 to indicate no message and 1 to indicate message is there.

    On sending core:

    • If flag == 0:
      • (if needed) Write message.
      • Write flag = 1

    On receiving core:

    • If flag == 1:
      • Copy message into new memory, or process message without moving.
      • Write flag = 0.

    Have flag be uint32_t type.