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

为什么要设置 ARCHCROSS_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
注意防火墙:TFTP使用UDP 69端口。如果你的PC开启了防火墙,记得放行这个端口。我曾经在客户现场调试,死活连不上TFTP,最后发现是防火墙把端口给堵了。

在开发板的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,改完代码直接编译,开发板那边重启一下应用就能看到效果。我曾经调试一个植保无人机的喷洒控制算法,一天要改几十次代码,没有NFS的话,光烧写系统就能把人逼疯。

2.3 开发板与PC连接

工具链和服务都配好了,最后一步:把开发板和PC连起来。

连接方式主要有三种:

  • 串口:用于控制台交互,查看启动日志,输入命令。
  • 网口:用于传输数据,TFTP、NFS、SSH都走网口。
  • USB:用于烧写系统或作为虚拟网卡使用。

2.3.1 串口连接

串口是嵌入式开发的生命线。不管系统怎么崩,只要串口还能输出,你就有机会救回来。

我一般用 minicomscreen 来连接串口:

# 查看串口设备
ls /dev/ttyUSB*   # 通常是 /dev/ttyUSB0

# 使用 screen 连接,波特率115200
sudo screen /dev/ttyUSB0 115200
小技巧:如果串口没有输出,先检查一下接线——TX接RX,RX接TX,GND接GND。我见过有人把TX和TX接在一起,结果什么也收不到。

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 验证整个流程

环境搭好了,我们来验证一下整个流程是否通畅:

  1. 在PC上编写一个简单的C程序:
// hello.c
#include <stdio.h>

int main() {
    printf("Hello, 植保无人机!\n");
    return 0;
}
  1. 用交叉编译器编译:
aarch64-linux-gnu-gcc -o hello hello.c
  1. 把编译好的文件放到TFTP目录:
cp hello /tftpboot/
  1. 在开发板上通过TFTP下载并运行:
tftp -g -r hello 192.168.1.10
chmod +x hello
./hello

如果看到输出“Hello, 植保无人机!”,恭喜你,环境搭建成功了!

总结一下:

这一章我们做了三件事:安装了交叉编译工具链,配置了TFTP和NFS服务,连接了开发板和PC。这三件事是嵌入式Linux开发的基石。你想想看,没有这些,你连代码都跑不到板子上,还谈什么无人机控制、数据记录?

下一章,我们会开始搭建植保无人机数据记录系统的软件框架。到时候,这些工具都会派上用场。