Ubuntu 16.04 32位系统下RT-Thread开发环境搭建全攻略
1. 项目概述为何要重温一个“过时”的旧系统环境如果你在2024年看到这个标题第一反应可能是“Ubuntu 16.04还是32位这都什么年代的配置了现在不都用Ubuntu 22.04或者24.04了吗” 没错从主流桌面开发的角度看这个环境确实显得有些“复古”。但作为一名嵌入式领域的从业者我深知这类需求的真实性与必要性。这个项目标题背后往往对应着一些特定的、甚至有些“棘手”的实际场景。你可能正在维护一个历史悠久的工业控制项目其配套的编译工具链和库文件只兼容老旧的32位系统或者你手头有一台性能有限但依然坚挺的旧电脑或工控机你想用它来学习或开发RT-Thread又或者你接手的项目文档明确要求必须在这个特定环境下进行构建以确保与生产线测试环境百分百一致。无论是哪种情况在Linux系统下为Ubuntu 16.04 LTS 32位英文版搭建RT-Thread开发环境都是一个需要精确操作、避开无数依赖陷阱的技术任务。它考验的不是追逐最新技术的能力而是解决实际兼容性问题的功底。本文将带你完整走一遍这个搭建过程。我不会只给你一串命令而是会解释每个步骤背后的原因分享我在这个特定环境里踩过的坑和总结的技巧。我们的目标是在这个“限定”的舞台上搭建一个稳定、高效、可用的RT-Thread开发环境让你能顺畅地进行代码编辑、编译、下载和调试。2. 环境准备与系统基础配置在开始安装任何开发工具之前我们必须先让Ubuntu 16.04 32位系统本身处在一个健康且高效的状态。这一步常常被新手忽略却直接决定了后续所有步骤的顺利程度。2.1 系统更新与基础工具安装刚安装好的Ubuntu 16.04其软件源列表可能已经失效因为该版本早已过了标准支持期。我们的第一步是更新源并安装一些不可或缺的基础工具。首先备份原有的源列表文件然后替换为仍可用的旧源镜像。这里我推荐使用阿里云的旧镜像仓库相对稳定。sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sudo sed -i s/security.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list更新软件包列表并升级现有软件。这个过程可能会比较慢因为需要从镜像站拉取老版本的元数据。sudo apt update sudo apt upgrade -y接下来安装一系列基础开发工具和依赖库。这些是编译任何C/C项目包括RT-Thread及其工具链的基石。sudo apt install -y build-essential # 包含gcc, g, make等 sudo apt install -y git wget curl # 版本管理和文件下载工具 sudo apt install -y python python3 # RT-Thread的scons构建工具依赖Python sudo apt install -y device-tree-compiler # 设备树编译工具某些BSP需要 sudo apt install -y libncurses5-dev # menuconfig配置界面依赖 sudo apt install -y libssl-dev # 一些网络相关功能可能需要 sudo apt install -y u-boot-tools # 处理uImage等镜像 sudo apt install -y net-tools # 网络调试工具注意在32位系统上某些软件包的最新版本可能已不提供32位构建。apt命令可能会提示某些包无法安装或已被更新的包替代。只要核心的build-essential和python能成功安装通常就不影响RT-Thread环境搭建。如果遇到无法满足的依赖可以尝试使用aptitude进行更智能的依赖解决或者寻找功能等效的旧版本包。2.2 配置本地环境与用户权限为了避免在后续操作中频繁使用sudo尤其是涉及串口设备操作时我们需要将当前用户添加到相关的用户组。将用户添加到dialout组以获得串口读写权限用于后续的串口调试和下载sudo usermod -a -G dialout $USER将用户添加到plugdev组这对于一些通过USB连接的调试器如J-Link、ST-Link的权限管理有帮助sudo usermod -a -G plugdev $USER这些组权限更改需要重新登录系统后才能生效。你可以注销当前桌面会话再登录或者如果是在SSH连接中可以断开重连。最后检查一下系统的基本信息确认环境无误uname -a # 应显示32位i686或i386内核 lsb_release -a # 应显示Ubuntu 16.04 LTS gcc --version # 查看GCC版本16.04默认大概是5.x版本 python --version # 查看Python2版本RT-Thread的scons构建系统主要依赖Python2.73. 获取与配置RT-Thread源码RT-Thread是一个高度模块化的实时操作系统其源码管理清晰。我们直接从官方仓库获取代码。3.1 克隆RT-Thread源码仓库选择一个合适的目录例如在用户家目录下创建workspace文件夹然后克隆代码。这里我们克隆主仓库它包含了内核、组件、BSP板级支持包等所有内容。cd ~ mkdir -p workspace/rt-thread cd workspace/rt-thread git clone https://github.com/RT-Thread/rt-thread.git cd rt-thread克隆完成后你可以查看一下目录结构。bsp目录下包含了所有官方支持的开发板BSP这是我们后续工作的起点。tools目录下有一些脚本工具。实操心得对于国内用户如果git clone速度过慢可以考虑使用Gitee的镜像仓库https://gitee.com/rtthread/rt-thread.git。两者的代码是同步的。但请注意在提交Issue或Pull Request时仍应关联官方GitHub仓库。3.2 认识RT-Thread的构建系统sconsRT-Thread默认使用scons作为构建工具。scons是一个用Python编写的软件构建工具类似于make但构建脚本是用Python语法写的更灵活。在RT-Thread中每个BSP目录下都有一个SConscript文件定义了如何编译该BSP。我们需要先安装scons。由于系统自带Python 2.7我们使用pip来安装。首先确保pip已安装sudo apt install -y python-pip # 安装Python2的pip然后安装sconspip install scons安装完成后可以测试一下scons --version正常情况下会显示SCons的版本号例如SCons by Steven Knight et al.: version 2.3.5 ...。注意事项在Ubuntu 16.04的默认源中通过apt直接安装的scons版本可能较老且可能与RT-Thread的构建脚本不完全兼容。因此强烈建议使用pip install scons来安装较新的版本。如果遇到与Python3的兼容性问题请确保你调用的是python2对应的scons。4. 交叉编译工具链的安装与配置这是整个环境搭建中最关键、也最容易出问题的一环。RT-Thread可以运行在多种架构的CPU上如ARM Cortex-M, RISC-V, MIPS等我们需要对应的交叉编译工具链才能在x86的Ubuntu电脑上编译生成目标芯片可执行的代码。4.1 工具链选型为何选择gcc-arm-none-eabi对于最流行的ARM Cortex-M系列内核GNU工具链gcc-arm-none-eabi是免费且功能强大的首选。none表示没有操作系统eabi是嵌入式应用二进制接口。我们将手动下载并安装它。为什么不使用系统包管理器apt安装因为Ubuntu 16.04官方源中的gcc-arm-none-eabi版本可能非常旧可能是4.x而较新的RT-Thread BSP和组件可能需要更高版本的编译器支持例如对C11标准的完整支持、更好的优化。手动安装允许我们选择更合适的版本。4.2 下载与安装ARM GCC工具链我们前往ARM官方开发者网站或国内镜像站下载。这里我们选择版本10.3-2021.10这是一个比较稳定且较新的版本对Cortex-M系列支持良好。在~/workspace目录下操作cd ~/workspace # 下载64位主机用的工具链注意即使Ubuntu是32位但工具链是运行在主机上编译目标代码通常下载64位版本效率更高 # 但如果你的32位Ubuntu是运行在纯32位硬件上可能需要寻找旧的32位主机工具链这非常困难。 # 幸运的是ARM官方从某个版本后不再提供32位Linux主机工具链。因此我们假设你的32位Ubuntu是运行在64位CPU上绝大多数情况并使用64位工具链。 # 工具链是预编译的二进制文件只要主机有对应的64位库支持即可运行。32位系统需要安装64位运行库支持。 # 首先安装运行64位程序所需的库 sudo apt install -y libc6:i386 libncurses5:i386 libstdc6:i386 lib32z1 # 然后下载64位工具链 wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2如果下载速度慢可以使用国内镜像wget https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchains/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2下载完成后解压并安装到/opt目录这是一个存放第三方软件的标准位置sudo tar -xjf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 -C /opt解压后工具链位于/opt/gcc-arm-none-eabi-10.3-2021.10目录。为了方便使用我们将其二进制文件路径添加到系统的PATH环境变量中。编辑当前用户的~/.bashrc文件nano ~/.bashrc在文件末尾添加以下行# ARM GCC Toolchain PATH export PATH$PATH:/opt/gcc-arm-none-eabi-10.3-2021.10/bin保存并退出编辑器在nano中按CtrlX然后按Y确认再按Enter保存。让配置立即生效source ~/.bashrc现在验证工具链是否安装成功arm-none-eabi-gcc --version你应该能看到类似arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 10.3-2021.10) 10.3.1 20210824 (release)的输出。这证明64位的工具链在32位系统上成功运行了。踩坑记录这是32位系统上最大的一个坑。直接运行64位工具链会报错“找不到文件”或“无法执行二进制文件”。必须首先安装libc6:i386等多架构运行库。如果安装后仍不行可能需要检查系统是否启用了多架构支持dpkg --print-foreign-architectures如果没有i386则需要运行sudo dpkg --add-architecture i386 sudo apt update。我们的第一步sudo apt install -y libc6:i386 ...已经隐含了这个操作。5. 编译第一个BSP以STM32为例工具链就绪后我们就可以尝试编译一个具体的板级支持包了。这里以最常用的stm32BSP中的stm32f407-atk-explorer正点原子探索者开发板为例。5.1 进入BSP目录并进行菜单配置cd ~/workspace/rt-thread/rt-thread/bsp/stm32/stm32f407-atk-explorer首先执行菜单配置命令。这会启动一个基于ncurses的图形化配置界面你可以在这里选择需要启用的RT-Thread组件、配置内核参数、使能外设驱动等。scons --menuconfig如果这是第一次运行它会自动调用pkgs --update来更新软件包列表可能会从GitHub拉取索引需要一点时间。进入界面后你可以浏览各个菜单项。对于初次测试我们可以先保持默认配置直接保存退出。在配置界面中使用方向键移动Enter键进入子菜单或选择选项Y键启用N键禁用Space键切换选择状态对于多选项目。Esc键返回上级菜单。配置完成后选择 Save 并回车使用默认的.config文件名保存然后选择 Exit 退出。5.2 使用scons编译工程保存配置后直接使用scons命令进行编译sconsscons会读取当前目录下的SConscript构建脚本以及我们刚才生成的.config文件开始编译整个工程。你会看到大量的编译命令滚动输出。编译成功的标志是最后生成一个名为rtthread.elf、rtthread.bin和rtthread.hex的文件。.bin和.hex是纯二进制和十六进制格式的固件可以直接烧录到芯片的Flash中。.elf文件包含调试信息用于调试。编译问题排查错误arm-none-eabi-gcc: not found说明环境变量PATH没有设置正确。请检查~/.bashrc中的路径是否正确并执行source ~/.bashrc。也可以使用绝对路径测试/opt/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gcc --version。错误scons: command not found说明scons没有安装成功。请用pip list | grep scons检查并重新安装。编译过程中提示缺少头文件或库这通常是BSP特定的依赖。请回到BSP目录仔细阅读README.md文件里面通常会列出额外的软件包需求。例如某些STM32 BSP可能需要安装libnewlib-arm-none-eabi但通常RT-Thread使用了自己的newlib实现包含在源码中。内存不足导致编译中断32位系统每个进程的可用内存地址空间有限约3GB如果开启多线程编译scons -j4可能因内存耗尽而崩溃。建议首次编译时使用单线程默认scons即为单线程或使用scons -j2。5.3 清理与重新编译如果需要清理编译产物可以运行scons -c这会删除build目录存放中间文件和生成的固件文件。如果修改了配置menuconfig或者更新了源码重新编译只需再次执行scons即可。scons具有智能的增量编译能力只会重新编译改动过的部分。6. 开发辅助工具安装与配置一个完整的开发环境除了编译还需要代码编辑、串口调试和程序烧录等工具。6.1 代码编辑与阅读工具在Linux下VSCode是一个强大的选择但Ubuntu 16.04官方源中的版本极旧。我们可以通过微软的官方仓库来安装较新版本。首先导入微软GPG密钥并添加仓库curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor microsoft.gpg sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg sudo sh -c echo deb [archamd64] https://packages.microsoft.com/repos/vscode stable main /etc/apt/sources.list.d/vscode.list注意这里添加的是amd64架构的仓库。对于32位系统需要安装64位架构支持之前已安装libc6:i386等并且VSCode本身是64位应用。更新并安装sudo apt update sudo apt install -y code安装完成后可以在应用菜单找到Visual Studio Code。打开后建议安装以下扩展以提升RT-Thread开发体验C/C(Microsoft)提供代码智能感知、跳转、调试支持。RT-Thread Studio(RT-Thread)提供RT-Thread项目创建、配置、包管理等功能部分功能可能需要较新版本的RT-Thread BSP支持。Cortex-Debug用于ARM Cortex-M芯片的调试支持。Serial Monitor用于查看串口日志。如果VSCode无法启动提示GLIBC版本过低等说明系统库太老无法支持新版的VSCode。这时可以考虑使用其他轻量级编辑器如Vim配合ctags、cscope或VSCodium社区构建的开源版本可能对旧系统兼容性更好或者直接使用sublime text。6.2 串口调试工具minicom在嵌入式开发中串口是查看系统日志、进行交互式调试的最重要通道。minicom是一个经典、稳定的终端程序。安装minicomsudo apt install -y minicom配置minicom。建议以root权限进行初始配置以便保存配置到系统默认位置sudo minicom -s这会进入一个配置菜单选择“Serial port setup”。按A键设置串口设备通常USB转串口设备在Linux下为/dev/ttyUSB0或/dev/ttyACM0。请根据实际情况填写如/dev/ttyUSB0。按E键设置波特率等参数通常按E进入后再按I选择波特率为115200 8N1这是RT-Thread最常见的配置。数据位、停止位、奇偶校验通常保持默认8N1即可。按F键将硬件流控制Hardware Flow Control设置为No。设置完成后按回车返回主菜单。选择“Save setup as dfl”将当前配置保存为默认配置。然后选择“Exit”。以后要使用串口只需在终端输入minicom即可。退出minicom的快捷键是CtrlA然后按X选择Yes。实操技巧为了避免每次插拔USB串口线后设备号变化比如从ttyUSB0变成ttyUSB1可以使用udev规则创建固定的符号链接。创建一个文件/etc/udev/rules.d/99-usb-serial.rules加入如下内容以常见的Silicon Labs CP210x芯片为例SUBSYSTEMtty, ATTRS{idVendor}10c4, ATTRS{idProduct}ea60, SYMLINKrtthread_uart重启后无论设备插在哪个USB口都可以通过/dev/rtthread_uart来访问。使用lsusb命令可以查看你设备的idVendor和idProduct。6.3 程序烧录工具OpenOCD与ST-Link对于STM32系列ST-Link是常用的调试编程器。我们需要安装openocd开源片上调试器来与ST-Link交互。Ubuntu 16.04源中的openocd版本较老。我们可以从源码编译一个较新的版本或者使用PPA。这里使用一个较新的PPAsudo add-apt-repository ppa:team-gcc-arm-embedded/ppa sudo apt update sudo apt install -y openocd安装后连接你的STM32开发板和ST-Link到电脑。首先检查设备是否被识别lsusb | grep -i stm应该能看到类似STMicroelectronics ST-LINK/V2的设备。创建一个简单的OpenOCD配置文件例如stlink.cfg# stlink.cfg source [find interface/stlink-v2.cfg] source [find target/stm32f4x.cfg] transport select hla_swd reset_config srst_only然后你可以通过OpenOCD连接到芯片openocd -f stlink.cfg如果连接成功OpenOCD会启动一个telnet服务器默认端口4444和一个GDB服务器默认端口3333。在另一个终端你可以使用telnet连接进行一些简单操作或者使用GDB进行调试。更常见的烧录方式是使用openocd直接编程.bin或.hex文件。编写一个烧录脚本flash.cfg# flash.cfg source [find interface/stlink-v2.cfg] source [find target/stm32f4x.cfg] transport select hla_swd reset_config srst_only init reset halt flash write_image erase /path/to/your/rtthread.bin 0x08000000 reset run shutdown然后执行openocd -f flash.cfg这将擦除芯片Flash并将rtthread.bin文件烧录到起始地址0x08000000然后复位并运行。注意事项OpenOCD的配置文件路径[find interface/stlink-v2.cfg]依赖于OpenOCD的安装位置。如果上述命令找不到文件可以使用绝对路径或者使用find /usr -name stlink-v2.cfg来定位文件。不同版本的ST-LinkV1, V2, V2-1和不同系列的STM32芯片F1, F4, H7等需要选择对应的interface和target配置文件。7. 环境验证与第一个程序运行现在让我们将之前编译的固件烧录到开发板并验证整个环境是否工作正常。7.1 烧录固件假设你已经按照6.3节配置好了OpenOCD和ST-Link并且开发板已正确连接。进入你的BSP目录确认rtthread.bin文件存在。修改flash.cfg脚本中的固件路径为实际路径。在终端中运行OpenOCD烧录命令openocd -f flash.cfg观察输出应该看到“write complete”、“verified”等成功信息最后是“shutdown”。7.2 连接串口查看输出打开一个新的终端窗口。运行minicom。给开发板上电或按复位键。你应该在minicom窗口中看到RT-Thread的启动Logo和系统初始化信息类似于\ | / - RT - Thread Operating System / | \ 4.1.1 build May 10 2024 2006 - 2024 Copyright by RT-Thread team msh 看到msh 提示符恭喜你RT-Thread已经在你的开发板上成功运行了。msh是RT-Thread的微型Shell你可以在这里输入命令与系统交互例如help查看命令列表list_thread查看当前运行的线程等。7.3 运行示例程序在msh中你可以尝试运行BSP中自带的示例。例如很多BSP都开启了finsh组件和led示例。你可以输入msh led_blink如果开发板上有LED并且驱动正确你应该能看到LED开始闪烁。输入ps可以查看当前所有线程你应该能看到led_blink线程正在运行。8. 常见问题排查与优化技巧即便按照步骤操作你也可能会遇到一些问题。这里汇总了一些常见问题及其解决方法。8.1 编译相关问题问题1scons编译时出现大量undefined reference错误尤其是_sbrk,_write等。原因这通常是链接时找不到底层系统调用syscall的实现。在RT-Thread中这些函数在libc组件中实现。解决确保在menuconfig中已经启用了libc组件。路径通常为RT-Thread Components - POSIX layer and C standard library - Enable libc APIs from toolchain。选择后可能需要选择具体的实现如newlib或minilibc。保存配置后重新编译。问题2编译成功但生成的固件大小异常大超过芯片Flash容量。原因默认的scons编译可能没有开启优化并且包含了调试信息。解决可以在scons命令后添加优化选项。例如使用scons -c清理后再执行scons CFLAGS-Os LFLAGS-Os-Os是优化代码大小。你也可以使用-O2优化速度。更彻底的方法是在menuconfig的RT-Thread Kernel - Kernel Device Object中关闭调试选项如Enable components debugging和Enable thread debugging information。问题3在32位系统上编译大型BSP如STM32H7系列时scons因内存不足而崩溃。原因32位进程地址空间有限并行编译-j会消耗大量内存。解决使用单线程编译scons。增加系统交换空间Swap。创建一个2GB的交换文件sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile要永久生效需将/swapfile none swap sw 0 0添加到/etc/fstab。如果必须并行编译尝试减少线程数如scons -j2。8.2 烧录与调试问题问题1OpenOCD无法连接报错“Error: open failed”或“Cannot find ST-Link device”。检查lsusb是否能识别到ST-Link设备。当前用户是否在plugdev组需要重新登录生效。尝试使用sudo运行OpenOCD如果可行则是权限问题需要检查udev规则。解决创建udev规则。创建文件/etc/udev/rules.d/49-stlinkv2.rules内容如下# ST-LINK/V2 SUBSYSTEMusb, ATTR{idVendor}0483, ATTR{idProduct}3748, MODE0666, GROUPplugdev # ST-LINK/V2-1 SUBSYSTEMusb, ATTR{idVendor}0483, ATTR{idProduct}374b, MODE0666, GROUPplugdev重新插拔设备或运行sudo udevadm control --reload-rules sudo udevadm trigger。问题2烧录成功但串口无任何输出。检查串口线连接是否正确TX接RXRX接TXGND接GND。minicom的波特率、数据位、停止位、奇偶校验是否与BSP中rtconfig.h或board.h中定义的BAUD_RATE一致通常是115200。开发板的启动模式Boot0, Boot1引脚是否设置为从主Flash启动。芯片是否真的在运行。尝试按复位键观察minicom是否有瞬间乱码有时是波特率不匹配的表现。解决最稳妥的方法是使用调试器ST-Link OpenOCD GDB单步调试查看程序是否卡在启动文件的某个地方如时钟初始化。8.3 环境优化与使用技巧技巧1使用env工具进行图形化包管理和系统配置。RT-Thread提供了一个强大的env工具它集成了scons、menuconfig、pkgs软件包管理器等功能并提供了更友好的命令行界面。在旧系统上可以从RT-Thread官网下载对应版本的env工具包通常是Windows版但其中的pkgs等Python脚本在Linux下也可用或者直接使用scons --menuconfig和pkgs --update命令组合。env工具能极大简化软件包的添加、删除和更新。技巧2为VSCode配置智能感知。在RT-Thread BSP根目录下执行scons --targetvsc命令可以生成VSCode的c_cpp_properties.json配置文件其中包含了所有头文件路径和宏定义能显著提升VSCode中代码补全和跳转的准确性。技巧3利用qemu进行无硬件模拟。如果你手头没有具体的开发板或者想在特定架构如ARM Cortex-A, RISC-V上学习RT-Thread可以使用QEMU进行模拟。RT-Thread的bsp目录下包含qemu-vexpress-a9ARM Cortex-A9等模拟器BSP。安装qemu-system-arm后直接在该BSP目录下scons编译然后运行qemu.sh脚本即可在QEMU窗口中运行RT-Thread这对于学习和调试内核非常方便。搭建这个“复古”环境的过程更像是一次对嵌入式开发基础工具的梳理。每一步的依赖、每一个配置选项、每一个错误提示都在加深你对构建系统、工具链和硬件平台之间关系的理解。当串口终端上终于跳出RT-Thread的Logo时那种解决问题的成就感是直接使用现成集成IDE无法比拟的。这个环境一旦搭建稳定就会成为一个可靠的基石让你能更专注于RT-Thread本身的学习和产品开发。