当前位置: 首页 > news >正文

ZYNQ7000 AXI DMA 接收中断(S2MM_introut)全解析:从硬件原理到Linux驱动开发

ZYNQ7000 AXI DMA 接收中断(S2MM_introut)全解析:从硬件原理到Linux驱动开发

文章目录

  • ZYNQ7000 AXI DMA 接收中断(S2MM_introut)全解析:从硬件原理到Linux驱动开发
    • 前言
    • 1. AXI DMA `S2MM_introut` 的作用
    • 2. 硬件映射:从 `IRQ_F2P` 到 GIC
    • 3. Linux 端如何检测该中断?
      • 方式 A:使用 Linux 内核自带的 Xilinx DMA 驱动
      • 方式 B:使用 UIO 驱动(推荐自定义开发使用)
    • 4. 进阶:如何判断中断产生的原因?
      • 4.1 关键寄存器 `S2MM_DMASR` (偏移量 `0x34`)
      • 4.2 用户空间判断与清除代码
    • 5. 总结

前言

在 ZYNQ7000 的软硬件协同设计中,AXI DMA(Direct Memory Access)是实现 PL(FPGA)与 PS(ARM CPU)之间高速数据传输的核心 IP。而在处理海量流式数据(如 ADC 采集、图像传输)时,S2MM(Stream to Memory Map,即接收通道)的中断机制是保证 CPU 实时处理数据的关键。

本文将深入解析 AXI DMA 的S2MM_introut中断:它的作用是什么?接入IRQ_F2P后如何在 Linux 端检测?以及如何判断具体是哪种原因触发了该中断?


1. AXI DMAS2MM_introut的作用

在 AXI DMA 中,S2MM代表数据从 PL 端(Axi-Stream)流向 PS 端 DDR 内存(Axi Memory Map)。

S2MM_introut就是该通道的硬件中断输出信号。当 S2MM 通道发生特定事件时,它会拉高该信号,请求 CPU 介入。默认情况下,它由以下三种事件触发(可在软件中配置使能):

  1. IOC (Interrupt on Complete - 传输完成中断):设置的一帧数据或一个 Scatter-Gather 描述符成功写入 DDR 内存后触发。这是最常用的中断,用于通知 CPU“数据已就绪”。
  2. Dly (Delay Interrupt - 延迟/超时中断):当数据传输中途暂停,且在设定的时间窗口内没有新数据到达时触发。常用于接收未知长度的流数据。
  3. Err (Error Interrupt - 错误中断):当 AXI 总线发生响应错误、地址解码错误或内部 FIFO 溢出时触发。

2. 硬件映射:从IRQ_F2P到 GIC

在 Vivado 中,我们通常将S2MM_introut连接到 ZYNQ PS 端的IRQ_F2P[15:0]接口。

  • 硬件路由IRQ_F2P是共享外设中断(SPI)。IRQ_F2P[15:0]对应的硬件中断号在 ZYNQ 内部被映射为61~6884~91
  • GIC 控制器:当 PL 端拉高S2MM_introut时,信号通过IRQ_F2P触达 PS 端的 GIC(通用中断控制器),GIC 再向 ARM 核心派发中断。

3. Linux 端如何检测该中断?

在 Linux 系统中,有传统官方内核驱动UIO(用户空间IO)两种检测方式。

方式 A:使用 Linux 内核自带的 Xilinx DMA 驱动

内核源码drivers/dma/xilinx/xilinx_dma.c已经实现了完整的中断底半部机制。

  1. 设备树配置:Vivado 导出的设备树会自动包含中断信息。
axi_dma_0: dma@40400000 { compatible = "xlnx,axi-dma-1.00.a"; reg = <0x40400000 0x10000>; interrupt-parent = <&intc>; interrupts = <0 29 4>, <0 30 4>; /* 30 对应 S2MM 的中断号 */ ... };
  1. 检测方式:在此模式下,驱动程序会自动申请中断。开发者在应用层只需通过标准的DMA Engine API(如dmaengine_submit)提交传输请求,并注册一个回调函数。当S2MM_introut触发时,内核会自动调用你的回调函数。

方式 B:使用 UIO 驱动(推荐自定义开发使用)

如果不想写复杂的内核驱动,可以通过 UIO 机制将中断直接透传到用户空间。
在设备树中将 DMA 节点的compatible改为"generic-uio",Linux 会在/dev/下生成uio0(或类似)设备。

用户空间 C 语言检测代码(阻塞读取):

#include<stdio.h>#include<fcntl.h>#include<unistd.h>#include<stdint.h>intmain(){intfd=open("/dev/uio0",O_RDWR);if(fd<0)return-1;// 1. 使能 UIO 中断uint32_tunmask=1;write(fd,&unmask,sizeof(unmask));printf("等待 S2MM 硬件中断...\n");// 2. 阻塞读取,当 S2MM_introut 触发时,read 会被唤醒返回uint32_tirq_count;read(fd,&irq_count,sizeof(irq_count));printf("捕获到中断!当前累计触发次数: %u\n",irq_count);close(fd);return0;}


4. 进阶:如何判断中断产生的原因?

当 Linux 端捕获到中断后,我们如何知道是传输完成(IOC)超时(Dly)还是错误(Err)导致的呢?

方法是:读取 AXI DMA 的状态寄存器S2MM_DMASR

4.1 关键寄存器S2MM_DMASR(偏移量0x34)

