您好,
SDK 中的 IMXRT EDMA API 似乎能够正确处理“正常情况”中断。然而,似乎没有任何处理错误中断的机制。不仅如此,似乎所有 DMA 都只有一个全局的 DMA_ERROR_IRQHandler。因此,如果您同时使用 DMA0 和 DMA1,当一切正常时,DMA0/DMA1 IRQHandler 将被调用,SDK 可以区分哪个 DMA 收到了正常中断。但是,如果出现 DMA 错误,由于只有一个全局错误中断处理程序,因此没有简单的方法可以知道错误发生在哪个 DMA(0 或 1 或其他)上。
就像我之前关于 LPUART 错误 IRQ 处理的问题一样。为什么 SDK 没有内置处理 DMA 错误并调用相应回调的功能?现在我必须手动确定错误发生在哪个 DMA 上,并在 SDK 之外调用特殊处理,而不是让它为我调用回调。
对于一个本应在生产代码中使用的 SDK 来说,似乎缺少很多健壮性功能,我敢打赌大多数人只是假设这些错误是由 SDK 在底层处理的,而没有考虑到它们实际上并没有被处理。
-m
尊敬的@nxp16 ,
您使用的是哪款 i.MX RT 设备?当您提到 DMA0 和 DMA1 时,您指的是两个 DMA 通道,还是两个 DMA 控制器外设?
并非所有 i.MX RT 设备都具有两个 eDMA 控制器。例如:
i.MX RT1180 包含两个 eDMA 控制器。在启动文件(例如 startup_mimxrt1189_cm33.c)中,您可以找到两个 DMA 错误处理程序:DMA_ERROR_IRQHandler 和 DMA4_ERROR_IRQHandler。
i.MX RT1050 仅包含一个 eDMA 控制器。在启动文件(例如 startup_mimxrt1052.c)中,只有一个 DMA 错误处理程序:DMA_ERROR_IRQHandler。
一般来说,DMA 错误是相对不常发生的事件。从硬件架构的角度来看,通道错误状态被聚合为模块级错误请求,从而触发 DMA 错误中断。因此,该软件必须检查每个通道的错误状态寄存器(例如,CHn_ES),以确定哪个特定通道导致了错误。
顺祝商祺!
张雪莉
抱歉,我指的是频道。我使用的是 IMXRT1172。
如果与之连接的外设出现问题,难道不会发生DMA错误吗?也就是说,如果是 LPSPI 和 DMA,那么任何 SPI 错误都会导致 DMA 错误吗?如果不是,那么在使用DMA时,SPI错误是否会触发SPI错误中断?
谢谢!
-m
尊敬的@nxp16 ,
不。在使用DMA时发生的外围设备错误并不一定意味着DMA控制器本身会报告错误。大多数情况下,SPI 错误和 DMA 错误由两个独立的状态和中断机制处理。
DMA 只报告 DMA 层、总线层或传输层错误。LPSPI 中的协议级或 FIFO 相关错误应通过 LPSPI 外设自身的状态标志和错误中断来处理。以 DMA 模式运行并不会自动将所有 SPI 错误转换为 DMA 错误。
顺祝商祺!
张雪莉
我猜也是这样。在这种情况下,SDK 的传输 API 就更不可靠了。必须在 SDK 之外处理外围设备和 DMA 错误,这需要相当多的额外工作,包括对默认 IRQ 处理程序进行一些变通的覆盖,并确保它们在处理任何错误后仍然调用 SDK 处理程序。令人沮丧的是,这些内容并未包含在 SDK 传输 API 中。
尊敬的@nxp16 ,
我理解您的担忧,我也同意将外围错误状态的处理与 SDK 传输 API 分开处理可能会增加所需的应用程序级代码量。感谢您的反馈。我会将您的意见转达给SDK团队。
顺祝商祺!
张雪莉
实际上,情况比我想象的还要糟糕。使用 EDMA LPSPI 传输 API 无法捕获 SPI 错误,因为 LPSPI_MasterTransferEDMA 调用的函数LPSPI_PrepareTransferEDMA会禁用所有 SPI 中断。因此,在调用它之前不可能启用错误中断,因为它会再次禁用它们,而之后就太晚了,因为 SPI EDMA 传输已经开始了。这是该API的一个重大漏洞。
-m
是的,这正是我目前不得不采取的权宜之计。然而,编辑 SDK 文件并不是一个好的解决方案,因为不幸的是,它们可能会随着 SDK 的更新而改变。
谢谢!
-m
尊敬的@nxp16 ,
谢谢你指出这一点。
我检查了LPSPI_PrepareTransferEDMA(LPSPI_Type *base) 的实现,发现它调用了LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable):
ShellyZhang_0-1784514572337.png
kLPSPI_AllInterruptEnable ,而只需禁用 EDMA 传输操作所需的中断,同时保持错误中断启用即可。