STM32F4 DMA好像溢出了
STM32F4 DMA seems to be overflowing
我在使用 STM32F4 DMA 时遇到问题。
我在循环模式下设置了我的 DMA 配置:
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);
这是 UART DMA 调用:
HAL_UART_Receive_DMA(&huart1,uartRxMsgBuffer, 40);
每个程序周期我都会汇集 NDTR 值以检查它是否已更改,如果已更改则我知道已接收到一些字节并可用于处理。
出于某种原因,在我开发代码时,我注意到当我向它发送超过 40 个字节的数据时,DMA Rx 缓冲区 uartRxMsgBuffer
被破坏了。
我有点迷茫,不知道从现在开始该去哪里,因为我检查了我的程序,我没有直接写入这个缓冲区,而且它有点被覆盖了。我还注意到,当我从代码中删除以下行时,DMA 起作用了:
uartm->msgProcessingBuffer[uartm->currentMsgProcessingBufferPointer][uartm->msgProcessingBufferCharPointer] = uartm->uartRxMsgBuffer[uartm->RxMsgPointerStart];
我尝试用下面的等效代码替换上面的代码,但它仍然不起作用:
strncpy(&uartm->msgProcessingBuffer[uartm->currentMsgProcessingBufferPointer][uartm->msgProcessingBufferCharPointer],&uartm->uartRxMsgBuffer[uartm->RxMsgPointerStart],1);
有 2 张 DMA 缓冲区损坏前后的图片(参见 pRxBuffPtr
数组)。我正在向它发送 123456789\r\n
流,当我第四次发送时,缓冲区已损坏。
这里没有任何问题。如果缓冲区已满,它将不再有终止的 0
字节,调试器不知道它在哪里结束,因为它在 huart1
结构中被声明为 unsigned char *
,所以它显示了缓冲区后面的一些其他变量的内容。
让您的缓冲区大一点,并在末尾包含一个保护值以供您自己查看:
char *uartRxMsgBuffer[50];
strcpy(uartRxMsgBuffer + 40, "--guard--");
我在使用 STM32F4 DMA 时遇到问题。 我在循环模式下设置了我的 DMA 配置:
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);
这是 UART DMA 调用:
HAL_UART_Receive_DMA(&huart1,uartRxMsgBuffer, 40);
每个程序周期我都会汇集 NDTR 值以检查它是否已更改,如果已更改则我知道已接收到一些字节并可用于处理。
出于某种原因,在我开发代码时,我注意到当我向它发送超过 40 个字节的数据时,DMA Rx 缓冲区 uartRxMsgBuffer
被破坏了。
我有点迷茫,不知道从现在开始该去哪里,因为我检查了我的程序,我没有直接写入这个缓冲区,而且它有点被覆盖了。我还注意到,当我从代码中删除以下行时,DMA 起作用了:
uartm->msgProcessingBuffer[uartm->currentMsgProcessingBufferPointer][uartm->msgProcessingBufferCharPointer] = uartm->uartRxMsgBuffer[uartm->RxMsgPointerStart];
我尝试用下面的等效代码替换上面的代码,但它仍然不起作用:
strncpy(&uartm->msgProcessingBuffer[uartm->currentMsgProcessingBufferPointer][uartm->msgProcessingBufferCharPointer],&uartm->uartRxMsgBuffer[uartm->RxMsgPointerStart],1);
有 2 张 DMA 缓冲区损坏前后的图片(参见 pRxBuffPtr
数组)。我正在向它发送 123456789\r\n
流,当我第四次发送时,缓冲区已损坏。
这里没有任何问题。如果缓冲区已满,它将不再有终止的 0
字节,调试器不知道它在哪里结束,因为它在 huart1
结构中被声明为 unsigned char *
,所以它显示了缓冲区后面的一些其他变量的内容。
让您的缓冲区大一点,并在末尾包含一个保护值以供您自己查看:
char *uartRxMsgBuffer[50];
strcpy(uartRxMsgBuffer + 40, "--guard--");