在嵌入式Linux系統(tǒng)中,Rockchip CIF(Camera Interface)驅(qū)動(dòng)是攝像頭硬件與上層應(yīng)用的“橋梁”——它不僅要實(shí)現(xiàn)設(shè)備初始化、格式協(xié)商、數(shù)據(jù)捕獲等核心功能,還需保障運(yùn)行穩(wěn)定性。本文將從「驅(qū)動(dòng)整體架構(gòu)」入手,拆解核心文件功能與調(diào)用關(guān)系,再聚焦「Sensor電源引用計(jì)數(shù)補(bǔ)丁」,詳解如何通過補(bǔ)丁解決實(shí)際運(yùn)行中的穩(wěn)定性問題,為驅(qū)動(dòng)開發(fā)與調(diào)試提供完整參考。
一、CIF驅(qū)動(dòng)整體架構(gòu):核心文件與功能拆解
Rockchip CIF驅(qū)動(dòng)位于drivers/media/platform/rockchip/cif/目錄下,包含5個(gè)核心文件(dev.c/subdev-itf.c/subdev-itf.h/procfs.c/capture.c),各文件分工明確、協(xié)同工作,共同支撐攝像頭的完整功能。
1.核心文件功能總覽
先通過一張腦圖快速梳理各文件的核心定位:

