2、开发环境搭建:交叉编译工具链安装、嵌入式Linux系统移植、Qt/Embedded环境配置

说实话,搭建开发环境这事儿,看着简单,但坑是真不少。我刚开始做呼吸机项目那会儿,光是在交叉编译工具链上就折腾了两天。后来总结出一个道理:环境搭得稳,后面才能睡得着觉。咱们一步步来。

2.1 交叉编译工具链安装

什么是交叉编译?说白了,就是在你的PC上编译出能在ARM板子上跑的程序。你的PC是x86架构,呼吸机主控板通常是ARM Cortex-A系列,这两者指令集不同,所以需要一套特殊的工具链。

核心要点:工具链版本必须与目标板内核匹配。我曾经因为用了高版本的gcc,编译出来的程序在板子上段错误,查了三天才发现是工具链ABI不兼容。

我个人习惯用Linaro提供的工具链,稳定且社区活跃。以ARM Cortex-A7为例,安装步骤如下:

# 下载Linaro交叉编译工具链
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz

# 解压到指定目录
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt/

# 配置环境变量
export PATH=/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm

小技巧:把环境变量写到 ~/.bashrc 里,这样每次打开终端就不用重新export了。我习惯在文件末尾加一行 source /opt/env_setup.sh,把所有交叉编译相关的变量集中管理。

验证是否安装成功:

arm-linux-gnueabihf-gcc --version
# 输出类似:arm-linux-gnueabihf-gcc (Linaro GCC 7.5.0) 7.5.0

嗯,看到版本号就说明工具链活了。这里要注意,有些新手会直接在板子上装gcc本地编译,这在资源紧张的嵌入式系统里是行不通的——你想想看,呼吸机的主控板通常只有256MB内存,跑个gcc编译能把系统卡死。

2.2 嵌入式Linux系统移植

系统移植,就是把Linux内核、根文件系统、设备树这些东西,搬到你的目标板上。呼吸机对实时性要求高,我建议用Linux内核的PREEMPT_RT补丁。

移植步骤大致分四步:

  1. 编译内核——配置适合呼吸机的内核选项
  2. 制作根文件系统——用Buildroot或Yocto
  3. 编写设备树——描述硬件资源
  4. 烧录启动——通过SD卡或NAND Flash

以我常用的i.MX6ULL平台为例:

# 下载内核源码
git clone https://github.com/embeddedlinux/linux-imx.git -b imx_4.19.35_1.1.0

# 配置内核(使用呼吸机专用配置)
make imx_v7_defconfig
make menuconfig  # 这里要开启PREEMPT_RT和SPI、I2C驱动

# 编译内核
make -j4 zImage
make -j4 dtbs

注意:呼吸机的显示屏幕通常通过SPI或RGB接口连接,内核配置里一定要把对应的显示驱动选上。我遇到过有人忘了配LCD驱动,结果屏幕死活点不亮,还以为是硬件坏了。

根文件系统我推荐用Buildroot,轻量且容易定制。配置时记得选上Qt/Embedded的运行时库:

# 在Buildroot配置中
Target packages → Graphic libraries and applications → Qt5 → 选中 qt5base, qt5declarative

# 编译
make

编译完成后,你会得到四个关键文件:zImage(内核)、.dtb(设备树)、rootfs.tar(根文件系统)、u-boot.imx(引导程序)。把它们烧到SD卡上:

sudo dd if=u-boot.imx of=/dev/sdb bs=1k seek=1
sudo dd if=zImage of=/dev/sdb1
sudo dd if=imx6ull-14x14-evk.dtb of=/dev/sdb1
sudo tar -xvf rootfs.tar -C /mnt/sd

2.3 Qt/Embedded环境配置

Qt/Embedded,现在叫Qt for Embedded Linux,是呼吸机界面开发的核心。为什么选它?因为Qt的QML做动画效果很流畅,呼吸机上的波形显示、报警动画都需要它。

配置步骤:

# 下载Qt源码
wget https://download.qt.io/archive/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz

# 解压并配置交叉编译
tar -xvf qt-everywhere-src-5.15.2.tar.xz
cd qt-everywhere-src-5.15.2

# 配置(关键参数)
./configure -prefix /opt/qt5.15.2-arm \
  -xplatform linux-arm-gnueabihf-g++ \
  -device linux-imx6-g++ \
  -no-opengl \
  -eglfs \
  -no-xcb \
  -qt-libpng \
  -qt-libjpeg \
  -qt-freetype \
  -no-gtk \
  -opensource \
  -confirm-license \
  -nomake examples \
  -nomake tests \
  -skip qtwebengine

为什么关掉OpenGL?呼吸机的主控芯片通常没有GPU,用eglfs(EGL文件系统)模式就够了。我刚开始不懂,开了OpenGL,结果编译出来的Qt在板子上跑不起来,报错说找不到GPU驱动。

编译安装:

make -j4
make install

安装完成后,把/opt/qt5.15.2-arm整个目录拷贝到板子的根文件系统里。然后在板子上设置环境变量:

export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_WIDTH=800
export QT_QPA_EGLFS_HEIGHT=480
export QT_QPA_EGLFS_PHYSICAL_WIDTH=154
export QT_QPA_EGLFS_PHYSICAL_HEIGHT=86
export LD_LIBRARY_PATH=/opt/qt5.15.2-arm/lib:$LD_LIBRARY_PATH

避坑指南:屏幕尺寸参数一定要和你的硬件匹配。我曾经因为写错了物理尺寸,导致触摸坐标偏移,点按钮A却触发了按钮B。后来用ts_calibrate校准了一下才解决。

最后,写个简单的测试程序验证一下:

# test.cpp
#include <QApplication>
#include <QLabel>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QLabel label("Hello, Ventilator!");
    label.show();
    return app.exec();
}

# 交叉编译
arm-linux-gnueabihf-g++ -o test test.cpp -I/opt/qt5.15.2-arm/include -L/opt/qt5.15.2-arm/lib -lQt5Core -lQt5Gui -lQt5Widgets

# 拷贝到板子上运行
./test

如果屏幕上出现了"Hello, Ventilator!",恭喜你,环境搭建成功了。接下来就可以正式开始写呼吸机的界面了。

嗯,总结一下今天的内容:工具链是基础,系统移植是骨架,Qt环境是血肉。这三样东西搭好了,后面的开发就会顺畅很多。我见过太多人卡在环境搭建这一步,其实只要按照步骤来,别跳步,基本不会出大问题。