第2章:开发环境搭建

好,咱们正式开始动手了。这一章我带你把开发环境搭起来。说白了,就是三件事:装好交叉编译工具链、配好模拟器、然后跑通第一个程序。

很多新手卡在这一步,其实挺冤的。工具链版本不对、路径没配好、模拟器参数写错……我当年刚接触NuttX时,光装环境就折腾了两天。嗯,后来发现是文档里一个路径写错了。所以这一章,我会把那些坑都指出来。

2.1 交叉编译工具链安装

NuttX支持几十种架构,ARM、RISC-V、Xtensa……你用的板子是什么核,就装对应的工具链。我个人习惯用ARM Cortex-M系列做演示,因为最常见。

核心原则:工具链版本必须与NuttX版本匹配。太新的GCC可能引入不兼容的ABI,太旧的又缺特性。

以ARM为例,我推荐用 gcc-arm-none-eabi。安装方式有两种:

  1. 包管理器安装(推荐新手)
    sudo apt-get install gcc-arm-none-eabi
    # Ubuntu/Debian 系
    brew install gcc-arm-none-eabi
    # macOS
  2. 手动下载(推荐进阶)

    去ARM官网下载最新版,解压到 /opt/usr/local。然后配环境变量:

    export PATH=$PATH:/opt/gcc-arm-none-eabi-10.3-2021.10/bin
    # 建议写入 ~/.bashrc 或 ~/.zshrc

注意:我曾经遇到过一个问题——用apt装的工具链版本太旧,编译NuttX的POSIX接口时报了奇怪的链接错误。后来换成10.3版本就解决了。所以,如果编译报错,先检查工具链版本。

验证安装是否成功:

arm-none-eabi-gcc --version
# 应该看到类似 "arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10)" 的输出

你想想看,如果这里输出的是 command not found,那八成是PATH没配好。别慌,检查一下路径写对了没。

2.2 模拟器环境配置

没有开发板?没关系。NuttX支持QEMU模拟器,你可以在电脑上直接跑。我个人觉得这是学习NuttX最好的方式——不用烧录、不怕变砖、调试方便。

安装QEMU:

sudo apt-get install qemu-system-arm
# 或者
brew install qemu

NuttX官方提供了几个QEMU支持的板级配置,比如 qemu-armv7aqemu-riscv。我建议从 qemu-armv7a:nsh 开始,因为它最简单。

小技巧:如果你用的是Windows,可以用WSL2。我试过,性能损失很小,而且能直接用Linux的命令行工具链。别用Cygwin,坑太多。

2.3 首次编译与运行

好,工具链和模拟器都装好了。现在我们来编译第一个NuttX镜像。

先克隆NuttX源码:

git clone https://github.com/apache/nuttx.git
cd nuttx

然后配置板级:

./tools/configure.sh qemu-armv7a:nsh
# 这个命令会生成 .config 文件

接着编译:

make -j$(nproc)
# 第一次编译会下载一些依赖,耐心等几分钟

编译成功后,你会看到 nuttx.binnuttx.elf 两个文件。前者是裸二进制,后者带调试信息。

运行它:

qemu-system-arm -M virt -kernel nuttx.bin -nographic
# -M virt 指定虚拟开发板
# -kernel 加载内核镜像
# -nographic 用终端交互

如果一切顺利,你会看到NuttX的启动日志,最后出现 nsh> 提示符。输入 help 看看有哪些命令可用。

常见问题:

  • 编译报错 "undefined reference to ...":八成是工具链版本不对。我建议用10.3或11.2版本。
  • QEMU启动后黑屏:检查一下 -nographic 参数有没有漏掉。或者试试 -serial mon:stdio
  • NSH提示符不出现:等几秒钟,或者按一下回车。有时候启动慢。

嗯,这里要注意一点:第一次编译时,NuttX会下载一些子模块(比如 apps/tools/)。如果网络不好,可能会卡住。你可以提前用 git submodule update --init 手动拉取。

我曾经在客户现场演示时,网络突然断了,编译卡在下载子模块那一步。后来我学乖了,出差前一定先 make distclean 然后重新编译一遍,确保所有依赖都缓存好了。

2.4 验证环境是否就绪

跑通第一个程序后,我建议你做三件事来确认环境没问题:

  1. 编译一个带网络功能的配置:比如 qemu-armv7a:netnsh,验证网络协议栈能正常初始化。
  2. 尝试调试:用 arm-none-eabi-gdb nuttx.elf 连接QEMU的GDB stub(启动QEMU时加 -s -S 参数)。
  3. 清理并重新编译make distclean && ./tools/configure.sh qemu-armv7a:nsh && make,确保整个过程可重复。

我的习惯:每次换新电脑或新系统,我都会先跑一遍这个流程。花10分钟验证环境,能省下后面调试时的一堆麻烦。

好了,环境搭好了。下一章我们开始分析板级支持包的目录结构,看看NuttX是怎么把内核和硬件联系起来的。