2025-02-06 9: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.