STM32CubeWL icon indicating copy to clipboard operation
STM32CubeWL copied to clipboard

Trace utility: using DMA TX and RX on interrupt may lead to deactivation of RX interrupt

Open PascalBod opened this issue 3 years ago • 3 comments

Symptom

A LoRaWAN application uses the trace utility to send and receive bytes on UART2. Bytes are sent using DMA TX with UTIL_ADV_TRACE_COND_FSend(), while reception uses RX interrupt, as configured by UTIL_ADV_TRACE_StartRxProcess(). When the application code requests to send a trace message, and a byte is received "at the same time", the RX interrupt is disabled. Consequence: the application can't received any further bytes.

Source of the problem

HAL_UART_Transmit_DMA() calls __HAL_LOCK(huart) before preparing the transmission.

When a byte is received, UART_RxISR_8BIT() is called. UART_RxISR_8BIT() calls HAL_UART_RxCpltCallback(). HAL_UART_RxCpltCallback() calls HAL_UART_Receive_IT(), in order to restart the RX on interrupt. HAL_UART_Receive_IT() calls __HAL_LOCK(huart) before configuring the RX.

If the byte is received while HAL_UART_Transmit_DMA() has just called __HAL_LOCK(huart) but not called __HAL_UNLOCK(huart) yet, then __HAL_LOCK(huart) in HAL_UART_Receive_IT() performs a return, without re-enabling RX on interrupt.

No further RX is possible.

Workaround

Following modification of vcom_Trace_DMA() prevents the problem from appearing:

    UTIL_ADV_TRACE_Status_t vcom_Trace_DMA(uint8_t *p_data, uint16_t size)
    {
      // Disable USART interrupts while starting the DMA TX otherwise an RX
      // interrupt could happen while USART's data is locked, and RXNEIE would
      // be left reset.
      HAL_NVIC_DisableIRQ(USARTx_IRQn);
      HAL_UART_Transmit_DMA(&huart2, p_data, size);
      HAL_NVIC_EnableIRQ(USARTx_IRQn);
      return UTIL_ADV_TRACE_OK;
    }

But I don't know whether this is the right solution.

PascalBod avatar Feb 19 '22 07:02 PascalBod

ST Internal Reference: 123428

ASELSTM avatar Feb 24 '22 15:02 ASELSTM

@PascalBod

Your fix will work.

However, the root cause of the problem is an incorrect implementation of __HAL_LOCK. See this answer on stackoverflow:

https://stackoverflow.com/a/49138649

and this discussion:

https://community.st.com/s/question/0D50X0000C5Tns8SQC/bug-stm32-hal-driver-lock-mechanism-is-not-interrupt-safe

Best regards Roman Jasmann

RomanJasmann avatar Feb 25 '22 15:02 RomanJasmann

@RomanJasmann Thanks for your comment. It confirms my feeling :slightly_frowning_face:

PascalBod avatar Feb 28 '22 06:02 PascalBod

Hi @PascalBod,

Thank you for your contribution. This issue has been fixed in the frame of version v1.3.0 of the STM32CubeWB. Please allow me then to close this thread.

With regards,

ASELSTM avatar Apr 07 '23 12:04 ASELSTM