0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Rockchip CIF驱动深度解析:从架构设计到电源计数补丁修复

jf_44130326 来源:Linux1024 2026-02-06 16:49 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式Linux系统中,Rockchip CIFCamera Interface)驱动是摄像头硬件与上层应用的桥梁”——它不仅要实现设备初始化、格式协商、数据捕获等核心功能,还需保障运行稳定性。本文将从「驱动整体架构」入手,拆解核心文件功能与调用关系,再聚焦「Sensor电源引用计数补丁」,详解如何通过补丁解决实际运行中的稳定性问题,为驱动开发与调试提供完整参考。

一、CIF驱动整体架构:核心文件与功能拆解

Rockchip CIF驱动位于drivers/media/platform/rockchip/cif/目录下,包含5个核心文件(dev.c/subdev-itf.c/subdev-itf.h/procfs.c/capture.c),各文件分工明确、协同工作,共同支撑摄像头的完整功能。

1.核心文件功能总览

先通过一张脑图快速梳理各文件的核心定位:

wKgZPGkaixeAMbf7AAIzmx7vtbg578.png

2.关键文件深度解析

1dev.c:设备管理总控

作为驱动的大脑dev.c负责初始化设备基础环境、管理全局状态,并提供用户可配置的属性接口

核心工作

a.设备初始化:在rkcif_plat_init中初始化原子变量(如power_cntstreamoff_cnt)、互斥锁(stream_lock)、媒体管道(pipe),为设备运行打下基础。

b.sysfs属性配置:实现compact_test(紧凑数据流模式)、is_use_dummybuf(虚拟缓冲区开关)等属性的读写函数,用户可通过/sys/class/video4linux/videoX/路径动态调整设备行为。

c.全局状态维护:通过rkcif_device_list链表管理所有CIF设备,rkcif_dev_mutex保证多设备操作的互斥性,避免并发冲突。

关键代码示例(设备初始化):

// drivers/media/platform/rockchip/cif/dev.cintrkcif_plat_init(structrkcif_device *cif_dev,structdevice_node *node,intirq){ // 初始化原子变量(电源、流关闭、传感器状态)  atomic_set(&cif_dev->power_cnt,0);  atomic_set(&cif_dev->streamoff_cnt,0);  atomic_set(&cif_dev->sensor_off,1); // 后续补丁新增:Sensor电源引用计数初始化  atomic_set(&cif_dev->sd_power_cnt,0);  // 初始化媒体管道(open/close回调)  cif_dev->pipe.open = rkcif_pipeline_open;  cif_dev->pipe.close = rkcif_pipeline_close; return0;}

2subdev-itf.c:传感器交互桥梁

subdev-itf.cCIF驱动与摄像头Sensor的直接交互接口,实现V4L2子设备协议,负责格式协商、电源控制、事件触发。

核心工作

a.格式协商:通过sditf_get_set_fmtSensor协商输入格式(分辨率、像素格式如SBGGR8),并配置CIF内部数据流参数。

b.电源控制sditf_s_power函数触发Sensor电源开关,是后续补丁重点修复的调用路径之一。

c.事件管理:订阅/触发V4L2_EVENT_FRAME_SYNC(帧同步)、V4L2_EVENT_EXPOSURE(曝光)事件,确保数据捕获时序正确。

关键代码示例(电源控制接口):

// 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);   // 后续补丁新增:调用统一电源管理函数    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;}

3capture.c:数据捕获执行核心

capture.c负责摄像头数据的实际捕获,包括流启动/停止、缓冲区处理、电源控制函数实现,是本次补丁修改的核心文件。

核心工作

a.流管理rkcif_do_start_stream启动数据捕获,rkcif_stream_init初始化流状态(如帧丢失计数frame_loss)。

b.电源控制函数rkcif_sensor_set_powerSensor电源开关的实际实现,补丁通过修改该函数引入引用计数逻辑。

c.文件操作rkcif_fh_open/rkcif_fh_release处理用户空间的设备打开/关闭请求,控制电源开关的调用时机。

