第2章:构建环境准备
搭建开发环境这件事,说难不难,说简单也不简单。我见过太多新手卡在这一步,折腾一整天连个hello world都跑不起来。今天我就把踩过的坑、总结的经验,一次性说清楚。
2.1 操作系统选择
我个人习惯用Ubuntu 20.04 LTS或22.04 LTS。为什么?因为NuttX的官方CI测试主要跑在这两个版本上。你用Windows也行,但得装WSL2,而且有些串口工具会出问题。
如果你非要用macOS,嗯,也可以。但要做好心理准备——某些工具链需要自己编译,Homebrew里的版本经常滞后。
2.2 安装必要工具
先把基础工具装好。打开终端,执行:
sudo apt update
sudo apt install -y \
build-essential \
git \
wget \
flex \
bison \
gperf \
python3 \
python3-pip \
python3-venv \
cmake \
ninja-build \
ccache \
libncurses-dev \
libusb-1.0-0-dev \
libhidapi-dev \
pkg-config
这里面有几个关键点:
- flex和bison:NuttX的Kconfig解析器依赖它们。缺了这两个,你连menuconfig都跑不起来。
- ccache:加速编译的神器。我建议你装上,特别是频繁修改配置时,能省一半时间。
- python3-venv:后面装西风工具链会用到。
gcc --version和python3 --version确认一下。我曾经遇到过系统自带的python3指向python2的奇葩情况。
2.3 下载NuttX源码
源码管理用的是Git。我个人习惯把NuttX相关代码都放在~/nuttx目录下:
mkdir -p ~/nuttx
cd ~/nuttx
git clone https://github.com/apache/nuttx.git
git clone https://github.com/apache/nuttx-apps.git apps
这里要注意两点:
- apps目录必须和nuttx平级。NuttX的构建系统默认在
../apps找应用代码。我第一次搞的时候把apps放错了位置,编译时一堆"找不到头文件"的错误。 - 建议切到稳定分支。master分支可能正在开发新功能,有时候会编译不过。我一般用
git checkout tags/nuttx-12.4.0这样的发布版本。
2.4 配置工具链
工具链的选择取决于你的目标芯片。这里我以最常用的ARM Cortex-M系列为例:
2.4.1 安装ARM GCC工具链
cd ~/nuttx
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
tar xjf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2
export PATH=~/nuttx/gcc-arm-none-eabi-10.3-2021.10/bin:$PATH
为什么选10.3版本?因为NuttX的构建脚本对这个版本测试最充分。我试过11.2版本,编译某些驱动时会报奇怪的链接错误。
gcc-arm-none-eabi包。Ubuntu仓库里的版本太旧了,有些新指令集不支持。我曾经因为这个折腾了两天,最后发现是工具链版本问题。
2.4.2 验证工具链
arm-none-eabi-gcc --version
arm-none-eabi-gdb --version
看到版本信息就对了。如果提示"command not found",检查一下PATH有没有设置对。
2.5 熟悉Kconfig结构
Kconfig是NuttX的配置系统。说白了,就是让你通过菜单选择要开启哪些功能。它的核心文件分布如下:
| 文件/目录 | 作用 |
|---|---|
| nuttx/Kconfig | 顶层配置入口,包含所有子模块 |
| nuttx/arch/Kconfig | 架构相关配置(ARM、RISC-V等) |
| nuttx/drivers/Kconfig | 驱动配置(UART、SPI、I2C等) |
| nuttx/fs/Kconfig | 文件系统配置(FAT、NFS、PROCFS等) |
| apps/Kconfig | 应用层配置(shell、网络工具等) |
配置语法其实很简单。举个例子,你想添加一个文件系统选项:
config FS_MYFS
bool "My Custom File System"
default n
depends on FS_READABLE
select FS_WRITABLE
help
Enable support for my custom file system.
这里bool表示开关选项,default n默认关闭,depends on是依赖关系,select是自动选中其他选项。
depends on和select别混用。depends on是"如果A不选,B就不显示";select是"选了B就自动选A"。我见过有人用select搞出循环依赖,编译时直接报错。
2.6 理解Makefile体系
NuttX的Makefile体系分三层:
- 顶层Makefile:在nuttx目录下,负责调用架构相关的构建规则
- 架构Makefile:在arch/arm/src/下,定义编译选项和链接脚本
- 模块Makefile:每个驱动或组件都有自己的Makefile
一个典型的模块Makefile长这样:
include $(TOPDIR)/Make.defs
CSRCS = myfs_util.c myfs_vfs.c
ifeq ($(CONFIG_FS_MYFS_DEBUG),y)
CSRCS += myfs_debug.c
endif
include $(TOPDIR)/Make.flat
这里CSRCS列出源文件,ifeq根据配置条件编译。最后include Make.flat是NuttX的通用编译规则。
Make.flat或Make.defs。我刚开始做移植时,想当然地写了自定义规则,结果链接时符号找不到,排查了整整一个下午。
2.7 第一次编译验证
环境搭好了,我们来验证一下。以STM32F4Discovery开发板为例:
cd ~/nuttx/nuttx
./tools/configure.sh stm32f4discovery:nsh
make -j$(nproc)
如果一切顺利,你会看到nuttx.bin和nuttx.elf生成。这说明你的环境完全OK。
-j参数,或者只加-j2。这样出错时能看到完整的错误信息。等确认没问题了,再用多核编译加速。
嗯,到这里环境就准备好了。下一章我们开始真正动手——把一个新的文件系统移植到NuttX里。到时候你会用到今天装的这些工具,也会频繁修改Kconfig和Makefile。所以这一章的基础一定要打牢。
公众号:蓝海资料掘金营,微信deep3321