4.0. 【TDA4 C71】UDMA —— C71上的DMA引擎实现

2,019 阅读5分钟

ref pdk_jacinto_08_00_00_37/docs/userguide/jacinto/family_cfg/jacinto/index_modules_udma_jacinto.html

1. 什么是UDMA

1.1. 首先,什么是DMA

DMA (Direct Memory Access,直接存储器访问) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。 —— 节选自百度百科

1.2. TDA4中的UDMA是什么

UDMA ( unified DMA ) 是 DMA 引擎,用于在 McASP、SPI、UART 和内存(DDR、L2、L3、MSMC)等不同外设之间执行直接内存访问 (DMA),而无需 CPU 干预下一代 TI SoC(如 J721E)。DMA 架构指定标准通信模块使用的数据结构,以促进直接内存访问 (DMA), 并为多核设备中的主机软件提供一致的应用程序编程接口 (API)。将数据结构和用于操作它们的API统称为导航器子系统(NAVSS)。

1.2.1. NAVSS的概述

NAVSS在硬件上包含UDMA模块和其他模块。观察NAVSS模块组成有助于理解接下来的内容。

1.2.2. UDMA支持的特性有哪些

本节出现的新名词,可到 0. TI C7x DSP —— 硬件一览 中查找
TR (transfer requests) 传输请求
PSIL (Packet Streaming Interface)

UDMA 驱动程序提供 API 来对导航器子系统 (NAVSS) 的 DMA 部分进行编程,以设置和启动传输。以下是驱动程序支持的高级功能

  • 在MAIN区域和MCU区域均有实现
  • 支持 SOC 中所有实例的 DMA 操作
  • 使用本地 NAVSS 通道拷贝 UDMAP
  • 使用TR提交DRU到DRU寄存器的拷贝 (DRU是MSMC:Multicore Shared Memory Controller中的数据路由)
  • 使用(PSIL)TR提交DRU到UDMA连接的其他外部模块的拷贝
  • PDMA 模块,用于启动与 UART、McASP、McSPI、ADC、MCAN 等 PDMA 外设之间的传输
  • DMA 与本机 PSIL 外设(如 EMAC、CPSW、SA2UL)之间的传输
  • 事件和中断管理,如 DMA 完成、通道链接、使用 IA 的中断共享
  • 跨 UDMAP DMA 通道、RX 流、外部 UTC 通道 (DRU)、中断聚合器 (IA)、中断路由器 (IR)、全局事件、环形加速器 (RA) 的实例和核心进行资源管理
  • 通过 SCICLIENT 与 DMSC RM 模块交互,实现所有非实时 (NRT) 配置
  • 支持 TI-RTOS 和 无操作系统

注意的点

  • UDMA 驱动程序不管理/分配描述符和 RA 内存。调用方需要分配并提供所需的内存。
  • UDMA 驱动程序不使用任何全局变量。所有必需的对象内存(如通道、驱动程序实例、事件等)应由调用方分配。

1.3. UDMA的性能数据

1.4. 如何调用UDMA

1.4.1. 底层头文件和API有哪些

#include <ti/drv/udma/udma.h>

需要包含的头文件只有一个。udma.h中include的其他头文件有众多API。分别提供NAVSS中不同的内存操作模块的调用API。

The UDMA driver API can be broadly divided into the following categories

  • UDMAP native channel API
  • DRU (External UTC) channel API
  • PDMA channel operations
  • Event and interrupt API
  • Ring API

1.4.2. 应用层(TI-RTOS/VisionApps)头文件和API有哪些

vision_apps/utils/udma/include/app_udma.h

这里的API基于底层头文件udma.h,调用过程中会产生额外内存和硬件开销。建议在算法代码中直接调用底层API。
内容包含

  • UDMA始化
  • 少数用于复制/填充帧的实用api

1.4.3. 应用层相关实现

SYSBIOS 往往指运行在C66、C71上的软件
LINUX指运行在A72上的软件

app_utils_memlibraryvision_apps/utils/memSYSBIOSapp_mem_tirtos.c
LINUXapp_mem_linux_dma_heap.c
app_utils_udmalibraryvision_apps/utils/udmaSYSBIOS

app_udma.c app_udma_test.c

1.4.4. 一点调用示例

1.4.4.1. A72-C71的DMA拷贝

在上图可以看到A72与C71的内存通过MSMC连接。我们可以通过DRU的直接提交TR执行拷贝。

1.4.4.1.1. udma_dru_direct_tr_testapp 测试程序

PSDKR(见本栏资源下载) 中的 udma_dru_direct_tr_testapp 测试程序通过 DRU 寄存器使用直接 TR 提交执行块复制。

1.4.4.1.2. app_udma实现

调用 VisionApps 中的 UDMA 封装 vision_apps/utils/udma/src/app_udma_test.c

需要使能代码中 use_nd_copyuse_dru 注意,这个 nd 的意思居然是 n x d 的意思,比如 3d

1.4.4.1.3. udma实现

// TODO 可以参考app_udma.c中的代码

1.4.4.2. 其他硬件的 DMA 调用实现

// TODO

2. 更底层的API和更详细的描述

参考 PSDKR(见本栏资源下载) 文档中的文件夹 pdk_jacinto_08_00_00_37/packages/ti/drv/udma/docs