
拿到瑞芯微RV1126 EVB板的第一天我做的事不是跑官方demo而是先把项目里真正要用的外设驱动调通。RV1126这颗四核A7NPU的SoC在智能IPC、机器视觉类产品里非常能打SC132GS全局快门摄像头负责高速抓拍CAN口接车载或工业总线USB口外接触摸屏、4G模块或者UVC摄像头几乎是这类项目的标准外设组合。这篇文章就手把手记录我在这块EVB板上从零添加SC132GS摄像头、CAN与USB驱动的完整过程包括设备树怎么改、内核怎么配、镜像怎么烧、踩过哪些坑。不管你是刚接触嵌入式Linux驱动的新手还是正在做瑞芯微平台评估的老手按这个流程走一遍外设驱动这块的脉络基本就清楚了。1. 先理清RV1126 EVB板驱动开发的整体思路1.1 RV1126 EVB板能做什么为什么先调外设驱动先给不熟的朋友补个背景。RV1126是瑞芯微面向AI视觉应用的一颗SoCCPU部分是四核Cortex-A7主频1.5GHz左右集成了2T算力NPU、14M ISP、硬件编解码单元还带MIPI CSI、MIPI DSI、USB、以太网、CAN等一堆外围接口。EVB板全称Evaluation Board就是官方或方案公司做的评估板把芯片关键引脚都引出来配上DDR、eMMC、电源管理和各种接口座子是项目预研阶段拿来验证硬件和软件方案最好的平台。很多朋友拿到EVB板第一反应是问“为什么摄像头插上去不出图”“CAN口为什么打不开”这通常不是板卡坏了而是系统里根本没有对应外设的驱动。EVB板出厂固件一般只默认带调试串口、以太网这类基础外设驱动摄像头、CAN、特定型号的USB转串口芯片都需要根据项目需求自行配置编译。这篇文章解决的就是这个问题。1.2 设备树是驱动开发的入口在讲具体配置之前先花一分钟把驱动开发的核心逻辑说清楚。现代Linux内核通过设备树来描述硬件设备树本质上就是硬件的“户口本”记录CPU有哪些外设、外设挂在哪个总线上、地址是多少、中断号是几、用哪个GPIO做复位等等。内核启动时解析这段描述再根据每个驱动里声明的compatible字符串来“认亲”匹配上了设备就注册进系统。所以添加一个新外设驱动大多数情况下只有两大步第一步在设备树里把硬件描述清楚第二步在内核配置里把对应驱动打开。后面所有工作都围绕这两步展开。这个思路在摄像头、CAN、USB、I2C、SPI这些外设上完全通用建议刚接触的朋友先把这句话消化掉。1.3 按“单外设验证”路线推进我没有一上来就把三个驱动一起改而是按SC132GS摄像头、CAN、USB的顺序逐个添加每加一个就编译烧录验证一次。这样做的原因很简单问题隔离。如果一次把三个驱动全改完再烧录一旦系统起不来或者某个设备不工作你很难判断是设备树写错了、驱动配置少了还是外设之间的配置打架了。一个外设验证通过再进入下一个出错时能立刻锁定是刚才改动的范围。这个习惯在EVB板阶段尤其重要。我的整体路线是先搭建编译环境并完成一次基线编译确认SDK能正常出包再逐个添加外设。整个过程看起来慢实际是最省时间的。2. 搭建可复用的内核编译环境2.1 直接使用厂商SDK别自己从零折腾工具链环境准备方面最核心的建议是不要自己去内核官网拉主线代码而是用瑞芯微发布的SDK。RV1126的官方SDK通常以压缩包或git仓库形式发布里面已经把内核、buildroot用户态、交叉编译工具链、烧录工具全部整合好还针对自家芯片做了大量板级补丁。用主线内核硬来光适配一个摄像头驱动可能就要折腾一周这在项目评估阶段完全没必要。交叉编译工具链也不需要单独装。RV1126的内核是32位ARM架构SDK里会自动准备好对应的arm-linux-gnueabihf工具链。通过SDK根目录的脚本编译时工具链路径会自动加入环境变量不需要手动指定CC变量这也是推荐直接用SDK的另一个原因。2.2 SDK目录里要关注的关键部分以我常用的SDK为例解压后重点看这几个目录kernel/Linux内核源码设备树、驱动源码都在这buildroot/根文件系统构建工具用来生成can-utils、v4l-utils这类用户态工具u-boot/引导程序源码rockdev/或out/编译产物输出目录烧录用的镜像最终在这里docs/官方说明文档很多常见问题答案其实就在里面不同版本或渠道发布的SDK目录会有些差异但整体思路一致。拿到SDK先读README或docs别急着敲命令这一步省不得。2.3 第一次编译的目标跑通baseline强烈建议在改任何东西之前先完成一次干净的SDK编译。这样你手里就有一个确定能启动的“基准镜像”后续所有改动都是在这个基准上加东西出了问题回退也容易。编译命令以SDK根目录脚本为准通常是source build/envsetup.sh lunch rv1126-userdebug ./build.sh kernel不同版本命令不完全一样以你手里的SDK为准。内核单独编译完成后检查输出目录里是否生成了boot.img或kernel.img确认后再进行下一步。如果这里就报错优先排查编译依赖、SDK版本与主机系统兼容性建议用Ubuntu 18.04或20.04的x64环境兼容性最稳。2.4 修改设备树后如何单独编译dtb调试阶段如果只改了设备树不需要每次都全量编译内核。RV1126的内核设备树路径一般在kernel/arch/arm/boot/dts/单独编译设备树可以用make dtbs编译完成后把生成的dtb文件替换到boot.img对应的位置或者根据SDK提供的脚本重新打包内核镜像。这一步能大幅缩短编译等待时间建议一上来就记住。3. 实战给RV1126添加SC132GS摄像头驱动3.1 SC132GS是什么一款全局快门MIPI sensorSC132GS是思特威推出的一款全局快门CMOS图像传感器像素130万1280x1024传感器尺寸1/2.7英寸支持MIPI CSI-2输出。和常见的卷帘快门Sensor相比全局快门在抓拍快速运动物体时不会出现拖影和果冻效应所以扫码设备、机器视觉、智能门禁这类场景非常喜欢用它。RV1126本身带ISP和MIPI CSI接口配合这种sensor做视觉方案非常合适。硬件连接上SC132GS一般通过MIPI CSI-2接口与RV1126相连同时需要I2C总线用于寄存器配置以及MCLK时钟、复位GPIO、供电使能PWDN等控制信号。把这组连接关系搞清楚是接下来写设备树的前提。3.2 先从原理图摸清Sensor引脚连接写设备树信息从哪里来答案就是EVB板的原理图。打开原理图找到SC132GS模组部分重点确认四件事Sensor挂在哪个I2C控制器上I2C地址是多少常见0x30但以原理图为准MIPI数据信号占用了几个lane常见是2-lane或4-lane复位脚和PWDN脚分别接到哪个GPIO是低有效还是高有效MCLK时钟频率是按多少MHz设计的常见24MHz很多人跳过这一步直接照抄网上的配置结果要么i2cdetect探测不到设备要么出图花屏回源头查才发现是GPIO搞反了或者lane数量不对。原理图信息就是设备树配置的第一手依据不要跳步。3.3 设备树添加SC132GS节点确认硬件之后打开内核设备树文件。RV1126的EVB设备树一般在kernel/arch/arm/boot/dts/目录下文件名类似rv1126-evb.dts。我以sensor挂在I2C3上、使用2-lane MIPI、复位脚为GPIO1_A0、PWDN脚为GPIO1_A1为例给出核心节点配置i2c3 { status okay; clock-frequency 400000; sc132gs: sc132gs30 { compatible smartsens,sc132gs; reg 0x30; reset-gpios gpio1 RK_PA0 GPIO_ACTIVE_LOW; pwdn-gpios gpio1 RK_PA1 GPIO_ACTIVE_HIGH; rockchip,camera-module-index 0; rockchip,camera-module-facing back; rockchip,camera-module-name default; rockchip,camera-module-lens-name default; port { sc132gs_out: endpoint { remote-endpoint mipi_in_ucam0; >i2cdetect -y 3如果0x30地址上有设备说明i2c通信已经打通。然后用v4l2-ctl确认video节点v4l2-ctl --list-devices正常会看到类似rkisp_mainpath的节点和对应的/dev/video0。抓一帧图像v4l2-ctl -d /dev/video0 --set-fmt-videowidth1280,height1024,pixelformatGREY --stream-mmap --stream-count1 --stream-to/tmp/test.raw把test.raw拉到PC上用工具查看确认图像不是全黑、全绿或花屏。图像正常SC132GS摄像头驱动就基本通了。4. 实战CAN驱动添加与通信验证4.1 内置CAN控制器与SPI转CAN方案怎么选CAN总线在车载和工业控制领域用得非常多RV1126 EVB板上通常会引出1到2路CAN接口。但“有CAN接口”和“芯片内置CAN控制器”是两回事动软件前先确认板卡的CAN方案。先说内置方案。RV1126片上内置了CAN控制器片外只需要加一颗CAN收发器芯片比如TJA1042、SN65HVD230把差分信号转换出来就能用。这种方案下驱动工作主要就是声明设备树节点和引脚复用再使能内核CAN子系统相对简单。另一种是外接方案比如通过SPI接口挂一颗MCP2515独立CAN控制器。这种在部分核心板或老方案里比较常见。配置时需要在设备树里添加SPI设备节点并打开SPI转CAN驱动。我这里用的EVB板是内置方案下面以内置方式展开外接方案会提一下配置思路。4.2 硬件检查终端电阻与收发器在动软件之前先做两个硬件检查。第一确认CANH和CANL之间有120Ω终端电阻。标准CAN总线两端各需要一颗120Ω电阻很多EVB板已经把终端电阻设计在板内没有的话就得外接否则通信会不稳定。第二确认收发器型号和供电这关系到设备树里引脚复用是否正确。这个检查能帮你省掉后面一半的排查时间。4.3 设备树声明CAN节点与引脚复用内置CAN控制器的设备树配置相对简洁。先确认引脚复用CAN0的TX/RX引脚需要通过pinctrl配置为CAN功能而不是默认的GPIO或UART功能。设备树大致结构如下can0 { status okay; pinctrl-names default; pinctrl-0 can0_pins; };can0_pins定义在公共dtsi文件里具体引脚号和SDK里的引脚宏定义有关必须参照原厂dtsi来确认不能照抄网上配置。如果板卡使用的是CAN1对应修改节点名和pinctrl即可。需要提醒的是如果引脚被其他功能占用比如同一个引脚已经被配置成UARTCAN节点即使status为okay也不会正常工作。4.4 打开内核CAN子系统配置设备树声明之后在defconfig里打开CAN相关配置。核心项包括CONFIG_CANy使能CAN协议栈CONFIG_CAN_DEVy使能CAN设备驱动框架CONFIG_CAN_ROCKCHIPy或对应平台驱动宏使能SoC内置CAN控制器驱动如果用SPI转CAN方案需要关注CONFIG_CAN_MCP251X同时确保SPI子系统和平台SPI控制器驱动已打开。配置完成后重新编译内核。4.5 can-utils实现CAN收发验证内核起来后先把CAN接口拉起来ip link set can0 up type can bitrate 500000500kbps是常用波特率具体以总线对端设备为准。然后用ip命令确认接口状态ip -details link show can0看到state UP说明接口已经工作。接下来用CAN盒或另一块板子做对端分别测试收发candump can0 cansend can0 123#DEADBEEF对端收到0x123这个ID且数据为DEADBEEF说明发送链路正常candump能收到对端发来的帧说明接收链路正常。收发都通CAN外设就算调完了。顺便说一句can-utils如果系统里没有在buildroot配置里选中对应package重新编译rootfs即可。5. 实战USB控制器与常用外设驱动配置5.1 梳理RV1126的USB资源与模式RV1126的USB资源通常包括一个USB 2.0 OTG口和一个USB 2.0 Host口具体以型号和EVB设计为准。OTG口既可以在device模式下连接PC做调试也可以切换成host模式外接U盘、摄像头、4G模块等。Host口是标准USB A口直接插外设用。在嵌入式Linux开发里USB部分说的“驱动开发”和很多人想的不一样。控制器驱动EHCI/OHCI或DWC2/DWC3内核里基本都有我们主要做两件事确保控制器和PHY在设备树里正确使能以及确保需要的外设驱动编译进内核。5.2 设备树里USB控制器和PHY的使能方法设备树里需要关注的节点包括USB PHY、控制器和对应的电源控制。以瑞芯微SDK为例通常会有类似节点u2phy { status okay; }; usbdrd3 { status okay; dr_mode otg; }; usb_host0_ehci { status okay; }; usb_host0_ohci { status okay; };dr_mode可以设成host、peripheral或otg根据项目需求决定。如果项目里不需要device模式直接设成host会更省心。但要注意OTG口如果兼做烧录调试口切换模式或使用对应switch时要参照EVB板说明避免把调试通道搞断。5.3 按需求打开常用USB外设驱动USB外设五花八门项目里最常用的是这几类USB转串口芯片CH340、CP210x、FT232对应内核里的CDC ACM驱动或USB-Serial驱动UVC摄像头标准免驱摄像头需要打开CONFIG_USB_VIDEO_CLASS4G模块多数走CDC ECM或RNDIS协议需要打开对应的USB网卡驱动USB无线网卡看芯片型号通常是RTL8188或MT7601这类往往需要额外移植以CH340为例插入设备后用lsusb确认VID/PID被识别到再看dmesg里是否出现ttyUSB0。如果lsusb能看到但ttyUSB0没出现大概率是内核里缺对应驱动去menuconfig搜索CH340打开重新编译即可。总原则就是先把控制器调通再按业务需要逐个开外设驱动别一次开一堆。5.4 三步完成USB外设验证USB验证说白了就三步。第一步插上看内核日志用dmesg | grep usb查看枚举过程第二步lsusb确认设备是否被识别第三步根据设备类型访问对应节点USB转串口就试/dev/ttyUSB0能否打开UVC摄像头就看有没有新增video节点4G模块就等它注册出wwan0网卡。哪一步断了就回到哪一步查配置这个排查闭环非常有效。6. 镜像烧录与多外设联合验证6.1 完整编译生成boot.img与rootfs三个外设都单独验证通过后再做一次完整编译。这里的“完整”是指把内核、设备树、buildroot用户态一次性构建生成boot.img、rootfs.img等分区镜像。瑞芯微平台的烧录方式常用两种Windows下用RKDevToolLinux下用upgrade_tool。不管用哪种都需要让板子进入Loader模式一般做法是按住板上的RECOVERY键再上电或者执行reboot loader命令具体看EVB板手册。6.2 烧录到EVB板的关键步骤烧录前强烈建议先备份板子原厂固件尤其是你手头只有这一块板、又没有别的固件来源的情况下这步是救命操作。烧录时选择对应分区镜像不要把boot.img烧到recovery分区这是新手最容易犯的低级错误。烧录完成后重新上电串口能看到内核完整启动日志再逐个验证外设是否正常工作。6.3 多外设联调的IO复用排查多外设同时工作时最常遇到的坑是IO复用冲突和电源不足。RV1126很多引脚是功能复用的比如某个引脚既能当CAN的TX又能当UART的TX设备树里两个节点同时使能就会冲突典型表现是某个接口时好时坏甚至系统启动卡死。遇到这种问题回到dtsi里查对应引脚复用定义把不用的功能关掉。另外USB口挂大功率设备时注意EVB板供电能力必要时外接5V电源否则会出现设备枚举失败或反复断连。7. 常见问题速查与避坑心得把这次实战中遇到过的典型问题整理成下表方便大家对照排查现象可能原因排查方向i2cdetect找不到SC132GSI2C地址不对、供电没给、MCLK没配对照原理图确认地址测量电源和时钟抓帧全黑或全绿曝光不对、lane数不匹配、ISP配置缺失检查data-lanes和驱动寄存器配置can0 up失败波特率参数错误、收发器未供电检查命令参数和硬件供电candump收不到数据终端电阻缺失、对端ID过滤错误检查120Ω电阻确认对端发送IDlsusb看不到USB设备控制器未使能、PHY供电问题dmesg查usb驱动加载日志ttyUSB0不出现内核缺CH340等驱动menuconfig打开对应驱动宏除表格以外有三条心得值得单独说。第一每次改设备树后要确认实际编译进去的确实是你改的那个dts。很多板子的设备树通过include包含头文件改错文件编译也不报错烧进去却没效果这种情况排查起来特别耗时间。编译后用dtc反编译一下生成的dtb搜索你添加的节点名能快速确认。第二能用命令行工具验证的就不要急着写应用层代码。v4l2-ctl、can-utils、lsusb、dmesg这些是最直接的验证武器先确认内核态正常再去写业务逻辑效率会高很多。第三日志是排错第一依据。遇到问题不要靠猜dmesg和串口内核日志里的关键字一定要学会看比如i2c、v4l2、can、usb哪一段报错就去哪一段对应的驱动源码里找答案。最后再分享一个我自己的习惯。每次拿到新板子我不会急着往上面堆业务功能而是先把调试串口、网口、摄像头、CAN这些基础设施驱动全部验证一遍把每一步改动记录成一个文档尤其是设备树里改了哪些引脚复用、defconfig里开了哪些宏都记下来。这个习惯在项目后期帮了我大忙很多问题追到源头其实就是某次设备树改动留下的隐患。这篇实战记录的流程说白了就是一套可以复用的外设驱动验证模板希望对你正在调的板卡也有帮助。