TDA4VM-LINUX-CSI-9296-9295-camera架构驱动分析和详细使用

2023-10-26

前言

TI在LINUX-SDK-8.01版本后才开始支持Linux V4L2接入CSI2,所以在使用前尽量先用RTOS-SDK接入CSI2的接口camera,正常工作后开始进行Linux V4L2的开发。
LINUX-SDK的安装使用,参考另一篇文档《优雅的玩转TDA4VM》
在TDA4VM中,一个CSI接口是默认启动16个虚拟通道的。

硬件架构

系统 硬件架构
Linux CSI2RX子系统由3个IP组成:Cadence DPHY,Cadence CSI2RX桥接, TI CSI2RX DMA 封装器
RTOS CSI2RX子系统由2个IP组成:Cadence DPHY,CSI2RX_drive

image.png
CSI2RX 子系统支持以下功能:

  • 符合 MIPI CSI v1.3 标准
  • 每个输入最多支持 16 个虚拟通道(部分 MIPI CSI v2.0 功能)。
  • 每通道数据速率高达 2.5 Gbps(线速)。
  • 支持 1、2、3 或 4 条数据通道连接到DPHY_RX。
  • 可编程格式包括 YUV420、YUV422、RGB、Raw 等。

驱动程序

该驱动程序基于 Video 4 Linux 2 (V4L2) API。它已实现 根据捕获设备的 V4L2 标准。司机只是 负责对用于捕获的SoC组件进行编程,例如DPHY,CSI-Bridge,DMA。对于相机传感器等外部设备,单独的 V4L2 子设备需要驱动程序。

link_freq计算

V4L2_CID_LINK_FREQ

数据总线频率。数据总线频率与媒体总线像素代码、总线类型(每个样本的时钟周期)一起定义了像素阵列中的像素速率(V4L2_CID_PIXEL_RATE),如果设备不是图像传感器,则可能定义其他像素速率()。帧速率可以通过像素时钟、图像宽度和高度以及水平和垂直消隐来计算。虽然像素速率控制可以在包含像素数组的子开发中以外的其他位置定义,但无法从该信息中获取帧速率。这是因为只有在像素阵列上,才能假设垂直和水平消隐信息是精确的:像素数组中不允许其他消隐。通过选择所需的水平和垂直消隐来选择帧速率。此控件的单位是 Hz。

V4L2_CID_PIXEL_RATE

子开发源垫中的像素率。此控件是只读的,其单位为像素/秒。Ex mipi 总线:pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample位深
mipi_link_freq = wh * fps * bits_per_sample / nr_of_lanes / 2
pixel_clk_rate = w
h * fps

CSI2RX寄存器调试

使用devmem2工具依次查看对应CSI2RX的寄存器,从而判断硬件是否有数据输入。

DPHY正常状态

0x04590B00(DPHY_RX_VBUS2APB_PCS_TX_DIG_TBIT0) = 0x000001ef
0x04504040(CSI_RX_IF_VBUS2APB_DPHY_LANE_CONTROL) = 0x0001F01F
0x04504048(CSI_RX_IF_VBUS2APB_DPHY_STATUS) = 0x00333306/0x00222206
0x04504060(CSI_RX_IF_VBUS2APB_INTEGRATION_DEBUG) = 0x10000000 // WAIT_FOR_PACKET
0x04504100(CSI_RX_IF_VBUS2APB_STREAM0_CTRL) = 0x00000001
0x04504104(CSI_RX_IF_VBUS2APB_STREAM0_STATUS) = 0x80000111
0x04580C10 ( DPHY_RX_VBUS2APB_ISO_PHY_ISO_CL_CNTRL_L ) = 0x00000029 //normal

寄存器配置

max9296

