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.

[参考译文] TM4C129ENCPDT:是否取消正在进行的 UDMA/UART 传输/从错误中恢复?

Guru**** 2465890 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/662072/tm4c129encpdt-cancel-udma-uart-transfer-in-progress-recover-from-errors

器件型号:TM4C129ENCPDT

使用 TivaWare 时、如何在不将系统置于不一致状态的情况下取消 UART 和已启动的存储器之间的 DMA 传输?

在此基础上、如果在传输过程中发生 UART 错误或其他一些硬件/软件错误、如何再次将 UART 和 DMA "清理"到工作状态?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、12月12日下午、

    对于您的问题的第一部分、我认为 Bob 回答的这个帖子应该为您提供所需的信息: https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/602918

    至于您问题的第二部分、我不确定这是特定于堆栈还是特定于应用的问题。

    • 如果您想要清理 UART/UDMA 通道、则 uDMAErrorStatusClear 和 uDMAChannelDisable 等 API 适用于 DMA 端、而对于 UART 端、您需要使用 UARTRxErrorClear、UARTDMADisable 和/或 UARTDisable 等 API。 UARTDisable 将刷新 TX FIFO、而 UARTDMADisable 不刷新 FIFO、而只是禁用 UART/UDMA 链接。
    • 如果您担心能够跟踪错误发生的时间并重新发送数据包、那么这将更具体地说明您如何处理传输错误的报告。 您需要一种重试机制、还可以跟踪失败的数据包、然后可以重新传输。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我还不那么担心更高级别的协议。

    目前、我们正在尝试使 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。