将自动变量的指针传递给DMA功能

时间:2019-02-05 20:20:19

标签: c pointers scope stm32 dma

问题专门针对使用DMA的STM32微控制器。

请考虑以下内容:

while(true){
    randomStuff();
    uint16_t distance;
    getDistance(&distance);
    HAL_UART_Transmit_DMA((uint8_t*)&distance, 2);
    doOtherStuff();
}

现在通常在使用单个线程时,这会很好,因为执行遵循线性流程,并且距离不会在调用函数完成之前超出范围。但是,这是对DMA外设的特殊调用,它不会阻塞并且允许执行继续,因此超出了“距离”变量的范围。

在此DMA函数中,我可以看到指针已被复制:

huart->pTxBuffPtr = pData;

此后,它将调用TDR应该是目标地址的地方:

HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size);

我不清楚指针的使用在什么时候结束以及我的作用域何时结束。这样安全吗?

我想避免使用动态分配,因为它是一个嵌入式系统,如果您过度使用动态分配,它会变得碎片化并崩溃。

1 个答案:

答案 0 :(得分:0)

功能

HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

获取指针pData,该指针立即复制到

huart->pTxBuffPtr = pData;

但是实际上并没有使用或发送该值,因为几行后您可以找到:

tmp = (uint32_t*)&pData;

然后:

HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);

因此,将&pData 复制到 tmp 时会使用您的指针,然后一直将其用于DMA调用,直到DMA配置为:

hdma->Instance->M0AR = SrcAddress;

因此,这是不安全的,因为从那里开始,您所知道的下一件事是DMA完成TX的中断。所以最后当您从

返回时
HAL_UART_Transmit_DMA

并跳转到

doOtherStuff();

您可能仍在使用指针。如前所述,将其声明为静态是一种解决方案,因为如果您再次使用&distance 调用DMA传输,内部状态机将防止出现问题。