2.關(guān)鍵文件深度解析
(1)dev.c:設(shè)備管理“總控”
作為驅(qū)動(dòng)的“大腦”,dev.c負(fù)責(zé)初始化設(shè)備基礎(chǔ)環(huán)境、管理全局狀態(tài),并提供用戶可配置的屬性接口。
?核心工作:
a.設(shè)備初始化:在rkcif_plat_init中初始化原子變量(如power_cnt、streamoff_cnt)、互斥鎖(stream_lock)、媒體管道(pipe),為設(shè)備運(yùn)行打下基礎(chǔ)。
b.sysfs屬性配置:實(shí)現(xiàn)compact_test(緊湊數(shù)據(jù)流模式)、is_use_dummybuf(虛擬緩沖區(qū)開關(guān))等屬性的讀寫函數(shù),用戶可通過/sys/class/video4linux/videoX/路徑動(dòng)態(tài)調(diào)整設(shè)備行為。
c.全局狀態(tài)維護(hù):通過rkcif_device_list鏈表管理所有CIF設(shè)備,rkcif_dev_mutex保證多設(shè)備操作的互斥性,避免并發(fā)沖突。
?關(guān)鍵代碼示例(設(shè)備初始化):
// drivers/media/platform/rockchip/cif/dev.cintrkcif_plat_init(structrkcif_device *cif_dev,structdevice_node *node,intirq){// 初始化原子變量(電源、流關(guān)閉、傳感器狀態(tài))atomic_set(&cif_dev->power_cnt,0);atomic_set(&cif_dev->streamoff_cnt,0);atomic_set(&cif_dev->sensor_off,1);// 后續(xù)補(bǔ)丁新增:Sensor電源引用計(jì)數(shù)初始化atomic_set(&cif_dev->sd_power_cnt,0);// 初始化媒體管道(open/close回調(diào))cif_dev->pipe.open = rkcif_pipeline_open;cif_dev->pipe.close = rkcif_pipeline_close;return0;}
(2)subdev-itf.c:傳感器“交互橋梁”
subdev-itf.c是CIF驅(qū)動(dòng)與攝像頭Sensor的直接交互接口,實(shí)現(xiàn)V4L2子設(shè)備協(xié)議,負(fù)責(zé)格式協(xié)商、電源控制、事件觸發(fā)。
?核心工作:
a.格式協(xié)商:通過sditf_get_set_fmt與Sensor協(xié)商輸入格式(分辨率、像素格式如SBGGR8),并配置CIF內(nèi)部數(shù)據(jù)流參數(shù)。
b.電源控制:sditf_s_power函數(shù)觸發(fā)Sensor電源開關(guān),是后續(xù)補(bǔ)丁重點(diǎn)修復(fù)的調(diào)用路徑之一。
c.事件管理:訂閱/觸發(fā)V4L2_EVENT_FRAME_SYNC(幀同步)、V4L2_EVENT_EXPOSURE(曝光)事件,確保數(shù)據(jù)捕獲時(shí)序正確。
?關(guān)鍵代碼示例(電源控制接口):
// drivers/media/platform/rockchip/cif/subdev-itf.cstaticintsditf_s_power(structv4l2_subdev *sd,inton){structsditf_priv *priv = v4l2_subdev_to_sditf(sd);structrkcif_device *cif_dev = priv->cif_dev;intret =0;mutex_lock(&cif_dev->stream_lock);if(on) {pm_runtime_get_sync(cif_dev->dev);// 后續(xù)補(bǔ)丁新增:調(diào)用統(tǒng)一電源管理函數(shù)ret |= rkcif_sensor_set_power(&cif_dev->stream[0],on);}else{pm_runtime_put_sync(cif_dev->dev);ret |= rkcif_sensor_set_power(&cif_dev->stream[0],on);}mutex_unlock(&cif_dev->stream_lock);returnret;}
(3)capture.c:數(shù)據(jù)捕獲“執(zhí)行核心”
capture.c負(fù)責(zé)攝像頭數(shù)據(jù)的實(shí)際捕獲,包括流啟動(dòng)/停止、緩沖區(qū)處理、電源控制函數(shù)實(shí)現(xiàn),是本次補(bǔ)丁修改的核心文件。
?核心工作:
a.流管理:rkcif_do_start_stream啟動(dòng)數(shù)據(jù)捕獲,rkcif_stream_init初始化流狀態(tài)(如幀丟失計(jì)數(shù)frame_loss)。
b.電源控制函數(shù):rkcif_sensor_set_power是Sensor電源開關(guān)的實(shí)際實(shí)現(xiàn),補(bǔ)丁通過修改該函數(shù)引入引用計(jì)數(shù)邏輯。
c.文件操作:rkcif_fh_open/rkcif_fh_release處理用戶空間的設(shè)備打開/關(guān)閉請(qǐng)求,控制電源開關(guān)的調(diào)用時(shí)機(jī)。
(4)procfs.c:調(diào)試信息“出口”
procfs.c通過/proc/driver/rkcif節(jié)點(diǎn)向用戶空間暴露驅(qū)動(dòng)運(yùn)行狀態(tài),便于調(diào)試定位問題。
?核心工作:
a.格式轉(zhuǎn)換:rkcif_pixelcode_to_string將媒體總線格式代碼(如MEDIA_BUS_FMT_SBGGR8_1X8)轉(zhuǎn)換為可讀字符串("SBGGR8")。
b.信息輸出:rkcif_show_clks輸出時(shí)鐘頻率、rkcif_show_format輸出當(dāng)前捕獲格式,幫助開發(fā)者確認(rèn)設(shè)備配置是否正確。
(5)subdev-itf.h:數(shù)據(jù)結(jié)構(gòu)“定義層”
僅定義struct capture_info結(jié)構(gòu)體,存儲(chǔ)攝像頭捕獲區(qū)域的偏移(offset_x/y)和分辨率(width/height),是格式協(xié)商、緩沖區(qū)分配的基礎(chǔ)數(shù)據(jù)載體。
二、驅(qū)動(dòng)模塊協(xié)同:調(diào)用關(guān)系與架構(gòu)流程圖
各文件并非獨(dú)立運(yùn)行,而是通過“初始化→配置→捕獲→調(diào)試”的流程協(xié)同工作,以下是核心調(diào)用關(guān)系與架構(gòu)圖:
1.核心調(diào)用流程(以“設(shè)備啟動(dòng)”為例)
1.初始化:dev.c的rkcif_plat_init初始化設(shè)備狀態(tài)→subdev-itf.c的sditf_init_buf分配緩沖區(qū)→capture.c的rkcif_stream_init初始化流。
2.用戶交互:用戶通過open調(diào)用觸發(fā)capture.c的rkcif_fh_open→加鎖后調(diào)用rkcif_sensor_set_power上電→subdev-itf.c的sditf_s_power與Sensor交互。
3.數(shù)據(jù)捕獲:rkcif_do_start_stream啟動(dòng)流→subdev-itf.c的事件機(jī)制同步幀數(shù)據(jù)→數(shù)據(jù)寫入緩沖區(qū)。
4.調(diào)試監(jiān)控:用戶讀取/proc/driver/rkcif→procfs.c的函數(shù)從dev.c獲取設(shè)備狀態(tài)并輸出。
2.架構(gòu)流程圖

