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.

[参考译文] CCS/TM4C129XNCZAD:UDMA 不退出 ISR

Guru**** 2433360 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/647502/ccs-tm4c129xnczad-udma-not-exiting-the-isr

器件型号:TM4C129XNCZAD

工具/软件:Code Composer Studio

我正在尝试通过 DMA - UART 发送和接收数据、并开始修改 UDMA_DEMO、我遇到了这样的问题、即 UART 中断服务例程始终会触发该问题。

我的疑问如下:

ui32Status = ROM_UARTIntStatus (UART0_BASE、1);返回0x00020000;并且我尝试清除故障(这会不断触发、我没有看到它被清除)。

这是任何建议的 DMA 传输完成位。

无效
InitUART0传输(uint32_t ui32SysClock)

//启用 UART 外设,并将其配置为即使 CPU 也能正常工作
//处于睡眠状态。
//
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
ROM_SysCtlPeripheralSlepEnable (SYSCTL_Periph_UART0);

//
//配置 UART 通信参数。
//
ROM_UARTConfigSetExpClk (UART0_BASE、ui32SysClock、9600、
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);

//
//将 TX 和 RX 触发阈值设置为4。 这将由使用
// uDMA 控制器发出信号,指示何时应传输更多数据。 。
//将配置 uDMA TX 和 RX 通道,以便可以传输4个通道
当 UART 准备传输更多数据时、//以突发方式传输字节。
//
ROM_UARTFIFOLevelSet (UART0_BASE、UART_FIFO_TX4_8、UART_FIFO_RX4_8);

//
//启用 UART 以进行操作,并为两个 TX 启用 UDMA 接口
//和 RX 通道。
//
ROM_UARTEnable (UART0_BASE);
ROM_UARTDMAEnable (UART0_BASE、UART_DMA_RX | UART_DMA_TX);

//

//
//将 UDMA UART0RX 通道的属性置于已知状态。 这些
默认情况下、//应已禁用。
//
ROM_uDMAChannelAttributeDisable (UDMA_CHANGE_UART0RX、
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIOR|
UDMA_ATTR_REQMASK);

//
//为配置主控制结构体的控制参数
// UART RX 通道。 主控制结构用于"A"
//部分乒乓接收。 传输数据大小为8位
//源地址不会递增,因为它将从读取
//寄存器。 目的地址增量是字节8位字节。 。
//仲裁大小设置为4以匹配 RX FIFO 触发阈值。
//如果可能,UDMA 控制器将使用4字节突发传输。 这种情况
//这种单字节传输会更有效一些。
//
ROM_uDMAChannelControlSet (UDMA_CHANGE_UART0RX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);

//
//为的替代控制结构配置控制参数
// UART RX 通道。 备用控制结构体用于"B"
//部分乒乓接收。 配置与相同
//主/A 控制结构。
//
ROM_uDMAChannelControlSet (UDMA_CHANGE_UART0RX | UDMA_ALT_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);

//
//设置 UART RX 主控件的传输参数
//结构。 模式设置为乒乓模式、传输源为
// UART 数据寄存器,目的是接收“A”缓冲区。 。
//传输大小设置为与缓冲区大小匹配。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_UART0RX | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
(void *)(UART0_BASE + UART_O_DR)、
g_ui8RxBufA、sizeof (g_ui8RxBufA);

//
//设置 UART RX 交替控制的传输参数
//结构。 模式设置为乒乓模式、传输源为
// UART 数据寄存器,目的是接收"B"缓冲区。 。
//传输大小设置为与缓冲区大小匹配。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_UART0RX | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
(void *)(UART0_BASE + UART_O_DR)、
g_ui8RxBufB、sizeof (g_ui8RxBufB));

//
//将 UDMA UART0TX 通道的属性置于已知状态。 这些
默认情况下、//应已禁用。
//
ROM_uDMAChannelAttributeDisable (UDMA_CHANGE_UART0TX、
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIOR|
UDMA_ATTR_REQMASK);

//
//设置 UDMA UART TX 通道的 USEBURST 属性。 这将会
//强制控制器在传输数据时始终使用突发
//将 TX 缓冲器连接到 UART。 这是比较有效的总线使用
//不是允许单次或突发传输的默认值。
//
ROM_uDMAChannelAttributeEnable (UDMA_CHANGE_UART0TX、UDMA_ATTR_USEBURST);

//
//配置 UART TX 的控制参数。 UDMA UART TX
//通道用于将数据块从缓冲区传输到 UART。
//数据大小为8位。 源地址增量为8位字节
//因为数据来自缓冲区。 目的增量为
//由于数据将被写入 UART 数据寄存器,因此不存在。 。
//仲裁大小设置为4,与 UART TX FIFO 触发器匹配
//阈值。
//
ROM_uDMAChannelControlSet (UDMA_CHANGE_UART0TX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_8 |
UDMA_DST_INC_NONE |
UDMA_ARB_4);

