当前位置:   article > 正文

NVIDIA JETSON 平台的 MIPI-CSI 相机驱动程序开发_nvcsi

nvcsi

由 Tegra 处理器驱动的 Nvidia Jetson 平台已经在边缘分析市场中占据了一席之地,尤其是在视频分析、机器视觉等领域。 凭借 MIPI-CSI、USB、千兆以太网等广泛的接口,可以通过许多不同的接口获取视频数据。其中,CSI 接口仍然是机器视觉应用的首选接口。

在这篇博客中,我们将详细讨论 Jetson Tegra 平台中的相机接口和数据流以及 MIPI CSI 驱动程序的典型配置和设置。具体来说,我们将考虑 Jetson Nano 和 Onsemi OV5693 相机。

Jetson 相机子系统

尽管 Tegra TX1、TX2、Xavier 和 Nano 平台之间存在显着的架构差异,但相机硬件子系统或多或少保持不变。下面捕获了相同的高级设计。

Nvidia Tegra 相机子系统

正如所见,主要组件及其功能是:

  • CSI Unit: MIPI-CSI兼容输入子系统,负责从摄像头获取数据,组织像素格式并将其发送到VI单元。有 6 个像素解析器 (PP) 单元,每个单元都可以接受来自单个 2 车道相机的输入。除了这个 6 摄像头模型之外,还可以重新配置输入,以便将 3 个单声道或立体声 4 通道摄像头连接到 PPA、CSI1_PPA 和 CSI2_PPA 对。
  • VI:视频输入单元通过 24 位总线接收来自 CSI 单元的数据,数据的位置由输入格式决定。然后可以将该数据路由到以下任何一个或两个相关方。VI 还具有一个带有 2 个通道的 Host 1x 接口——一个用于控制对相机的 I2C 访问,另一个用于 VI 寄存器编程。
  • 内存:写入系统内存以供应用程序进一步使用。
  • 图像信号处理器 ISP A:用于预处理输入数据并将其转换/打包为不同的格式。ISP A 还可以从内存中获取数据。
  • 图像信号处理器 ISP B:用于预处理输入数据并将其转换/打包为不同的格式。ISP A 还可以从内存中获取数据。

VI Unit 提供了一种称为 VI 同步点 (syncpts) 的硬件-软件同步机制,用于等待满足特定条件并增加计数器或希望计数器达到特定值。多个预定义索引可用,每个索引对应于一次功能,例如帧开始、行结束、ISP 处理的完成。例如,软件可以选择等待,直到通过下一个与索引对应的计数器值指示的 VI 接收到一个帧。

借助这些强大的组件,Tegra 相机子系统提供了无缝处理来自不同格式的多个来源的数据的选项。

Linux 4 Tegra 相机驱动程序

了解了硬件子系统后,我们现在将研究 Tegra 相机接口的软件架构。Nvidia 通过其 Linux4Tegra (L4T) 软件支持 Linux 操作系统。相机驱动程序通过 CSI 总线以传感器的本机格式配置和读取来自相机传感器的数据,并可选择将它们转换为不同的格式。

Nvidia 提供两种类型的相机访问路径,可以根据相机和应用程序用例进行选择:

  • 直接 V4L2 接口

主要用于从相机捕获 RAW 数据,这是一条不进行任何处理且数据直接由用户应用程序使用的最小路径。

  • 相机核心库接口

在此模型中,相机数据通过少数 Nvidia 库(例如 Camera Core、libArgus)使用。在这种情况下,可以有效地利用内核中可用的 GPU 对输入数据进行各种数据处理。

在任何一种情况下,应用程序都可以是 Gstreamer 插件或自定义插件。

Jetson OV5693 相机

为了深入了解,让我们考虑默认随 Tegra TX1 和 TX2 载板一起提供的 5MP(2592 x 1944,拜耳传感器)Omnivision CSI 摄像头模块 OV5693。高级软件架构如下:

L4T 相机驱动架构

OV5693 摄像头通过 TCA9548 I2C 扩展芯片连接到 I2C 总线 0x06(默认\I2C 地址为 0x36)。这可以通过在 SID 引脚上添加一个上拉电阻来更改为 0x40。

OV5693 驱动程序使用 I2C 总线驱动程序触发,并将自身注册到 Tegra V4L2 相机框架。这反过来又会暴露 /dev/videoX 设备,应用程序可以使用该设备来消费数据。

