当前位置: 首页 > news >正文

v4l2驱动框架——ctrl_handler

文章目录

  • ctrl_handler
    • ov13850的handler代码
    • 应用层使用对焦例子

ctrl_handler

  1. V4L2控制框架(Control Framework)是Linux内核中为视频设备提供统一参数管理机制的子系统。它通过v4l2_ctrl_handler管理所有设备控制项(如曝光、增益、白平衡等),实现了用户空间与驱动之间的标准化参数交互接口。
  2. 每个控制项代表一个可调节参数,包含以下关键属性:
    • id:控制项标识符(如V4L2_CID_EXPOSURE)
    • type:数据类型(整数、布尔、菜单等)
    • flags:属性标志(只读、易失、可执行等)
    • minimum/maximum:取值范围
    • step:步进值
    • default_value:默认值
    • val/val64:当前值存储

ov13850的handler代码

// 函数功能:初始化OV13850传感器的V4L2控制项(曝光、增益、消隐等)// 参数:ov13850 - 指向OV13850传感器私有数据结构的指针// 返回值:成功返回0,失败返回错误码staticintov13850_initialize_controls(structov13850*ov13850){// 定义局部变量:conststructov13850_mode*mode;// 指向当前分辨率模式的指针structv4l2_ctrl_handler*handler;// V4L2控制处理器(管理所有控制项)structv4l2_ctrl*ctrl;// 单个控制项指针s64 exposure_max,vblank_def;// 最大曝光时间,默认垂直消隐值(64位有符号整数)u32 h_blank;// 水平消隐值(32位无符号整数)intret;// 函数返回值(错误码)// 第1行:获取控制处理器指针(存储在ov13850结构体中)handler=&ov13850->ctrl_handler;// 第2行:获取当前传感器工作模式(分辨率、帧率等配置)mode=ov13850->cur_mode;// 第3-5行:初始化V4L2控制处理器,预分配8个控制项的空间// v4l2_ctrl_handler_init初始化控制处理器,第二个参数8表示预期会有8个控制项ret=v4l2_ctrl_handler_init(handler,8);if(ret)// 如果初始化失败returnret;// 返回错误码// 第6行:设置控制处理器的互斥锁,使用传感器自己的mutex保证线程安全// 当用户空间同时修改多个控制项时,用这个锁防止竞争条件handler->lock=&ov13850->mutex;// 第7-10行:创建"MIPI链接频率"控制项(只读)// v4l2_ctrl_new_int_menu创建整数菜单类型控制项:// - V4L2_CID_LINK_FREQ: 控制项ID,表示MIPI接口的数据传输频率// - 0, 0: 最小索引和最大索引都是0,表示只有1个菜单项// - link_freq_menu_items: 菜单项数组,如{891000000}表示891MHzctrl=v4l2_ctrl_new_int_menu(handler,NULL,V4L2_CID_LINK_FREQ,0,0,link_freq_menu_items);if(ctrl)// 如果控制项创建成功ctrl->flags|=V4L2_CTRL_FLAG_READ_ONLY;// 设置为只读,用户不能修改// 第11-12行:创建"像素率"控制项(只读)// v4l2_ctrl_new_std创建标准控制项:// - V4L2_CID_PIXEL_RATE: 控制项ID,表示每秒输出的像素数// - 0: 最小值(通常为0)// - OV13850_PIXEL_RATE: 最大值(如4208*3120*30≈394M像素/秒)// - 1: 步进值(每次调整的变化量)// - OV13850_PIXEL_RATE: 默认值(与最大值相同,固定值)v4l2_ctrl_new_std(handler,NULL,V4L2_CID_PIXEL_RATE,0,OV13850_PIXEL_RATE,1,OV13850_PIXEL_RATE);// 第13行:计算水平消隐值// hts_def: 水平总时间(包括有效像素和消隐期)// width: 有效像素宽度// h_blank = 总时间 - 有效时间 = 消隐时间h_blank=mode->hts_def-mode->width;// 第14-17行:创建"水平消隐"控制项(只读)// V4L2_CID_HBLANK: 水平消隐控制项// 所有参数(最小值、最大值、默认值)都设为h_blank,表示这个值固定不可调ov13850->hblank=v4l2_ctrl_new_std(handler,NULL,V4L2_CID_HBLANK,h_blank,h_blank,1,h_blank);if(ov13850->hblank)// 如果控制项创建成功ov13850->hblank->flags|=V4L2_CTRL_FLAG_READ_ONLY;// 设置为只读// 第18行:计算默认垂直消隐值// vts_def: 垂直总行数(包括有效行和消隐行)// height: 有效图像高度(行数)// vblank_def = 总行数 - 有效行数 = 消隐行数vblank_def=mode->vts_def-mode->height;// 第19-23行:创建"垂直消隐"控制项(可调)// V4L2_CID_VBLANK: 垂直消隐控制项// &ov13850_ctrl_ops: 控制项操作集,当用户修改时会调用ov13850_set_ctrl()// vblank_def: 最小值(当前模式的默认消隐)// OV13850_VTS_MAX - mode->height: 最大值(传感器支持的最大总行数减去有效行数)// 1: 步进值(每次调整1行)// vblank_def: 默认值(当前模式的消隐值)ov13850->vblank=v4l2_ctrl_new_std(handler,&ov13850_ctrl_ops,V4L2_CID_VBLANK,vblank_def,OV13850_VTS_MAX-mode->height,1,vblank_def);// 第24行:计算最大曝光时间// 最大曝光时间 = 垂直总行数 - 4(留出4行余量,防止曝光时间过长影响下一帧)exposure_max=mode->vts_def-4;// 第25-29行:创建"曝光时间"控制项(可调)// V4L2_CID_EXPOSURE: 曝光时间控制项(单位:行时间)// OV13850_EXPOSURE_MIN: 最小值(如1行时间)// exposure_max: 最大值(计算得出)// OV13850_EXPOSURE_STEP: 步进值(如1行)// mode->exp_def: 默认值(当前模式的默认曝光)ov13850->exposure=v4l2_ctrl_new_std(handler,&ov13850_ctrl_ops,V4L2_CID_EXPOSURE,OV13850_EXPOSURE_MIN,exposure_max,OV13850_EXPOSURE_STEP,mode->exp_def);// 第30-34行:创建"模拟增益"控制项(可调)// V4L2_CID_ANALOGUE_GAIN: 模拟增益控制项// OV13850_GAIN_MIN: 最小值(如1倍,对应寄存器值0x00)// OV13850_GAIN_MAX: 最大值(如16倍,对应寄存器值0xFF)// OV13850_GAIN_STEP: 步进值(如寄存器值增加1)// OV13850_GAIN_DEFAULT: 默认增益值ov13850->anal_gain=v4l2_ctrl_new_std(handler,&ov13850_ctrl_ops,V4L2_CID_ANALOGUE_GAIN,OV13850_GAIN_MIN,OV13850_GAIN_MAX,OV13850_GAIN_STEP,OV13850_GAIN_DEFAULT);// 第35-39行:创建"测试图案"控制项(菜单类型,可调)// V4L2_CID_TEST_PATTERN: 测试图案控制项// ARRAY_SIZE(ov13850_test_pattern_menu) - 1: 最大索引值(菜单项数-1)// 0: 最小索引值// 0: 默认索引值// ov13850_test_pattern_menu: 菜单字符串数组,如{"Disabled", "Color Bars", ...}ov13850->test_pattern=v4l2_ctrl_new_std_menu_items(handler,&ov13850_ctrl_ops,V4L2_CID_TEST_PATTERN,ARRAY_SIZE(ov13850_test_pattern_menu)-1,0,0,ov13850_test_pattern_menu);// 第40-45行:检查控制处理器是否有错误if(handler->error){ret=handler->error;// 获取错误码dev_err(&ov13850->client->dev,// 打印错误信息到内核日志"Failed to init controls(%d)\n",ret);gotoerr_free_handler;// 跳转到错误处理}// 第46行:将控制处理器关联到V4L2子设备// 这样用户空间就可以通过子设备节点访问这些控制项ov13850->subdev.ctrl_handler=handler;// 第47行:成功返回0return0;// 第49-53行:错误处理标签err_free_handler:// 释放控制处理器及其所有控制项v4l2_ctrl_handler_free(handler);// 第52行:返回错误码returnret;}//vm149c的对焦staticintvm149c_init_controls(structvm149c_device*dev_vcm){structv4l2_ctrl_handler*hdl=&dev_vcm->ctrls_vcm;conststructv4l2_ctrl_ops*ops=&vm149c_vcm_ctrl_ops;v4l2_ctrl_handler_init(hdl,1);v4l2_ctrl_new_std(hdl,ops,V4L2_CID_FOCUS_ABSOLUTE,0,VCMDRV_MAX_LOG,1,VCMDRV_MAX_LOG);if(hdl->error)dev_err(dev_vcm->sd.dev,"%s fail error: 0x%x\n",__func__,hdl->error);dev_vcm->sd.ctrl_handler=hdl;returnhdl->error;}