//
//设置 uDMA UART TX 通道的传输参数。 这将会
//配置传输源和目的以及传输大小。
//使用基本模式是因为外设正在进行 UDMA 传输
//请求。 源是 TX 缓冲区、目的是 UART
//数据寄存器。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_UART0TX | UDMA_PRI_SELECT、
UDMA_MODE_BASIC、g_ui8TxBuf、
(void *)(UART0_BASE + UART_O_DR)、
sizeof (g_ui8TxBuf));

//
//现在,UDMA UART TX 和 RX 通道都被引脚以启动 A
//传输。 一旦启用通道、外设将会启动
//发出传输请求,数据传输将开始。
//
ROM_uDMAChannelEnable (UDMA_CHANGE_UART0RX);
ROM_uDMAChannelEnable (UDMA_CHANGE_UART0TX);

//
//启用 UART DMA TX/RX 中断。
//
ROM_UARTIntEnable (UART0_BASE、UART_INT_DMATX | UART_INT_DMARX);

//
//启用 UART 外设中断。
//

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我不会发现 InitUART0Transfer()有任何问题。 除了您删除回送模式外、它与 TivaWare 示例大致相同。

    如何清除 UART0中断标志?

    在 UART0IntHandler 内部、是否继续触发 UART DMA 传输? 如果您不想继续 DMA 传输、则不应在 DMA 传输完成后重新启动另一个 DMA 传输。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Charles:

    非常感谢您的回复、我已删除其中的 DMA 发送部分...

    我将按如下方式清除该标志:

    我是否需要禁用 TX 中断? 我尝试通过添加这些行来禁用 DMA 和禁用 TX 中断、但我使用 了 FaultISR (void)

     ROM_UARTDMADisable (UART0_BASE、UART_DMA_TX);
     ROM_UARTIntDisable (UART0_BASE、UART_INT_DMATX);

    我正在读取中断状态 、它是0x00020000;我尝试清除它、但它没有被清除。

    我的代码的目的只是为了能够在我将数据串写入缓冲区并启用 DMA 时发送一些数据串... 并在我到达时从另一端接收任何响应。

    问题是、系统始终处于 ISR 中、从不离开 ISR、我在这里缺少什么吗?

    无效
    UARTIntHandler (空)

       uint32_t ui32Status;
       uint32_t ui32模式;

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

       HWREG (UART0_BASE + UART_O_ICR)= 0x00020000;
       ui32Status = ROM_UARTIntStatus (UART0_BASE、1);

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

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

       //
       //如果主控制结构体指示停止,则表示"A"
       //接收缓冲完成。  UDMA 控制器仍应接收
       //将数据输入"B"缓冲区。
       //
       if (ui32Mode = uDMA_MODE_STOP)
       {
           //
           //递增计数器以指示数据已接收到缓冲区 A 中  
           //一个实际应用,此应用将用于向主线程发出信号
           //数据已接收,因此主线程可以处理数据。
           //-------------------- >在缓冲区 A-->???中设置接收到的数据标志

            G_ui32RxBufACount++;

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

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

       //
       //如果副控制结构体指示停止,则表示"B"
       //接收缓冲完成。  UDMA 控制器仍应接收
       //将数据输入到"A"缓冲区中。
       //
       if (ui32Mode = uDMA_MODE_STOP)
       {
           //
           //递增计数器以指示数据已接收到缓冲区 A 中  
           //一个实际应用,此应用将用于向主线程发出信号
           //数据已接收,因此主线程可以处理数据。
           //
           G_ui32RxBufBCount++;

           ///---------- >缓冲区已满... 将数据移动到内核中的内存位置--- 在这里设置一个标志----

        //
           ROM_uDMAChannelTransferSet (UDMA_CHANGE_UART0RX | UDMA_ALT_SELECT、
                                      UDMA_MODE_PINGONG、
                                      (void *)(UART0_BASE + UART_O_DR)、
                                      g_ui8RxBufB、sizeof (g_ui8RxBufB));
       }

            //下次要进行传输时,必须重新启用 uDMA TX 通道。

               //


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

    您声称自己是"不退出中断"-但您的"清除中断"是否不可能出现"在 ISR 服务中太晚"-因此无法完全/正确执行-导致"无限返回"到该 ISR?

    进入和退出 ISR 后、ISR 是否会变得更明确/更有洞察力?    我不相信您已经(现在)"做出了这样的决定"未 能退出 ISR。"

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

    实际上、我想知道代码中发生了什么错误、我怀疑继续返回 ISR 是因为中断未被清除、实际上就是这样。

    在清除 DMATXIC 中断之前、我应该禁用 UARTDMACTL 中的通道、并且我通过这种方式实现了、

    ui32Status = ROM_UARTIntStatus (UART0_BASE、1);
    //UARTIntDisable (UART0_BASE);

    IF (ui32Status = 0x00020000)


    //在这里做点事情..........
    ROM_UARTDMADisable (UART0_BASE、UART_DMA_TX);
    ROM_UARTIntClear (UART0_BASE、ui32Status);