2025-02-06 09:48 PM - edited 2025-02-06 10:26 PM
Hi guys, I was trying to implement HAL_UART_Transmit_DMA() since I am using freeRTOS. It auto trigger a reset for my stm32f427.
Tried HAL_UART_Transmit(), everything works well. Only HAL_UART_Transmit_DMA() causing the reset, Did I missed anything?
for (uint8_t j=1; j!=CPH_MAX_N_PORTS; ++j) // can change to +1 after disabling drone troubleshoot port { if(byte_1 == j) { if ((ports_handle[j-1])->hdmatx == NULL) { USER_LOG_ERROR("TX DMA not linked for UART!"); } HAL_UART_DMAStop(ports_handle[j-1]); // Stop RX DMA before TX ports_handle[j-1]->gState = HAL_UART_STATE_READY; __HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TC); // TX Complete Interrupt __HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TE); // TX Error Interrupt if (ports_handle[j-1]->hdmatx == NULL) { USER_LOG_ERROR("TX DMA not linked for UART!"); } if (ports_handle[j-1]->gState != HAL_UART_STATE_READY) { USER_LOG_ERROR("UART TX is busy (State: %d)", ports_handle[j-1]->gState); } if (!(ports_handle[j-1]->hdmatx->Instance->CR & DMA_SxCR_TCIE)) { USER_LOG_WARN("TX DMA Interrupts not enabled! Enabling now..."); __HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TC); __HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TE); } USER_LOG_INFO("UART TX State: %d", HAL_UART_GetState(ports_handle[j-1])); if (HAL_UART_GetState(ports_handle[j-1]) == HAL_UART_STATE_READY) { if(HAL_UART_Transmit(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER,10) != HAL_OK) // forward the buffer { USER_LOG_ERROR("UART transmission failed for port %d!", j); } } else { USER_LOG_ERROR("UART transmission busy for port %d!", j); USER_LOG_ERROR("UART state -> %d!", HAL_UART_GetState(ports_handle[j-1])); } HAL_UARTEx_ReceiveToIdle_DMA(ports_handle[j-1], DMARxBuf[j], BUFFER_SIZE); // restart the DMA __HAL_DMA_DISABLE_IT(DMAs_handle[j-1],DMA_IT_HT); // disable the interrupt as we don’t need the Half Transfer interrupt valid_port_found = true; break; } }
* none of the error log was triggered. Initially, I tried without the non-essential code as below and I got the state value of 0x22 which is HAL_UART_STATE_BUSY_RX and that is why I am adding those extra lines of code. But then I realized that the state is always the same even if I am using HAL_UART_Transmit.
if (HAL_UART_GetState(ports_handle[j-1]) == HAL_UART_STATE_READY) { if(HAL_UART_Transmit(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER,10) != HAL_OK) // forward the buffer { USER_LOG_ERROR("UART transmission failed for port %d!", j); } } else { USER_LOG_ERROR("UART transmission busy for port %d!", j); USER_LOG_ERROR("UART state -> %d!", HAL_UART_GetState(ports_handle[j-1])); }
From my perspective, DMA for RX works fine, which I do receive what I want. It only resets when i call HAL_UART_Transmit_DMA.
Below is the line of code when calling HAL_UART_Transmit_DMA:
if(HAL_UART_Transmit_DMA(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER) != HAL_OK)
OR should I ask what is the correct way to do HAL_UART_Transmit_DMA?
Solved! Go to Solution.
2025-02-06 11:48 PM - edited 2025-02-06 11:49 PM
Okay I found the reason,
HAL_UART_Transmit_DMA(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER)
is reading on the buffer and I am continuing parsing the buffer in the loop.
My hypothesis,
since it is not a blocking function, and the cur_msg_pos is continuously incrementing while I parsing the message, the system might read random memory causing overflow and reset.
Solution:
Make a copy for everything AND place a flag within HAL_UART_TxCpltCallback()
Then check for the flag before sending stuff.
2025-02-06 11:48 PM - edited 2025-02-06 11:49 PM
Okay I found the reason,
HAL_UART_Transmit_DMA(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER)
is reading on the buffer and I am continuing parsing the buffer in the loop.
My hypothesis,
since it is not a blocking function, and the cur_msg_pos is continuously incrementing while I parsing the message, the system might read random memory causing overflow and reset.
Solution:
Make a copy for everything AND place a flag within HAL_UART_TxCpltCallback()
Then check for the flag before sending stuff.