nvidia jetson相機開發--傳感器驅動編程指南(1)sensor driver programming guide

/本文檔適用於R32.2.1版本/ 實現相機傳感器驅動器使得可以經過傳感器提供的原始格式經過CSI總線獲取相機數據。 根據相機和應用程序的不一樣,有兩種類型的相機編程路徑。node

• Camera Core Library Interface • Direct V4L2 Interface編程

Camera Core User Mode Library Interface架構

相機核心用戶模式庫提供應用程序和內核模式V4L2驅動程序之間的全部控件和數據處理。使用相機核心庫界面的典型用例包括:框架

•使用Tegra ISP功能的應用程序 •必須將RGB格式轉換爲YUV格式併爲拜耳傳感器執行各類後處理任務的應用程序ide

具備應用程序和內核模式V4L2驅動程序的Linux for Tegra架構框架是:模塊化

框架

Direct V4L2 Interface 在支持直接V4L2接口的應用程序中,使用此接口與NVIDIA V4L2驅動程序進行通訊,而無需使用相機核心用戶模式庫。 使用此路徑從傳感器捕獲RAW數據或驗證傳感器驅動程序。 應用程序使用內核模式V4L2驅動程序以下: 函數

image.png
提供一個拜耳像素格式傳感器須要客戶開發: • Device Tree in the kernel • V4L2 sensor driver 有兩種不一樣版本的驅動程序可用於傳感器驅動程序開發。 版本是: •版本1.0:過去版本中使用的設計。 某些版本1.0功能在之後的版本中不可用。 •2.0版:使用新的Tegra V4L2 Camera Framework來模塊化代碼,簡化傳感器驅動程序架構並將冗餘代碼封裝在一個公共位置的新版本。 NVIDIA建議將此版本用於任何新的驅動程序開發。

提供的示例使用Sony IMX185傳感器。 索尼IMX185傳感器的源代碼在如下文件中: • Version 1.0 driver: imx185_v1.c • Version 2.0 driver: imx185.c佈局

相機模塊和設備樹Camera Modules and Device Tree

安裝在目標平臺上的相機模塊能夠包括一個或多個設備。 典型的後置攝像頭模塊包括互補金屬氧化物半導體(CMOS)傳感器。 典型的前置攝像頭模塊能夠包括單個CMOS傳感器。post

將一個或多個攝像頭模塊添加到設備樹spa

  1. 在內核源代碼樹中找到或建立tegra-camera-platform設備節點:

    /hardware/nvidia/platform/t19x/common/kernel-dts/t19x-common-modules/tegra194-camera-imx185-a00.dtsi

  2. 在Tegra-camera-platform設備節點中,使用一個或多個模塊建立模塊表(modules)。 每一個module必須包含其基本信息以及該模塊內部設備的定義。

注意: 相機相關設備節點中的全部值字段必須使用字符串數據類型,但引用其餘設備節點的文件除外。

A typical device-tree node for a camera module is:

tegra-camera-platform {
    compatible = "nvidia, tegra-camera-platform";
    modules {
        module0 {
            badge = "imx185_bottom_liimx185";
	       position = "bottom";
            orientation = "0";
            drivernode0 {
                pcl_id = "v4l2_sensor";
                devname = "imx185 30-001a";
                proc-device-tree = "/proc/device-tree/i2c@3180000/tca9546@70/i2c@0/imx185_a@1a";
            };
        };
    };
};
複製代碼

模塊屬性

The information for moduleX: module (or moduleX: modules) is:

Property Value
badge 標識此模塊的惟一名稱。命名badge_info屬性的三個部分的準則:•第一部分是模塊的攝像機板ID(camera_board_id)。 •第二部分包含模塊的位置,例如後部或前部。 •第三部分包含部件號的最後六個字符,您能夠在供應商的模塊數據表中找到該字符。 若是部件號不可用,請使用惟一標識符。 若是您的系統有多個相同的模塊,請爲每一個模塊建立一個惟一的名稱。 例如,若是您有後置攝像頭,則能夠調用後置攝像頭模塊imx185_rear_liimx185。
position The camera-facing information. The positions supported depends on the number of cameras in the system: • Two-camera system: rear and front. • Three-camera system: bottom, top, and center. • Six-camera system: bottomleft, bottomright, centerleft, centerright, topleft, and topright.
orientation 基於索引的傳感器方向。 當設備具備帶兩個攝像頭的顯示器時,一般使用如下索引:•後面:0 •正面:1 對於其餘相機佈局,每一個相機都須要一個惟一的索引。

