使用 TivaWare 时、如何在不将系统置于不一致状态的情况下取消 UART 和已启动的存储器之间的 DMA 传输?
在此基础上、如果在传输过程中发生 UART 错误或其他一些硬件/软件错误、如何再次将 UART 和 DMA "清理"到工作状态?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
使用 TivaWare 时、如何在不将系统置于不一致状态的情况下取消 UART 和已启动的存储器之间的 DMA 传输?
在此基础上、如果在传输过程中发生 UART 错误或其他一些硬件/软件错误、如何再次将 UART 和 DMA "清理"到工作状态?
您好、12月12日下午、
对于您的问题的第一部分、我认为 Bob 回答的这个帖子应该为您提供所需的信息: https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/602918
至于您问题的第二部分、我不确定这是特定于堆栈还是特定于应用的问题。
我还不那么担心更高级别的协议。
目前、我们正在尝试使 UART 和 DMA 的低级功能可靠地工作。
我们的通信是一种简单的来回通信:我们传输一个数据块。 然后我们等待收到答复。 然后、我们传输下一个块、等等。 这在没有 DMA 的情况下工作、但速度慢且开销高。 我们实施了 DMA、以减轻在存储器和 UART FIFO 之间穿梭字节的负担、减少剩余字节数量等
我们在主上下文中进行大多数处理、但在 UART 中断中检测完成情况。
它可以工作、但仅在完美条件下工作。
如果出现某些错误、则表明我们的代码一直被卡住、无法正常恢复。
当我们检测到错误(例如等待完整答复到达的超时)时、我们执行了以下操作:
//在 DMA 侧禁用 DMA MAP_uDMAChannelDisable (u->RxDmaCh); //在 UART 侧禁用 DMA MAP_UARTDMADisable (u->Base、UART_DMA_RX);
这会停止 DMA、但并未完全恢复、并且我们的代码被卡住。 我们将导致"卡死"的原因跟踪到对 MAP_UDMAChannelModeGet ()的调用,以在启动新传输之前测试通道模式是否为 UDMA_MODE_STOP。 代码实际上不是"卡住"的、但在模式更改为 UDMA_MODE_STOP 的预期值之前、我们的状态机不会进入下一状态。 上面的两个调用使控制结构体处于不一致的状态:模式保持 UDMA_MODE_BASIC。
我找不到 TivaWare 函数来复位它、因此我调用 map_uDMAChannelTransferSet ()、传递模式的 UDMA_MODE_STOP。
这似乎起作用,但在以下惊人的方式中间歇性地失败:一段时间内一次(由于某种比赛情况?) 软件将完全锁定(卡在实际位置)。 我将其跟踪到不断触发的 UART ISR。 尽管我们调用了 MAP_UARTIntClear (),但仍有一些东西会不断地发出中断,我们只会退出 ISR 处理程序以立即重新输入中断。 主上下文似乎位于 MAP_uDMAChannelDisable()调用周围的某个位置。
为减轻这种情况、恢复现在如下所示:
//在 UART MAP_UARTIntDisable (u->Base、UART_INT_DMARX)中禁用 DMA 中断; //在 DMA 端禁用 DMA MAP_uDMAChannelDisable (u->RxDmaCh); //在 UART 端禁用 DMA MAP_UARTDMADISABLE (u->Base、UART_MAP_RX)上禁用 DMA; //禁用 DMA (u->UARTDA_RAP_URAP_RAP_UDR_UDAF );//取消置位 DMA (URAP_URAP_URAP_URAP_DR_UDAF);//取消置位 DMA (UARTDA_URAP_URAP_URAP_URAP_RAP_RAP_URAP_RAP_DR_UDAF) //清除 DMA 中断标志,以防 已经置位 MAP_UARTIntClear (u->Base、UART_INT_DMARX);
我们仍在陷入困境、并正在跟踪原因。
我要说、我们似乎需要大量代码来管理 UART 和 DMA。