//使能
max9296_write(priv, 0x0313, 0x02);
//关闭
max9296_write(priv, 0x0313, 0x00);
    max9296_write(priv, 0x0010, 0x31);
    msleep(100);
    max9296_write(priv, 0x0313, 0x00);
    msleep(1);
    max9296_write(priv, 0x048B, 0x07);
    msleep(1);
    max9296_write(priv, 0x048D, 0x1E);
    msleep(1);
    max9296_write(priv, 0x048E, 0x1E);
    msleep(1);
    max9296_write(priv, 0x0490, 0x00);
    msleep(1);
    max9296_write(priv, 0x0491, 0x01);
    msleep(1);
    max9296_write(priv, 0x0492, 0x01);
    msleep(1);
    // max9296_write(priv, 0x04AD, 0x2A);
    max9296_write(priv, 0x04AD, 0x15);//206
    msleep(1);
    max9296_write(priv, 0x0320, 0x2C);
    msleep(1);
    max9296_write(priv, 0x0051, 0x02);
    msleep(1);
    max9296_write(priv, 0x0052, 0x01);
    msleep(1);

max9295

    max9295_write(priv, 0x0010, 0x21);
    msleep(100);
    max9295_write(priv, 0x02be, 0x10);
    msleep(500);
    max9295_write(priv, 0x0318, 0x5E);
    msleep(1);
    max9295_write(priv, 0x02D3, 0x00);
    msleep(500);
    max9295_write(priv, 0x02D3, 0x10);
    msleep(100);
    max9295_write(priv, 0x02D6, 0x00);
    msleep(500);
    max9295_write(priv, 0x02D6, 0x10);
    msleep(100);

驱动源码

...
static int max9295_probe(struct i2c_client *client)
{
	struct max9295_priv *priv;
	struct device *dev = &client->dev;
	int ret;

	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	
	priv->client = client;
	i2c_set_clientdata(client, priv);
	
	priv->regmap = devm_regmap_init_i2c(client, &max9295_i2c_regmap);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);
	
	if (max9295_read(priv, 0x0000) != MAX9295_ID)
		return -EFAULT;
	
	max9295_mipi_configure(priv);
	
	// max9295_v4l2_register(priv);
	dev_info(dev, "Successfully probed 9295 (rev/mask)\n");
	return 0;

}
...
...
static int max9296_probe(struct i2c_client *client)
{
	struct max9296_priv *priv;
	int ret;
	

	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	
	mutex_init(&priv->mutex);
	
	priv->client = client;
	i2c_set_clientdata(client, priv);
	
	priv->regmap = devm_regmap_init_i2c(client, &max9296_i2c_regmap);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);
	
	/*parse_dt*/
	ret = max9296_parse_dt(priv);
	if (ret)
		goto err_powerdown;
	
	ret = max9296_init(&client->dev);
	if (ret < 0)
		goto err_cleanup_dt;
	dev_err(&client->dev, "Successfully probed 9296 ok\n");
	return 0;

err_cleanup_dt:
	max9296_cleanup_dt(priv);
err_powerdown:
	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
	return ret;
}
...

创建设备树节点

确定主设备树

使用dmesg工具,查看启动日志,找到启动所用的主设备树。
记录到内核环形缓冲区的每个消息都有一个附加的级别。 级别表示信息的重要性。 包含的级别有:

  • emerg : 系统无法使用;
  • alert : 必须立即采取措施;
  • crit : 严重的情况;
  • err : 错误;
  • warn : 警告;
  • notice : 正常但是重要的情况;
  • info : 消息;
  • debug : 调试信息;

通过使用 -l(level)参数并将级别的名称作为命令行参数传递,可以提取与特定级别匹配的消息。 如果查看“informational”级别的消息,请使用如下命令:

$ dmesg -l info  //列出的所有消息都是"info"消息。 它们不包含错误或警告,仅包含有用的通知。

从启动日志确认设备树为k3-j721e-common-proc-board.dts。

修改主设备树

&main_i2c6 {
	pinctrl-names = "default";
	pinctrl-0 = <&main_i2c6_pins_default>;
	clock-frequency = <400000>;

	exp5: gpio@20 {
		compatible = "ti,tca6408";
		reg = <0x20>;
		gpio-controller;
		#gpio-cells = <2>;
	};
	
	des@48 {
		compatible = "maxim,max9296";
		reg       = <0x48>;
		ports {
			#address-cells = <1>;
			#size-cells = <0>;
	
			/* CSI-2 */
			port@4 {
				reg = <4>;
				max9296_0_csi_out: endpoint {
					clock-lanes = <0>;
					data-lanes = <1 2 3 4>;
					remote-endpoint = <&csi2_phy0>;
				};
			};
		};
	};
	
	ser@40 {
		compatible = "maxim,max9295";
		reg = <0x40>;
	
	};

};