要启动 OV5693 驱动程序,必须处理以下内容,并在下一节中进一步说明:

  • 设备树中的相应节点
  • V4L2 兼容传感器驱动程序

在下一节中,我们将看到如何为 OV5693 摄像头设置设备树。

Tegra 相机的设备树更改

该  tegra194相机-e3333-a00.dtsi文件位于/硬件/ NVIDIA /平台/ t19x /普通/内核DTS / t19x常见模块/文件夹。

Tegra相机平台:

tegra-camera-platform 由一个或多个模块组成,这些模块定义了连接到 Tegra SoC 的相机/传感器的基本信息。虽然顶部的公共部分包含有关所有连接的综合信息,但每个模块子部分都单独定义了它们。在这种情况下,单个 OV5693 摄像头通过两个 MIPI 通道连接。

  1. <span style="color:#333333"><span style="background-color:#f5f5f5"><code>tegra-camera-platform {
  2. compatible = "nvidia, tegra-camera-platform";
  3. num_csi_lanes = <2>; //Number of lanes
  4. max_lane_speed = <1500000>; //Maximum lane speed
  5. min_bits_per_pixel = <12>; //bits per pixel
  6. vi_peak_byte_per_pixel = <2>; //byte per pixel
  7. vi_bw_margin_pct = <25>; //Don't care
  8. max_pixel_rate = <160000>; //Don't care
  9. isp_peak_byte_per_pixel = <5>;//Don't care
  10. isp_bw_margin_pct = <25>; //Don't care
  11. modules {
  12. module0 { //OV5693 basic details
  13. badge = "ov5693_right_iicov5693";
  14. position = "right";
  15. orientation = "1";
  16. drivernode0 {
  17. pcl_id = "v4l2_sensor";
  18. devname = "ov5693 06-0036";
  19. proc-device-tree = "/proc/device-tree/i2c@31c0000/tca9548@77/i2c@6/ov5693_a@36"; //Device tree node path
  20. };
  21. };
  22. };
  23. }; </code></span></span>

设备树节点

在设备树节点中,必须添加所有相机属性(输出分辨率、FPS、Mipi 时钟等)以确保设备正常运行。

  1. <span style="color:#333333"><span style="background-color:#f5f5f5"><code>I2c@31c0000 { //I2C-6 base address
  2. tca9548@77 { //I2C expander IC
  3. i2c@6 {
  4. ov5693_a@36 {
  5. compatible = nvidia,ov5693";
  6. reg = <0x36>; //I2C slave address
  7. devnode = "video0";//device name
  8. /* Physical dimensions of sensor */
  9. physical_w = "3.674"; //physical width of the sensor
  10. physical_h = "2.738"; //physical height of the sensor
  11. /* Enable EEPROM support */
  12. has-eeprom = "1";
  13. /* Define any required hw resources needed by driver */
  14. /* ie. clocks, io pins, power sources */
  15. avdd-reg = "vana"; //Power Regulator
  16. iovdd-reg = "vif"; //Power Regulator
  17. mode0 { // OV5693_MODE_2592X1944
  18. mclk_khz = "24000"; //MIPI driving clock
  19. num_lanes = "2"; //Number of lanes
  20. tegra_sinterface = "serial_a"; //Serial interface
  21. phy_mode = "DPHY"; //physical connection mode
  22. discontinuous_clk = "yes";
  23. dpcm_enable = "false"; //Don't care
  24. cil_settletime = "0"; //Don't care
  25. active_w = "2592"; //active width
  26. active_h = "1944"; //active height
  27. mode_type = "bayer"; //sensor type
  28. pixel_phase = "bggr"; //output format
  29. csi_pixel_bit_depth = "10"; //bit per pixel
  30. readout_orientation = "0"; //Don't care
  31. line_length = "2688"; //Total width
  32. inherent_gain = "1"; //Don't care
  33. mclk_multiplier = "6.67"; //pix_clk_hz/mclk_khz
  34. pix_clk_hz = "160000000"; //Pixel clock HTotal*VTotal*FPS
  35. gain_factor = "10"; //Don't care
  36. min_gain_val = "10";/* 1DB*/ //Don't care
  37. max_gain_val = "160";/* 16DB*/ //Don't care
  38. step_gain_val = "1"; //Don't care
  39. default_gain = "10"; //Don't care
  40. min_hdr_ratio = "1"; //Don't care
  41. max_hdr_ratio = "1"; //Don't care
  42. framerate_factor = "1000000"; //Don't care
  43. min_framerate = "1816577"; //Don't care
  44. max_framerate = "30000000";
  45. step_framerate = "1";
  46. default_framerate = "30000000";
  47. exposure_factor = "1000000"; //Don't care
  48. min_exp_time = "34"; //Don't care
  49. max_exp_time = "550385"; //Don't care
  50. step_exp_time = "1"; //Don't care
  51. default_exp_time = "33334"; //Don't care
  52. embedded_metadata_height = "0";//Don't care
  53. };
  54. };
  55. };
  56. };
  57. };
  58. </code></span></span>

