Ubuntu 22.04 编译安装 Apache NuttX 13.1.0 指南

在 Ubuntu 22.04 上编译安装 Apache NuttX 13.1.0,覆盖 sim 模拟器目标与 STM32 ARM 交叉编译目标的完整实测指南。

Apache NuttXNuttXApacheRTOS嵌入式安装部署Ubuntu 22.042026/10/15

Ubuntu 22.04 编译安装 Apache NuttX 13.1.0 指南

目标:在一台 Ubuntu 22.04 服务器上从官方源码包编译 Apache NuttX 13.1.0:先构建 sim 模拟器目标并运行 NSH 采集验证,再以 gcc-arm-none-eabi 完成 STM32 交叉编译,全流程已在 Ubuntu 22.04 实测通过。

一、环境信息

项目内容
操作系统Ubuntu 22.04.5 LTS(内核 6.8.0-138-generic)
系统架构x86_64(amd64)
编译工具链gcc 11.4.0、GNU Make 4.3、flex 2.6.4、bison 3.8.2、gperf 3.1、genromfs
配置工具python 3.10.12 + kconfiglib 14.1.0(menuconfig/olddefconfig 等)
交叉工具链arm-none-eabi-gcc 10.3.1(apt 包 gcc-arm-none-eabi)
NuttX 版本13.1.0(apache-nuttx-13.1.0.tar.gz 与 apache-nuttx-apps-13.1.0.tar.gz)
源码布局/opt/nuttx/nuttx 与 /opt/nuttx/apps 同级
产物nuttx(sim:x86-64 ELF;stm32f4discovery:ARM 32 位 ELF)

说明:NuttX 是 Apache 旗下实时操作系统,采用自研的 Makefile + Kconfig 构建体系;apps 是官方应用仓库(NSH、示例、网络应用等),与 nuttx 源码同级目录放置即可被构建系统发现。

💡 技术拓展:RTOS 构建系统怎么选?NuttX 自研体系(Kconfig + Make,本文实测)零额外依赖,配置项即 C 宏;Zephyr 的 CMake + west 依赖重但生态新;Mynewt 的 newt 自带包管理(见本站 Mynewt 系列)。NuttX 的特点是用 tools/configure.sh <板>:<配置> 一条命令落配置,再用一条 make 出固件,学习曲线最平。本文全部围绕 NuttX 自研构建体系展开。

二、前置条件与依赖安装

2.1 安装编译工具

apt-get update
apt-get install -y gcc g++ make libncurses-dev flex bison gperf genromfs git wget curl unzip

回显(输出节选):

Setting up gperf (3.1-1build1) ...
Setting up genromfs (0.5.2-2) ...

验证:

gcc --version | head -1
make --version | head -1
gperf --version | head -1

回显:

gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
GNU Make 4.3
GNU gperf 3.1

2.2 安装 Kconfig 工具链(含关键排障)

NuttX 配置阶段依赖 kconfig-tweak、menuconfig、olddefconfig 等命令。Ubuntu 22.04 没有 kconfig-frontents 软件包(apt-cache policy 查询为空),可用 pip 的 kconfiglib:

apt-get install -y python3-pip
pip3 install kconfiglib
ls /usr/local/bin/ | grep -E "menuconfig|olddefconfig|savedefconfig" | head

回显(输出节选):

defconfig
menuconfig
olddefconfig
savedefconfig

踩坑一:kconfiglib 不提供 kconfig-tweak。tools/configure.sh 调用的 sethost.sh 直接执行 kconfig-tweak,实测缺它时报 kconfig-tweak: command not found。kconfiglib.py 无按文件名分发的能力(实测符号链接为 kconfig-tweak 后执行报语法错误),需写一个最小替换脚本覆盖 sethost.sh 用到的 4 种调用(--file/--enable/--disable/--set-str/--set-val):

