第二章 驱动开发环境搭建

说实话,做结构光模组驱动开发,环境搭建这一步最容易被轻视。

我见过太多人,拿到SDK就开始写代码,结果编译报错半天找不到原因。最后发现,是交叉编译工具链版本不对。嗯,这种坑,我踩过不止一次。

今天咱们就把这套环境,从头到尾捋一遍。

2.1 嵌入式Linux开发环境配置

我个人习惯用Ubuntu 20.04 LTS作为开发机。为什么?因为大部分芯片厂商的SDK,都是基于这个版本验证的。

你想想看,如果你用最新的Ubuntu 24.04,可能gcc版本太高,编译老旧的kernel直接报错。何必跟自己过不去?

推荐配置:

  • 操作系统:Ubuntu 20.04 LTS(64位)
  • 内存:至少16GB(我建议32GB,编译大项目时你就知道好处了)
  • 磁盘:至少100GB空闲空间(SDK解压、编译中间文件都很占地方)
  • CPU:4核以上(多线程编译能省一半时间)

装好系统后,第一件事就是安装基础依赖包。别一个一个手动装,直接跑这条命令:

sudo apt-get update
sudo apt-get install -y build-essential git vim cmake \
    libncurses5-dev libssl-dev flex bison \
    u-boot-tools device-tree-compiler \
    python3 python3-pip python3-dev

这里有个细节——libncurses5-dev。我刚开始做驱动开发时,编译内核配置界面总报错,查了半天才发现少了这个包。说白了,它就是内核的menuconfig图形界面依赖。

2.2 交叉编译工具链安装

交叉编译,说白了就是在PC上编译出能在ARM芯片上跑的程序。

结构光模组常用的主控芯片,无非就是瑞芯微RK系列、全志V系列、或者海思Hi系列。不同芯片,工具链也不同。

以瑞芯微RK3588为例,我一般用gcc-arm-10.3版本:

# 下载工具链
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz

# 解压到指定目录
tar -xf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/

# 配置环境变量
export PATH=/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-

小技巧:把环境变量写到~/.bashrc里,这样每次打开终端就不用重新export了。

我个人习惯在/opt下建一个toolchains目录,把所有工具链都放进去,方便管理。

验证工具链是否装好:

aarch64-none-linux-gnu-gcc --version

如果输出版本号,就说明成功了。

注意:我曾经遇到过一个问题——工具链版本和内核版本不匹配。编译出来的驱动模块加载时,直接报Invalid module format。后来发现,是工具链的gcc版本和编译内核时用的gcc版本不一致。

所以,一定要用芯片厂商官方推荐的工具链版本。

2.3 SDK获取与编译

SDK,就是芯片厂商提供的软件开发包。里面包含了内核源码、uboot、文件系统、以及各种驱动示例。

获取SDK通常有两种方式:

  • 官方Git仓库:比如瑞芯微的rk3588-linux-sdk,直接git clone
  • 百度网盘/阿里云盘:有些厂商把SDK打包成压缩包,需要手动下载

我建议用Git方式,方便后续更新。但要注意,SDK通常很大(10GB+),下载时记得加--depth=1参数,只拉取最新版本:

git clone --depth=1 https://github.com/rockchip-linux/rk3588-linux-sdk.git

下载完成后,先看看SDK的目录结构:

rk3588-linux-sdk/
├── kernel/          # Linux内核源码
├── u-boot/          # uboot源码
├── buildroot/       # 文件系统构建工具
├── external/        # 第三方库和驱动
├── docs/            # 文档
└── device/          # 设备树和板级配置

编译SDK,一般分三步走:

  1. 编译uboot:生成启动引导程序
  2. 编译内核:生成内核镜像和设备树
  3. 编译文件系统:生成根文件系统镜像

以RK3588为例,编译命令通常是:

# 编译uboot
cd u-boot
make rk3588_defconfig
make -j8

# 编译内核
cd ../kernel
make rockchip_linux_defconfig
make -j8 Image.gz dtbs

# 编译文件系统
cd ../buildroot
make rockchip_rk3588_defconfig
make -j8

关键点:第一次编译时,buildroot会下载很多软件包。如果网络不好,可能会失败。我建议提前把dl/目录下的包下载好,或者用国内镜像源。

编译完成后,会在output/目录下生成镜像文件:

文件 说明
uboot.img uboot镜像
boot.img 内核+设备树+ramdisk
rootfs.img 根文件系统
update.img 完整升级包

2.4 硬件调试工具准备

做驱动开发,光有软件环境还不够。你得准备好硬件调试工具。不然出了问题,只能干瞪眼。

2.4.1 示波器

示波器,说白了就是看信号波形的。结构光模组里,最常测的就是这些信号:

  • MIPI CSI时钟:看频率对不对,抖动大不大
  • I2C数据线:看通信时序是否正常
  • 激光器调制信号:看脉宽和频率是否符合要求
  • 电源纹波:看供电是否干净

我个人推荐用4通道、带宽200MHz以上的示波器。比如普源DS1104Z或者泰克TDS2024C。如果预算有限,二手市场淘一个也行。

经验之谈:测MIPI信号时,探头要用1x档,不要用10x档。10x档会衰减信号,导致测出来的幅度不对。我曾经因为这个,查了整整两天,最后发现是探头设置错了。

2.4.2 逻辑分析仪

逻辑分析仪,就是看数字信号时序的。它不像示波器那样看模拟波形,而是看高低电平的变化。

做结构光驱动,逻辑分析仪主要用来:

  • 分析I2C通信:看寄存器读写是否正常
  • 分析SPI通信:看数据是否传输正确
  • 分析GPIO时序:看激光器使能、曝光同步等信号
  • 分析中断信号:看帧同步、数据就绪等中断是否正常

我常用的逻辑分析仪是Saleae Logic 8,8通道、100MHz采样率。对于结构光模组来说,完全够用了。而且它的软件界面很友好,支持协议解析。

注意:逻辑分析仪的采样率,至少要是被测信号频率的4倍。比如I2C频率是400kHz,那采样率至少要1.6MHz。但实际上,我建议用10倍以上,这样波形看起来更清晰。

2.4.3 其他必备工具

除了示波器和逻辑分析仪,还有一些小工具也很重要:

  • USB转串口模块:CH340或FT232,用来查看内核打印信息
  • 万用表:测电压、测通断
  • 热风枪和烙铁:焊接调试线、更换元器件
  • 杜邦线和排针:连接调试信号

2.5 环境验证:跑一个Hello World

环境搭好了,工具也准备好了。咱们来验证一下,能不能正常编译和运行。

写一个简单的驱动模块:

// hello_drv.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello, Structured Light Module!\n");
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye, Structured Light Module!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple hello driver for structured light module");

编写Makefile:

obj-m := hello_drv.o

KDIR := /path/to/your/kernel/source
CROSS_COMPILE := aarch64-none-linux-gnu-
ARCH := arm64

all:
    $(MAKE) -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules

clean:
    $(MAKE) -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) clean

编译:

make

如果一切顺利,会生成hello_drv.ko文件。把它拷贝到开发板上,加载:

insmod hello_drv.ko
dmesg | tail

看到Hello, Structured Light Module!,就说明环境搭建成功了。

到这里,你的驱动开发环境就全部就绪了。

接下来,就可以正式开始写结构光模组的驱动了。


公众号:蓝海资料掘金营,微信deep3321