Linux 在哪里调用摄像头驱动进行图片传输
Where does Linux call a camera driver for image delivery
OV5640 相机的 Linux driver 提供了有限的功能。
static struct i2c_driver ov5640_i2c_driver = {
.driver = {
.name = "ov5640",
.of_match_table = ov5640_dt_ids,
},
.id_table = ov5640_id,
.probe = ov5640_probe,
.remove = ov5640_remove,
};
这些功能是 name
、probe
和 remove
。
我对驱动程序不是很熟悉,但我找不到驱动程序中渲染像素的任何部分,因此我无法将它们存储到数组中。我也找不到任何用于读取像素的虚拟内存地址。
捕获图像数据传输发生在代码的哪一部分?
我正在寻找两个位置:一个在驱动程序中,一个在调用驱动程序的更高级别中。
简答
您可以从以下位置捕获视频帧:
- 弄清楚你的 IPU 驱动程序在哪里并嗅探那里的数据。
- 使用 V4L2 API 编写 user-space 应用程序来捕获帧。
第二个选项是首选并且更容易。
详细解答
这里有 3 个驱动程序:
- 摄像头驱动程序:通过 I2C 实现控制路径(例如启动流)
示例:"ovti,ov5640"
- CSI Receiver driver (CSI-2 host controller driver): 基本上就是一个PHY,将CSI-2数据格式转换成IPU的一些内部数据格式。
示例:"fsl,imx6-mipi-csi2"
- IPU(图像处理单元)驱动程序:实现了很多功能,例如图像 DMA、视频捕获等
示例:"fsl,imx6q-ipu"
- 捕获子系统驱动可以从IPU驱动中分离出来。
示例:"fsl,imx-capture-subsystem"
有时 CSI RX 和 IPU 驱动程序合并为单个 IP-core(如 TI AM57xx 芯片中的视频输入端口)。有时视频捕获可以在单独的驱动程序中实现(尽管它是 IPU 的一部分)。这只是您正在处理的平台架构问题,但主要思想是相同的。
看看这张照片:
因此,如果您正在寻找挂钩数据的位置,它应该在以下位置之一:
- 在您的 IPU 驱动程序中:驱动程序可能正在执行到 RAM 的 DMA 传输,将该 RAM 位置提供给 V4L2。这就是您可以尝试嗅探图像数据的地方。由于您没有引用您的平台,因此您需要自己找到该驱动程序。查看
drivers/media/platform/
和 drivers/staging/media/
的内部,它应该在那里的某个地方。此外,探索您的设备树文件,ov5640
节点应该引用 port
节点中的 CSI/IPU 驱动程序。
- 在你的user-space app: V4L2 用户space 界面允许你捕获视频帧;有关详细信息,请参阅 this example。
您可以尝试通过一些已知的 V4L2 常量搜索内核源代码树来找到您的捕获驱动程序,例如:
$ grep -lIr V4L2_BUF_TYPE_VIDEO_CAPTURE drivers/media/platform/* drivers/staging/media/*
或尝试从您的设备树文件中找到它。例如,在 iMX6 平台上,所有相关节点如下所示:
ov5640: camera@3c {
compatible = "ovti,ov5640";
port {
ov5640_to_mipi_csi2: endpoint { remote-endpoint = <&mipi_csi2_in>; };
};
};
mipi_csi: mipi@21e0000 {
compatible = "fsl,imx6-mipi-csi2";
port@0 {
mipi_csi2_in: endpoint { remote-endpoint = <&ov5640_to_mipi_csi2>; };
};
};
ipu1: ipu@2800000 {
compatible = "fsl,imx6q-ipu";
ipu1_csi0: port@0 { };
};
capture-subsystem {
compatible = "fsl,imx-capture-subsystem";
ports = <&ipu1_csi0>;
};
但我建议您尝试从 user-space 应用程序中捕获视频帧,就像完成了一样 here, as doing so in kernel driver could be difficult task. Also, in user-space app it would be easier to save captured frame to jpg file, like it's done here。
iMX6 资源
有很多 iMX6 的文档 w.r.t。那里的相机:
- 内核 iMX6 V4L2 文档:link
- iMX6 TRM(技术参考手册):all docs, direct link
- iMX Linux 参考手册:link
- 类似 this
的应用说明
- 这样的幻灯片:HW Accelerated Video Streaming with V4L2 and OpenGL on iMX6
OV5640 相机的 Linux driver 提供了有限的功能。
static struct i2c_driver ov5640_i2c_driver = {
.driver = {
.name = "ov5640",
.of_match_table = ov5640_dt_ids,
},
.id_table = ov5640_id,
.probe = ov5640_probe,
.remove = ov5640_remove,
};
这些功能是 name
、probe
和 remove
。
我对驱动程序不是很熟悉,但我找不到驱动程序中渲染像素的任何部分,因此我无法将它们存储到数组中。我也找不到任何用于读取像素的虚拟内存地址。
捕获图像数据传输发生在代码的哪一部分? 我正在寻找两个位置:一个在驱动程序中,一个在调用驱动程序的更高级别中。
简答
您可以从以下位置捕获视频帧:
- 弄清楚你的 IPU 驱动程序在哪里并嗅探那里的数据。
- 使用 V4L2 API 编写 user-space 应用程序来捕获帧。
第二个选项是首选并且更容易。
详细解答
这里有 3 个驱动程序:
- 摄像头驱动程序:通过 I2C 实现控制路径(例如启动流)
示例:"ovti,ov5640"
- CSI Receiver driver (CSI-2 host controller driver): 基本上就是一个PHY,将CSI-2数据格式转换成IPU的一些内部数据格式。
示例:"fsl,imx6-mipi-csi2"
- IPU(图像处理单元)驱动程序:实现了很多功能,例如图像 DMA、视频捕获等
示例:"fsl,imx6q-ipu"
- 捕获子系统驱动可以从IPU驱动中分离出来。
示例:"fsl,imx-capture-subsystem"
- 捕获子系统驱动可以从IPU驱动中分离出来。
有时 CSI RX 和 IPU 驱动程序合并为单个 IP-core(如 TI AM57xx 芯片中的视频输入端口)。有时视频捕获可以在单独的驱动程序中实现(尽管它是 IPU 的一部分)。这只是您正在处理的平台架构问题,但主要思想是相同的。
看看这张照片:
因此,如果您正在寻找挂钩数据的位置,它应该在以下位置之一:
- 在您的 IPU 驱动程序中:驱动程序可能正在执行到 RAM 的 DMA 传输,将该 RAM 位置提供给 V4L2。这就是您可以尝试嗅探图像数据的地方。由于您没有引用您的平台,因此您需要自己找到该驱动程序。查看
drivers/media/platform/
和drivers/staging/media/
的内部,它应该在那里的某个地方。此外,探索您的设备树文件,ov5640
节点应该引用port
节点中的 CSI/IPU 驱动程序。 - 在你的user-space app: V4L2 用户space 界面允许你捕获视频帧;有关详细信息,请参阅 this example。
您可以尝试通过一些已知的 V4L2 常量搜索内核源代码树来找到您的捕获驱动程序,例如:
$ grep -lIr V4L2_BUF_TYPE_VIDEO_CAPTURE drivers/media/platform/* drivers/staging/media/*
或尝试从您的设备树文件中找到它。例如,在 iMX6 平台上,所有相关节点如下所示:
ov5640: camera@3c {
compatible = "ovti,ov5640";
port {
ov5640_to_mipi_csi2: endpoint { remote-endpoint = <&mipi_csi2_in>; };
};
};
mipi_csi: mipi@21e0000 {
compatible = "fsl,imx6-mipi-csi2";
port@0 {
mipi_csi2_in: endpoint { remote-endpoint = <&ov5640_to_mipi_csi2>; };
};
};
ipu1: ipu@2800000 {
compatible = "fsl,imx6q-ipu";
ipu1_csi0: port@0 { };
};
capture-subsystem {
compatible = "fsl,imx-capture-subsystem";
ports = <&ipu1_csi0>;
};
但我建议您尝试从 user-space 应用程序中捕获视频帧,就像完成了一样 here, as doing so in kernel driver could be difficult task. Also, in user-space app it would be easier to save captured frame to jpg file, like it's done here。
iMX6 资源
有很多 iMX6 的文档 w.r.t。那里的相机:
- 内核 iMX6 V4L2 文档:link
- iMX6 TRM(技术参考手册):all docs, direct link
- iMX Linux 参考手册:link
- 类似 this 的应用说明
- 这样的幻灯片:HW Accelerated Video Streaming with V4L2 and OpenGL on iMX6