攝像頭ov13850移植筆記
大家好,我是Peter,除了核心外,後面
會持續增加驅動的內容。
今天推薦一篇。
0、環境
soc : rk3568
board: EVB1-DDR4-V10
軟 件:Android 11
Linux:4。19。232
一、ov13850簡介
1。 產品引數
品牌:Omnivision
型號:CMK-OV13850
介面:MIPI
畫素:1320W
OV13850彩色影象感測器是一款低電壓、高效能1/3。06英寸1320萬畫素CMOS影象感測器,使用OmniBSI+?技術提供了單-1320萬畫素(4224×3136)攝像頭的功能。透過序列攝像頭控制匯流排(SCCB)介面的控制,它提供了全幀、下采樣、開窗的10位MIPI影象。
OV13850擁有一個能夠在10位1320萬畫素解析度下以每秒24幀(fps)的速度執行的影象陣列,使用者可以完全控制影象質量、格式和輸出資料傳輸。所有需要的影象處理功能,包括曝光控制、白平衡、缺陷畫素消除等,都可以透過SCCB介面進行程式設計。
此外,OmniBSI影象感測器使用專有的感測器技術,透過減少或消除固定圖案噪聲、汙跡等常見的影象汙染光源來提高影象質量,從而產生乾淨、完全穩定的彩色影象。
為了提供定製資訊,OV13850包括一個單程式設計(OPT)儲存器。OV13850擁有最多4車道的MIPI介面。
OV13850適用於低功耗相機模組。
以下是測試用的攝像頭&擴充套件板:
2。 特性
●鏡頭尺寸:1/3。06英寸 ●畫素大小:1。12毫米×1。12毫米 ●31。2°CRA為6mm z高度 ●可程式設計控制幀速率,映象和翻轉,裁剪和視窗 ●1320萬畫素AT30fps ●雙線序列匯流排控制(SCCB) ●閃光燈輸出控制閃光 ●支援輸出格式:10位RAW RGB ●支援影象大小:13。2MP(4224×3136)、10MP(4224×2376)、4K2K(3840×2160)、EIS 1080P(2112×1188)、EIS 720P(1408×792)、more3 ●支援2×2 Binning ●可達4車道MIPI序列輸出介面 ●標準系列SCCB介面 ●8k bit的嵌入式一次性可程式設計(OTP)儲存器(見側注) ●兩個片上鎖相環(PLLs) ●可程式設計控制:增益、曝光、幀率、影象大水、水平反射鏡、垂直翻轉裁剪和平移 ●內建溫度感測器 ●影象質量控制:缺陷校正,自動黑電平校準,鏡頭陰影校正,和高度計行HDR。●保證感測器結溫:-300C到+850C ●電源核心:1。14V-1。26V;模擬:2。6-3。0V輸入/輸出:1。7-3。0V ●封裝:PLCC40
3。 ov13850引腳圖
4。 ov13850功能模組
定時脈衝發生器輸出時鐘來訪問成像陣列的行,預先填充電荷並且按順序對陣列的行進行取樣。
在預先填充電荷和取樣的時間間隔內,每個畫素點的電荷曝光時減少入射光。
這是在滾動快門的體系結構的曝光時間。
曝光時間透過調整預先填充電荷和取樣之間的時間間隔控制。
在每一行的畫素資料取樣後,透過類比電路(AMP)進一步處理:糾正偏移量和將資料乘以相應的增益。
模擬處理後透過10位ADC的輸出陣列中的每個畫素的資料。
ISP(image sensor processor)透過影象輸出介面單元,經過mipi介面(MCP/MDP)將影象資料傳送出去。
5。 畫素陣列
OV13850感測器的影象陣列4256列3152行(13414912畫素)
顏色過濾器是安排在Bayer模式
Binning mode 2x2 binning
Binning mode 通常用於低解析度
6。 mirror 和 flip
OV13850提供影象mirror(左右翻轉) 和 flip(上下翻轉)模式
二、驅動移植
瑞芯微支援的攝像頭,有個support list,
此次從該list中選擇了ov13850
1。 驅動原始檔及對應指令碼
預設sdk裡面已經將支援的所有攝像頭驅動都新增到了核心,所以不需要移植該驅動了,
但是還是要確認下移植驅動對應的一些資訊
源程式
rk_android11。0_sdk_220718\kernel\drivers\media\i2c\ov13850。c
rk_android11。0_sdk_220718\kernel\include\config\video\ov13850。h
kernel/drivers/media/i2c/Makefile
115 obj-$(CONFIG_VIDEO_OV13850) += ov13850。o
kernel/drivers/media/i2c/Kconfig
1282 config VIDEO_OV13850
1283 tristate
“OmniVision OV13850 sensor support”
1284 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
1285 depends on MEDIA_CAMERA_SUPPORT
1286 select V4L2_FWNODE
1287 ——-
help
——-
1288 This is a Video4Linux2 sensor driver
for
the OmniVision
1289 OV13850 camera。
驅動對應的宏開關
kernel/arch/arm64/configs/rockchip_defconfig
581 CONFIG_VIDEO_OV13850=y
2。 裝置樹
1)典型ov系列攝像頭連結示意圖
ov系列攝像頭與SOC連線的主要的引腳有:i2c、rst、pwdn、mclk、MIPI Clk、MIPI DATA
這幾根線是驅動工程師必須捋清楚的
2)電路圖
本次我們直接將攝像頭插在公版的影片介面,用的是通道0,使用了4個lane【不知道具體硬體資訊就問硬體工程師】
由電路圖可知,幾個關鍵引腳關係:
reset訊號:GPIO3 B6
power down訊號:GPIO4 B4
I2C通道:4
clock:cif
3)裝置樹節點
參考sdk中其他平臺的ov13850節點來填寫
kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10。dtsi
ov13850: ov13850@10 {
status =
“okay”
;
compatible =
“ovti,ov13850”
;
reg = <0x10>;
clocks = <&cru CLK_CIF_OUT>;
clock-names =
“xvclk”
;
power-domains = <&power RK3568_PD_VI>;
pinctrl-names =
“default”
;
pinctrl-0 = <&cif_clk>;
reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_HIGH>;
pwdn-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing =
“back”
;
rockchip,camera-module-name =
“ZC-OV13850R2A-V1”
;
rockchip,camera-module-lens-name =
“Largan-50064B31”
;
port {
ov13850_out: endpoint {
remote-endpoint = <&mipi_in_ucam0>;
data-lanes = <1 2 3 4>;
};
};
};
114 &csi2_dphy0 {
115 status =
“okay”
;
116
117 ports {
118
#address-cells = <1>;
119
#size-cells = <0>;
120 port@0 {
121 reg = <0>;
122
#address-cells = <1>;
123
#size-cells = <0>;
124
125 mipi_in_ucam0: endpoint@1 {
126 reg = <1>;
127 remote-endpoint = <&ov13850_out>;
128 data-lanes = <1 2 3 4>;
129 };
……
152 };
裝置樹的資訊最終轉換成i2c_client,並傳遞給ov13850驅動ov13850_probe()
compatible = "ovti,ov13850";與驅動的of_match_table
保持一致
@rk_android11
。0
_sdk\kernel\drivers\media\i2c\ov13850。c
#
if
IS_ENABLED(CONFIG_OF)
static
const
struct
of_device_id
ov13850_of_match
[] = {
{ 。compatible =
“ovti,ov13850”
},
{},
};
MODULE_DEVICE_TABLE(of, ov13850_of_match);
#
endif
static
const
struct
i2c_device_id
ov13850_match_id
[] = {
{
“ovti,ov13850”
,
0
},
{ },
};
static
struct
i2c_driver
ov13850_i2c_driver
= {
。driver = {
。name = OV13850_NAME,
。pm = &ov13850_pm_ops,
。of_match_table = of_match_ptr(ov13850_of_match),
},
。probe = &ov13850_probe,
。remove = &ov13850_remove,
。id_table = ov13850_match_id,
};
關於攝像頭驅動,
彭老師後面會繼續更一篇文章講解。
3。 安卓配置檔案
在以下兩個檔案增加對應攝像頭資訊,
hardware/rockchip/camera/etc/camera/camera3_profiles_rk356x。xml
hardware/rockchip/camera/etc/camera/camera3_profiles。xml
一口君直接參考的其他檔案,
然後找一個相近型號的攝像頭修改的
三、檢視攝像頭相關資訊
1。 開機log
移植成功後,確認下對應的驅動log
10-26 17:58:54。659 0 0 I ov13850 4-0010: driver version: 00。01。05
10-26 17:58:54。659 0 0 W ov13850 4-0010: Failed to get power-gpios, maybe no use
10-26 17:58:54。659 0 0 W ov13850 4-0010: 4-0010 supply avdd not found, using dummy regulator
10-26 17:58:54。659 0 0 I ov13850 4-0010: Linked as a consumer to regulator。0
10-26 17:58:54。659 0 0 W ov13850 4-0010: 4-0010 supply dovdd not found, using dummy regulator
10-26 17:58:54。659 0 0 W ov13850 4-0010: 4-0010 supply dvdd not found, using dummy regulator
10-26 17:58:54。660 0 0 E ov13850 4-0010: could not get default pinstate
10-26 17:58:54。660 0 0 E ov13850 4-0010: could not get sleep pinstate
10-26 17:58:54。665 0 0 I ov13850 4-0010: Detected OV00d850 sensor, REVISION 0xb2
10-26 17:58:54。665 0 0 I rockchip-csi2-dphy csi2-dphy0: dphy0 matches m00_b_ov13850 4-0010:bus
type
4
2。 檢視ov13850裝置
驅動載入成功後,會有以下資訊
檢視攝像頭裝置節點:
rk3568_r:/
# ls /dev/video* -l
ls /dev/video* -l
crw-rw——
1
media camera
81
,
0
2022
-10
-31
06
:
56
/dev/video0
crw-rw——
1
media camera
81
,
1
2022
-10
-31
06
:
56
/dev/video1
crw-rw——
1
media camera
81
,
2
2022
-10
-31
06
:
56
/dev/video2
crw-rw——
1
media camera
81
,
3
2022
-10
-31
06
:
56
/dev/video3
crw-rw——
1
media camera
81
,
4
2022
-10
-31
06
:
56
/dev/video4
crw-rw——
1
media camera
81
,
5
2022
-10
-31
06
:
56
/dev/video5
crw-rw——
1
media camera
81
,
6
2022
-10
-31
06
:
56
/dev/video6
crw-rw——
1
media camera
81
,
7
2022
-10
-31
06
:
56
/dev/video7
crw-rw——
1
media camera
81
,
8
2022
-10
-31
06
:
56
/dev/video8
3。 檢視sys檔案系統中檔案資訊
核心會為攝像頭在目錄/sys/class/video4linux下分配裝置資訊描述檔案
rk3568_r:/
# grep ov13850 /sys/class/video4linux/v*/name
grep ov13850 /sys/class/video4linux/v*/name
/sys/class/video4linux/v4l-subdev3/name:m00_b_ov13850 4-0010
rk3568_r:/
# grep “” /sys/class/video4linux/v*/name | grep mainpath
grep
“”
/sys/class/video4linux/v*/name | grep mainpath
/sys/class/video4linux/video0/name:rkisp_mainpath
4。 檢視拓撲 media-ctl -d /dev/media0 -p
rk3568_r:/
# media-ctl -d /dev/media0 -p
media-ctl -d /dev/media0 -p
Opening media device /dev/media0
Enumerating entities
Found 13 entities
Enumerating pads and links
Media controller API version 0。0。255
Media device information
————————————
driver rkisp-vir0
model rkisp0
serial
bus info
hw revision 0x0
driver version 0。0。255
Device topology
- entity 1: rkisp-isp-subdev (4 pads, 7 links)
type
V4L2 subdev subtype Unknown
device node name /dev/v4l-subdev0
pad0: Sink
[fmt:SBGGR10/4224x3136
crop。bounds:(0,0)/4096x3072
crop:(0,0)/4096x3072]
<-
“rkisp-csi-subdev”
:1 []
<-
“rkisp_rawrd0_m”
:0 []
<-
“rkisp_rawrd2_s”
:0 []
pad1: Sink
<-
“rkisp-input-params”
:0 []
pad2: Source
[fmt:YUYV2X8/4096x3072
crop。bounds:(0,0)/4096x3072
crop:(0,0)/4096x3072]
->
“rkisp_mainpath”
:0 []
->
“rkisp_selfpath”
:0 []
pad3: Source
->
“rkisp-statistics”
:0 []
- entity 6: rkisp-csi-subdev (6 pads, 5 links)
type
V4L2 subdev subtype Unknown
device node name /dev/v4l-subdev1
pad0: Sink
<-
“rockchip-csi2-dphy0”
:1 []
pad1: Source
->
“rkisp-isp-subdev”
:0 []
pad2: Source
->
“rkisp_rawwr0”
:0 []
pad3: Source
pad4: Source
->
“rkisp_rawwr2”
:0 []
pad5: Source
->
“rkisp_rawwr3”
:0 []
- entity 13: rkisp_mainpath (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video0
pad0: Sink
<-
“rkisp-isp-subdev”
:2 []
- entity 19: rkisp_selfpath (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video1
pad0: Sink
<-
“rkisp-isp-subdev”
:2 []
- entity 25: rkisp_rawwr0 (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video2
pad0: Sink
<-
“rkisp-csi-subdev”
:2 []
- entity 31: rkisp_rawwr2 (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video3
pad0: Sink
<-
“rkisp-csi-subdev”
:4 []
- entity 37: rkisp_rawwr3 (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video4
pad0: Sink
<-
“rkisp-csi-subdev”
:5 []
- entity 43: rkisp_rawrd0_m (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video5
pad0: Source
->
“rkisp-isp-subdev”
:0 []
- entity 49: rkisp_rawrd2_s (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video6
pad0: Source
->
“rkisp-isp-subdev”
:0 []
- entity 55: rkisp-statistics (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video7
pad0: Sink
<-
“rkisp-isp-subdev”
:3 []
- entity 61: rkisp-input-params (1 pad, 1 link)
type
Node subtype V4L
device node name /dev/video8
pad0: Source
->
“rkisp-isp-subdev”
:1 []
- entity 67: rockchip-csi2-dphy0 (2 pads, 2 links)
type
V4L2 subdev subtype Unknown
device node name /dev/v4l-subdev2
pad0: Sink
<-
“m00_b_ov13850 4-0010”
:0 []
pad1: Source
->
“rkisp-csi-subdev”
:0 []
- entity 70: m00_b_ov13850 4-0010 (1 pad, 1 link)
type
V4L2 subdev subtype Sensor
device node name /dev/v4l-subdev3
pad0: Source
[fmt:SBGGR10/4224x3136]
->
“rockchip-csi2-dphy0”
:0 []
從entity70資訊中可以看到:
該Entity完整的名稱是:m00_b_ov13850 4-0010
它是一個V4L2 subdev(Sub-Device) Sensor
它對應的節點是/dev/v4l-subdev3,應用程式(如v4l2-ctl)可以開啟它,並進行配置
它僅有一個輸出(Source)節點,記為pad0
它的輸出格式是[fmt:SBGGR10/4224x3136],其中SBGGR10是一種mbus-code的簡稱
它的Source pad0 連結到“rockchip-csi2-dphy0”的pad0,並且當前的狀態是 ENABLED。
三、拍照測試
1。 抓幀
rk3568_r:/
# v4l2-ctl -d /dev/video0 ——set-fmt-video=width=800,height=600,pixelformat=NV12 ——stream-mmap=3 ——stream-to=/sdcard/out。yuv ——stream-skip=9 ——stream-count=1
m-mmap=3 ——stream-to=/sdcard/out。yuv ——stream-skip=9 ——stream-count=1 <
<<<<<<<<< 7。51 fps
<
【看到<<<<<<<<< 7。51 fps 說明成功】
引數說明
-d: 攝像頭對應裝置檔案
——
set
-fmt-video:指定了寬高及pxielformat(用FourCC表示)。NV12即用FourCC表示的pixelformat
——stream-mmap:指定buffer的型別為mmap,即由kernel分配的物理連續的或經過iommu對映的buffer
——stream-to:指定幀資料儲存的檔案路徑
——stream-skip:指定丟棄(不儲存到檔案)前3幀
——stream-count:指定抓取的幀數,不包括——stream-skip丟棄的數量
其他引數
——
set
-selection,指定對輸入影象進行裁剪。特別是當RKISP1的前級大小發生變化時要保證selection不大於前級輸出大小。RKCIF的裁剪則是透過——
set
-crop引數設定的
——stream-poll,該選項指示v4l2-ctl採用非同步IO,即在dqbuf前先用select等等幀資料完成,從而保證dqbuf不阻塞。否則dqbuf將會阻塞直到有資料幀到來
2。 顯示圖片:
將檔案**/sdcard/out。yuv
與驅動的
adb pull**命令複製出來,
運行於windows下:
adb pull /sdcard/out。yuv
再複製到ubuntu中,執行以下命令顯示圖片【用其他可以開啟yuv格式圖片的工具也可以】
ffplay out。yuv -f rawvideo -pixel_format nv12 -video_size 800x600
【拍照時選擇其他較高解析度會出錯,暫時還沒解決這個問題,有知道的可以聯絡我:yikoupeng】
四、引數設定
1。 顯示攝像頭引數
顯示攝像頭引數
rk3568_r:/
# v4l2-ctl -d /dev/video0 -l
v4l2-ctl -d /dev/video0 -l
User Controls
exposure 0x00980911 (int) : min=4 max=3324 step=1 default=1536 value=1536
Image Source Controls
vertical_blanking 0x009e0901 (int) : min=192 max=29631 step=1 default=192 value=192
horizontal_blanking 0x009e0902 (int) : min=576 max=576 step=1 default=576 value=576 flags=
read
-only
analogue_gain 0x009e0903 (int) : min=16 max=248 step=1 default=16 value=16
Image Processing Controls
link_frequency 0x009f0901 (intmenu): min=0 max=0 default=0 value=0 flags=
read
-only
pixel_rate 0x009f0902 (int64) : min=0 max=120000000 step=1 default=120000000 value=120000000 flags=
read
-only
test_pattern 0x009f0903 (menu) : min=0 max=4 default=0 value=0
2。 增加曝光exposure
exposure值區間為: 4-3324 命令例項:
v4l2-ctl -d /dev/video0 ——
set
-ctrl exposure=3324
3。 增加圖片亮度analogue_gain
analogue_gain用於設定顯示的影象的亮度
analogue_gain值區間:16-248
命令例項:
v4l2-ctl -d /dev/video0 ——
set
-ctrl analogue_gain=240
analogue_gain=16現象
analogue_gain=244現象【效果非常明顯】
4。 測試顯示資訊test_pattern
引數test_pattern,可以用於測試顯示影象
0:攝像頭
1-3 測試圖片 命令例項:
v4l2-ctl -d /dev/video0 ——
set
-ctrl test_pattern=0
test_pattern = 1
test_pattern = 2
test_pattern = 3
5。 修改Entity的format、size
舉例一,GC2053攝像頭支援多個解析度的輸出,預設為1920x1080。現將輸出解析度改為640x480:
media-ctl -d/dev/media0 ——
set
-v4l2
‘ “m00_b_ov13850 4-0010”:0[fmt:SBGGR10//640x480]’
修改GC2053輸出後,rkisp-isp-subdev的大小及video device crop也相應要修改。因為後級的大小不能大於前級的大小。
~/>$ media-ctl -d/dev/media0 ——
set
-v4l2
‘ “rkisp-isp-subdev”:0[fmt:SBGGR10/640x480]’
~/>$ media-ctl -d/dev/media0 ——
set
-v4l2
‘ “rkisp-isp-subdev”:0[crop: (0, 0)/640x480]’
~/>$ media-ctl -d/dev/media0 ——
set
-v4l2
‘ “rkisp-isp-subdev”:2[crop: (0, 0)/640x480]’
~/>$ v4l2-ctl -d/dev/video0\
——
set
-selection=target=crop, top=0, left=0, width=640, height=480
五、遇到問題解決
1。 解決閃退
主要是camera3_profiles_rk356x。xml和camera3_profiles。xml這兩個檔案中沒有ov13850的資訊
所以找到這兩個檔案,增加相對應的攝像頭資訊 改檔案位於sdk的目錄如下:
hardware/rockchip/camera/etc/camera/
內容比較多,只貼出我修改那一段 【我將其他攝像頭都刪除了】
“0” name= “ov13850” moduleId= “m00” > “SUPPORTED_HW_RKISP1” /> <!—— Color Correction ——> “OFF” /> <!—— Control ——> “OFF” /> “OFF,50HZ,60Hz,AUTO” /> “ON,OFF” /> “FALSE” /> ………… “SENSOR_TYPE_RAW” /> <!—— SENSOR_TYPE_SOC or SENSOR_TYPE_RAW ——> 檔案camera3_profiles。xml引數的說明,瑞芯微官方有相應的說明文件 2。 app 提示沒有許可權連線&開啟裝置失敗 10-24 15:20:15。535 1668 1668 D CAM_Camera2OneCamMgr: Getting First BACK Camera 10-24 15:20:15。535 1668 1668 I CameraManagerGlobal: Connecting to camera service 10-24 15:20:15。539 346 346 W ServiceManager: Permission failure: android。permission。CAMERA_OPEN_CLOSE_LISTENER from uid=10090 pid=1668 10-24 15:20:15。542 1668 1668 D CAM_Camera2OneCamMgr: Getting First FRONT Camera 10-24 15:20:15。543 1668 1668 W CAM_Camera2OneCamMgr: No front-facing camera found,try to find external facing camera。 10-24 15:20:15。544 1668 1668 W CAM_Camera2OneCamMgr: No external camera found。 該log位於以下檔案 。/packages/apps/Camera2/src/com/android/camera/one/v2/Camera2OneCameraManagerImpl。java: 172 修改檔案 packages/apps/Camera2/AndroidManifest。xml 增加下面兩處,會解決連線ManagerService 錯誤問題 “android。permission。CAMERA_OPEN_CLOSE_LISTENER” /> android:sharedUserId= “android。uid。system” 同時將裝置樹檔案 將mipi_in_ucam0裡的reg修改為1,如果有其他攝像頭資訊,一次往後填寫或者刪除。 114 &csi2_dphy0 { 115 status = “okay” ; 116 117 ports { 118 #address-cells = <1>; 119 #size-cells = <0>; 120 port@0 { 121 reg = <0>; 122 #address-cells = <1>; 123 #size-cells = <0>; 124 125 mipi_in_ucam0: endpoint@1 { 126 reg = <1>; 127 remote-endpoint = <&ov13850_out>; 128 data-lanes = <1 2 3 4>; 129 }; …… 【這個reg是什麼意思,有知道的老鐵可以給我留言】 3。 APP開啟裝置失敗 從log看,沒有任何permission問題,攝像頭也打開了,但是就是連線失敗,主要是xml檔案的sensorType 設定不對 hardware/rockchip/camera/etc/camera/camera3_profiles_rk356x。xml hardware/rockchip/camera/etc/camera/camera3_profiles。xml 找到這兩個檔案下面的值 “SENSOR_TYPE_RAW” /> <!—— SENSOR_TYPE_SOC or SENSOR_TYPE_RAW ——> 修改為 “SENSOR_TYPE_SOC” /> <!—— SENSOR_TYPE_SOC or SENSOR_TYPE_RAW ——> 六、後續 後面還會持續更新驅動相關的內容,感興趣的朋友關注我。