1
votes

I'm having a problem in with STM32F4 DMA. I have set up my DMA config as follows in circular mode:

hdma_usart1_rx.Instance = DMA2_Stream2;
hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart1_rx);

__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);

This is the UART DMA call:

HAL_UART_Receive_DMA(&huart1,uartRxMsgBuffer, 40);

Every program cycle I pool the NDTR value to check if It has changed, if it does I then know that some bytes were received and are available for processing. For some reason as I developed my code I noticed that the DMA Rx buffer uartRxMsgBuffer was being corrupted when I send more than 40 bytes of data to it.

I got kind of lost don't know where to go from this point on because I checked my program and I'm not writing directly to this buffer and somewhat it's getting overwritten. I also noticed that when I remove the following line from my code the DMA works:

uartm->msgProcessingBuffer[uartm->currentMsgProcessingBufferPointer][uartm->msgProcessingBufferCharPointer] = uartm->uartRxMsgBuffer[uartm->RxMsgPointerStart];

I tried replacing the code above for the equivalent one bellow and it's still not working:

strncpy(&uartm->msgProcessingBuffer[uartm->currentMsgProcessingBufferPointer][uartm->msgProcessingBufferCharPointer],&uartm->uartRxMsgBuffer[uartm->RxMsgPointerStart],1);

There are 2 pictures of the DMA buffer before and after corruption (see the pRxBuffPtr array). I'm sending streams of 123456789\r\n to it, when I send for the 4th time the buffer gets corrupted.

enter image description here

enter image description here

1

1 Answers

3
votes

There's nothing wrong here. If the buffer is filled up, it'll no longer have a terminating 0 byte, the debugger doesn't know where it ends, since it's declared as unsigned char * in the huart1 struct, so it's showing the contents of some other variable behind the buffer.

Make your buffer a bit larger, and include a guard value at the end to see it for yourself:

char *uartRxMsgBuffer[50];
strcpy(uartRxMsgBuffer + 40, "--guard--");