该寄存器映射在 AXI DMA 基地址偏移0x34处。其 Bit 12、13、14 对应了三种中断状态:

Bit 位名称掩码含义描述
Bit 12IOC_Irq0x00001000传输完成。如果是1,说明一帧数据成功写入内存。
Bit 13Dly_Irq0x00002000延迟/超时。如果是1,说明超时计数器溢出(无新数据)。
Bit 14Err_Irq0x00004000错误。如果是1,说明发生了严重的 AXI 总线或内部错误。

4.2 用户空间判断与清除代码

在使用 UIO 的情况下,通过mmap映射 DMA 寄存器基地址后,可以通过如下逻辑进行判断。

⚠️ 注意:AXI DMA 的中断标志位是“写 1 清零”(W1C),判断完必须手动清零,否则会导致中断风暴死机!

// 假设 dma_virtual_base 是通过 mmap 得到的 DMA 基虚拟地址volatileuint32_t*s2mm_dmasr=(uint32_t*)((uint8_t*)dma_virtual_base+0x34);// 1. 读取当前状态寄存器的值uint32_tstatus=*s2mm_dmasr;// 2. 判断具体原因if(status&0x1000){printf("-> 中断原因: 传输完成 (IOC)\n");// TODO: 此时可以安全读取 DDR 中的数据}if(status&0x2000){printf("-> 中断原因: 延迟超时 (Delay)\n");}if(status&0x4000){printf("-> 中断原因: 硬件错误 (Error)\n");// 进阶:可以继续判断 Bit[6:4] 确定是 Slave 错误还是 Decode 错误}// 3. 极其重要:清除中断标志(W1C - 写 1 清零)// 只清除这三个中断位,不影响其他状态位*s2mm_dmasr=(status&0x7000);


5. 总结

ZYNQ7000 AXI DMA 的S2MM_introut构成了一条从 PL 到 Linux 应用层的完整通知链:

  1. PL端硬件产生事件→ \rightarrow
  2. 拉高S2MM_introut通过IRQ_F2P送达GIC→ \rightarrow
  3. Linux 内核捕获并唤醒等待的进程→ \rightarrow
  4. 应用层/驱动读取0x34状态寄存器识别具体原因→ \rightarrow
  5. 处理数据并写1清零中断位。
http://www.jsqmd.com/news/621806/

相关文章:

  • Python 里把 JSON 转成字典
  • 2026年评价高的门窗/阳光房门窗/佛山智能门窗/极窄门窗优质公司推荐 - 品牌宣传支持者
  • Python 列表与元组:从核心区别到实战选型
  • 保姆级教程:用ABAP BAPI_PRODORDCONF_CREATE_TT实现多工序报工与自动收货(含完整代码)
  • [具身智能-336]:Python定义一个函数示例说明,不带参数和带参数分别说说明,还有->提示
  • 组合专机-给喷油泵下体零件设计组合机床(论文 CAD图纸)
  • TMI拓尔微 TMI3408 SOT23-5 DC-DC电源芯片
  • F12实战:Cookie的增删改查与登录态管理
  • FireRed-OCR Studio惊艳案例:将200页技术手册PDF转为可搜索Markdown
  • 2026年防爆地磅选型指南:地磅汽车衡/地磅电子汽车衡/地磅电子秤/地磅衡器/天津地磅/天津电子秤/工业电子秤/选择指南 - 优质品牌商家
  • ImageNet验证集标签映射实战:从devkit解析到文件重组织的完整指南
  • RS-422 vs RS-485:硬件工程师必须知道的5个关键差异点
  • 彻底告别OpenClaw使用焦虑:我给他装上了“透视眼”和“批量克隆模组手
  • 一个LLM网关需要处理哪些工程问题?多模型路由与成本归因实战
  • 【内部流出】某TOP3电商Loom迁移白皮书精要版(含GC调优参数、监控埋点规范、5类典型Case复盘)
  • 5G专网外场UDP灌包实战:从iperf命令到峰值速率验证
  • 2026年热门的大白菜包装机/叶菜包装机/青岛鸡排包装机/鸡排包装机厂家推荐与选型指南 - 品牌宣传支持者
  • PyTorch 2.8通用镜像实战:RTX 4090D下构建AI辅助编程环境
  • 组合机床多轴箱设计(六孔)
  • 告别 Shared Memory 瓶颈:Vulkan Subgroup 架构解析与硬核实战指南
  • 关于idea的使用
  • AI Agent投资回报率的科学计算方法
  • ESP32项目空间总不够用?一份自定义分区表(partitions.csv)的配置心得与避坑指南
  • 2026年评价高的包子包装机/鸡排包装机/叶菜包装机品牌厂家推荐 - 品牌宣传支持者
  • Aurix TC3XX开发实战:GPT12模块的四种工作模式到底该怎么选?(附MCAL配置差异)
  • 开发一款定制小游戏需要多久?流程 + 案例全解
  • ThreadLocalMap内部大揭秘:从哈希冲突到弱引用,手把手带你模拟一个自己的ThreadLocal
  • 优思学院|QC新七大手法——七个质量管理者必学工具
  • IntelliGit 第 1 期 | 项目启动:从 0 到 1 理解架构、搭建环境与团队协作
  • nli-distilroberta-base效果展示:跨领域(科技/医疗/法律)NLI泛化能力实测