Jetson平台GMLS2全局快门相机驱动安装与设备树实战指南 简介面向英伟达Jetson开发板上的GMSL2相机接入需求这份资源提供了一套基于ROS的驱动配置工作空间适合嵌入式视觉开发者与自动驾驶研究人员。它围绕GMSL2高带宽、低延迟接口的特性涵盖环境准备、驱动编译、参数配置与话题数据流验证等环节可帮助用户快速完成相机驱动在Jetson环境下的安装与调试。包体以7z格式分发共281个文件、约104KB文件以catkin构建体系的cmake/make脚本为主辅以sh/bash执行脚本、Python与C源码含my_publisher、my_subscriber示例节点、launch启动文件及xml/pc等配置结构完整便于直接复用与二次开发。已有1584人学习。通过这套资源读者可掌握GMSL2相机驱动的编译安装流程理解ROS工作空间的目录组织与依赖管理并获得可运行的示例节点用于图像数据流测试为后续目标检测、SLAM等应用集成奠定基础。1. Jetson GMLS2 相机驱动的安装第一步就卡在版本选择上这块 GMLS2 全局快门相机模组在我把 Jetson GMLS2 相机驱动装上之前一度让我以为是模组本身坏了接上 Orin NX 的 CSI 口之后 /dev/video0 根本没出现dmesg 里连续刷 I2C 超时和 probe failed。后来把驱动源码的 Makefile 和板子当前内核号对了一遍才发现模块是用旧版本内核构建树编出来的跟当前内核的 vermagic 对不上insmod 直接被拒。这类问题在 Jetson 相机方案里几乎人人都会撞见因为平台把内核、设备树、sensor 驱动三层绑得很死任何一层错位后面全是白忙。Jetson 的相机栈不像普通 PC 上插个 UVC 摄像头那样即插即用。GMLS2 这类全局快门模组走的是 CSI-2 接口驱动是一个内核态的 V4L2 subdev 模块从 JetPack 4.x 到 6.x内核从 4.9 换到 5.10 再到 5.15驱动必须跟着重新编译设备树也要重新适配。装不好最典型的表现就是设备节点不出现、取流黑屏、触发模式不出图而这些坑八成都不是相机坏了是环境与源码错配。下面这套流程是我实际跑通的顺序先把环境编号确认清楚再装内核头、编译驱动模块、改设备树 overlay中间穿插五个高频翻车现场的排查方法最后用一套三连测命令验证驱动真正能用。适合正在给 Jetson 接 CSI 相机的开发者尤其是第一次做全局快门模组方案的照着走可以少交不少学费。2. 装驱动前先定环境JetPack 版本、内核头文件和 CSI 口的对应关系2.1 先看 L4T 版本和内核号别让驱动源码搭错车GMLS2 驱动是内核模块它跟 L4TLinux for Tegra也就是 JetPack 的底座系统版本绑定得很死。JetPack 4.6、5.x、6.x 背后分别是 32.x、35.x、36.x 三个大版本的 L4T内核号从 4.9 跳到 5.10 再跳到 5.15。驱动源码只要在其中一个环境里编译过换到另一个环境基本必挂这不是代码逻辑问题是内核构建树不匹配。拿到板子第一件事不是解压驱动源码而是把当前环境编号记下来三条命令就能定位cat /etc/nv_tegra_release # 第一行输出就是 L4T 版本例如 R35.2.1 (aarch64) dpkg -l | grep -i jetpack # 查看已安装的 JetPack 组件版本 uname -r # 当前内核版本号第一行输出类似# R35.2.1 (aarch64)这样的编号这个编号后面找内核头、对驱动源码全靠它。uname -r输出的是内核完整版本比如5.10.104-tegra注意结尾那个-tegra后缀不能丢这是 Jetson 定制内核的标志普通 Linux 的 5.10 头文件编出来的模块在 Jetson 上一样会被拒。常见版本对应关系如下自己对照手头的板子JetPackL4T内核说明4.6.x32.7.x4.9老 Nano / Xavier 常用设备树写法偏旧5.0.x35.1.x5.10建议新项目不要选这个版本5.1.x35.2.x / 35.3.x5.10Orin NX / Orin Nano 主环境本文按此展开6.x36.x5.15相机框架变化大老驱动需要较大适配为什么小版本也要对死因为内核模块加载时校验 vermagic只有uname -r完全一致才放行。L4T 35.2.1 和 35.3.1 都是 5.10 内核但内核修订版和配置不同编出来的模块带不同元数据insmod 照样报 Invalid module format。我一般会把版本号写在纸条上贴在板卡散热片上这个习惯救过我两次。顺带把板卡型号也确认一下后面写设备树要用cat /sys/firmware/devicetree/base/modelOrin NX、Orin Nano、Xavier NX 的 CSI 控制器和 I2C 总线编号不一样设备树 compatible 也不同。输出类似NVIDIA Orin NX Developer Kit或NVIDIA Orin Nano 8GB记下来就行。2.2 安装内核头文件没有它GMLS2 驱动连编译都过不去内核模块编译需要内核头文件加完整构建树也就是/usr/src/linux-headers-$(uname -r)这个目录里面要有.config、Makefile、include目录。很多第一次编驱动的人卡在make: 在目录 /lib/modules/.../build 下没有可执行文件就是因为头文件没装或者 build 符号链接断了。Jetson 上装头文件最省事的就是 aptsudo apt update sudo apt install linux-headers-$(uname -r) ls -l /lib/modules/$(uname -r)/build/lib/modules/$(uname -r)/build是一个符号链接指向/usr/src/下对应的头文件目录。刷完系统后这条链接有时候是断的需要手动补sudo ln -s /usr/src/linux-headers-$(uname -r) /lib/modules/$(uname -r)/build如果 apt 源里找不到对应版本的头文件常见做法是把对应 L4T 的 BSP 包解压取出 kernel devel 部分或者直接用 SDK 重刷一次镜像让 apt 源带上配套 headers。我一般优先选重刷镜像因为只补头文件不补内核后续编出来的模块跟板子上的固件版本还是有细微对不上的风险。装完头文件后检查一下内核配置里跟 sensor 驱动相关的开关是否打开zcat /proc/config.gz | grep -E CONFIG_MODVERSIONS|CONFIG_VIDEO_V4L2CONFIG_MODVERSIONSy时内核符号表校验很严格头文件任何一点错位都会编出模块但加载时报 Unknown symbol这其实是好事能快速暴露错配问题。如果CONFIG_VIDEO_V4L2不是 y 或 m后面的 subdev 框架根本编不过去这种情况我只遇到过两次都是镜像本身被裁剪过重刷镜像解决。另外建议直接在板子上原生编译不要一上来就搞交叉编译。Jetson 板子编一个 sensor 驱动最多一两分钟交叉编译还得配 arm64 工具链反而引入更多版本匹配变量。除非板子完全没网络且手里只有 x86 机器否则不要走交叉编译这条绕路。2.3 确认 CSI 口和 I2C 地址硬件接错是最大的隐形坑软件环境定了再来处理物理连接。GMLS2 模组从包装拿出来第一件事是确认软排线方向。Orin NX 的 CSI 接口有 A/B 两组每组若干条 lane软排线金色触点方向接反表面看着插进去了实际上 lane 全错位后面取流全黑都算轻的。软件层先确认 I2C 总线。CSI 相机通常挂在靠近 CSI 连接器的那条 I2C 上先扫一遍全部总线sudo i2cdetect -l sudo i2cdetect -y -r 0 sudo i2cdetect -y -r 7 sudo i2cdetect -y -r 30i2cdetect -l列出所有 I2C 总线编号-y跳过交互确认-r用 SMBus read 方式探测。很多 sensor 只响应读命令不加-r会漏检这是排查时最容易漏掉的细节。Orin NX 上相机 I2C 一般在 bus 7 或 bus 30 附近具体以板卡原理图为准不同载板差异很大别只盯着一个总线号。GMLS2 模组的 I2C 地址我手上这块丝印标 0x1a同一系列也有 0x10 或 0x1b 的变体以模组丝印或 datasheet 为准。注意设备树里reg写的是 7bit 地址i2cdetect 显示的也是 7bit不要在八位地址换算上把自己绕进去——0x1a 就是 0x1a不是 0x35。这类换算问题在资料里很常见遇到就头疼一次。提示i2cdetect 在预期地址上全是--时优先检查模组供电和复位引脚而不是反复换驱动源码。硬件没点亮软件层做再多也是白搭。3. 编译 GMLS2 驱动模块源码结构、Makefile 修改与 insmod 加载3.1 解包驱动源码先弄清 gmls2.c 和 Makefile 各自管什么拿到驱动包后先解压别急着 make花两分钟看清里面是什么tar xzf gmls2-jetson-driver.tar.gz cd gmls2-jetson-driver find . -maxdepth 2 -type f | sort解出来通常是这几个文件文件作用gmls2_core.cV4L2 subdev 驱动主体含 probe 和 sensor 初始化流程gmls2_mode.c各分辨率对应的 mode0/mode1 时序参数gmls2.h寄存器地址宏定义和私有结构体gmls2.dts设备树 overlay 源文件Makefile外挂模块构建脚本README版本对应表和安装顺序说明gmls2_core.c里有一个static const struct of_device_id gmls2_of_match[]里面写的 compatible 字符串就是设备树要匹配的关键。例如compatible gmls2-sensor设备树节点里的 compatible 必须和它一个字符都不差这是整个安装流程里最容易被忽略的关联点。README 里通常会写明这个驱动适配的 L4T 版本先拿它和你 2.1 节记下来的编号对一下。gmls2_mode.c里的 mode 表是驱动真正干活的部分每个 mode 定义了一组分辨率和帧率。如果以后要改输出分辨率改的是这个文件加设备树里的 mode 节点而不是核心逻辑。先把源码结构看清后面排错才知道去哪一层找问题。3.2 修改 Makefile 的三个关键变量然后编译出 gmls2.ko驱动包自带的 Makefile 通常长这样关键变量就几个GMLS2_VERSION ? 1.0.0 KERNEL_DIR ? /lib/modules/$(shell uname -r)/build PWD : $(shell pwd) obj-m : gmls2.o gmls2-objs : gmls2_core.o gmls2_mode.o ccflags-y -DPLATFORM_TEGRA all: $(MAKE) -C $(KERNEL_DIR) M$(PWD) modules clean: $(MAKE) -C $(KERNEL_DIR) M$(PWD) clean install: sudo make -C $(KERNEL_DIR) M$(PWD) modules_install sudo depmod -aKERNEL_DIR决定用哪套内核构建树只要 2.2 节/lib/modules/$(uname -r)/build符号链接正常默认值就不用改。obj-m : gmls2.o加上gmls2-objs两行意思是把两个源文件合成一个 gmls2.ko新手最容易在这里把 gmls2_core.c 也单独编成一个模块那样 insmod 顺序就乱了。ccflags-y里的-DPLATFORM_TEGRA是宏开关很多 Jetson sensor 驱动靠它决定是否走 tegra-camera-platform 框架路径删掉后功能会不完整。然后就是编译make clean make ls -l gmls2.ko modinfo gmls2.ko | grep vermagic uname -r编译输出会看到CC [M] gmls2_core.o、LD [M] gmls2.ko等字样。编完后两条命令对比 vermagic这个值必须和你板子上的uname -r一致。不一致就回到 2.2 重装头文件从零再编一遍不要试图手动改模块元数据。还有一个小细节驱动包如果在 Windows 下解压过Makefile 的行尾可能是 CRLFmake 会报missing separator这种看不懂的错误。遇到就sed -i s/\r$// Makefile *.c *.h转一遍格式这是我从别人那里接手的驱动包最常见的隐藏炸弹。3.3 加载驱动模块并看 dmesg根据 probe 日志判断进没进对路径编译出 gmls2.ko 后先手动加载确认能绑定到设备再配置开机自启sudo insmod gmls2.ko lsmod | grep gmls2 dmesg | tail -n 40如果驱动和硬件都在正常状态dmesg 里应该能看到类似gmls2 0-001a: Detected GMLS2 sensor, id0x...这样的 probe 成功日志然后lsmod里出现一行gmls2。如果看到Failed to read sensor id基本是 I2C 地址或供电问题回到 2.3 的 i2cdetect 排查。如果看到Unknown symbol是内核头错配回到 2.2。如果 dmesg 里什么相关日志都没有说明驱动根本没找到要绑定的设备树节点问题在下一章的 overlay而不是模块本身。确定能正常加载后配置成开机自动加载sudo depmod -a echo gmls2 | sudo tee /etc/modules-load.d/gmls2.confdepmod -a生成模块依赖表让 modprobe 能按名找到 gmls2.ko。/etc/modules-load.d/gmls2.conf里的模块名会在开机时由 systemd 自动加载。如果重启后发现lsmod | grep gmls2为空先检查这个配置文件有没有被系统服务读取systemctl status systemd-modules-load可以看到加载日志。4. 设备树才是驱动能被认出的前提overlay 编写、dtc 编译与替换4.1 在 dts 里给 GMLS2 补一个 sensor 节点参数逐个对着填insmod 成功只是第一步sensor 要能被 tegra-camera 框架识别设备树里必须挂一个 I2C 子节点外加 tegra-camera-platform 的 module 描述。否则驱动 probe 时根本找不到要绑定的设备连报错日志都不会有。我见过有人在这步反复折腾 insmod其实问题根本不在模块。驱动包里的 gmls2.dts 一般已经写好了主体关键是核对节点参数跟你的板卡和模组是否一致/dts-v1/; /plugin/; / { overlay-name GMLS2 Single CAM; compatible nvidia,p3768-0000, nvidia,jetson-orin-nx; // 以 /proc/device-tree/model 输出为准 fragment0 { target cam_i2c; // Orin 上 CSI 相机 I2C 的标签按你板卡 dtsi 里实际标签修改 __overlay__ { #address-cells 1; #size-cells 0; status okay; gmls2: gmls21a { compatible gmls2-sensor; // 必须与 gmls2_core.c 里 of_match 完全一致 reg 0x1a; // i2cdetect 探测到的 7bit 地址 status okay; reset-gpio gpio 42 GPIO_ACTIVE_LOW; pwr-gpio gpio 44 GPIO_ACTIVE_HIGH; mclk-frequency 24000000; mode0 { mclk_multiplier 1; tegra_sinterface serial_a; tegra_pixels_per_line 2200; tegra_lines_per_frame 1150; lane_count 2; active_w 1920; active_h 1080; pixel_t y8; // 黑白模组常见彩色模组改成对应格式 pixel_phase y; }; }; }; }; };逐个说参数。target cam_i2c指向 CSI 相机所在 I2C 控制器Orin 的 dtsi 里通常标成cam_i2c或类似名字不同版本命名会变最稳的办法是grep -n cam_i2c /usr/src/linux-headers-$(uname -r)/...找到实际标签再填别照抄网上其它板卡的写法。reg 0x1a对应 i2cdetect 看到的地址。reset-gpio和pwr-gpio的引脚编号要从板卡的 pinmux 配置里查同一个功能在不同载板上编号完全不同。mode0 节点里lane_count是 CSI lane 数取决于模组支持几 lane 和排线实际接了几条active_w/active_h是输出分辨率pixel_t决定了 V4L2 看到的像素格式黑白 GMLS2 一般是y8彩色模组会是别的格式以模组 datasheet 为准。tegra_sinterface serial_a表示接在 CSI A 口接错口就需要改成serial_b并检查线序。还要补一个 tegra-camera-platform 的模块描述片段否则 v4l2 设备可能注册不出来fragment1 { target tegra_camera_platform; __overlay__ { modules { module0 { badge gmls2_front; position front; orientation 1; drivername gmls2; // 必须等于 gmls2.ko 去掉 .ko 后的模块名 subdev_id 0; }; }; }; };drivername gmls2这一行写的就是 insmod 的模块名两边不一致时 probe 会静默失败v4l2 设备不出来还不报错。这个字段是我排错时最先检查的地方。4.2 用 dtc 编译 overlay 并更新 extlinux.conf 引导设备树源文件改好后在板子上编译成 dtbosudo apt install -y device-tree-compiler dtc - -I dts -O dtb -o gmls2.dtbo gmls2.dts ls -l gmls2.dtbo-这个参数不能漏它让 dtc 生成 overlay symbol 表bootloader 或 fdtoverlay 工具靠它把 overlay 正确叠加到主 dtb 上。没有-编出来的 dtbo 在合并时会报phandle redefined或__symbols__ not found。如果报 phandle 相关错误一般是 dts 里用了板卡 dtsi 中不存在的 target 标签回头核对 4.1 的target cam_i2c写法。合并前先备份原 dtb这是后悔药改坏了的唯一退路sudo mkdir -p /boot/backup sudo cp /boot/tegra234-p3768-0000*.dtb /boot/backup/JetPack 5.x 上 extlinux 方式是最稳的。查看引导配置sudo vim /boot/extlinux/extlinux.conf配置文件里的 primary 段大概长这样LABEL primary MENU LABEL primary kernel LINUX /boot/Image FDT /boot/tegra234-p3768-0000.dtb INITRD /boot/initrd.imgFDT行指向主设备树文件。我这里没有用 overlay 目录方式而是直接把 overlay 合并进主 dtb 再替换这是 extlinux 场景下最不容易出问题的方法sudo fdtoverlay -i /boot/tegra234-p3768-0000.dtb /boot/gmls2.dtbo -o /boot/gmls2-merged.dtb sudo cp /boot/gmls2-merged.dtb /boot/tegra234-p3768-0000.dtb syncfdtoverlay -i是输入主 dtb-o是输出合并后的新 dtb中间列出的就是刚才编好的 gmls2.dtbo。合并后节点已经进入主 dtboverlay 本身可以删除或留着。改完 extlinux.conf 和 dtb 后一定要执行sync否则断电可能导致引导文件写入不完整板子变砖的机率不小。还有一个需要提前确认的点如果主板开启了 secure boot 并且要求签名校验替换过的 dtb 会在 U-Boot 阶段被拒表现为开机卡死或反复重启。这种情况要么在烧写时关闭 secure boot要么对 dtb 走签名流程。新手建议先关掉安全启动把驱动跑通再回头处理签名。4.3 重启后在 /proc/device-tree 里确认设备树确实生效改完设备树必须重启才生效然后按下面的顺序验证sudo reboot ls /proc/device-tree/ | grep -i gmls2 cat /proc/device-tree/gmls21a/status/proc/device-tree是当前内核实际加载的设备树的内存视图和你磁盘上的 dtb 文件还不是一回事。grep 能看到 gmls2 节点且 status 文件内容为okay说明设备树真正生效了。如果 model 输出的板卡型号和 2.1 节记的不一致说明 extlinux.conf 的 FDT 行指向了别的 dtb先回头改引导。这里有个二分法很好用节点不在说明 dtb 没合并对回到 4.2 检查 fdtoverlay 和 FDT 行节点在但驱动不 probe说明 compatible 不匹配或模块没加载回 3.3 和 4.1 检查字符串。用这个办法能快速把问题定位到设备树层还是驱动层不用瞎猜。5. 避坑手册GMLS2 驱动安装最常见的 5 个翻车现场5.1 /dev/video0 不出现设备树没生效而不是驱动没装上现象insmod 成功lsmod 里有 gmls2dmesg 也没报错但ls /dev/video*什么都没有v4l2-ctl --list-devices只列出板载其它摄像头。原因最常见的不是驱动问题而是设备树节点没进去或者 tegra-camera-platform 的 module0 里 drivername 写错。这是典型的设备树问题伪装成驱动问题新手往往在这一步反复重编内核模块白费时间。解决先按 4.3 的二分法确认节点在不在节点在的话检查 tegra_camera_platform 的 drivername 是否等于模块名然后把 udev 规则触发一遍或直接重启sudo udevadm trigger dmesg | grep -iE v4l2|video_device|gmls2 ls -l /dev/video*5.2 insmod 报 version magic 和未知符号内核头与源码错配现象sudo insmod gmls2.ko报Invalid module format或者Unknown symbol加一串地址。前者是版本元数据不符后者是符号表校验不过。原因内核头文件版本与当前内核不一致或者 CONFIG_MODVERSIONSy 时符号 CRC 对不上。这类错误排在翻车率第一几乎都是换过 JetPack 版本或手动补装过头文件导致的。解决先对比指纹modinfo gmls2.ko | grep vermagic uname -r不一致就重装linux-headers-$(uname -r)然后清理编译产物从头编一遍。我一般直接删掉当前目录下所有 .o 和 .ko 再走make clean make增量编译有时会把旧的符号 CRC 带进新模块这种问题我看过别人浪费掉一个下午算是玄学里比较常见的一种。5.3 能枚举但取流黑屏CSI 线序和 MCLK 频率没对上现象/dev/video0 存在v4l2-ctl --list-formats-ext也能列出格式但用 GStreamer 拉流后画面全黑或者满是噪点雪花。原因CSI lane 线序接错、lane_count 和实际排线不匹配、MCLK 频率配置错误是最常见的三类。曝光参数过小导致的黑屏也偶发但那不是驱动问题。解决先排除曝光因素把曝光和增益调大再看v4l2-ctl -d /dev/video0 --set-ctrl exposure20000 v4l2-ctl -d /dev/video0 --set-ctrl gain10还黑就用 media-ctl 看链路状态media-ctl -p -d /dev/media0 | grep -A5 gmls2链路正常但画面黑基本就是 lane 配置或 MCLK 问题。把 4.1 里 mode0 的 lane_count 在 2 和 4 之间切换或者确认mclk-frequency 24000000和模组实际需要的时钟一致。带滚动噪点的黑屏八成就是 MCLK 没起振或 lane 时序错位不是代码 bug。5.4 i2cdetect 探测不到传感器供电、复位和总线都可能是凶手现象在预期地址处 i2cdetect 显示--把整个总线扫完也一无所获。原因模组没上电、复位引脚被拉死在低电平、I2C 总线号看错、或者电平不匹配。我踩过一个坑是软排线 1 脚对到 40 脚整个 lane 全错位但插得挺紧排线反过来插才正常。解决按顺序排查。先把所有总线扫一遍不要只看一个号sudo i2cdetect -y -r 0 sudo i2cdetect -y -r 1 sudo i2cdetect -y -r 7 sudo i2cdetect -y -r 30然后查 GPIO 状态cat /sys/kernel/debug/gpio | grep -iE cam|gmls2如果 reset-gpio 被拉低模组永远处于复位状态i2cdetect 当然什么都看不到。还有一个硬件细节要重视Jetson 的 CSI I2C 一般是 1.8V 电平如果模组标称 3.3V 的 I2C需要电平转换板硬接极可能烧模组这个别赌。5.5 全局快门触发模式不出图trigger 信号或缺省参数问题现象内触发模式下帧率和画面都正常切成外部触发后v4l2-ctl --stream-count一帧都不涨或者画面一直停在旧缓存。原因外部触发信号根本没进来GPIO 被其它外设的 pinmux 占用或者驱动默认走 software trigger用户没把触发模式切到 hardware。全局快门相机对外部触发的依赖比卷帘快门强得多出图异常优先怀疑时序而不是驱动逻辑。解决先切到驱动支持的触发模式再验证v4l2-ctl -d /dev/video0 --set-ctrl trigger_mode2 v4l2-ctl -d /dev/video0 --stream-count5 --stream-to/tmp/gmls2_trig.rawtrigger_mode的取值和 control 名字以驱动注册为准先用v4l2-ctl -L -d /dev/video0查看全部可用 control。没帧数增长就查 GPIO 冲突cat /sys/kernel/debug/gpio | grep -iE cam|trigger最后确认外部触发信号的电平和极性是否匹配模组要求3.3V 的 trigger 信号接到 1.8V 引脚上大概率不识别。触发时序参数上升沿还是下降沿触发、曝光延时多少微秒通常在驱动 mode 节点里配不同模组默认值差别很大出图异常时逐个改参数重编每次改动记在笔记里方便回溯。6. 装完怎么验证跑通v4l2-ctl 枚举 GStreamer 取流 触发模式三连测6.1 先用 v4l2-ctl 确认设备枚举和格式参数驱动和设备树都就位后第一轮验证是枚举和格式v4l2-ctl --list-devices v4l2-ctl --list-formats-ext -d /dev/video0 v4l2-ctl --get-fmt-video -d /dev/video0--list-devices应该能看到带 gmls2 标识的设备节点--list-formats-ext会列出 sensor 支持的像素格式和分辨率组合黑白模组一般是 Y8彩色模组是 UYVY 之类的格式。--get-fmt-video显示当前默认格式分辨率应该和模式0里配的一致。如果设备能列出但 formats 为空说明 mode 表没注册全回到 4.1 检查设备树 mode 节点。6.2 再用 GStreamer 拉流截图检查画面枚举通过只算一半真正的考验是能不能取到有效画面。用 GStreamer 直接抓 30 帧存成 JPEGgst-launch-1.0 v4l2src device/dev/video0 num-buffers30 ! \ video/x-raw,formatY8,width1920,height1080,framerate60/1 ! \ videoconvert ! jpegenc ! multifilesink location/tmp/gmls2_%03d.jpg这条管线的意思是从 /dev/video0 取 30 帧指定 Y8 格式和 1920x108060转成 JPEG 后存成带编号的文件。抓完看文件大小每张几十 KB 到一两百 KB 是正常文件只有几 KB 基本就是黑图。如果 Jetson 上装了 nvargus 服务还可以走 ISP 通道验证一下整条链路gst-launch-1.0 nvarguscamerasrc sensor-id0 ! \ video/x-raw(memory:NVMM),formatNV12,width1920,height1080 ! \ nvjpegenc ! multifilesink location/tmp/gmls2_nv_%03d.jpgnvargus 通道能出图说明不只是 sensor 输出正常tegra ISP 链路也通了这一层验证很重要因为很多应用最终跑的是 nvarguscamerasrc 而不是裸 v4l2src。6.3 最后验证触发模式收在一条习惯上内触发取流通过后全局快门模组还要过触发这一关尤其是做机器视觉项目的基本都靠外部触发同步v4l2-ctl -d /dev/video0 --set-ctrl trigger_mode2 v4l2-ctl -d /dev/video0 --stream-count5 --stream-to/tmp/gmls2_trig.raw ls -l /tmp/gmls2_trig.raw触发模式下抓 5 帧文件大小可以自己验算宽度乘以高度乘以单像素字节数再乘以帧数对得上说明触发链路是通的。如果文件大小是 0回到 5.5 查 GPIO 和时序。这就是我每次装完驱动都要跑的三连测v4l2-ctl 枚举确认设备GStreamer 取流确认画面触发模式确认同步。从那以后我每次拿到新的 JetPack 镜像或新板卡第一件事永远是uname -r、i2cdetect -l、cat /proc/device-tree/model三连把环境标签留在终端里再动驱动源码。这套三连测也一样枚举、取流、触发全过驱动才算真正出厂。希望你这次也能一次跑通少走一遍我当时反复 insmod 又反复翻车的弯路希望帮到你。本文还有配套的精品资源点击获取