ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

XS9922视频解码器Linux驱动开发与V4L2调试全指南

XS9922视频解码器Linux驱动开发与V4L2调试全指南 简介面向嵌入式Linux驱动开发者的xs9922视频解码器驱动包适用于kernel 5.9环境解决主控通过MIPI CSI接口接收模拟高清/标清视频信号的问题。芯片完成模数转换、视频解码与2D图像处理后输出YCbCr支持HDCCTV高清协议和CVBS标清协议兼容720P/1080P及960H/D1制式。资源共3个文件压缩包仅17KB包含1个txt说明、1个寄存器配置头文件xs9922_reg_cfg.h和1个驱动源文件xs9922.ctxt文件用于说明编译与加载要点头文件定义寄存器映射C源文件实现解码器初始化和视频流控制逻辑。目前已有67人学习下载适合正在调试xs9922驱动或需要快速移植到kernel 5.9的开发者。通过阅读源码可以掌握芯片初始化流程、寄存器配置方法以及MIPI CSI接口的对接细节节省从数据手册从头编写驱动的时间。1. 谁在用 xs9922 视频解码器为什么驱动这么难调在车载环视、安防录像机这类设备里XS9922 视频解码器承担一个很明确的活把模拟摄像头输出的 CVBS 或模拟高清信号转成数字视频流通过 BT656 或 MIPI CSI-2 送进主控 SoC。也就是说CPU 不直接碰视频数据驱动只是通过 I2C 配置寄存器。可恰恰因为数据不经过 CPU链路一断你看到的就是黑屏、花屏或颜色错乱硬件可能并没有坏。驱动难调难在它不是一颗 SPI Flash 那样写几个寄存器完事的器件。你要同时处理上电时序、寄存器初始化、V4L2 格式协商、MIPI 通道匹配和帧中断任何一个环节掉链子输出就是花的。这篇沿着这条链讲清楚 XS9922 在 Linux 媒体框架里的挂载方式、初始化时序、格式协商以及五个高频踩坑点适合做 linux 驱动开发和平台接入的工程师照着排。2. XS9922 在 Linux 视频媒体框架里的挂载subdev、media 拓扑和三条通道老读者可能先入为主以为视频解码器驱动就是学习笔记里那种register_chrdev的字符设备驱动框架。实际不是。XS9922 是视频源要跟 SoC 内部的 CSI 接收控制器、ISP 串成一条媒体链路所以标准做法是写成 V4L2 subdev挂进 media controller 拓扑。用户态看到的是/dev/video0这个字符设备但它背后是一条由多个 kernel 实体串起来的流。2.1 三条通道I2C 控制、像素数据、逻辑 link 不能混为一谈动手写驱动前先把三件事分开。第一是 I2C 控制通道用来配置寄存器、读芯片 ID、查输入信号是否锁定数据量小挂在 i2c2 这类总线上。第二是像素数据通道XS9922 把解码后的视频流通过 BT656 并口或 MIPI CSI-2 多 lane 送到 SoC这条通道上每秒跑十几兆字节和 I2C 不在一个量级。第三是 V4L2 框架里的逻辑 link它描述的是“哪个实体的哪个 pad 把数据交给下游的哪个 pad”只存在于内核拓扑图里不是一根物理线。这三条通道经常被混淆。最常见的翻车是把 I2C 探测当作驱动工作的全部probe 能读到芯片 ID 就以为万事大吉结果流拉不起来因为像素通道的时钟、lane 映射没人配置。反过来也有同事在一个没有 MIPI 接口的板子上照着原厂参考代码移植I2C 一切正常图像永远出不来——因为 SoC 根本没有 CSI 接收单元。写代码前先对照原理图把这三条通道走通一遍能省下一整周的调试时间。通道类型物理介质驱动职责数据量I2C 控制I2C 总线寄存器读写、状态查询小每次几个字节像素数据BT656 并口或 MIPI CSI-2时钟、lane、格式匹配大每帧数百 KB逻辑 linkmedia 拓扑定义 entity/pad/link 关系无数据传输2.2 media-ctl 看拓扑先确认解码器挂在哪、接到谁框架搭好之后第一步验证不是看 dmesg 里 probe 成功没有而是用 media-ctl 把拓扑打出来。下面几条 linux 常用命令在调试阶段要反复用v4l2-ctl --list-devices media-ctl -d /dev/media0 -pv4l2-ctl --list-devices告诉你板子上有几个 video 节点media-ctl -p打印整个媒体拓扑。正常的拓扑里应该能看到 XS9922 作为一个 entity 出现pad0 是 Source下游接着 CSI 接收器或者 ISP。如果media-ctl -p里根本没有 XS9922 这个实体说明 subdev 注册失败了优先查v4l2_i2c_subdev_init和media_entity_pads_init的调用路径。拓扑里还要留意 link 状态。打印结果里每个 link 后面会标[ENABLED]或[DISABLED]。旧的 SoC 平台需要显式把解码器和 CSI 之间的 link 打开命令是media-ctl -d /dev/media0 -l xs9922:0-csi2-rx:0[1]方括号里的1表示 enable0表示 disable。很多驱动在 probe 里注册了实体但没建 link或者 link 被固件默认关掉拉流就永远超时。把这条命令加进开机脚本或者驱动初始化流程能让链路状态可复现。2.3 典型链路里的挂载顺序解码器 → CSI RX → videoX以常见 SoC 的 CSI-2 接收方案为例完整的媒体链路长这样XS9922 的 pad0 作为源接到 CSI 接收控制器的 sink padCSI 控制器内部可能还有多个 virtual channel每个 vc 映射一个 video 设备节点。换句话说/dev/video0不是 XS9922 直接暴露的设备而是它下游经过 CSI 之后的采集节点。这个层级关系决定了驱动的架构XS9922 只管把自己这侧的格式、时钟、输出配置好真正把数据搬进内存的是 CSI 控制器对应的驱动。所以你经常看到一个现象——解码器这边s_stream(1)已经返回成功但/dev/video0拉流还是没数据问题大概率出在 CSI 侧的 virtual channel 或 lane 分配上。有些 SoC 会把 CSI 接收器实现成独立的 platform_driver通过 device tree 里的remote-endpoint属性关联到解码器节点。此时 XS9922 驱动里需要做的就是在开机初始化时找到 endpoint 对面的 csi 驱动句柄把它封装成csi_ops结构体存放等s_stream时再调用。这样做的原因是把平台相关逻辑隔离在解码器驱动之外换 SoC 时只换 endpoint 绑定不重写解码逻辑。提示如果板子是并口 BT656 接入而非 MIPI媒体链路里往往没有 csi2-rx 实体XS9922 直接连到 ISP 或直接到视频采集模块。拓扑不一样挂载方式跟着变先看media-ctl -p实际打印结果再改代码。3. 从设备树到 probe 成功上电时序、寄存器初始化与 ID 探测这一章解决“让解码器活过来”。很多移植失败的案例不是代码写错而是上电时序和寄存器访问顺序不对。XS9922 这类模拟视频解码器内部有 PLL、ADC 和色度解码模块供电乱了或者晶振没起稳就访问寄存器读到的是随机值之后所有配置都是白写。3.1 上电时序电源、复位脚和晶振的顺序不能靠猜常见接入方式是解码器挂在某个 I2C 控制器下复位脚接一个 GPIO参考时钟由 SoC 提供。设备树里至少要表达出这几层关系i2c2 { status okay; clock-frequency 400000; xs9922: video-decoder48 { compatible vendor,xs9922; /* 按平台实际填写 */ reg 0x48; /* 7bit 地址,以原理图为准 */ reset-gpios gpio1 15 GPIO_ACTIVE_LOW; pinctrl-names default; pinctrl-0 xs9922_pinctrl; mclk-frequency 24000000; /* 24MHz 参考时钟常见,以手册为准 */ vdd-supply reg_3v3; }; };注意reg 0x48是 7bit 地址。内核 i2c 子系统在发起传输时会把地址左移一位变成 8bit 写地址你自己的驱动、i2cdetect 扫描、芯片手册三方必须用同一套口径否则会出现“手册上明明是这个地址就是探测不到”的怪事。建议先跑一遍i2cdetect -y 2看看总线上有没有设备再对照原理图确认。上电顺序上我的习惯是先给电源域供电复位脚保持有效低电平至少 10ms等晶振输出稳定后再释放复位。释放复位之后不要立刻写业务寄存器给芯片 20ms 左右让内部 PLL 锁定。这个等待时间用usleep_range实现驱动里最怕的是mdelay那种忙等把系统调度卡死。static int xs9922_power_on(struct xs9922_dev *xs) { /* 复位脚已经由 pinctrl 配置为输出,低电平复位 */ gpiod_set_value_cansleep(xs-reset_gpio, 1); msleep(20); /* 释放复位,等内部 PLL 建立,读取 ID 之前必须完成这一步 */ gpiod_set_value_cansleep(xs-reset_gpio, 0); usleep_range(20000, 50000); return 0; }这里的 20ms 和 20~50ms 是经验值具体以手册里的上电时序表为准。移植到量产的板子时我建议把这段时序用示波器抓一遍确认复位下降沿和 I2C 首次访问之间确实留够了时间。3.2 初始化寄存器表read-modify-write别整段覆盖视频解码器的寄存器初始化常见做法是先拿原厂参考代码里的寄存器表再按实际板子裁掉用不到的通道。这张表通常包含几十组“寄存器地址 配置值”。直接把整表顺序写入的写法看着省事但有个隐患同一颗寄存器里往往同时放着功能使能位、格式选择位和状态标志位你写一个值进去可能把别的位盖掉。比较规范的实现是先定一组寄存器读写接口再提供一个 update 函数做 read-modify-writestatic const struct regmap_config xs9922_regmap_cfg { .reg_bits 8, .val_bits 8, .max_register 0xff, }; static int xs9922_read(struct xs9922_dev *xs, u8 reg, u8 *val) { unsigned int tmp; int ret regmap_read(xs-regmap, reg, tmp); if (!ret) *val (u8)tmp; return ret; } static int xs9922_update_bits(struct xs9922_dev *xs, u8 reg, u8 mask, u8 val) { unsigned int cur; int ret; ret regmap_read(xs-regmap, reg, cur); if (ret) return ret; return regmap_write(xs-regmap, reg, (cur ~mask) | (val mask)); }初始化函数里每个功能模块用一个独立 mask 操作static int xs9922_hw_init(struct xs9922_dev *xs) { /* 1. 复位视频内核,等待内部逻辑就绪 */ xs9922_update_bits(xs, XS9922_REG_SYS, BIT(0), BIT(0)); usleep_range(10000, 20000); xs9922_update_bits(xs, XS9922_REG_SYS, BIT(0), 0); usleep_range(1000, 2000); /* 2. 打开输入自动检测,让芯片自己识别 CVBS 或模拟高清信号 */ xs9922_update_bits(xs, XS9922_REG_AUTODET, 0x03, 0x03); usleep_range(50000, 60000); /* 3. 配置输出口径:BT656 8bit,逐行输出 */ xs9922_update_bits(xs, XS9922_REG_OUTFMT, 0x07, BT656_PROGRESSIVE); return 0; }代码里XS9922_REG_SYS、XS9922_REG_AUTODET这些宏定义在xs9922_regs.h地址值从手册寄存器表里抄。不同批次手册对寄存器命名可能不一样看到XDCR_AUTODET、VOUT_FMT这类命名不要慌按 bit 描述和手册里的默认值对照填。初始化完成后把关键寄存器读回来打印一次确认写进去的值没有被芯片内部逻辑改掉——这一步能提前暴露地址错位问题。3.3 probe 里做四件事建 regmap、读 ID、注册 subdev、设 padprobe 函数是驱动的地基。XS9922 这类 I2C subdev 的 probe我的写法是固定四步走。先分配私有数据结构再初始化 regmap然后读芯片 ID最后注册 V4L2 subdev 和 media pad。缺一步后面都会在奇怪的地方炸。static int xs9922_probe(struct i2c_client *client) { struct xs9922_dev *xs; unsigned int chip_id; int ret; xs devm_kzalloc(client-dev, sizeof(*xs), GFP_KERNEL); if (!xs) return -ENOMEM; xs-client client; i2c_set_clientdata(client, xs); /* regmap 接管所有寄存器访问,出错返回负 errno */ xs-regmap devm_regmap_init_i2c(client, xs9922_regmap_cfg); if (IS_ERR(xs-regmap)) return PTR_ERR(xs-regmap); /* 先读 ID 再往下走,读不到一定是地址或上电问题 */ ret regmap_read(xs-regmap, XS9922_REG_CHIP_ID, chip_id); if (ret || chip_id ! XS9922_CHIP_ID) { dev_err(client-dev, chip id mismatch, expect 0x%02x, got 0x%02x\n, XS9922_CHIP_ID, chip_id); return -ENODEV; } xs9922_power_on(xs); xs9922_hw_init(xs); /* V4L2 subdev 初始化,ops 绑定到 s_stream/get_fmt 等回调 */ v4l2_i2c_subdev_init(xs-sd, client, xs9922_subdev_ops); xs-sd.flags | V4L2_SUBDEV_FL_HAS_DEVNODE; /* 这个 entity 在媒体拓扑里的角色是一个视频桥接/接口器件 */ xs-sd.entity.function MEDIA_ENT_F_VID_IF_BRIDGE; xs-sd.entity.ops xs9922_entity_ops; xs-pads[0].flags MEDIA_PAD_FL_SOURCE; ret media_entity_pads_init(xs-sd.entity, 1, xs-pads); if (ret) return ret; return 0; }这段代码里有几个参数值得说明。devm_regmap_init_i2c注册的 regmap 配置里max_register 0xff意味着访问地址超过 255 的寄存器会直接返回错误这是对芯片寄存器空间边界的兜底。V4L2_SUBDEV_FL_HAS_DEVNODE标志决定该 subdev 是否创建独立的/dev/v4l-subdevX设备节点调试时建议打开量产时如果不需要可以通过 media controller 配置可以去掉。MEDIA_ENT_F_VID_IF_BRIDGE表示这个实体是视频接口转换器件比默认的 UNKNOWN 更容易在拓扑里一眼看懂。新版内核里subdev 初始化后通常还要调v4l2_subdev_init_finish它会完成 state 相关的初始化。不同内核版本的接口有差异编译不过时先看头文件里的函数原型这个属于常规适配工作。probe 到这里还没完还需要在 remove、runtime PM 和电源管理回调里补对称的释放逻辑这部分代码量不大但漏了会在休眠唤醒后出现“图像没了”的怪问题。4. 让图像流起来V4L2 格式协商、s_stream 和最小拉流命令初始化完成、probe 成功只能说明解码器已经能通过 I2C 控制。接下来要让数据真正流动。V4L2 的流程是用户态先 set format再 stream on中间会触发驱动里的s_stream回调。这一章的每个环节都直接影响出图质量。4.1 格式协商BT656 输出的 mbus code 该怎么定XS9922 走 BT656 输出时把 8bit 数据线上的像素按 Y、U、Y、V 顺序发送。内核里对应的总线格式不是YUYV这种单个像素的格式而是要区分MEDIA_BUS_FMT_UYVY8_2X8和MEDIA_BUS_FMT_YUYV8_2X8。2X8表示一个时钟周期内的两个 8bit 值连起来构成一个像素。选错这个格式画面颜色会整体偏掉这在后面的避坑章节还会展开。get_fmt回调要如实上报当前输出端的格式。解码器在自动检测到输入制式后会把宽高和场信息更新到内部变量里get_fmt直接返回这些值static int xs9922_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct xs9922_dev *xs v4l2_get_subdevdata(sd); fmt-format.width xs-cur_width; fmt-format.height xs-cur_height; fmt-format.code MEDIA_BUS_FMT_UYVY8_2X8; fmt-format.field V4L2_FIELD_NONE; /* 已去隔行则用 NONE,否则 ALTERNATE */ return 0; }field参数特别值得较真。CVBS 原始信号是隔行的如果芯片内部没有去隔行电路驱动应上报V4L2_FIELD_ALTERNATE让后级 ISP 或应用层去做去隔行。硬要上报V4L2_FIELD_NONE拿到的数据会被 SoC 当成逐行读帧率看起来对但画面横向拉丝。这个判断要看手册里输出模块的说明别想当然。4.2 s_stream 回调开流时到底要开些什么v4l2-ctl --stream-mmap触发 stream on 后内核会一路把调用传到 XS9922 的s_stream。很多人把这个回调写成一个输出使能 bit写完了事。实际正确的开流顺序是先让下游 CSI 接收端做好接收准备再让解码器往外吐数据。static int xs9922_s_stream(struct v4l2_subdev *sd, int enable) { struct xs9922_dev *xs v4l2_get_subdevdata(sd); int ret; if (!enable) { /* 先停芯片输出,再关接收端时钟,顺序反了底下会有残留帧 */ xs9922_update_bits(xs, XS9922_REG_OUT, BIT(0), 0); if (xs-csi_ops) xs-csi_ops-disable(xs-csi_priv); return 0; } /* CSI RX 先起来,时钟 lane 就绪,再让解码器吐数据 */ ret xs-csi_ops-enable(xs-csi_priv, xs-fmt); if (ret) return ret; usleep_range(10000, 20000); /* 等 D-PHY 时钟稳定 */ return xs9922_update_bits(xs, XS9922_REG_OUT, BIT(0), BIT(0)); }这里csi_ops是平台相关的封装通常在 probe 里根据设备树 endpoint 找到下游驱动后赋值。它内部做的是配置 CSI lane 数、虚拟通道、时钟极性这些硬件相关参数。enable里有一个隐藏细节CSI 接收端配置的时钟极性和数据格式必须和解码器输出侧一致否则后面读到的帧校验永远是错的。停流时建议保持一个固定习惯先停发送端再停接收端。反过来做CSI 接收端在等待数据时被关闭可能导致 DMA 停在半空下次开流时 buffer 状态不对出现第一帧花屏。4.3 最小拉流命令v4l2-ctl 出图GStreamer 播放驱动写完不看图等于没写。最小验证先走 v4l2-ctlv4l2-ctl -d /dev/video0 --list-formats-ext v4l2-ctl -d /dev/video0 --set-fmt-videowidth720,height576,pixelformatUYVY v4l2-ctl -d /dev/video0 --stream-mmap --stream-count60 --stream-to/tmp/cap.yuv第一条命令列出驱动支持的格式比对s_format上报的宽高和像素格式是否一致。第二条手动指定采集格式第三条抓 60 帧到文件。抓出来的/tmp/cap.yuv是裸 YUV 数据没有容器头直接用播放器打开时要手动指定宽高和格式。要实时看效果就用 GStreamer 拉一个最小管道gst-launch-1.0 v4l2src device/dev/video0 ! video/x-raw,formatUYVY,width720,height576,framerate25/1 ! videoconvert ! autovideosink这个管道的formatUYVY必须和驱动上报的像素格式一致否则 GStreamer 会报 caps 协商失败。videoconvert负责把所有格式转到显示需要的 RGB 空间它对调试阶段足够用量产时建议换成 SoC 厂商自带的硬件转换插件减少 CPU 占用。第一次跑这个管道如果黑屏把日志级别拉高再看GST_DEBUG3 gst-launch-1.0 ...日志里如果有not-linked说明 caps 没匹配上有no buffer或timeout说明驱动侧压根没出帧回上一节查 s_stream 链路。5. 驱动调试避坑黑屏、花屏、颜色不对的五类排查真正磨时间的是调试点。这里把高频问题按“现象 → 原因 → 解决”列清楚都是实际调 XS9922 这类解码器驱动的血泪经验。5.1 现象一probe 成功但等不到帧中断现象内核里能看到 XS9922 注册成功v4l2-ctl --stream-count1一直等到超时没有帧中断上报。原因数据通道没通。最常见是 MIPI virtual channel 没对上。解码器输出走 vc0而 SoC 的 CSI 接收控制器监听 vc1两边各说各话。其次是时钟 lane 极性问题D-PHY 的 DDR 时钟采样沿配反了。解决先查 CSI 控制器侧的调试寄存器确认 lane 有没有进入 HS 状态是否有 data lane 数据。然后在 CSI 驱动里把 virtual channel 参数改成和解码器输出一致或者让解码器端改 vc0。时钟极性问题在 CSI 控制器配置里翻转 clock lane 的极性再试。注意多数 SoC 的 CSI 驱动把时钟极性默认设为某个固定值不会自动跟随上游。改这个参数时留意 CSI 驱动代码里的注释。5.2 现象二花屏拉丝像被切成两半现象图像能出来但整体横向错开像两个半场拼到一帧里或者有规则的斜纹。原因隔行场被当成逐行读。CVBS 信号分奇偶场解码器如果输出隔行场而驱动上报V4L2_FIELD_NONESoC 会把两场交错读成一帧画面就拉丝。解决先查解码器手册里输出模块是否内置去隔行。有去隔行确认对应 bit 置位后上报V4L2_FIELD_NONE没有去隔行把get_fmt里的 field 改成V4L2_FIELD_ALTERNATE让后级 ISP 或应用层处理。另外一个隐蔽原因PAL/NTSC 制式变了宽高不对也会产生类似拉丝。把自动检测到的制式通过寄存器读出来和输入信号源比对。5.3 现象三颜色偏绿发紫红色蓝色互换现象画面内容清晰但颜色完全不对常见是绿色变多、紫色色调人脸变成青面。原因UYVY 和 YUYV 字节序反了。解码器输出的是 Cb Y Cr Y 顺序CSI 接收端按 Y Cb Y Cr 解读UV 分量全部对调色相自然错乱。解决把 V4L2 像素格式从V4L2_PIX_FMT_UYVY改成V4L2_PIX_FMT_YUYV或者反过来看哪边颜色正常用哪边。注意设备树里 CSI 侧也可能有格式配置两边要一起改。还有一个低频原因通道亮度信号对比度寄存器被助理手改过颜色饱和度和色相同时漂移。遇到这种就做一次关键寄存器读回对比排除之前初始化表覆盖错位。5.4 现象四v4l2-ctl 拉流出错-EPIPE / 超时现象v4l2-ctl --stream-mmap报EPIPE或者 ioctl 超时dmesg 里 vb2 queue 报错。原因格式协商没打通。比如 XS9922 上报 720x576但中间 CSI 模块只支持到某个裁剪区间或者用户态显式设置了不同分辨率。另一个常见原因是 vb2 buffer 数量太少DMA 还没来得及搬运queue 就满了。解决先比对整条拓扑上每个 entity 的格式是否一致用media-ctl -p看链路各端点打印的格式。buffer 数量可以在调用VIDIOC_REQBUFS时请求 4 个或更多v4l2-ctl 默认数量有时在带宽不足时撑不住。如果是 DMA 超时查中断号有没有注册、dmesg 里是否有 pending 中断残留。5.5 现象五寄存器写不进、读出来 0xFF现象probe 阶段读 chip ID 失败或者寄存器读回全是 0xFFI2C 传输返回成功但值不对。原因先排除地址口径问题。手册给 8bit 地址 0x90设备树里写的却是 0x90内核左移一位后实际访问 0x120超出 7bit 寻址范围。这个坑在国产芯片的资料里尤其常见。另一个原因是解码器电源域没起来芯片根本没上电I2C 总线上的设备表现为读回 0xFF。解决用i2cdetect -y 总线号扫描看设备出现在哪个地址。设备树 reg 一律写 7bit 地址手册给 8bit 就把最高位去掉再除以 2。电源问题用电压表量解码器电源引脚确认上电时序代码真的被执行了而不是被哪个 initcall 顺序绕过。6. 验收 XS9922 驱动用彩条信号源和帧率统计说话6.1 准备一个标准彩条源先把制式、颜色、场序一次测完调驱动到最后阶段别拿真实摄像头瞎试。我习惯准备一台能输出标准彩条和测试图的信号源HDMI 转 CVBS 的转换盒子也行关键是要能稳定切 PAL/NTSC 制式、能出 100% 彩条。接上之后先确认解码器自动检测到正确制式再读信号锁定状态寄存器最后拉流看画面。彩条的作用是让颜色偏差一目了然白平衡一偏马上能看出来。6.2 用帧率与丢帧统计确认驱动能上线出图只是及格要上线还要看帧率。用 v4l2-ctl 抓 300 帧并计时time v4l2-ctl -d /dev/video0 --stream-mmap --stream-count300 --stream-to/dev/null300 帧耗时除以帧数就是实际帧率。PAL 源按 25fps 算NTSC 按 30fps 算偏差超过 2% 就要查时钟配置。丢帧统计没有统一 sysfs 接口时可以连续抓两段相同时长的流对比帧数是否一致。驱动里也可以在vb2_ops的buf_queue回调里加一个计数打印跑完一轮看两次计数差值这个习惯能救你很多时候。我现在的习惯是每次交付 XS9922 驱动都先跑一遍 300 帧计时再盯着屏幕看 10 分钟动态画面确认没有偶发花屏才敢说驱动能用。这条一次都不省的流程帮我挡过不少潜伏问题。希望帮到你。本文还有配套的精品资源点击获取
返回列表