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:DMA 中断-如何确定接收到多少个数据包? (突发或单次运输?)

Guru**** 2478505 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/688367/tm4c129encpdt-dma-interrupt---how-to-determine-how-many-packets-were-received-burst-or-single-trasmission

器件型号:TM4C129ENCPDT

大家好、我正在运行 Tiva DMA_example (乒乓 UART 接收)、我想知道在接收 DMA 中断时传输了多少字节。 我需要知道它是单次传输还是突发传输、以便处理 DMA 数据缓冲区 A 和 B

在 Tiva DMA 代码示例中断处理程序中:

//
//
// UART1的中断处理程序。 在 DMA 时将发生此中断
//使用 UART1 UDMA 通道完成传输。 它也是如此
//如果外设发出错误信号则触发。 该中断处理程序将会执行
//在接收乒乓缓冲器 A 和 B 之间切换。它还将重新启动 TX
//如果之前的传输完成,则进行 uDMA 传输。 这将保留 UART
//连续运行(将 TX 数据循环回 RX)。
//
//
无效
UART1 IntHandler (空)

uint32_t ui32Status;
uint32_t ui32模式;

//
//读取 UART 的中断状态。
//
ui32Status = ROM_UARTIntStatus (UART1_BASE、1);

//
//清除任何挂起状态,即使由于没有 UART,应该没有任何挂起状态
//中断已启用。 如果启用了 UART 错误中断
//这些中断可能在这里发生,应该被处理。 UDMA 的影响
//用于 RX 和 TX、那么这两个中断都不应该
//已启用。
//
ROM_UARTIntClear (UART1_BASE、ui32Status);

//
//检查 DMA 控制表以查看乒乓"A"传输是否为
//完成。 "A"传输使用接收缓冲器"A"和主缓冲器
//控制结构。
//
ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_UART1RX | UDMA_PRI_SELECT);

//
//如果主控制结构体指示停止,则表示"A"
//接收缓冲完成。 UDMA 控制器仍应接收
//将数据输入"B"缓冲区。
//
if (ui32Mode = uDMA_MODE_STOP)

//
//递增计数器以指示数据已接收到缓冲区 A 中
//一个实际应用,此应用将用于向主线程发出信号
//数据已接收,因此主线程可以处理数据。
//
G_ui32RxBufACount++;

//我不知道数据是单次还是突发数据...

//
//使用主缓冲区为"A"缓冲区设置下一个传输
//控制结构。 进入"B"缓冲器的持续接收为时
//完成,UDMA 控制器将切换回这个。 这种情况
//示例重复使用缓冲区 A,但更复杂的应用可能
//使用一组旋转的缓冲区来增加该时间
//主线程必须先处理缓冲区中的数据,然后再处理
//重复使用。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_UART1RX | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
(void *)(UART1_base + UART_O_DR)、
g_ui8RxBufA、sizeof (g_ui8RxBufA);

//
//检查 DMA 控制表以查看乒乓"B"传输是否为
//完成。 "B"传输使用接收缓冲器"B"和副缓冲器
//控制结构。
//
ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_UART1RX | UDMA_ALT_SELECT);

//
//如果副控制结构体指示停止,则表示"B"
//接收缓冲完成。 UDMA 控制器仍应接收
//将数据输入到"A"缓冲区中。
//
if (ui32Mode = uDMA_MODE_STOP)

//
//递增计数器以指示数据已接收到缓冲区 A 中
//一个实际应用,此应用将用于向主线程发出信号
//数据已接收,因此主线程可以处理数据。
//
G_ui32RxBufBCount++;

//
//使用替代设置"B"缓冲区的下一个传输
//控制结构。 接收到"A"缓冲器的时间
//完成,UDMA 控制器将切换回这个。 这种情况
//示例重复使用缓冲区 B,但更复杂的应用程序可以
//使用一组旋转的缓冲区来增加该时间
//主线程必须先处理缓冲区中的数据,然后再处理
//重复使用。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_UART1RX | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
(void *)(UART1_base + UART_O_DR)、
g_ui8RxBufB、sizeof (g_ui8RxBufB));

//
//如果 UART1 DMA TX 通道被禁用,则表示 TX DMA 传输
//完成。
//
if (!ROM_uDMAChannelIsEnabled (UDMA_CHANGE_UART1TX))

//
//开始到 UART1 TX 的另一个 DMA 传输。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_UART1TX | UDMA_PRI_SELECT、
UDMA_MODE_BASIC、g_ui8TxBuf、
(void *)(UART1_base + UART_O_DR)、
sizeof (g_ui8TxBuf));

//
//必须重新启用 uDMA TX 通道。
//
ROM_uDMAChannelEnable (UDMA_CHANGE_UART1TX);

在数据表中:

请求类型
μ μDMA 控制器可响应来自外设的两种请求:单次请求或猝发请求。 每个
外设可以支持任一种或两种类型的请求。 单个请求意味着外设
已准备好传输一个数据单元、而猝发请求意味着外设已准备好传输
多个项目。
μ μDMA 控制器的响应会有所不同、具体取决于外设是否为单个
或突发请求。 如果两者都有效、并且 μ μDMA 通道已设置为突发模式
传输、则以猝发请求优先。