我的成像設備Individual Imaging Device

一個成像設備能夠是一個相機模塊內的組件,他能夠是: •傳感器 sensor
•聚焦器 focuser •閃光燈 flash 必須將所需信息添加到設備樹節點以支持設備操做。 每一個設備樹節點對應一個設備,分配一個設備樹節點包含如下內容: • The name of the device 設備名稱 • The slave address for the device 設備從機地址(設備從機地址可從設備數據手冊中獲取) • A compatible string that identifies the node 標識該節點的匹配字符串

注意: 除引用其餘設備節點的設備外,相機相關設備節點中的全部值字段都必須使用字符串數據類型。 An example device-tree node for the IMX185 V4L2 sensor driver is:

imx185_a@1a {
compatible = "nvidia,imx185";
reg = <0x1a>;
physical_w = "15.0";
physical_h = "12.5";
sensor_model ="imx185";
post_crop_frame_drop = "0";
use_decibel_gain = "true";
delayed_gain = "true";
use_sensor_mode_id = "true";

mode0 {
    mclk_khz = "37125";
    num_lanes = "4";
    tegra_sinterface = "serial_a";
    phy_mode = "DPHY";
    discontinuous_clk = "no";
    dpcm_enable = "false";
    cil_settletime = "0";
    dynamic_pixel_bit_depth = "12";
    csi_pixel_bit_depth = "12";
    mode_type = "bayer";
    pixel_phase = "rggb";
    active_w = "1920";
    active_h = "1080";
    readout_orientation = "0";
    line_length = "2200";
    inherent_gain = "1";
    mclk_multiplier = "2";
    pix_clk_hz = "74250000";

    gain_factor = "10";
    min_gain_val = "0";         /* 0dB */
    max_gain_val = "480";       /* 48dB */
    step_gain_val = "3";        /* 0.3 */
    default_gain = "0";
    min_hdr_ratio = "1";
    max_hdr_ratio = "1";
    framerate_factor = "1000000";
    min_framerate = "1500000";
    max_framerate = "30000000"; /* 30 */
    min_exp_time = "30";        /* us */
    max_exp_time = "660000";    /* us */
    step_exp_time = "1";
    default_exp_time = "33334"; /* us */
    embedded_metadata_height = "1";
};
. . .
ports {
    #address-cells = <1>;
    #size-cells = <0>;
    port@0 {
        reg = <0>;
        liimx185_imx185_out0: endpoint {
        port-index = <0>;
        bus-width = <4>;
        remote-endpoint = <&liimx185_csi_in0>;
    };
};
複製代碼

}; 設備屬性 對於V4L2傳感器設備的設備樹節點,請爲設備定義所需的硬件資源,以下所示:

property value
compatible 指定設備標識符。 Linux內核使用此關鍵字將設備驅動程序綁定到特定設備。
reg 指定i2c從機地址
mclk 指定設備的輸入時鐘名稱。默認值爲extperiph1。extperiph1的最大頻率爲24 MHz。 若是MCLK> 24 MHz,則使用外部時鐘源。
xxx-gpio 指定設備的通用輸入/輸出(GPIO)引腳,其中XXX是攝像機的GPIO引腳。相機的默認GPIO引腳包括: •H3 - Camera0重置 •H6 - Camera0掉電 •T6 - Camera1重置 •T5 - Camera1斷電
xxx-supply 指定設備的調節器,其中XXX是在設備樹中的其餘位置定義的實際調節器名稱。 -supply後綴是必需的。 如下是定義的監管機構: •vana-supply = <&en_vdd_cam_hv_2v8>; //模擬2.8v •vdig-supply = <&en-vdd-cam_1v2>; //數字1.2v •vif-supply = <&en-vdd-cam>; //界面1.8v •vvcm-supply = <&en_vdd_vcm_2v8>; //模擬2.8v for vcm
xxx-reg 指定調節器的名稱,其中XXX是傳感器驅動器的調節器名稱。 該字段的值是帶有後綴-reg的調節器名稱。 如下是定義的監管機構: •avdd-reg =「vana」; •dvdd-reg =「vdig」 •iovdd-reg =「vif」 •vcmvdd-reg =「vvcm」
physical_w 指定傳感器的物理寬度(以毫米爲單位)
physical_h 指定傳感器的物理高度(以毫米爲單位)
sensor_model* 指定該模塊中的傳感器
set_mode_delay_ms* 指定捕獲開始後第一幀的最長等待時間(以毫秒爲單位)
post_crop_frame_drop* 指定應用傳感器裁剪設置後要刪除的幀數。有關更多信息,請參閱IMX185傳感器驅動程序文檔。
use_decibel_gain* 對於使用分貝表示模擬增益的傳感器,請使用此選項。 設置爲true時,驅動程序接收的模擬增益值以分貝(dB)表示,基於用戶模式庫中的如下轉換:dB = 20 * log(模擬增益)有關更多信息,請參閱IMX185傳感器驅動程序文檔。
delayed_gain* 用於延遲增益設置。 設置爲true時,用戶模式驅動程序會將更新後的增益值延遲一幀發送給驅動程序。 默認爲「false」。有關更多信息,請參閱IMX185傳感器驅動程序文檔。
user_sensor_mode_id* 設置爲true時,用戶模式驅動程序使用TEGRA_CAMERA_CID_SENSOR_MODE_ID控件選擇特定傳感器模式並繞過默認模式選擇邏輯。 默認爲「false」。有關更多信息,請參閱IMX185傳感器驅動程序文檔。
* 可選的 能夠在不一樣的DTSI文件中指定此表中的屬性。 例如,能夠在平臺DTSI文件中指定時鐘,GPIO和調節器屬性,而且能夠在傳感器DTSI文件中指定其他屬性。

property-value pairs 適用於V4L2實現的傳感器模式的屬性 - 值對是:

注意: 下表中的全部屬性均按模式設置,必須精確設置

property value
modeX 指定傳感器模式信息,即基於X:0的索引。
ports 提供媒體控制器圖形綁定信息。有關更多信息,請參閱端口綁定
mclk_khz 指定標準mipi驅動時鐘,以khz爲單位
num_lanes 指定傳感器編程輸出的通道數。
tegra_sinterface 指定通道所鏈接的基本Tegra串行接口。
dsicontinuous_clk 指定傳感器編程爲在MIPI通道上使用不連續時鐘的指示。
cil_settletime 指定MIPI通道的THS-Settle時間的值。 0值嘗試根據mclk_multiplier參數自動校準。若是您不使用自動校準,則可使用如下公式計算值: 85ns + 6 * UI <(cli_settletime + 5)<145ns + 10 * UI。 其中UI是單位間隔,而且等於時鐘通道上HS狀態的持續時間。有關詳細信息,請參閱MIPI聯盟D-PHY規範。
dpcm_enable 指定是否爲此模式啓用dpcm壓縮。設置爲true或false。
active_h 指定像素有效區域的高度。
active_w 指定像素有效區域的寬度
pixel_t(棄用) 不推薦使用此屬性並將其替換爲如下屬性:•mode_type •csi_pixel_bit_depth •pixel_phase
mode_type 指定傳感器模式類型。 可能的值包括: •yuv •bayer •bayer_wdr_pwl - 寬動態範圍模式,使用分段線性函數壓縮多重曝光融合像素數據。 還在傳感器上執行多重曝光融合。 有關更多信息,請參閱IMX185傳感器驅動程序文檔。
csi_pixel_bit_depth 指定CSI總線上最終傳感器輸出的位深度。「mode_type = bayer_wdr_pwl」表示在應用基於分段線性函數的壓縮以後的位深度輸出。有關更多信息,請參閱IMX185傳感器驅動程序文檔。
pixel_phase* Specifies the sensor pixel phase. Possible values include: • uyvy • vyuy • yuyv • yvyu • rggb • bggr • grbg • gbrg For more information, consult to the IMX185 Sensor Driver documentation.
line_length 指定用於校準相機堆棧中的要素的傳感器模式的像素線寬水平時序大小。 該值必須等於或大於active_w。
mclk_multiplier (deprecated) 指定MCLK的乘數,以計時硬件的捕獲序列。 使用如下等式計算此值: mclk_multiplier =所需的ISP時鐘頻率/ mclk。 此值必須大於pixel_clk_hz / mclk以防止ISP欠載。
pix_clk_hz 指定用於計算曝光,幀速率等的傳感器像素時鐘。該值基於輸入時鐘(mclk)和傳感器模式表中的PLL設置計算。 有關如何計算此值,請參閱傳感器數據表。\有關更多信息,請參閱傳感器像素時鐘。
inherent_gain 指定從模式固有得到的增益,即像素合併。若是您不知道此值,請設置爲1。

分段線性壓縮函數示例 分段線性壓縮功能的示例以下:

image.png
• Input signal has 16-bit depth • Output signal has 12-bit depth • csi_pixel_bit_depth = 「12」 • dynamic_pixel_bit_depth = 「16」 The control point properties are:

Property Value
num_control_point 4
control_point_x_0 0
control_point_x_1 2048
control_point_x_2 16384
control_point_x_3 65536
control_point_y_0 0
control_point_y_1 2048
control_point_y_2 2944
control_point_y_3 3712

示例數字重疊WDR曝光幀(3840x2160) 該圖示出了雙曝光DOL(數字重疊)多幀的示例。

image.png
適用於4K數字重疊WDR幀的此圖的值爲:
image.png

•LI(行信息)標題像素有助於區分垂直空白週期(VBP)行和不一樣的曝光行。所以,上圖中有三種LI:VBP,長曝光和短曝光。 VP(行)由VI(視頻輸入)模塊基於LI濾除。 •num_of_exposure表示每次數字重疊捕獲中的曝光次數。對於4K數字重疊WDR的上述示例,這是2(兩次曝光)。 •num_of_ignored_lines表示位於每一個曝光幀頂部且未包含在輸出幀中的行數。這包括OB行和Ignored Area Effective Pixel行,二者都使用與它們所在的曝光幀相同的LI頭。所以,這些行由VI模塊讀取並被裁剪掉。對於上面的示例,此值爲14行= 8 OB行+ 6個忽略區域有效像素行。 •num_of_lines_offset_0表示在雙曝光DOL多幀中單次曝光和幀中出現的VBP行數。相同數量的VBP行出如今長曝光幀的末尾和短曝光幀的開始處。對於上面的示例,該值爲50(長曝光幀結束時爲50行,短曝光幀開始時爲50行)。 •num_of_ignored_pixels表示每行開頭的LI像素,用於區分不一樣的曝光行和VBP行。對於上面的示例,此值爲4(四個像素)。 •num_of_left_margin_pixels表示每行上圖像日期以前左側的邊距像素。這些是裁剪對齊所必需的。對於上面的示例,此值爲12(12像素)。 •num_of_right_margin_pixels表示每行圖像日期後右側的邊距像素。這些是裁剪對齊所必需的。對於上面的示例,此值爲0(零像素)。 •active_w表示像素活動區域的總寬度。在這種狀況下,它是3840 + 4(LI)+12(左邊距)+ 0(右邊距)= 3856。 •active_h表示像素活動區域的總高度。在這種狀況下,它是(2160 + 8(OB)+ 6(忽略區域有效像素+50(VBP))* 2 = 4448。 Port Binding端口綁定

vi {
num-channels = <1>;
ports {
    #address-cells = <1>;
    #size-cells = <0>;
    port@0 {
        reg = <0>;
        liimx185_vi_in0: endpoint {
            port-index = <2>;
            bus-width = <4>;
            remote-endpoint = <&liimx185_csi_out0>;
          };
      };
  };
};

nvcsi {
num-channels = <1>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
    reg = <0>;
    ports {
        #address-cells = <1>;
        #size-cells = <0>;
        port@0 {
            reg = <0>;
            liimx185_csi_in0: endpoint@0 {
                port-index = <0>;
                bus-width = <4>;
                remote-endpoint = <&liimx185_imx185_out0>;
            };
        };
        port@1 {
            reg = <1>;
            liimx185_csi_out0: endpoint@1 {
                remote-endpoint = <&liimx185_vi_in0>;
            };
        };
    };
};
};
複製代碼

端口綁定屬性是:

function description
port 指定媒體填充端口鏈接。 全部成像器設備都有一個介質墊,用於綁定與VI的鏈接。
port-index 定義傳感器端口鏈接。 對於成像器設備,例如聚焦器或閃光燈,不須要該字段。有關更多信息,請參閱端口索引。
bus-width 經過識別鏈接到傳感器的CSI通道的數量來定義總線寬度。
remote-endpoint 定義綁定兩個端口的標籤。 綁按期望一個端口用於接收器,另外一個端口用於源。

驗證相機接口綁定

  • 執行如下命令

    //if have sudo apt-get install media-player-info sudo media-ctl -p -d /dev/media0

    對於自己不帶該命令的系統能夠經過apt-get install進行安裝: sudo apt-get install v4l-utils

返回的輸出相似於如下內容:

Media controller API version 0.1.0
Media device information
------------------------
driver          tegra-vi4
model           NVIDIA Tegra Video Input Device
serial          
bus info        
hw revision     0x3
driver version  0.0.0

Device topology
- entity 1: 150c0000.nvcsi-0 (2 pads, 2 links)
        type V4L2 subdev subtype Unknown flags 0
        device node name /dev/v4l-subdev0
pad0: Sink
	<- "imx185 30-001a":0 [ENABLED]
pad1: Source
	-> "vi-output, imx185 30-001a":0 [ENABLED]

- entity 2: imx185 30-001a (1 pad, 1 link)
        type V4L2 subdev subtype Sensor flags 0
        device node name /dev/v4l-subdev1
pad0: Source
	[fmt:SRGGB12/1920x1080 field:none]
	-> "150c0000.nvcsi-0":0 [ENABLED]

- entity 3: vi-output, imx185 30-001a (1 pad, 1 link)
        type Node subtype V4L flags 0
        device node name /dev/video0
pad0: Sink
	<- "150c0000.nvcsi-0":1 [ENABLED]
複製代碼

Sensor Pixel Clock傳感器像素時鐘

相機軟件使用傳感器像素時鐘來計算傳感器的曝光和幀速率。 必須正確設置才能避免潛在問題。 根據傳感器供應商提供的信息,有幾種方法能夠得到正確的傳感器像素時鐘頻率:

  • Using PLL multiplier and PLL pre/post dividers: MCLK Multiplier = PLL Multiplier / PLL Pre-divider / PLL Post-divider pixel_clk_hz = MCLK * MCLK Multiplier For example: MCLK = 24MHz PLL Multiplier = 30 PLL Pre-divider = 3 PLL Post-divider = 3 MCLK Multiplier = 30 / 3 / 3 = 6.67 Pixel_clk_hz = 24000000 * 6.67 = 160000000 • Using sensor CSI lane output rate: pixel_clk_hz = sensor data rate per lane (Mbps) * number of lanes / bits per pixel For example: Sensor data rate = 891 Mbps (per lane) Number of lanes = 4 Bits per pixel = 10 pixel_clk_hz = 891 Mbps * 4 / 10 = 356400000 • Using frame size and frame rate pixel_clk_hz = sensor output size * frame rate

注意: 傳感器輸出大小不是最終輸出大小。 它是傳感器用於生成最終輸出大小的總像素數。 例如: 傳感器輸出尺寸= 2200 * 1125(實際輸出尺寸1920 * 1080) 幀速率= 30 FPS pixel_clk_hz = 2200 * 1125 * 30 = 742500000

SerDes Pixel Clock 對於使用串行器/解串器芯片(GMSL或FPD Link)的傳感器模塊,SoC接收的幀是從SerDes輸出的,而不是從傳感器輸出的。 所以,必須正確指定SerDes像素時鐘才能正確配置SoC相機接口並避免緩衝區溢出問題。 必須根據用例(鏈接到SerDes的攝像機數量)設置SerDes像素時鐘。 若是您不肯定採用什麼用例,請設置爲SerDes最大輸出速率。 Port Index 端口索引用於指定兩個不一樣模塊之間的鏈接。 對於VI模塊,端口索引表示輸入流。 對於CSI模塊,它表示攝像機所鏈接的實際CSI端口。 下圖顯示了不一樣Jetson平臺的端口索引映射。

For NVIDIA® Jetson™ TX2 and NVIDIA® Jetson Nano™:

image.png

For NVIDIA® Jetson AGX Xavier™:

image.png
相關文章
相關標籤/搜索