第二章 驱动开发环境搭建
说实话,做结构光模组驱动开发,环境搭建这一步最容易被轻视。
我见过太多人,拿到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,一般分三步走:
- 编译uboot:生成启动引导程序
- 编译内核:生成内核镜像和设备树
- 编译文件系统:生成根文件系统镜像
以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