数据表第708页:

注:在本例中、外设发出单次请求或猝发请求并不重要。 但对我来说很重要!
由于外设具有在8级触发的 FIFO、因此仲裁数目设置为
如果外设发出猝发请求、那么传输8个字节、就是这样
可以容纳的数据。 如果外设发出单次请求(如果有任何数据)
在 FIFO 中)、然后一次传输一个字节。 如果这对应用很重要
只能在突发模式下进行传输、因此应在中设置通道采用猝发 SET[8]位
DMA 通道采用猝发置位寄存器(DMAUSEBURSTSET)。

我想将 XFERSIZE (传输大小)寄存器置位、但它似乎包含了完成 DMA 周期所需的未完成项(当中断触发时应该为零)。 所以这对我没有帮助。

提前感谢您。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Matheus、
    如果看 InitUART1 Transfer()内的示例,FIFO 电平阈值设置为4,这意味着当 RXFIFO 包含4字节数据时,它将向 DMA 模块发送 DMA 请求。 响应 DMA 请求、DMA 将读取 RXFIFO 中的4个字节的数据。 传输完成后、UART 模块将向 CPU 发送一个 RXDMA 中断。

    //
    //将 TX 和 RX 触发阈值设置为4。 这将由使用
    // uDMA 控制器发出信号,指示何时应传输更多数据。 。
    //将配置 uDMA TX 和 RX 通道,以便可以传输4个通道
    当 UART 准备传输更多数据时、//以突发方式传输字节。
    //
    ROM_UARTFIFOLevelSet (UART1_base、UART_FIFO_TX4_8、UART_FIFO_RX4_8);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Charles、当 UART FIFO 只接收一个字节时、它还会生成 DMA 请求(以及在这一个字节传输后的 DMA 中断)。 当我收到此中断时、我需要一种方法来了解 UART 请求是单次传输 DMA 请求(一个字节传输)还是突发传输 DMA 请求(正如您在答复中所说的4个字节)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Matheus、

     在本示例中、当您接收到中断时、这必须意味着 DMA 已传输4个字节的数据、并且它必须已响应突发请求。 您需要确保 DMA 仲裁大小配置为与 UART FIFO 深度相同的数字。 假设您希望将80字节的数据接收到 UART FIFO 中。 您可以将 FIFO 触发级别设置为 FIFO 的1/4、这意味着只要 FIFO 中有4个或更多字节的数据、它就会生成突发请求。 在 DMA 中、您还设置了仲裁大小为4的通道。 响应突发请求时、它将始终从 UART RXFIFO 中读取4个字节。 在这种情况下、我认为 UART 不会发出单个请求、因为您已将 UART 配置为 FIFO 模式。 UART 需要20次才能向 DMA 模块生成 DMA 请求以完成80字节的传输。 对于 UART FIFO 触发级别、仲裁数目不得与之不匹配。 例如、如果您总共有81个字节要传输。 在这种情况下、在传输80个字节后、FIFO 中将剩余一个字节。 我认为有两种可能的结果。 一种是 UART 不会生成 DMA 请求、因为您处于 FIFO 模式、且触发级别为4字节。 UART FIFO 将在发送 DMA 请求之前等待3个字节的到达。 我认为这是最可能的情况。 第二种情况是、UART 为该单字节数据发送单个请求。 我真的怀疑这种情况会发生。 如果请求被发送到 DMA、并且您仍将 DMA 配置为仲裁大小为4字节、则 DMA 将从 FIFO 读取4字节、这将产生欠载情况、除非您之前已使用重新配置 DMA 一个字节仲裁大小。  

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

    您好!

    数据表第1295页:

    DMA 操作
    UART 模块为 μ μDMA 控制器提供了一个接口、可分别传输和传输通道
    接收。 UART 的 DMA 操作通过 UART DMA 控制来启用
    (UARTDMACTL)寄存器。 启用 DMA 操作后、UART 会在上发出 DMA 请求
    当相关 FIFO 能够传输数据时、接收或发送通道。 对于接收通道、
    只要接收 FIFO 中有数据、就会产生单次传输请求。 突发传输
    只要接收 FIFO 中的数据量达到或超过 FIFO 触发值、就会发出请求
    UARTIFLS 寄存器中配置的输出电平。

    根据该节的内容、UART 也会发送一个单个字节的 DMA 请求。 为了处理数据、我需要知道 DMA 请求是单次请求还是突发请求。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    只有在非 FIFO 模式下才会发生这种情况。 如果处于 FIFO 模式并且 UART 在接收 FIFO 中有任何数据时产生单次传输请求、那么它会使 FIFO 深度选择(即1/8、1/4、1/2等)无用、不会? 原因是、只要从 UART RX 引脚接收到一个数据、FIFO 中就至少有一个数据。 除非将 DMA 配置为仲裁大小1、否则 DMA 永远不会与任何仲裁大小一起工作、否则 DMA 读取的内容将超过 UART RXFIFO 中可用的内容。