
简介这份资源面向嵌入式驱动开发与摄像头模组调试人员提供 JX-F23 图像传感器的驱动源码用于在目标平台上完成传感器识别、数据采集与视频流输出。传感器支持 1920×1080 分辨率、30FPS 帧率适用于实时监控、视频会议、运动摄影等高清视频场景驱动需兼顾兼容性、效率、稳定性与功耗管理。压缩包为 rar 格式共 6 个文件约 42KB包含 2 个 c 源文件、2 个 o 目标文件、1 个 h 头文件与 1 个 Makefile分别承担驱动逻辑实现、编译产物、寄存器与接口定义以及构建配置结构紧凑便于直接编译与移植。目前已有 387 人学习下载。读者可据此理解传感器驱动的初始化流程、寄存器配置与中断处理思路并借助 Makefile 快速搭建编译环境为二次开发与排错提供参考。1. JX-F23 sensor 驱动到底是个什么活从一颗 CMOS 到能出图的完整链路手里拿到一块标着 JX-F23 的模组上电以后 I2C 能扫到地址但 /dev 下就是不出 video 节点或者出了节点一抓图全是绿屏、花屏、卡在第一帧——这类场景基本就是 sensor 驱动没配对。JX-F23 属于 F23 系列的 CMOS sensor走的是标准 MIPI CSI-2 输出配套的 soi_f23 驱动包干的事就是把「上电时序、I2C 寄存器初始化、MIPI 通道配置、V4L2 子设备注册」这一整条链路用代码固定下来让内核能把它当成一个正常的摄像头子设备去枚举。它解决的不是「算法怎么调」而是「图从哪来」这个更底层的问题。适合谁做嵌入式视觉、RV1126B 这类国产 SoC 平台 bring-up 的驱动工程师以及需要把 F23 sensor 接进 Linux V4L2 框架、跑通 sensor 出图全流程的从业者。如果你只是想在应用层调个 OpenCV这份东西暂时用不上但只要涉及换 sensor、改分辨率、调曝光它就是绕不开的第一环。2. 拆开 soi_f23 驱动包文件结构、注册流程与设备树怎么对2.1 驱动包里的文件各自管什么拿到 soi_f23 这类驱动包先别急着 make先把目录结构过一遍心里有个「哪个文件改哪一层」的映射后面排错能省一半时间。常见做法是它按 Linux 内核驱动的标准分层来组织核心就三类文件驱动主体、寄存器表、设备树片段。文件/目录作用改动频率f23sensor.cV4L2 subdev 主体probe/remove、上电、流控低除非改框架f23sensor.h结构体、宏、寄存器地址定义中改分辨率常动f23_regs_*.h各分辨率/帧率的寄存器初始化序列高调参主战场*.dtsi设备树节点I2C 地址、GPIO、时钟、MIPI lane高换板必改Makefile/Kconfig编译进内核或编成模块低驱动主体的注册流程本质是把 sensor 挂到 V4L2 的异步匹配框架上。probe 里干的事按顺序是拿 GPIO 和 regulator、上电、复位、读 chip id 确认是不是 F23、注册 subdev、注册 media entity。任何一步失败probe 就返回错误/dev/videoX 就不会出现。所以「没节点」这个问题八成卡在 probe 的前几步而不是流控。2.2 设备树节点怎么写才对得上设备树是驱动和硬件之间的合同写错了驱动再对也白搭。JX-F23 挂在哪个 I2C 控制器下、复位脚接哪个 GPIO、MIPI 用几 lane、时钟给多少全在这里声明。下面是一个典型片段参数按你实际板子改i2c3 { status okay; clock-frequency 400000; /* F23 寄存器访问常用 400kHz */ f23: f2336 { compatible soi,f23sensor; /* 必须和驱动 of_match_table 一致 */ reg 0x36; /* 7bit I2C 地址常见 0x36/0x30 */ clocks cru CLK_MIPI_CAMARAOUT_M2; clock-names xvclk; power-domains power RK3588_PD_VI; pinctrl-names default; pinctrl-0 mipim0_camera2_clk; reset-gpios gpio1 RK_PB0 GPIO_ACTIVE_LOW; pwdn-gpios gpio1 RK_PB1 GPIO_ACTIVE_HIGH; port { f23_out: endpoint { remote-endpoint mipi_in; >obj-m f23sensor.o f23sensor-objs : f23sensor_main.o f23sensor_regs.o逻辑说明obj-m表示编成可加载模块f23sensor-objs把多个源文件合成一个模块目标。参数说明如果你的驱动只有一个 .c第二行可以省掉。编完insmod f23sensor.ko然后dmesg | tail看 probe 日志。常见做法是先确认i2cdetect -y 3能看到 0x36再 insmod顺序反了会误判成驱动问题。加载后ls /dev/video*应该多出节点v4l2-ctl --list-devices能看到 sensor 名字这一步过了才轮到抓图。3. 从 probe 到出图上电时序、I2C 寄存器与 MIPI 配置的实操3.1 上电时序为什么你的 sensor 读不到 IDF23 这类 CMOS 对上电顺序有要求典型是「先供 AVDD 模拟电再 DOVDD IO 电最后 DVDD 数字电」复位脚在电稳定后拉低再拉高中间要留毫秒级延时。顺序错了最直接的现象就是读 chip id 返回 0x00 或 0xFF。驱动里这段通常长这样static int f23_power_on(struct f23_priv *f23) { int ret; ret regulator_enable(f23-avdd); /* 模拟电先上 */ if (ret) return ret; usleep_range(1000, 1200); ret regulator_enable(f23-dovdd); /* IO 电 */ if (ret) return ret; usleep_range(1000, 1200); ret regulator_enable(f23-dvdd); /* 数字电最后 */ if (ret) return ret; usleep_range(5000, 6000); /* 等电彻底稳 */ gpiod_set_value_cansleep(f23-reset, 0); /* 拉低复位 */ usleep_range(1000, 1200); gpiod_set_value_cansleep(f23-reset, 1); /* 释放复位 */ usleep_range(10000, 12000); /* 等内部初始化 */ return 0; }逻辑说明三路电按 AVDD→DOVDD→DVDD 顺序开每步之间留延时复位在电稳之后操作。参数说明usleep_range的上下限别抠太死给足余量复位释放后的 10ms 是 sensor 内部 PLL 锁定的时间短了读 ID 会随机失败。这段是血泪经验——很多人把三路电一起开ID 时好时坏查半天以为是 I2C 问题其实是时序。3.2 I2C 寄存器初始化分辨率切换改哪里sensor 出图前要灌一整套寄存器序列把 PLL、MIPI 输出、曝光、增益、窗口都设好。F23 的寄存器是 16bit 地址 8bit 数据写序列一般放在f23_regs_*.h里按分辨率分文件。切换 1080p 和 720p本质是换一份序列static const struct regval f23_1080p_regs[] { {0x0103, 0x01}, /* soft reset */ {0x0100, 0x00}, /* stream off配置前必须停流 */ {0x36e9, 0x80}, /* PLL 相关按模组晶振改 */ {0x36ea, 0x0b}, {0x36eb, 0x0c}, {0x36ec, 0x0a}, /* ... 中间省略上百条窗口/时序寄存器 ... */ {0x0100, 0x01}, /* stream on */ }; static int f23_set_regs(struct f23_priv *f23, const struct regval *regs, u32 len) { u32 i; int ret; for (i 0; i len; i) { ret f23_write_reg(f23, regs[i].addr, regs[i].val); if (ret) { dev_err(f23-dev, write 0x%04x fail\n, regs[i].addr); return ret; } } return 0; }逻辑说明寄存器表按「软复位→停流→PLL→窗口→开流」的顺序排顺序不能乱尤其0x0100停流必须在改窗口之前。参数说明PLL 那几条0x36e9 附近和模组晶振频率强相关24MHz 和 27MHz 晶振的配置完全不同抄错就是无图或帧率不对。f23_write_reg内部一般走i2c_transfer失败要打日志别静默返回。3.3 MIPI 通道与 V4L2 流控抓图命令和预期结果寄存器配好、MIPI lane 对上以后用 v4l2-ctl 抓一帧验证# 列出 sensor 支持的分辨率 v4l2-ctl -d /dev/video0 --list-formats-ext # 设成 1080p、YUYV抓 10 帧存文件 v4l2-ctl -d /dev/video0 \ --set-fmt-videowidth1920,height1080,pixelformatYUYV \ --stream-mmap --stream-count10 \ --stream-tof23_1080p.raw # 看 raw 大小对不对1920*1080*2*10 ≈ 41MB ls -l f23_1080p.raw逻辑说明--list-formats-ext确认驱动上报的分辨率和你寄存器表一致--stream-mmap走内存映射抓流--stream-to落盘。参数说明raw 文件大小 宽×高×每像素字节×帧数对不上说明格式或分辨率没生效。常见做法是抓完用ffmpeg -f rawvideo -pix_fmt yuyv422 -s 1920x1080 -i f23_1080p.raw out.png转成图看内容绿屏多半是 MIPI 没锁或 lane 配错花屏多半是 PLL 或窗口寄存器错。4. 避坑与排查F23 驱动 bring-up 最常见的五个翻车点4.1 现象i2cdetect 扫不到 0x36原因上电时序不对或复位脚没释放或 I2C 地址被模组改成 0x30。解决先用万用表量三路电是否到位再确认复位脚电平最后i2cdetect -y 3全地址扫一遍看有没有别的地址冒出来。别一上来就怀疑驱动。4.2 现象probe 成功但 /dev/video 不出节点原因compatible和驱动of_match_table不一致或 media entity 注册失败。解决dmesg | grep f23看 probe 走到哪一步/sys/bus/i2c/devices/3-0036/下有没有 driver 软链。常见是 dtsi 里 compatible 写成了soi,f23而驱动里是soi,f23sensor。4.3 现象有节点抓图全绿或全黑原因MIPI lane 数配错或 link-frequencies 和 sensor 输出不匹配或 stream on 寄存器没写。解决先确认 dtsi 的>#define F23_PWR_DELAY_US 1000 #define F23_RESET_DELAY_US 10000 #define F23_STREAM_DELAY_US 5000第二chip id 读取做成 probe 的硬门槛读不到直接返回-ENODEV别让它带病注册否则后面抓图出问题你都不知道是 ID 没读对。第三寄存器表按「公共序列 分辨率差异序列」拆开公共部分软复位、PLL只维护一份改分辨率只动差异部分减少抄错。第四验证不只看能不能出图还要看连续抓 300 帧有没有丢帧、有没有 I2C 超时# 连续抓 300 帧同时盯内核日志 v4l2-ctl -d /dev/video0 --stream-mmap --stream-count300 \ --stream-to/dev/null dmesg -w | grep -i f23\|i2c.*timeout逻辑说明--stream-to/dev/null只跑流不落盘专测稳定性dmesg -w实时盯 I2C 超时和 MIPI 错误。参数说明300 帧大约 10 秒30fps够暴露大部分时序裕量问题。如果这中间出现i2c timeout多半是 I2C 速率 400kHz 在这块板子上跑不稳降到 100kHz 再试。还有一个容易被忽略的点曝光和增益的默认值。F23 出图全黑有时不是链路问题是默认曝光寄存器给太小环境光一暗就全黑。我习惯在初始化序列末尾给一组「室内可用」的曝光增益默认值再交给上层 3A 去调。从那以后我每次 bring-up 新 sensor都强制走一遍「量电→扫 I2C→读 ID→抓单帧→抓 300 帧」这五步少一步后面都要还债。希望帮到你。本文还有配套的精品资源点击获取