Skip to main content
Graduate II
September 25, 2025
Question

How to make CM4 use the same UART instance as CM7 on STM32H7?

  • September 25, 2025
  • 4 replies
  • 767 views

Post edited by a ST moderator. Please use </> button to paste your code. 

Hi,

I’m working with an STM32H7 (dual-core) and I want both CM4 and CM7 to be able to transmit on the same UART. On CM7, I initialize the UART normally MX_USART1_UART_Init(). On CM4, I try to send data via HAL and I’ve protected access with a hardware semaphore.

Problem is that CM4 doesn’t see the properly initialized huart1 from CM7 and nothing is transmitted.

What exactly do I need to do so that CM4 can use the same huart1, i tried the

 __attribute__((section(".RAM_D2"))) UART Handle TypeDef huart1;

but it doesn't work ither. . Also why both cores declares huart1on their own??

Thanks in advance for any help!

code:

int __io_putchar(int ch)
{
// Take semaphore
HAL_HSEM_FastTake(UART_HSEM_ID);

if (ch == '\n') {
uint8_t cr = '\r';
HAL_UART_Transmit(&huart1, &cr, 1, HAL_MAX_DELAY);
}

HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);

// Release semaphore
HAL_HSEM_Release(UART_HSEM_ID, 0);

return ch;
}

 

    This topic has been closed for replies.

    4 replies

    Super User
    September 25, 2025

    You need to trick the system by modifying huart1 on the CM4 to reflect the initialized state of the peripheral. Typically this is just the State parameter, but I think on UART there's a gState and something else. See what they are after CM7 initialization and explicitly set them to that on the CM4 side once you can guarantee the peripheral is actually initialized.

    Graduate II
    September 25, 2025

     

    So basically, on the CM4 side I just keep my own declaration:

    UART_HandleTypeDef huart1;

    and then just add stuff like:

    huart1.gState = HAL_UART_STATE_READY;

    huart1.RxState = HAL_UART_STATE_READY;

    Is this the correct approach, or am I totally going the wrong way?
     
    Super User
    September 25, 2025

    Yep, that's the way I would do it.

    You'll need to ensure only one core talks to the peripheral at once, so gated behind an HSEM or something like that. Only pass off the HSEM when both states are READY.

    Note that HAL_HSEM_FastTake can fail if the HSEM is already taken. Your code just silently ignores this.

    Graduate II
    September 26, 2025

    I'm not entirely convinced of the value of doing this. The two MCU have a different decoding space and the compiler/Linker allocate the RAM they control separately. 

    If you have some memory that you're explicitly sharing it might make more sense to manage as a FIFO buffer, control ownership of that so you can _write() larger blocks of characters or strings, and have one MCU manage the dispatch to the USART via an interrupt/callback method. Interleaving at a character level might result in streams of gibberish. 

    I'd probably just use register level code for putchar type implementation and avoid the RAM instance for HAL

    Graduate II
    September 26, 2025

    In the end I tried initializing huart1 on both cores, with access protected using HSEM, and it looks like even for longer texts (RTOS statistical data) everything is being transmitted in the correct order.