加载驱动

lsmod max9295.ko
lsmod max9296.ko
$ ls /dev  //查看一个CSI接口,video节点是否正常创建16

成像显示

gst-launch-1.0 v4l2src device="/dev/video2" ! video/x-raw ,width=1920, height=1080, framerate=30/1 ! waylandsink
sleep 1
gst-launch-1.0 v4l2src device="/dev/video2" ! video/x-raw, width=1920, height=1080, format=UYVY ! autovideosink


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TDA4VM-LINUX-CSI-9296-9295-camera架构驱动分析和详细使用 的相关文章

  • Docker:如何创建堆栈、多个映像或一个基础映像?

    I am new using Docker and I got the doubt of using one image base for my stack or I have to define each image depending
  • 如何在bash中使用kill SIGUSR2?

    我在linux中使用iptraf来监控网络流量 shell命令是 让iptraf在后台运行 iptraf s eth0 f B L traffic dat 如果我想得到结果 我必须先停止 iptraf 所以我使用 shell 命令 kill
  • 使用 tac 和 sed 反转文件

    我有一个用例 我需要搜索并替换文件中最后一次出现的字符串并将更改写回文件 下面的案例是该用例的简化版本 我正在尝试反转该文件 进行一些更改 再次将其反转并写入该文件 我为此尝试了以下代码片段 tac test sed s a b sed i
  • 如何在 Ubuntu x64 中使用 ptrace 插入 int3?

    我正在努力追随本指南 http eli thegreenplace net 2011 01 27 how debuggers work part 2 breakpoints 通过设置断点达到相同的结果 唯一的区别是我在 x64 系统上 所以
  • Linux C++ 错误:未定义对“dlopen”的引用

    我在 Linux 上使用 C Eclipse 工作 并且想要使用一个库 Eclipse 向我显示一个错误 undefined reference to dlopen 你知道解决办法吗 这是我的代码 include
  • 找出Linux上一个进程使用了​​多少内存页

    我需要找出进程分配了多少内存页 每个页面是 4096 进程内存使用情况我在查找正确值时遇到一些问题 当我查看 gome system monitor 时 内存映射下有几个值可供选择 Thanks 这样做的目的是将内存使用量除以页数并验证页大
  • Pthreads - 高内存使用率

    我正在用 C 编写一些东西 在 256Mb 系统上的 Linux 中创建大量 Pthread 我通常有 200Mb 的免费空间 当我使用少量线程运行该程序时 它可以工作 但是一旦我让它创建大约 100 个线程 它就会出现错误 因为系统内存不
  • 应用程序中两个不同版本的库

    考虑一个场景 其中有两个不同版本的共享库 考虑 A 1 so 链接到 B so A 2 so 链接到 C so 现在 B so 和 C so 都链接到 d exe 当 B so 想要调用 A 1 so 中的函数时 它最终会调用 A 2 so
  • 如何将一个文本文件拆分为多个 *.txt 文件?

    我有一个文本文件file txt 12 MB 包含 something1 something2 something3 something4 有没有办法分开file txt分成 12 个 txt 文件 比方说file2 txt file3 t
  • 使用 shell 脚本发送 HTML 邮件

    如何使用 shell 脚本发送 HTML 电子邮件 首先 您需要撰写消息 最低限度由这两个标头组成 MIME Version 1 0 Content Type text html 以及适当的消息正文 p Hello world p 获得后
  • 如何在C(Linux utf8终端)中打印“盒子抽屉”Unicode字符?

    我正在尝试显示 方框图范围 2500 257F 中的 Unicode 字符 它应该是标准 utf8 Unicode 标准 版本 6 2 我根本做不到 我首先尝试使用旧的 ASCII 字符 但 Linux 终端以 utf8 显示 并且没有显示
  • bash while 循环的布尔表达式中的 -lt 意味着什么?

    我猜测它代表小于基于输出 但是我在哪里可以找到有关此语法的文档 bin bash COUNTER 0 while COUNTER lt 10 do echo The counter is COUNTER let COUNTER COUNTE
  • BASH:输入期间按 Ctrl+C 会中断当前终端

    我的 Bash 版本是 GNU bash version 4 3 11 1 release x86 64 pc linux gnu 我有一段这样的代码 while true do echo n Set password read s pas
  • Crontab 每 5 分钟一次 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我如何告诉 crontab 每 5 分钟运行一次 但从每小时的第二分钟开始 换句话说 我想在以下时间执行我的脚本minute 5 2 例如 我的脚本应
  • 如何并行执行4个shell脚本,我不能使用GNU并行?

    我有4个shell脚本dog sh bird sh cow sh和fox sh 每个文件使用 xargs 并行执行 4 个 wget 来派生一个单独的进程 现在我希望这些脚本本身能够并行执行 由于某些我不知道的可移植性原因 我无法使用 GN
  • /sys/device/ 和 dmidecode 报告的不同 CPU 缓存大小

    我正在尝试获取系统中不同缓存级别的大小 我尝试了两种技术 a 使用 sys device 中的信息 这是输出 cat sys devices system cpu cpu0 cache index1 size 32K cat sys dev
  • 如何从 C++ 程序中重新启动 Linux?

    我有一个 Qt 4 GUI 我需要在下拉菜单中提供一个选项 允许用户选择重新启动计算机 我意识到这对于以其他方式重新启动计算机的能力来说似乎是多余的 但选择需要保留在那里 我尝试使用 system 来调用以下内容 suid root she
  • 为 Linux 编译 Objective-C 应用程序(API 覆盖范围)

    我可能在这里问一些奇怪的问题 但我不确定从哪里开始 问题是我正在考虑使用 Obj C 和 Foundation 类在 Mac 上编写一个命令行工具 但存在一个非常大的风险 那就是我希望能够为不同的 Linux 发行版编译它 以便将来作为服务
  • Linux 使用 boost asio 拒绝套接字绑定权限

    我在绑定套接字时遇到问题 并且以用户身份运行程序时权限被拒绝 这行代码会产生错误 acceptor new boost asio ip tcp acceptor io boost asio ip tcp endpoint boost asi
  • 为什么 fork 炸弹没有使 android 崩溃?

    这是最简单的叉子炸弹 我在许多 Linux 发行版上执行了它 但它们都崩溃了 但是当我在 android 终端中执行此操作时 即使授予后也没有效果超级用户权限 有什么解释为什么它没有使 Android 系统崩溃吗 一句话 ulimit Li