cat > /usr/local/bin/kconfig-tweak <<'EOF'
#!/bin/bash
# Minimal kconfig-tweak replacement for NuttX sethost.sh
f=.config; mode=""; sym=""; val=""
while [ $# -gt 0 ]; do
  case "$1" in
    --file) f="$2"; shift 2;;
    --enable|--disable|--set-str|--set-val) mode="$1"; sym="$2"; shift 2;;
    *) val="$1"; shift;;
  esac
done
base="${sym#CONFIG_}"
case "$mode" in
  --enable)
    sed -i "s|^# ${base} is not set|${sym}=y|; s|^${sym}=n$|${sym}=y|" "$f"
    grep -q "^${sym}=" "$f" || echo "${sym}=y" >> "$f" ;;
  --disable)
    sed -i "s|^${sym}=y$|# ${base} is not set|" "$f" ;;
  --set-str)
    if grep -q "^${sym}=" "$f"; then sed -i "s|^${sym}=.*$|${sym}=\"${val}\"|" "$f"; else echo "${sym}=\"${val}\"" >> "$f"; fi ;;
  --set-val)
    if grep -q "^${sym}=" "$f"; then sed -i "s|^${sym}=.*$|${sym}=${val}|" "$f"; else echo "${sym}=${val}" >> "$f"; fi ;;
esac
exit 0
EOF
chmod +x /usr/local/bin/kconfig-tweak

解说:sethost.sh 在 Linux 宿主上只做“禁用 WINDOWS/MACOS/BSD 宏、启用 HOST_LINUX 与 SIM_X8664_SYSTEMV、olddefconfig”几个动作,上述脚本完全覆盖其调用面。补齐后 configure.sh 正常走通。

踩坑二:xxd 缺失导致链接失败。sim:nsh 配置启用了 /etc romfs 镜像,构建时把 init.rc 经 genromfs 打包后用 xxd 转 C 数组;Ubuntu 默认无 xxd,实测链接报大量 undefined reference to romfs_img:

apt-get install -y vim-common
which xxd

回显:

/usr/bin/xxd

注意:若曾在缺 xxd 状态下编译过,中间产物 etctmp.c 已是坏文件且时间戳较新不会被重生成,需删除 boards/sim/sim/sim/src/etctmp.c 后重编(详见 FAQ Q3)。

三、获取源码并校验

mkdir -p /opt/nuttx && cd /opt/nuttx
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-13.1.0.tar.gz
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-13.1.0.tar.gz.sha512
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-apps-13.1.0.tar.gz
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-apps-13.1.0.tar.gz.sha512

官方 .sha512 为多行无文件名格式,逐包校验:

for f in apache-nuttx-13.1.0.tar.gz apache-nuttx-apps-13.1.0.tar.gz; do
  wget -q https://dlcdn.apache.org/nuttx/13.1.0/$f.sha512 -O - | sha512sum -c -
done

回显:

apache-nuttx-13.1.0.tar.gz: OK
apache-nuttx-apps-13.1.0.tar.gz: OK

解说:dlcdn 的 .sha512 文件内容为“摘要 空格 文件名”单行格式,恰好能被 sha512sum -c 直接校验,两个包实测均为 OK。本地留存基线值:

sha256sum apache-nuttx-13.1.0.tar.gz apache-nuttx-apps-13.1.0.tar.gz

回显:

3f0fd8c0289b01865fdec3bba3d7747635b8f568fb8d6450b1a98aa0a3438d33  apache-nuttx-13.1.0.tar.gz
86fdee110058f0303041b9b62d467aa0795a5f11a3caeeab108c558ebba45ac4  apache-nuttx-apps-13.1.0.tar.gz

解压为标准布局(nuttx/ 与 apps/ 同级):

tar xzf apache-nuttx-13.1.0.tar.gz
tar xzf apache-nuttx-apps-13.1.0.tar.gz
mv apache-nuttx-apps-13.1.0 apps
ls

回显:

apache-nuttx-13.1.0.tar.gz  apps  nuttx  apache-nuttx-apps-13.1.0.tar.gz

解说:主线包解压后目录名就是 nuttx/(无版本前缀);apps 包解压为 apache-nuttx-apps-13.1.0/,重命名为 apps 即成标准布局。构建系统按 ../apps 相对路径找应用仓库。

四、配置 sim 模拟器目标

cd /opt/nuttx/nuttx
./tools/configure.sh sim:nsh

回显(输出节选):

  Copy files
  Select the host platform: Linux
  Refreshing...

解说:configure.sh 做三件事——拷贝 boards/sim/sim/sim/configs/nsh/defconfig 为 .config、执行 sethost.sh 调整宿主宏、olddefconfig 补齐依赖项。生成物为 .config 与 Make.defs:

grep -E "CONFIG_HOST_LINUX=|CONFIG_SIM_X8664_SYSTEMV=|CONFIG_NSH_LIBRARY" .config | head -3

回显:

CONFIG_HOST_LINUX=y
CONFIG_NSH_LIBRARY=y

解说:HOST_LINUX 确认宿主设置成功;NSH_LIBRARY 表示 NSH shell 已并入配置。如需改配置,用 make menuconfig(kconfiglib 的 menuconfig,实测可用)保存退出即可。

五、编译与运行验证

5.1 编译

make -j$(nproc)

回显(输出节选):

LD: nuttx
make: Leaving directory '/opt/nuttx/nuttx'

验证产物:

ls -l nuttx

回显:

-rwxr-xr-x 1 root root 4663747 Oct 14 17:36 nuttx

解说:sim 目标产物约 4.5MB,是宿主 x86-64 可执行文件(ELF64),直接可运行。

5.2 运行 NSH

NuttX sim 本就是设计为在 Linux 开发机上直接运行的官方特性,执行产物即进入交互式 NSH:

./nuttx

回显:

NuttShell (NSH) NuttX-13.1.0
nsh> uname -a
NuttX 13.1.0 2b5c0de5e9 Oct 14 2026 17:36:14 sim sim
nsh>

解说:banner 表明版本 13.1.0、目标板 sim、架构 sim。把命令写进文件管道喂入即可批量执行(NSH 命令实测明细见本系列《Apache NuttX 13.1.0 NSH 常用命令详解》)。

5.3 systemd 托管说明

NuttX sim 是开发期工具,不建议作为系统服务常驻;如确需后台挂起,用 tmux/screen 会话托管即可,不写 systemd 单元(固件模拟进程无守护化价值)。

六、ARM 交叉编译方案

6.1 安装交叉工具链

apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi
arm-none-eabi-gcc --version | head -1

回显:

arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1 20210621 (release)

6.2 切换目标并编译

make distclean
./tools/configure.sh stm32f4discovery:nsh
make -j$(nproc)

回显(输出节选):

LD: nuttx

验证产物架构:

ls -l nuttx nuttx.hex
arm-none-eabi-readelf -h nuttx | grep -E "Class|Machine|Entry"
arm-none-eabi-size nuttx

回显:

-rwxr-xr-x 1 root root 276056 Oct 14 17:41 nuttx
-rw-r--r-- 1 root root 257696 Oct 14 17:41 nuttx.hex
  Class:                             ELF32
  Machine:                           ARM
  Entry point address:               0x8000189
   text    data     bss     dec     hex filename
  90711     884    4604   96199   177c7 nuttx

解说:ELF32 + ARM 确认是 STM32 固件;text 90711 字节说明 nsh 精简配置体积约 89KB;nuttx.hex 是烧录用 Intel HEX。distclean 会清掉 sim 配置与产物,两个目标切换需重编(FAQ Q7 给出共存技巧)。烧录不属本文范围,产物可交由 st-flash/openocd 流程。

七、方案对比

