2、嵌入式Linux开发环境搭建:交叉编译工具链安装、TFTP/NFS服务配置、开发板与PC连接
好,咱们正式开始动手了。这一章,说白了就是搭台子。你想想看,没有工具,再牛的工程师也写不出能跑在无人机上的代码。嵌入式Linux开发,跟你在PC上写个C程序完全是两码事——你的代码要在PC上编译,然后扔到ARM架构的开发板上跑。这就引出了我们今天的主角:交叉编译工具链。
我个人习惯,先把环境理清楚,再动手。不然出了问题,你都不知道是代码的锅,还是工具的锅。我在项目中遇到过好几次,新手折腾一整天,最后发现是交叉编译器版本不对,白费功夫。
2.1 交叉编译工具链安装
什么是交叉编译?简单说,就是在你的x86架构的PC上,编译出能在ARM架构的开发板上运行的二进制文件。你的PC是“宿主机”,开发板是“目标机”。
嗯,这里要注意:千万别用PC自带的gcc去编译。我见过有人这么干,编译出来的程序一运行就报“Illegal instruction”,因为指令集都不一样。
2.4.1 获取工具链
常用的交叉编译工具链有几种来源:
- 芯片厂商官方提供:比如NXP、TI、Rockchip,都会提供配套的交叉编译器。这是最稳妥的方式。
- Linaro项目:一个开源组织,专门维护ARM架构的工具链。我个人比较推荐,更新快,社区活跃。
- Buildroot或Yocto构建:如果你用这些构建系统,它们会自动下载并配置好工具链。
以Linaro的ARM64工具链为例,下载并解压:
# 下载ARM64交叉编译器
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
# 解压到指定目录,我习惯放在 /opt 下
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz -C /opt/
2.4.2 配置环境变量
解压完只是第一步。你得让系统知道这个编译器在哪。配置环境变量,说白了就是告诉终端:“嘿,找编译器的时候,去这个目录看看。”
我建议你把它写到 ~/.bashrc 里,这样每次打开终端都自动生效:
# 编辑 ~/.bashrc
vim ~/.bashrc
# 在文件末尾添加以下内容
export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
# 保存退出后,使配置生效
source ~/.bashrc
为什么要设置 ARCH 和 CROSS_COMPILE?这两个变量在编译Linux内核时特别有用。内核的Makefile会自动识别它们,省得你每次都要手动指定。
aarch64-linux-gnu-gcc --version
如果能看到版本信息,说明工具链已经就绪。我曾经遇到一个新手,环境变量配错了,结果输出版本号是PC的gcc,折腾了半天才发现。
2.2 TFTP/NFS服务配置
工具链装好了,接下来要解决一个问题:怎么把编译好的程序送到开发板上?
你当然可以用U盘拷,但每次改代码都要插拔,效率太低了。做嵌入式开发,尤其是调试阶段,TFTP和NFS是两大神器。
2.2.1 TFTP服务:快速传输内核和镜像
TFTP,全称Trivial File Transfer Protocol,简单文件传输协议。它没有认证机制,也不支持列出目录,但胜在轻量、快速。我一般用它来传输内核镜像(uImage/zImage)和设备树文件(.dtb)。
在Ubuntu上安装和配置TFTP服务:
# 安装tftp-hpa(客户端)和tftpd-hpa(服务端)
sudo apt-get install tftp-hpa tftpd-hpa
# 创建TFTP根目录,我习惯放在 /tftpboot
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot
# 修改配置文件 /etc/default/tftpd-hpa
sudo vim /etc/default/tftpd-hpa
# 内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
在开发板的U-Boot中,你可以这样使用TFTP下载文件:
# 设置开发板IP和PC IP
setenv ipaddr 192.168.1.100
setenv serverip 192.168.1.10
# 从PC下载内核镜像到开发板内存
tftp 0x42000000 uImage
# 从PC下载设备树文件
tftp 0x43000000 imx6ull-14x14-evk.dtb
2.2.2 NFS服务:挂载根文件系统
TFTP适合传单个文件,但如果你要调试应用程序,每次都要下载、烧写,太麻烦了。NFS(Network File System)可以让你把PC上的一个目录直接挂载到开发板上,作为根文件系统使用。
这样做的好处是:你在PC上修改代码、编译,开发板那边立刻就能看到更新。说白了,就是“热更新”。
配置NFS服务:
# 安装NFS服务器
sudo apt-get install nfs-kernel-server
# 创建NFS共享目录,我习惯放在 /nfsroot
sudo mkdir -p /nfsroot
sudo chmod 777 /nfsroot
# 编辑 /etc/exports,添加共享配置
sudo vim /etc/exports
# 添加以下内容(假设开发板网段是192.168.1.x)
/nfsroot 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
在开发板的U-Boot中,设置内核启动参数,让内核从NFS挂载根文件系统:
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.10:/nfsroot,proto=tcp rw ip=192.168.1.100:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off'
# 然后启动内核
bootm 0x42000000 - 0x43000000
调试阶段,你可能会频繁修改应用程序。如果用NFS,改完代码直接编译,开发板那边重启一下应用就能看到效果。我曾经调试一个植保无人机的喷洒控制算法,一天要改几十次代码,没有NFS的话,光烧写系统就能把人逼疯。
2.3 开发板与PC连接
工具链和服务都配好了,最后一步:把开发板和PC连起来。
连接方式主要有三种:
- 串口:用于控制台交互,查看启动日志,输入命令。
- 网口:用于传输数据,TFTP、NFS、SSH都走网口。
- USB:用于烧写系统或作为虚拟网卡使用。
2.3.1 串口连接
串口是嵌入式开发的生命线。不管系统怎么崩,只要串口还能输出,你就有机会救回来。
我一般用 minicom 或 screen 来连接串口:
# 查看串口设备
ls /dev/ttyUSB* # 通常是 /dev/ttyUSB0
# 使用 screen 连接,波特率115200
sudo screen /dev/ttyUSB0 115200
2.3.2 网口连接
网口用于高速数据传输。调试阶段,我建议把PC和开发板用网线直连,不要经过路由器。这样可以避免网络干扰,也方便设置静态IP。
PC端设置静态IP:
sudo ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
开发板端(在U-Boot或Linux中)设置静态IP:
# U-Boot中
setenv ipaddr 192.168.1.100
setenv serverip 192.168.1.10
# Linux中
ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
然后测试连通性:
# 在PC上ping开发板
ping 192.168.1.100
# 在开发板上ping PC
ping 192.168.1.10
能ping通,说明网络连接没问题。接下来就可以用TFTP传文件、用NFS挂载根文件系统了。
2.3.3 验证整个流程
环境搭好了,我们来验证一下整个流程是否通畅:
- 在PC上编写一个简单的C程序:
// hello.c
#include <stdio.h>
int main() {
printf("Hello, 植保无人机!\n");
return 0;
}
- 用交叉编译器编译:
aarch64-linux-gnu-gcc -o hello hello.c
- 把编译好的文件放到TFTP目录:
cp hello /tftpboot/
- 在开发板上通过TFTP下载并运行:
tftp -g -r hello 192.168.1.10
chmod +x hello
./hello
如果看到输出“Hello, 植保无人机!”,恭喜你,环境搭建成功了!
这一章我们做了三件事:安装了交叉编译工具链,配置了TFTP和NFS服务,连接了开发板和PC。这三件事是嵌入式Linux开发的基石。你想想看,没有这些,你连代码都跑不到板子上,还谈什么无人机控制、数据记录?
下一章,我们会开始搭建植保无人机数据记录系统的软件框架。到时候,这些工具都会派上用场。