4procfs.c:调试信息出口

procfs.c通过/proc/driver/rkcif节点向用户空间暴露驱动运行状态,便于调试定位问题。

核心工作

a.格式转换rkcif_pixelcode_to_string将媒体总线格式代码(如MEDIA_BUS_FMT_SBGGR8_1X8)转换为可读字符串("SBGGR8")。

b.信息输出rkcif_show_clks输出时钟频率、rkcif_show_format输出当前捕获格式,帮助开发者确认设备配置是否正确。

5subdev-itf.h:数据结构定义层

仅定义struct capture_info结构体,存储摄像头捕获区域的偏移(offset_x/y)和分辨率(width/height),是格式协商、缓冲区分配的基础数据载体。

二、驱动模块协同:调用关系与架构流程图

各文件并非独立运行,而是通过初始化配置捕获调试的流程协同工作,以下是核心调用关系与架构图:

1.核心调用流程(以设备启动为例)

1.初始化dev.crkcif_plat_init初始化设备状态subdev-itf.csditf_init_buf分配缓冲区capture.crkcif_stream_init初始化流。

2.用户交互:用户通过open调用触发capture.crkcif_fh_open加锁后调用rkcif_sensor_set_power上电subdev-itf.csditf_s_powerSensor交互。

3.数据捕获rkcif_do_start_stream启动流subdev-itf.c的事件机制同步帧数据数据写入缓冲区。

4.调试监控:用户读取/proc/driver/rkcifprocfs.c的函数从dev.c获取设备状态并输出。

2.架构流程图

wKgZPGkaixeASfEvAAC3Nhb1Owg613.jpg

三、补丁修复:Sensor电源引用计数问题拆解

在理解驱动架构后,我们聚焦本次关键补丁——修复Sensor电源引用计数问题。该补丁针对Kernel 6.1版本,解决了驱动运行中过早断电”“重复上电等稳定性隐患。

1.补丁背景:原驱动的3大问题

CIF驱动对Sensor电源的管理缺乏引用计数机制,导致多场景下异常:

问题1:无计数跟踪:多个模块(如预览+录像)同时使用Sensor时,无法记录当前使用者数量,一个模块调用断电后,其他模块会因Sensor断电崩溃。

问题2:调用时机混乱rkcif_sensor_set_poweropen/release中调用时机错误(如解锁后调用),并发场景下计数错乱。

问题3:路径覆盖不全subdev-itf.csditf_s_power未经过统一电源函数,绕过计数逻辑,导致部分场景电源失控。

2.修复思路:引入原子引用计数

补丁核心是通过原子变量sd_power_cnt(定义在dev.c,声明在dev.h)跟踪电源使用状态,规则如下:

