NXP EDMA学习(3):Scatter/Gather模式之串口循环缓冲区的实现

本文详细介绍了NXP EDMA如何实现硬件循环缓冲区,通过TCD Pool初始化、eDMA回调函数以及如何获取缓冲区接收长度。在串口通信中,利用eDMA的Scatter/Gather模式可以高效处理循环缓冲,避免中断处理的开销。文章还探讨了回调函数的作用以及如何计算接收数据的大小,强调了及时处理接收到的数据以防止数据丢失的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实际应用中,循环缓冲区的使用十分广泛,如果DMA每次接收一定字节然后再在中断中写入自己定义的循环缓冲区,这样又失去了使用DMA的意义。所以硬件上的循环缓冲区的实现非常重要。大部分芯片支持DMA循环模式,而NXP的eDMA则可以通过Scatter/Gather模式来实现硬件循环缓冲区。

1 TCD Pool初始化

硬件循环缓冲区的代码与上一节大体相同,只不过增加了一个tcdPool,在前面的初始化完成后,无需调用UART_ReceiveEDMA,而是执行下面的函数来启动硬件循环缓冲区:

__attribute__((aligned(ALIGN))) uint8_t g_ringBuffer[256];
__attribute__((section("DataQuickAccess"))) __attribute__((aligned(sizeof(edma_tcd_t)))) edma_tcd_t tcdMemoryPoolPtr[1];
/* Start ring buffer configuration. */
static void EXAMPLE_StartRingBufferEDMA(void)
{
    edma_transfer_config_t xferConfig;

    /* 添加tcdPool到edma结构体中 */
    EDMA_InstallTCDMemory(&g_uartRxEdmaHandle, tcdMemoryPoolPtr, 1U);

    /* 参考上一节博客的分析 */
    EDMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(UART0), sizeof(uint8_t), g_ringBuffer,
                         sizeof(uint8_t), sizeof(uint8_t), 256, kEDMA_PeripheralToMemory);

    /* 开始传输:设置可以被加载到TCD内存中的TCD的数量 */
    g_uartRxEdmaHandle.tcdUsed = 1U;
    /* 表示下一个加载到tcd内存池的索引 */
    g_uartRxEdmaHandle.tail    = 0U;
    /* 初始化自己声明的tcd内存池中的寄存器为0,但该函数会使能CSR.DREQ=1,表示主循环结束后关闭DMA请求 */
    EDMA_TcdReset(&g_uartRxEdmaHandle.tcdPool[0U]);
    
    /* 将在EDMA_PrepareTransfer中设置到的参数应用到tcdPool中
     * 由于使能了Scatter/Gather模式,理论上不能在每次主循环结束后关闭DMA请求,故在此函数中清除DREQ位
     */
    EDMA_TcdSetTransferConfig(&g_uartRxEdmaHandle.tcdPool[0U], &xferConfig, tcdMemoryPoolPtr);

    /* 打开主循环完成中断,为了计算收到数据的字节数 */
    g_uartRxEdmaHandle.tcdPool[0U].CSR |= DMA_CSR_INTMAJOR_MASK;

    /* 将tcdPool中的TCD内容加载到DMA通道对应的TCD内存中 */
    EDMA_InstallTCD(DMA0, UART_RX_DMA_CHANNEL, &g_uartRxEdmaHandle.tcdPool[0U]);

    /* 开始eDMA传输 */
    EDMA_StartTransfer(&g_uartRxEdmaHandle);

    /* 使能串口DMA传输:UARTx->C2.RIE */
    UART_EnableRxDMA(UART0, true);
}

(1)EDMA_InstallTCDMemory

上一节,我们分析了串口eDMA的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tilblackout

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值