维度sim:nsh(本文主线)stm32f4discovery:nsh(交叉编译)其他 ARM 板
工具链宿主 gcc 11.4.0arm-none-eabi-gcc 10.3.1按芯片选
产物形态x86-64 ELF,直接运行ARM ELF32 + hex,烧录同左
运行验证开发机上直接跑 NSH需真机/仿真器需真机
配置入口tools/configure.sh sim:nshtools/configure.sh stm32f4discovery:nsh同格式
适用阶段逻辑开发/测试/学习真机部署真机部署
实测结论通过编译通过(未烧录)—

解说:NuttX 官方推荐工作流即“sim 先行、真机收尾”; boards/ 下 500+ 板级配置都以 <板>:<配置> 形式可用,切换成本只有一条命令。

八、常见问题(FAQ)

Q1:configure.sh 报 kconfig-tweak: command not found? A:Ubuntu 22.04 无 kconfig-frontents 包。pip3 install kconfiglib 提供了 menuconfig/olddefconfig 但不含 kconfig-tweak,按 2.2 节脚本补一个最小实现即可;只依赖 sed/grep,无需编译。

Q2:make 链接报 undefined reference to romfs_img? A:sim:nsh 需要把 init.rc 打包进 romfs,构建规则调用 xxd 而 Ubuntu 默认没装。apt-get install vim-common 后重编;若之前失败过,还要删掉 boards/sim/sim/sim/src/etctmp.c 这个坏中间产物再编(时间戳问题导致它不会自动重生成)。

Q3:装了 xxd 还是链接失败? A:检查 Makefile 里 romfs 目标的中间文件(etctmp.c/etctmp)是否残留坏内容。rm -f boards/sim/sim/sim/src/etctmp.c 后 make 重新走一遍生成链即可,实测恢复正常。

Q4:运行 ./nuttx 报错或卡住? A:sim 目标以交互方式运行,管道喂命令时注意最后加 exit;若报 tcsetattr 类错误,确认 stdin 是终端或管道(重定向文件也支持)。图形类 sim 配置(nx/uikit)才需要 X 环境,nsh 无需。

Q5:make menuconfig 中文乱码或方向键无效? A:确认终端 UTF-8 且 libncurses-dev 已装;kconfiglib 的 menuconfig 是 Python 实现,对终端兼容性好于老 kconfig-frontents,实测方向键/空格/ESC 正常。

Q6:如何恢复改乱的 .config? A:make distclean 彻底清空后重新 configure.sh;或用 make olddefconfig 按当前 .config 补齐缺失项。想导出精简 defconfig 用 make savedefconfig(kconfiglib 版可用)。

Q7:sim 和 arm 目标能共存吗? A:同一源码树同一时刻只有一份 .config,切目标需 make distclean + configure.sh。要共存就复制两份源码目录(如 /opt/nuttx/nuttx 与 /opt/nuttx-arm/nuttx),代价是磁盘与重复编译时间。

Q8:交叉编译产物怎么确认没用错工具链? A:arm-none-eabi-readelf -h nuttx 看 Machine 应为 ARM(实测 0x28)、Class 为 ELF32;宿主 gcc 产物则是 x86-64 ELF。Entry point 与链接脚本(ld.script)匹配即说明目标选对。

Q9:apps 仓库放哪里才被识别? A:与 nuttx/ 同级并命名为 apps/(实测 mv apache-nuttx-apps-13.1.0 apps)。构建系统按固定相对路径引用,放别处会在 make 阶段报找不到 apps 相关目标。

Q10:如何卸载? A:见下节。

九、卸载

cd /opt/nuttx/nuttx
make distclean
rm -rf /opt/nuttx
pip3 uninstall -y kconfiglib
apt-get purge -y gcc-arm-none-eabi

解说:distclean 恢复源码树到发布状态;删除源码目录、pip 包与交叉工具链即完全卸载;kconfig-tweak 包装脚本一并删除(rm -f /usr/local/bin/kconfig-tweak)。

十、参考链接