Skip to main content
STUser21
Associate II
February 23, 2021
Question

STM32 UART HAL and LL failed

  • February 23, 2021
  • 3 replies
  • 2193 views

Sorry ST guys but the UART HAL and LL_HAL ist a total fail!

I developing over 15 years all kind of serial communication with linux and different microcontrollers. Now I regret my desistion to use the STM32WB MCU.

I'm trying over two weeks the get a stable UART communication running with different data length (5 to 50 bytes). All tries with DMA or Interrupt are failed. All this ST HAL examples are not realy usefull and if I search for some input I can read a lot and I mean a loooot of similar problem at the forums....

Now I have to think about to went awai from this MCU or I have to write my own working HAL from scratch.

It seams the marketing did a good job but the rest ???? I dont know....

A unhappy user....

This topic has been closed for replies.

3 replies

KnarfB
Super User
February 23, 2021

Sorry to hear that. Not sure if marketing is listening because most people here are community developers. Maybe you want to share stripped down code here, showing your issues.

KnarfB

STUser21
STUser21Author
Associate II
February 25, 2021

I started from zero with a new STM32CubeMX and STM32CubeIDE project including the latest HAL librarys. I use the Nucleo dev board and create a UART setup with interrupts, thats all.

static void MX_USART1_UART_Init(void)
{
 huart1.Instance = USART1;
 huart1.Init.BaudRate = 115200;
 huart1.Init.WordLength = UART_WORDLENGTH_8B;
 huart1.Init.StopBits = UART_STOPBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_8;
 huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
 {
 Error_Handler();
 }
}

I can receive fixed data lenght with 5 bytes:

HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_Buffer, 5);

The MCU is sending the answer with:

HAL_UART_Transmit_IT(&huart1, buffer, bufsize);

BUT the data are NOT right in any way:

0693W000007ZQlkQAG.png 

If I send the exact same buffer content with: HAL_UART_Transmit(&huart1, buffer, bufsize, 20); the data are transmitted right!

0693W000007ZQm4QAG.png 

Now thats the big question why HAL_UART_Transmit_IT() can not send the data right??? There is nothing else running at this code, it just receive and sends some data. How the MCU should work savely in combination with some real working code if the HAL cannot do the simple serial job?? In this case I can not trust the HAL library.

Amel NASRI
ST Technical Moderator
February 25, 2021

Hi @STUser21​ ,

I am interested to get your complete project to reproduce the issue on my side. So could you please share your main.c & .ioc files?

How you declare buffer variable and how you are calling HAL_UART_Transmit_IT may have impact.

Thanks.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
waclawek.jan
Super User
February 23, 2021

Okay, and have you tried the good old readin the manual and proceed accordingly, step by step?

Polled UART is hardly a rocket science and interior is not much harder. DMA is next step.

JW

STUser21
STUser21Author
Associate II
February 25, 2021

Welcome to the 21 century, but polling was maybe ok in the 80ies. Polling it no rocket science thats right, but if you want to use a high end MCU/CPU thats the totaly wrong way....

Why put ST this effort into examples and libraries which are not working properly. A stable serial communication should be/is the basic for all MCU...

Piranha
Principal III
February 24, 2021

STM32 HAL USART reality:

  1. The whole library pretends to be interrupt/thread safe, but it isn't. The most obvious flaw is the broken HAL lock mechanism, but that is not nearly the only race condition. Peripheral specific Tx/Rx locks and other code are also full of race conditions.
  2. All modules are full of missing volatile qualifiers, memory barriers, compiler barriers, alignment, cache management etc.
  3. USART API is incapable of receiving/transmitting continuous data streams. For transmission it limits data rate, but for reception it means loosing data under completely normal conditions.
  4. When a blocking USART call fails because of timeout, it doesn't even return how much data was actually transmitted/received.
  5. USART driver should have implemented a software FIFO, but it doesn't. Ideally FIFO should be lock-free and read/written by ISR or DMA on a driver's side.

Expecting such a broken bloatware to perform reliably is illogical. Typically the strategy of HAL developers and users is to ignore the bugs and pretend they do not exist. In case of USART for something sane look here:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

That said, the STM32 hardware is mostly pretty nice and decent. Therefore write your own sane software and... the sky is the limit.

STUser21
STUser21Author
Associate II
February 25, 2021

Thanks Piranha for your clear words and it confirms my assumption. I will check out the USART example you posted. The documentation looks promising to get a save an good solution...