gpt4 book ai didi

c - Atmel SAMD21 DMA 中止问题

转载 作者:行者123 更新时间:2023-12-01 14:06:18 26 4
gpt4 key购买 nike

由于某些设计要求,我需要在运行时更改 DMA 描述符。为了实现这一点,我遵循以下步骤:

  • 中止 DMA channel 。 DMA 硬件然后将当前执行的描述符保存在
    同一 DMA channel 的 write_back RAM 位置。
  • 等到中止完成
  • 修改 write_back RAM 位置上的 DMA 描述符。
  • 再次启用 DMA channel

  • 这是我正在使用的代码片段:
    //Select DMA channel
    DMAC->CHID.reg = DMAC_CHID_ID(cSPIDMAResource0.channel_id);

    //Abort Selected DMA channel
    DMAC->CHCTRLA.reg &= ~DMA_CHANNEL_ENABLE_BIT_POS;

    //Wait until Abort completed
    while((DMAC->CHCTRLA.reg & DMA_CHANNEL_ENABLE_BIT_POS) == DMA_CHANNEL_ENABLE_BIT_POS);

    /*
    Modify Descriptor here
    */

    //Enable DMA channel
    DMAC->CHCTRLA.reg |= DMA_CHANNEL_ENABLE_BIT_POS;

    上述步骤工作正常,没有任何问题,但从长远来看,我面临着描述符损坏问题。

    当执行 DMA 中止时,DMA 硬件将当前正在执行的描述符存储在另一个 DMA channel 的 write_back RAM 位置(而不是自己的 write_back RAM 位置)。

    如果有人知道出了什么问题,或者知道如何完全避免描述符损坏问题,我想尝试一下。

    最佳答案

    为什么不使用 atmel 软件框架的 dma 驱动程序?这是他们如何进行中止。

    void dma_abort_job(struct dma_resource *resource)
    {
    uint32_t write_size;
    uint32_t total_size;

    Assert(resource);
    Assert(resource->channel_id != DMA_INVALID_CHANNEL);

    system_interrupt_enter_critical_section();

    DMAC->CHID.reg = DMAC_CHID_ID(resource->channel_id);
    DMAC->CHCTRLA.reg = 0;

    system_interrupt_leave_critical_section();

    /* Get transferred size */
    total_size = descriptor_section[resource->channel_id].BTCNT.reg;
    write_size = _write_back_section[resource->channel_id].BTCNT.reg;
    resource->transfered_size = total_size - write_size;

    resource->job_status = STATUS_ABORTED;
    }

    可以解释该问题的一个区别是通过 system_interrupt_leave_critical_section() 禁用中断。在用于中止 dma channel 的寄存器写入期间。

    关于c - Atmel SAMD21 DMA 中止问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33750367/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com