应用层使用对焦例子

  1. 命令行,对焦手动

    v4l2-ctl-d/dev/v4l-subdev3 --set-ctrlfocus_absolute=32这里为什么是3,是因为子设备注册时候的顺序是csi2,phy,ov13850,vm149c(从0开始这个刚好就是3)
  2. subdev设备文件

    intset_focus_absolute(intfd,intvalue){structv4l2_controlctrl;ctrl.id=V4L2_CID_FOCUS_ABSOLUTE;ctrl.value=value;if(ioctl(fd,VIDIOC_S_CTRL,&ctrl)<0){perror("set_focus_absolute failed");return-1;}printf("Focus set to %d\n",value);return0;}intmain(){// 打开子设备节点(通常是 /dev/v4l-subdevX 或 /dev/v4l2-sensor)// 打开VM149C设备节点(需要先确认正确的节点)intfd=open("/dev/v4l-subdev3",O_RDWR);if(fd<0){perror("Failed to open VM149C");return-1;}// 设置焦距(范围0-VCMDRV_MAX_LOG)set_focus_absolute(fd,0);close(fd);return0;}
http://www.jsqmd.com/news/1119554/

相关文章:

  • PCB阻抗设计实战:基于嘉立创480种叠层模板的4层板50Ω单端线宽计算
  • 在 Simulink 中搭建一个基于 Cuk 拓扑的双向主动均衡电路,并实现精准的闭环控制。
  • Rockchip RK3576芯片架构与AIoT应用解析
  • 5步掌握GmsCore:开源Play Services替代方案完全指南
  • AI 生成的文档如何导出?职场高效选 AI 导出鸭,多端适配轻松完成海量 AI 文档快速导出
  • Does Model Size Matter? A Comparison of Small and Large Language Models for Requirements Classifi...
  • 小学期学习——第五周
  • 小学期第一周学习笔记
  • OpenSpeedy终极指南:Windows游戏加速引擎的完整解析
  • 2024服务器应急响应实战:病毒木马排查与安全加固全流程
  • UVa 532 Dungeon Master
  • C++学习:类和对象
  • Deepseek-V4 vs Claude-Opus:编程场景下的工程直觉与语义理解实战对比
  • 游戏化编程学习:CodeCombat如何让你在冒险中掌握Python和JavaScript
  • 5分钟快速部署Coraza WAF:开源、高性能的Web应用防火墙实战指南
  • 品牌食品被指存在异物:三维协同证据体系构建
  • 终极指南:3分钟学会用E-Hentai Downloader免费下载漫画档案 [特殊字符]
  • 合同系统中关于合同文本的管理
  • AES加密图片全攻略:从原理到跨平台实战
  • Web安全核心攻击与防御:SQL注入、XSS、CSRF实战解析
  • NYC出租车数据分析终极指南:30亿行程数据的高效处理与智能分析
  • 第三周学习记录
  • Linux系统学习总串()(网络管理以及可能出现的问题处理)
  • Systemd和Systemctl的关系及相关理解
  • LangFlow 1.x 系列【4】首页侧边栏与用户菜单功能说明
  • 十倍利润!30美元成本的产品卖到300美元,论独立站选品的重要性
  • 小学期第八周
  • 终极E-Hentai漫画下载指南:免费开源工具完整教程
  • E-Hentai漫画收藏神器:一键打包下载全攻略
  • 如何让产品参与测试/验证