问题专门针对使用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);
我不清楚指针的使用在什么时候结束以及我的作用域何时结束。这样安全吗?
我想避免使用动态分配,因为它是一个嵌入式系统,如果您过度使用动态分配,它会变得碎片化并崩溃。
答案 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传输,内部状态机将防止出现问题。