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

ISP DMA TEST

定义理解

Camera ISP 场景

Camera ISP 场景下在 ISP → Memory 的数据流里:ISP 内部有 DMA 引擎(通常叫 ISP output DMA / Write DMA)。
ISP 出一帧时,数据通过 内部 DMA 硬件写入内存。

一帧传完,ISP 会产生“frame done”中断,有些 SoC 把这个中断叫做 ISP 中断,本质上是 ISP 内部 DMA 完成触发的中断。

也就是说:在 Camera ISP 里,应用看到的中断不是“通用 DMA 控制器的中断”,而是 ISP 内部的帧完成中断。
但它的意义和 DMA 完成中断是一样的:告诉 CPU 有一帧写好了,可以 DQBUF 了。

驱动层处理逻辑

ISP/DMA 完成一帧 → 硬件产生中断 → GIC 送到 CPU。

驱动的中断 handler 被调用。驱动在 handler 里标记该 buffer 已完成 → 之后把它放入 done 队列;
唤醒等待队列(select/poll/unblock DQBUF), 应用 VIDIOC_DQBUF → 成功取到这一帧。
如果中断没来 → buffer 永远不会进 done 队列 → 应用只能报 EAGAIN。

总结

DMA 完成一定会有中断,否则 CPU/驱动不知道哪块 buffer 填好了。
在 ISP 这种专用硬件里,这个中断通常以 ISP frame done IRQ 的形式暴露出来(但实际上就是 DMA 完成事件)。

测试DMA读写模块测试

ISP_APB_DMA_TASK_TYPE

typedef struct  ISP_APB_DMA_TASK_TYPE{uint32_t    task_valid; //1:task enableuint32_t    task_mode ; //0:auto clean task on done. 1:manualuint32_t    task_type ; //0:read task 1:write taskuint32_t    task_lens ; //rd:reg_num-1 wr:reg_num*2-1;uint32_t    task_caddr; //command ddr addressuint32_t    task_daddr; //rd cmd to ddr address
}ISP_APB_DMA_TASK_t;

ISP_APB_DMA_TASK_t 这个结构体其实就是一个 DMA 描述符(task descriptor),用来告诉 ISP 的 DMA 引擎:
要做一个任务(读/写)读/写多少寄存器,数据要从哪里来 ,要到哪里去;

读任务(task_type = 0)

DMA 任务作用:从寄存器 → DDR
task_caddr
存放要读的寄存器地址列表。
例如:0x1000, 0x1004, 0x1008 ...

DMA 会依次按照这些寄存器地址去 APB 读寄存器。

task_daddr
DMA 把读出来的数据写到 DDR 里的起始地址(即 task_daddr 指定的位置)。
最终 DDR 里的数据会长这样:
[reg0_value][reg1_value][reg2_value]...

写任务(task_type = 1)工作中一般用到写任务

DMA 任务作用:从 DDR → 寄存器
task_caddr :存放命令对: (寄存器地址 + 要写的值)。
通常一个写命令需要两个 word:[addr0][data0][addr1][data1][addr2][data2]...;所以 task_lens = reg_num * 2 - 1

task_daddr:在 写任务 中通常不用(或者保留),因为数据已经和地址一起放在 task_caddr 的 DDR buffer 里了。
DMA 引擎只需要去 task_caddr 取 (寄存器地址, 数据) 对(根据实际要求填写buffer),依次写入寄存器。

对比总结

字段 读任务(read) 写任务(write)
task_lens reg_num - 1 reg_num * 2 - 1
task_caddr 存放寄存器地址列表 存放 (寄存器地址, 数据) 对,或者(数据,寄存器地址、或者地址偏移量等)
task_daddr 存放寄存器值的 DDR 地址 通常不用(数据在 caddr 里)

注释

task_caddr = 任务的命令区(告诉 DMA 要操作哪些寄存器 / 要写哪些数据)
task_daddr = 数据存放区(只在读任务时真正使用,写的时候通常不用)

  • RDMA(读任务,task_type=0)

reg_num = 你要读的寄存器个数。
DMA 控制器每次按 "一个寄存器的宽度(比如 4字节)" 去搬数据。
所以 task_lens 配置时,告诉硬件 "我要读多少个寄存器 - 1"。task_lens = reg_num - 1;

比如要读 4 个寄存器,就配 task_lens = 3。
原因是很多硬件寄存器里的长度字段定义是 "实际长度 - 1",因为 0 就代表 1 个元素,避免出现歧义。

  • WDMA(写任务,task_type=1)

写的时候不只是写寄存器值,还需要告诉硬件 "写哪个寄存器 + 写的值"。所以一个寄存器写操作,实际上需要 两个 32-bit 命令字:
地址字段(寄存器地址)4字节 + 数据字段(要写的值) 4字节
因此 一个寄存器对应两个 word。task_lens = reg_num * 2 - 1;