在本例中,像素时钟计算如下:

pix_clk_hz = HTotal*VTotal*FPS

OV5693:- 2592×1944@30fps

2592×1944 的总高度和总宽度为 2688×1984

pix_clk_hz = 2688 x 1984 x 30 = 159989760

pix_clk_hz 是 ~160000000

而 mclk 乘数是

mclk_multiplier = pix_clk_hz / mclk_khz
mclk_multiplier = 160000000 / 24000000 = 6.66

DTS绑定

如前所述,相机数据流如下:

传感器输出CSI输入CSI输出VI输入
ov5693_ov5693_out0ov5693_csi_in0ov5693_csi_out0ov5693_vi_in0

硬件 – 设备树节点数据流映射

内部端口之间的绑定是通过使用以下设置完成的。

  1. <span style="color:#333333"><span style="background-color:#f5f5f5"><code>ports {
  2. #address-cells = <1>;
  3. #size-cells = <0>;
  4. port@0 {
  5. reg = <0>;
  6. ov5693_ov5693_out0: endpoint {
  7. port-index = <0>;
  8. bus-width = <2>;
  9. remote-endpoint = <&ov5693_csi_in0>;
  10. };
  11. };
  12. };
  13. nvcsi@15a00000 {
  14. num-channels = <1>;
  15. #address-cells = <1>;
  16. #size-cells = <0>;
  17. status = "okay";
  18. channel@0 {
  19. reg = <0>;
  20. ports {
  21. #address-cells = <1>;
  22. #size-cells = <0>;
  23. port@0 {
  24. reg = <0>;
  25. ov5693_csi_in0: endpoint@0 {
  26. port-index = <0>;
  27. bus-width = <2>;
  28. remote-endpoint = <&ov5693_ov5693_out0>;
  29. };
  30. };
  31. port@1 {
  32. reg = <1>;
  33. ov5693_csi_out0: endpoint@1 {
  34. remote-endpoint = <&ov5693_vi_in0>;
  35. };
  36. };
  37. };
  38. };
  39. };
  40. host1x {
  41. vi@15c10000 {
  42. num-channels = <1>;
  43. ports {
  44. #address-cells = <1>;
  45. #size-cells = <0>;
  46. port@0 {
  47. reg = <0>;
  48. ov5693_vi_in0: endpoint {
  49. port-index = <0>;
  50. bus-width = <2>;
  51. remote-endpoint = <&ov5693_csi_out0>;
  52. };
  53. };
  54. };
  55. };
  56. </code></span></span>

驱动程序通过 Host1x DMA 引擎模块从 VI 输出中获取数据。

覆盖

L4T 采用 DTB 覆盖机制来启用/禁用驱动程序。ov5693 驱动程序可以通过将其状态字段设置为“okay”在 DTS 中启用。

  1. <span style="color:#333333"><span style="background-color:#f5f5f5"><code>fragment-ov5693@0 {
  2. ids = "2180-*";
  3. override@0 {
  4. target = <&ov5693_cam0>;
  5. _overlay_ {
  6. status = "okay";
  7. };
  8. };
  9. };
  10. </code></span></span>

在启动过程中,如果检测到正确的相机模块,则添加到设备树节点的覆盖层以及进一步的驱动程序和设备注册由相机驱动程序 (ov5693.c) 完成,如下一篇博客所述。

关于 Embien: Embien 是领先的产品工程服务,在 Nvidia Tegra 和 Jetson 平台上提供专业知识。我们一直在通过不同接口将各种类型的相机与 Nvidia 平台连接起来,并通过 libargus 框架以及定制的 Gstreamer 插件和应用程序启用它们。我们的客户包括国防、航空电子、工业自动化、医疗、汽车和半导体领域的财富 500 强公司。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/475388
推荐阅读
  

闽ICP备14008679号