随机推荐

  • css3实现圆环加载进度条动画

    最近有人问我关于css3圆环的问题 要实现一个圆环 并且有加载特效 于是我看了看一般关于圆环实现的原理 以及自己手写了一个加载动画 可能体验还不是特别好 但是能用 话不多说 一下是代码 html结构 div class circle div
  • 考研资源免费分享

    1 408王道 链接 https pan baidu com s 1ac5HxvBzGtlet0CQWmtF2g 密码 eifm 2 英语全程班讲义及听力 链接 https pan baidu com s 1R 8fG5PUoRvia X5
  • 【C语言】数组排序方法总结

    一 冒泡排序 相邻元素两两比较 按照要求交换位置 n个元素一共要比较n 1趟 每趟要两两比较未排序元素个数 1次 include
  • Android 系统状态栏下拉界面的定制化开发

    Android 系统状态栏下拉界面的定制化开发 在 Android 开发中 我们经常需要对系统界面进行定制化 以满足特定的用户需求 其中 对 Android 系统状态栏下拉界面 SystemUI 进行定制化开发是一项常见的需求 本文将介绍如
  • 基本flex弹性盒布局

    flex弹性盒布局是css中最基础的一种布局方法 它可以帮助前端程序员更方便更灵活的对页面进行布局排版 以下就为大家整理一些常见的flex布局的代码和作用 希望可以帮助到有需要的人 弹性盒flex display flex 开启弹性盒 未开
  • 受益终生的十大经典管理学定律

    1 彼得原理 每个组织都是由各种不同的职位 等级或阶层的排列所组成 每个人都隶属于其中的某个等级 彼得原理是美国学者劳斯 彼得在对组织中人员晋升的相关现象研究后 得出一个结论 在各种组织中 雇员总是趋向于晋升到其不称职的地位 彼得原理有时也
  • 汉明码详细讲解

    汉明码 是R Hamming与1940年于贝尔实验室提出的 1 奇偶校验码 奇偶校验码 假设传输信息位为K n 1位 表示为a1 an 1 加上一位奇偶校验位 冗余位 a0 构成一个n位的码字a0 an 1 在接收端校验时 可按照关系式 s
  • 【VTK】装配体Assembly的使用

    VTK 装配体Assembly的使用 昨天晚上实现了一个可拖动的坐标轴MovableAxesWidget 今天给他加个使用场景 准备做一个简单的机械臂运动学仿真程序 模型用的HIWIN的机械臂 官网可以下载到模型 hiwin 毕业第一份工作
  • 作为一个程序员,最重要的能力是什么?很多人工作多年后才知道

    我认为程序员只需分三类 天才的程序员 理想的程序员 平庸的程序员 天才在生活中毕竟是少数 今天我们就来聊聊理想的程序员和平庸的程序员有什么区别 理想的程序员与平庸的程序员只有一墙之隔 两者的差距只有6个一点点 而人与人的差距 正是在这日积月
  • 获取下拉框选中的索引值

    selectedIndex 属性可设置或返回下拉列表中被选选项的索引号 var myselect document getElementById id var index myselect selectedIndex if index 1
  • Mission Impossible——《图灵的秘密》读后感

    图灵的秘密 是关于图灵1936年那篇开创性论文的解读 内容很多很难 需要的背景知识包括数理逻辑 lambda演算 以及一些基本的数论 读完的笔记也许都会比原书多 这里想简洁或者宏观性地谈谈几个主角之间的 故事 实际上说争论更准确 初 我目前
  • 机器学习算法(一):逻辑回归模型(Logistic Regression, LR)

    目录 1 LR 1 1 直观表述 1 2 决策边界 Decision Boundary 2 权值求解 2 1 代价函数 似然函数 2 1 1 为什么损失函数不用最小二乘 即逻辑斯蒂回归损失函数为什么使用交叉熵而不是MSE 2 1 2 代价函
  • Linux中安装Redis教程

    1 在CentOS7中新建一个文件夹 然后在这个文件夹中下载 Redis 执行下面的命令 你也可以选择其他的包 如 redis 5 0 10 tar gz 我用这个包安装成功了 wget http download redis io rel
  • Set接口

    Set接口简介 Set接口和List接口一样 同样继承自Collection接口 它与Collection接口中的方法基本一致 并没有对Collection接口进行功能上的扩充 只是比Collection接口更加严格了 与List接口不同的
  • ICMP协议

    参考链接 https www cnblogs com embedded linux p 7068130 html 1 一个新搭建好的网络 往往需要先进行一个简单的测试 来验证网络是否畅通 但是IP协议并不提供可靠传输 如果丢包了 IP协议并
  • nginx基础配置(简单上手)

    全局块 配置影响nginx全局的指令 一般运行nginx服务器的用户组 ngnix进程pid存放路径 日志存放路径 配置文件引入 允许生成woker process数等 events块 配置影响nginx服务器或与用户的网络连接 有每个进程
  • element-ui组件库中Calendar日历组件使用心得(可能用到的常用方法和如何添加监听)

    最近接触到一个需求 做一个值班排班表 拿到低保真之后一直在考虑是如何实现这个排班表 考虑过自己写 也考虑过 fullcalendar vue插件 经过一些评估之后最终选择了项目本身使用的element ui组件库中Calendar日历组件
  • Kafka监控工具,LinkedIn详解

    Kafka监控工具包括以下几种 Kafka Manager 这是一个开源的Kafka集群管理工具 可以监控Kafka集群的健康和性能 并提供可视化的用户界面 Kafka Monitor 这是LinkedIn开发的一个监控工具 可以监控Kaf
  • PPYOLOE

    PP YOLOE是基于PP YOLOv2的单阶段Anchor free模型 超越了多种流行的yolo模型 PP YOLOE有一系列的模型 即s m l x 可以通过width multiplier和depth multiplier配置 PP
  • TDA4VM-LINUX-CSI-9296-9295-camera架构驱动分析和详细使用

    前言 TI在LINUX SDK 8 01版本后才开始支持Linux V4L2接入CSI2 所以在使用前尽量先用RTOS SDK接入CSI2的接口camera 正常工作后开始进行Linux V4L2的开发 LINUX SDK的安装使用 参考另