比如要写 4 个寄存器,需要 8 个 word → task_lens = 7。

举例说明点击查看代码

*//wr src0
./devmem3 w 0x78c40000 0x1234567 //第一个四字节,先写值再写地址;
./devmem3 w 0x78c40004 0x000000 //第二个四字节, 0xff00 0000 基地址,编译地址0x000000 ,最终地址是 0xff00 0000  ./devmem3 w 0xff010404 0x0 //MIPI_DMA_CTL0
./devmem3 w 0xff0100c8 0x0
./devmem3 w 0xff0100cc 0x0
./devmem3 w 0xff010400 0x100109./devmem3 w 0xff0104c0 0x1
./devmem3 w 0xff0104c0 0x5
./devmem3 w 0xff0100c0 0x0./devmem3 w 0xff0104c4 0x78c40000 //task_caddr
./devmem3 w 0xff0104cC 0xC0000001 // MIPI_DMA_SRC0_PING_TASK0 读写属性 读写长度等./devmem3 w 0xff010404 0x80000000./devmem3 w 0xff010410 0x0 ./devmem3 w 0xff0100c8 0x1
./devmem3 w 0xff0100c8 0x10001 //MIPI_ISP_RDMA_CTRL0 dma_trig./devmem3 r 0xff000000
./devmem3 r 0xff010408 //读取中断状态 如果完成 则是1 表示中断正常
./devmem3 r 0xff0104cC
=================================================
*//wr src1
./devmem3 w 0xff000000 0x0./devmem3 w 0x78c40000 0x1234567
./devmem3 w 0x78c40004 0x00000./devmem3 w 0xff010404 0x0
./devmem3 w 0xff0100c8 0x2
./devmem3 w 0xff0100cc 0x0
./devmem3 w 0xff010400 0x100109./devmem3 w 0xFF0104F4 0x1
./devmem3 w 0xFF0104F4 0x5
./devmem3 w 0xff0100c0 0x1./devmem3 w 0xFF0104F8 0x78c40000
./devmem3 w 0xff0104cc 0xC0000001./devmem3 w 0xff010404 0x80000000./devmem3 w 0xff010410 0x0./devmem3 w 0xff0100c8 0x1
./devmem3 w 0xff0100c8 0x10001./devmem3 r 0xff000000
./devmem3 r 0xff010408
./devmem3 r 0xff0104cC
http://www.zskr.cn/news/13872.html

相关文章:

  • 洛谷题单指南-进阶数论-P5091 【模板】扩展欧拉定理
  • RAG is really dead? 大模型和知识之间的桥梁没了? - spader
  • 在 Unity 中运用 SoundTouch 插件控制音频倍速播放
  • 基于 SciPy 的矩阵运算与线性代数应用详解 - 详解
  • sway - wayland下截图方案
  • 科学史笔记
  • 2025 年真空泵品牌最新权威推荐排行榜:覆盖真空泵维修,真空泵机组,真空泵油,真空泵配件领域选择指南
  • InnoDB ReplicaSet和其他数据库高可用方案有什么区别?
  • 完整教程:南华 NHJX-13 型底盘间隙仪:机动车底盘安全检测的核心设备
  • vue3使用路由配置
  • 个人行业选择
  • C语言的指针与cpp的引用
  • 进程互斥的硬件实现方式(比较难懂的一节课,但是我搞懂了)
  • 【征文计划】基于Rokid眼镜平台的AR历史情景课堂创意应用 - 指南
  • 华清远见携STM32全矩阵产品及创新机器狗亮相2025 STM32研讨会,共启嵌入式工艺探索新程
  • 母线操作术语
  • 【Linux指令 (一)】Linux 命令行入门:从零开始理解Linux平台理论核心概念与基础指令
  • 完整教程:国检集团官网UI设计展示——专业界面设计实力呈现
  • HAProxy+keepalived+nginx实现高性能负载均衡集群 转发
  • 京东JoyAgent环境搭建与推理测试
  • 2025 年最新推荐 OCR 图片识别软件厂商权威排行榜:聚焦文字识别与表格转换优质服务商全景评测
  • 实用指南:Go tool pprof 与 Gin 框架性能分析完整指南
  • win10 环境变量不可编辑
  • 2025云南游选哪家?久游国际旅行社吃住超便利
  • .NET开发中3秒判断该用 IEnumerable 还是 IQueryable
  • 最想要的答案,一定不在备选项中
  • 【论文阅读 | IF 2025 | LFDT-Fusion:潜在特征引导的扩散 Transformer 模型在通用图像融合中的应用】 - 教程
  • PaddleLabel百度飞桨Al Studio图像标注平台安装和使用指南(包冲突 using the ‘flask‘ extra、眼底医疗分割材料集演示)
  • 订单模块
  • 手写MyBatis第78弹:装饰器模式在MyBatis二级缓存中的应用:从LRU到防击穿的全方案实现 - 指南