上电(on=1:仅当sd_power_cnt0→1时,才执行Sensor上电(避免重复上电)。

断电(on=0:仅当sd_power_cnt1→0时,才执行Sensor断电(避免过早断电)。

全路径覆盖:所有电源操作(open/releasesditf_s_power)均调用rkcif_sensor_set_power,确保计数不遗漏。

3.补丁对各文件的修改(附路径)

1capture.c:核心逻辑修改(路径:

drivers/media/platform/rockchip/cif/capture.c

修改1rkcif_sensor_set_power函数重构

从静态函数改为全局函数,新增计数逻辑:

// 原函数:直接操作电源,无计数staticintrkcif_sensor_set_power(...){ ... }// 补丁后:新增计数控intrkcif_sensor_set_power(structrkcif_stream *stream,inton){ structrkcif_device *cif_dev = stream->cifdev;  // 断电:计数>0时减1,未到0则不执行断电 if(!on&& atomic_dec_if_positive(&cif_dev->sd_power_cnt))   return0; // 上电:计数+1后>1,说明已有模块使用,不重复上电 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:调整open/release中函数调用时机

rkcif_sensor_set_power解锁后移到锁内,确保并发安全:

// open函数:锁内调用,避免并发计数错乱staticintrkcif_fh_open(...){  mutex_lock(&cifdev->stream_lock);  ret = rkcif_sensor_set_power(stream,on);// 补丁后:锁内调用  mutex_unlock(&cifdev->stream_lock);}// release函数:先断电计数,再释放资源staticintrkcif_fh_release(...){  mutex_lock(&cifdev->stream_lock);  ret = rkcif_sensor_set_power(stream,on);// 补丁后:锁内调用  v4l2_pipeline_pm_put(...);// 后释放资源  mutex_unlock(&cifdev->stream_lock);}

2dev.c:初始化计数变量(路径:

drivers/media/platform/rockchip/cif/dev.c

rkcif_plat_init中新增sd_power_cnt初始化,确保计数从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); // 补丁新增:初始化Sensor电源计数

3dev.h:声明变量与函数(路径:

drivers/media/platform/rockchip/cif/dev.h

新增sd_power_cntstruct rkcif_device

structrkcif_device{ atomic_t      power_cnt; atomic_t      streamoff_cnt; atomic_t      sensor_off; atomic_t      sd_power_cnt;// 补丁新增:Sensor电源引用计数 // ... 其他成员};

声明rkcif_sensor_set_power函数(因函数从static改为全局):

intrkcif_sensor_set_power(structrkcif_stream *stream,inton);// 补丁新增

4subdev-itf.c:补全调用路径(路径:drivers/media/platform/rockchip/cif/subdev-itf.c

sditf_s_power中调用rkcif_sensor_set_power,确保该路径纳入计数管理:

staticintsditf_s_power(...){ // ... 原有逻辑 if(on) {    pm_runtime_get_sync(cif_dev->dev);    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);// 补丁新增  } // ... 原有逻辑}

4.修复价值:从隐患稳定

解决功能异常:多模块共用Sensor时,避免一个模块退出导致整体崩溃(如预览退出后录像仍正常)。

保护硬件寿命:避免重复上电导致Sensor电源模块过热,延长硬件寿命。

符合V4L2规范:遵循按需开关电源的框架要求,提升驱动兼容性。

四、总结:驱动架构与补丁的启示

Rockchip CIF驱动通过模块化设计实现了功能解耦——dev.c管全局、subdev-itf.c管交互、capture.c管执行、procfs.c管调试,这种架构既便于维护,又能灵活扩展(如新增HDR模式)。

而本次补丁则体现了内核驱动开发的核心原则

1.资源管理需计数:多模块共享的资源(如Sensor电源),必须通过引用计数跟踪使用状态。

2.并发操作需锁保护:关键逻辑(如计数修改)必须在互斥锁内执行,避免并发错乱。

3.调用路径需全覆盖:确保所有触发点都经过统一逻辑,不遗漏任何场景。

对于嵌入式开发者而言,理解驱动架构是定位问题的基础,而补丁的修复思路则为资源管理类问题提供了通用参考——小到电源计数,大到内存管理,核心都是清晰跟踪状态、规范操作流程

若你的设备基于Rockchip芯片且使用Kernel 6.1,建议及时合入该补丁,为摄像头稳定运行保驾护航~

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5212

    文章

    20763

    浏览量

    338752
  • Linux
    +关注

    关注

    88

    文章

    11854

    浏览量

    219822
  • Rockchip
    +关注

    关注

    0

    文章

    93

    浏览量

    19694
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【WEBENCH 大赛作品】WEBENCH FPGA 电源架构设

    使用WEBENCH® FPGA Power Architect 设计工具,进行FPGA的电源架构设计作品地址:https://www.elecfans.com/uploads/ComDoc/20150716/55a754d88f528.zip
    发表于 07-16 14:54

    【原创】Dex分包架构设计—实现安卓热修复

    【原创】Dex分包架构设计—实现安卓热修复回复即可获取下载链接[hide=d15]链接:http://pan.baidu.com/s/1c2fYJZy 密码:iw16 学习群:150923287 [/hide]
    发表于 07-26 17:50

    tvp5158 D1+3CIF metadata怎么解析

    hello, 请问一下,一路D1+3CIF的帧,由line interlace模式来配置,reg B1-B8应该怎么配,我capture的帧大小怎么算,怎么解析这个metadata数据重新拼成对应的图像?
    发表于 05-28 01:55

    功能安全---AUTOSAR架构深度解析 精选资料分享

    AUTOSAR架构深度解析本文转载于:AUTOSAR架构深度解析AUTOSAR的分层式设计,用于
    发表于 07-23 08:34

    AUTOSAR架构深度解析 精选资料推荐

    AUTOSAR架构深度解析本文转载于:AUTOSAR架构深度解析目录AUTOSAR
    发表于 07-28 07:40

    AUTOSAR架构深度解析 精选资料分享

    AUTOSAR架构深度解析本文转载于:AUTOSAR架构深度解析AUTOSAR的分层式设计,用于
    发表于 07-28 07:02

    rockchip-isp1驱动程序和rockchip SoC上图像信号处理模块的基本信息介绍

    概述以下文档提供了rockchip-isp1驱动程序和rockchip SoC上图像信号处理模块的基本信息,并附有示例和详细信息。ISP 详细ISP 包括:MIPI serial camera
    发表于 04-15 16:34

    介绍WEBENCH 电源架构设计工具使用方法与技巧

    WEBENCH 电源架构设计工具概述(简短版本)
    的头像 发表于 08-06 01:33 4349次阅读

    瑞芯微系列芯片的CIF和ISP的新驱动结构及开发指南资料免费下载

    本文档主要介绍 Rockchip 系列芯片的 CIF, ISP 的新驱动结构, 以及在此基础上, 如何编写/移植 Sensor 驱动,上层如何应用 demo 及工具测试。
    发表于 04-24 08:00 0次下载
    瑞芯微系列芯片的<b class='flag-5'>CIF</b>和ISP的新<b class='flag-5'>驱动</b>结构及开发指南资料免费下载

    苹果重新发布补丁用于修复iOS越狱的漏洞

    苹果周一发布了iOS 12.4.1,重新修复了在iOS 12.3中打补丁,但在iOS 12.4中补丁取消的漏洞。苹果表示,该补丁解决了黑客可能“以系统权限执行任意代码”的问题。
    的头像 发表于 08-27 12:22 2766次阅读

    深度:嵌入式系统的软件架构设计!资料下载

    电子发烧友网为你提供深度:嵌入式系统的软件架构设计!资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助广大的电子工程师们。
    发表于 04-25 08:43 22次下载
    <b class='flag-5'>深度</b>:嵌入式系统的软件<b class='flag-5'>架构设</b>计!资料下载

    架构与微架构设

    下面将从芯片的架构设计、微架构设计、使用设计文档、设计分区、时钟域和时钟组、架构调整与性能改进、处理器微架构设计策略等角度进行说明,并以视频H.264编码器设计为例。
    的头像 发表于 05-08 10:42 2347次阅读
    <b class='flag-5'>架构</b>与微<b class='flag-5'>架构设</b>计

    GPU架构深度解析

    GPU架构深度解析图形处理到通用计算的进化之路图形处理单元(GPU),作为现代计算机中不可或缺的一部分,已经最初的图形渲染专用处理器,发
    的头像 发表于 05-30 10:36 2083次阅读
    GPU<b class='flag-5'>架构</b><b class='flag-5'>深度</b><b class='flag-5'>解析</b>

    电机驱动EMC整改:传导辐射,问题诊断与修复

    电机驱动EMC整改:传导辐射,问题诊断与修复|深圳南柯电子
    的头像 发表于 10-30 09:38 879次阅读

    Windows平台EtherCAT实时控制:抖动抑制虚拟化架构解析

    Windows平台EtherCAT实时控制:抖动抑制虚拟化架构解析
    的头像 发表于 01-29 15:26 514次阅读
    Windows平台EtherCAT实时控制:<b class='flag-5'>从</b>抖动抑制<b class='flag-5'>到</b>虚拟化<b class='flag-5'>架构</b><b class='flag-5'>解析</b>