cancel
Showing results for 
Search instead for 
Did you mean: 

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

Patryk_Kucia
Associate III

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;
}

 

6 REPLIES 6
TDK
Super User

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.

If you feel a post has answered your question, please click "Accept as Solution".
Patryk_Kucia
Associate III

 

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?
 

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.

If you feel a post has answered your question, please click "Accept as Solution".

You've indicate that for the CM7 you initialize the UART normally MX_USART1_UART_Init(). But you didn't say that was that done on the CM4 as well?

In the IOC, did you select both CM4 and CM7? If the CM7 was the initializer, then MX_USART1_UART_Init() is not called in the CM4, so huart1 is not initialized. You have to call that function manually to initialize huart1 on the CM4.

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.
CAN Jammer an open source CAN bus hacking tool

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Patryk_Kucia
Associate III

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.