三、補(bǔ)丁修復(fù):Sensor電源引用計(jì)數(shù)問題拆解
在理解驅(qū)動(dòng)架構(gòu)后,我們聚焦本次關(guān)鍵補(bǔ)丁——修復(fù)Sensor電源引用計(jì)數(shù)問題。該補(bǔ)丁針對(duì)Kernel 6.1版本,解決了驅(qū)動(dòng)運(yùn)行中“過早斷電”“重復(fù)上電”等穩(wěn)定性隱患。
1.補(bǔ)丁背景:原驅(qū)動(dòng)的3大問題
原CIF驅(qū)動(dòng)對(duì)Sensor電源的管理缺乏“引用計(jì)數(shù)”機(jī)制,導(dǎo)致多場景下異常:
?問題1:無計(jì)數(shù)跟蹤:多個(gè)模塊(如預(yù)覽+錄像)同時(shí)使用Sensor時(shí),無法記錄“當(dāng)前使用者數(shù)量”,一個(gè)模塊調(diào)用斷電后,其他模塊會(huì)因Sensor斷電崩潰。
?問題2:調(diào)用時(shí)機(jī)混亂:rkcif_sensor_set_power在open/release中調(diào)用時(shí)機(jī)錯(cuò)誤(如解鎖后調(diào)用),并發(fā)場景下計(jì)數(shù)錯(cuò)亂。
?問題3:路徑覆蓋不全:subdev-itf.c的sditf_s_power未經(jīng)過統(tǒng)一電源函數(shù),繞過計(jì)數(shù)邏輯,導(dǎo)致部分場景電源失控。
2.修復(fù)思路:引入“原子引用計(jì)數(shù)”
補(bǔ)丁核心是通過原子變量sd_power_cnt(定義在dev.c,聲明在dev.h)跟蹤電源使用狀態(tài),規(guī)則如下:
?上電(on=1):僅當(dāng)sd_power_cnt從0→1時(shí),才執(zhí)行Sensor上電(避免重復(fù)上電)。
?斷電(on=0):僅當(dāng)sd_power_cnt從1→0時(shí),才執(zhí)行Sensor斷電(避免過早斷電)。
?全路徑覆蓋:所有電源操作(open/release、sditf_s_power)均調(diào)用rkcif_sensor_set_power,確保計(jì)數(shù)不遺漏。
3.補(bǔ)丁對(duì)各文件的修改(附路徑)
(1)capture.c:核心邏輯修改(路徑:
drivers/media/platform/rockchip/cif/capture.c)
?修改1:rkcif_sensor_set_power函數(shù)重構(gòu)
從靜態(tài)函數(shù)改為全局函數(shù),新增計(jì)數(shù)邏輯:
// 原函數(shù):直接操作電源,無計(jì)數(shù)staticintrkcif_sensor_set_power(...){ ... }// 補(bǔ)丁后:新增計(jì)數(shù)控制intrkcif_sensor_set_power(structrkcif_stream *stream,inton){structrkcif_device *cif_dev = stream->cifdev;// 斷電:計(jì)數(shù)>0時(shí)減1,未到0則不執(zhí)行斷電if(!on&& atomic_dec_if_positive(&cif_dev->sd_power_cnt))return0;// 上電:計(jì)數(shù)+1后>1,說明已有模塊使用,不重復(fù)上電if(on&& atomic_inc_return(&cif_dev->sd_power_cnt) >1)return0;// 僅滿足“首次上電”或“最后一次斷電”,才操作Sensor電源if(cif_dev->terminal_sensor.sd)v4l2_subdev_call(..., core, s_power,on);return0;}
?修改2:調(diào)整open/release中函數(shù)調(diào)用時(shí)機(jī)
將rkcif_sensor_set_power從“解鎖后”移到“鎖內(nèi)”,確保并發(fā)安全:
// open函數(shù):鎖內(nèi)調(diào)用,避免并發(fā)計(jì)數(shù)錯(cuò)亂staticintrkcif_fh_open(...){mutex_lock(&cifdev->stream_lock);ret = rkcif_sensor_set_power(stream,on);// 補(bǔ)丁后:鎖內(nèi)調(diào)用mutex_unlock(&cifdev->stream_lock);}// release函數(shù):先斷電計(jì)數(shù),再釋放資源staticintrkcif_fh_release(...){mutex_lock(&cifdev->stream_lock);ret = rkcif_sensor_set_power(stream,on);// 補(bǔ)丁后:鎖內(nèi)調(diào)用v4l2_pipeline_pm_put(...);// 后釋放資源mutex_unlock(&cifdev->stream_lock);}
(2)dev.c:初始化計(jì)數(shù)變量(路徑:
drivers/media/platform/rockchip/cif/dev.c)
在rkcif_plat_init中新增sd_power_cnt初始化,確保計(jì)數(shù)從0開始:
atomic_set(&cif_dev->power_cnt,0);atomic_set(&cif_dev->streamoff_cnt,0);atomic_set(&cif_dev->sensor_off,1);atomic_set(&cif_dev->sd_power_cnt,0); // 補(bǔ)丁新增:初始化Sensor電源計(jì)數(shù)
(3)dev.h:聲明變量與函數(shù)(路徑:
drivers/media/platform/rockchip/cif/dev.h)
?新增sd_power_cnt到struct rkcif_device:
structrkcif_device{atomic_t power_cnt;atomic_t streamoff_cnt;atomic_t sensor_off;atomic_t sd_power_cnt;// 補(bǔ)丁新增:Sensor電源引用計(jì)數(shù)// ... 其他成員};
?聲明rkcif_sensor_set_power函數(shù)(因函數(shù)從static改為全局):
intrkcif_sensor_set_power(structrkcif_stream *stream,inton);// 補(bǔ)丁新增
(4)subdev-itf.c:補(bǔ)全調(diào)用路徑(路徑:drivers/media/platform/rockchip/cif/subdev-itf.c)
在sditf_s_power中調(diào)用rkcif_sensor_set_power,確保該路徑納入計(jì)數(shù)管理:
staticintsditf_s_power(...){// ... 原有邏輯if(on) {pm_runtime_get_sync(cif_dev->dev);ret |= rkcif_sensor_set_power(&cif_dev->stream[0],on);// 補(bǔ)丁新增}else{pm_runtime_put_sync(cif_dev->dev);ret |= rkcif_sensor_set_power(&cif_dev->stream[0],on);// 補(bǔ)丁新增}// ... 原有邏輯}
4.修復(fù)價(jià)值:從“隱患”到“穩(wěn)定”
?解決功能異常:多模塊共用Sensor時(shí),避免“一個(gè)模塊退出導(dǎo)致整體崩潰”(如預(yù)覽退出后錄像仍正常)。
?保護(hù)硬件壽命:避免重復(fù)上電導(dǎo)致Sensor電源模塊過熱,延長硬件壽命。
?符合V4L2規(guī)范:遵循“按需開關(guān)電源”的框架要求,提升驅(qū)動(dòng)兼容性。
四、總結(jié):驅(qū)動(dòng)架構(gòu)與補(bǔ)丁的啟示
Rockchip CIF驅(qū)動(dòng)通過“模塊化設(shè)計(jì)”實(shí)現(xiàn)了功能解耦——dev.c管全局、subdev-itf.c管交互、capture.c管執(zhí)行、procfs.c管調(diào)試,這種架構(gòu)既便于維護(hù),又能靈活擴(kuò)展(如新增HDR模式)。
而本次補(bǔ)丁則體現(xiàn)了內(nèi)核驅(qū)動(dòng)開發(fā)的核心原則:
1.資源管理需“計(jì)數(shù)”:多模塊共享的資源(如Sensor電源),必須通過引用計(jì)數(shù)跟蹤使用狀態(tài)。
2.并發(fā)操作需“鎖保護(hù)”:關(guān)鍵邏輯(如計(jì)數(shù)修改)必須在互斥鎖內(nèi)執(zhí)行,避免并發(fā)錯(cuò)亂。
3.調(diào)用路徑需“全覆蓋”:確保所有觸發(fā)點(diǎn)都經(jīng)過統(tǒng)一邏輯,不遺漏任何場景。
對(duì)于嵌入式開發(fā)者而言,理解驅(qū)動(dòng)架構(gòu)是定位問題的基礎(chǔ),而補(bǔ)丁的修復(fù)思路則為“資源管理類問題”提供了通用參考——小到電源計(jì)數(shù),大到內(nèi)存管理,核心都是“清晰跟蹤狀態(tài)、規(guī)范操作流程”。
若你的設(shè)備基于Rockchip芯片且使用Kernel 6.1,建議及時(shí)合入該補(bǔ)丁,為攝像頭穩(wěn)定運(yùn)行保駕護(hù)航~
-
嵌入式
+關(guān)注
關(guān)注
5209文章
20654瀏覽量
336945 -
Linux
+關(guān)注
關(guān)注
88文章
11817瀏覽量
219534 -
Rockchip
+關(guān)注
關(guān)注
0文章
92瀏覽量
19654
發(fā)布評(píng)論請(qǐng)先 登錄
【W(wǎng)EBENCH 大賽作品】WEBENCH FPGA 電源架構(gòu)設(shè)計(jì)
【原創(chuàng)】Dex分包架構(gòu)設(shè)計(jì)—實(shí)現(xiàn)安卓熱修復(fù)
tvp5158 D1+3CIF metadata怎么解析
功能安全---AUTOSAR架構(gòu)深度解析 精選資料分享
AUTOSAR架構(gòu)深度解析 精選資料推薦
AUTOSAR架構(gòu)深度解析 精選資料分享
rockchip-isp1驅(qū)動(dòng)程序和rockchip SoC上圖像信號(hào)處理模塊的基本信息介紹
介紹WEBENCH 電源架構(gòu)設(shè)計(jì)工具使用方法與技巧
瑞芯微系列芯片的CIF和ISP的新驅(qū)動(dòng)結(jié)構(gòu)及開發(fā)指南資料免費(fèi)下載
蘋果重新發(fā)布補(bǔ)丁用于修復(fù)iOS越獄的漏洞
深度:嵌入式系統(tǒng)的軟件架構(gòu)設(shè)計(jì)!資料下載
架構(gòu)與微架構(gòu)設(shè)計(jì)
GPU架構(gòu)深度解析
電機(jī)驅(qū)動(dòng)EMC整改:從傳導(dǎo)到輻射,問題診斷與修復(fù)
Windows平臺(tái)EtherCAT實(shí)時(shí)控制:從抖動(dòng)抑制到虛擬化架構(gòu)解析
Rockchip CIF驅(qū)動(dòng)深度解析:從架構(gòu)設(shè)計(jì)到電源計(jì)數(shù)補(bǔ)丁修復(fù)
評(píng)論