第2章:NuttX开发环境搭建
好,咱们直接进入正题。搭建开发环境这件事,说简单也简单,说复杂也复杂。我见过不少新手,一上来就卡在环境配置上,折腾一整天还没编译通过。其实说白了,就是几个关键步骤没搞对。
我个人习惯用Ubuntu 20.04 LTS作为开发主机。为什么选这个版本?因为我在项目中踩过坑——Ubuntu 22.04的某些库版本和NuttX的旧版本不兼容,编译时会报一些莫名其妙的错误。所以,如果你刚开始学,老老实实用20.04,省心。
2.1 交叉编译工具链安装
交叉编译,说白了就是在你的PC上编译出能在ARM、RISC-V等嵌入式芯片上运行的代码。你想想看,你的电脑是x86架构,而汽车上的MCU通常是ARM Cortex-R或Cortex-M系列,没有交叉编译工具链,你拿什么编译?
安装步骤其实就几条命令:
# 更新软件源
sudo apt update
# 安装必备工具
sudo apt install -y \
build-essential \
git \
flex \
bison \
libncurses-dev \
libgmp-dev \
libmpfr-dev \
libmpc-dev \
texinfo \
wget
# 下载ARM交叉编译工具链
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 -C /opt/
# 配置环境变量
echo 'export PATH=$PATH:/opt/gcc-arm-none-eabi-10.3-2021.10/bin' >> ~/.bashrc
source ~/.bashrc
# 验证安装
arm-none-eabi-gcc --version
验证安装成功后,你会看到类似这样的输出:
arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
嗯,看到这个就说明工具链装好了。不过要注意,不同芯片架构需要不同的工具链。比如你要用RISC-V,那就得装riscv64-unknown-elf-gcc。我在一个项目中同时用了ARM和RISC-V两颗芯片,环境变量里配了两套工具链,切换时特别容易搞混。后来我写了个脚本,每次编译前自动检测芯片类型,这才彻底解决。
2.2 NuttX源码下载与配置
源码下载,我推荐用git clone。别去官网下压缩包,那玩意儿更新不及时。NuttX的代码库分两部分:主仓库和apps仓库。主仓库是内核代码,apps仓库是应用程序和库。
# 创建工作目录
mkdir ~/nuttx_workspace
cd ~/nuttx_workspace
# 克隆主仓库
git clone https://github.com/apache/nuttx.git
# 克隆apps仓库
git clone https://github.com/apache/nuttx-apps.git apps
# 切换到稳定版本(比如nuttx-12.4.0)
cd nuttx
git checkout nuttx-12.4.0
cd ../apps
git checkout nuttx-12.4.0
下载完成后,目录结构应该是这样的:
~/nuttx_workspace/
├── nuttx/ # 内核源码
│ ├── arch/ # 架构相关代码
│ ├── drivers/ # 设备驱动
│ ├── fs/ # 文件系统
│ ├── include/ # 头文件
│ ├── sched/ # 调度器
│ └── ...
└── apps/ # 应用程序
├── examples/ # 示例程序
├── system/ # 系统工具
├── netutils/ # 网络工具
└── ...
2.3 使用make menuconfig进行内核裁剪
内核裁剪,这是NuttX开发中最核心的一步。你想想看,汽车上的MCU资源有限,Flash可能就512KB,RAM才128KB。如果不裁剪,一个完整的内核就能吃掉大半资源,你的应用代码往哪放?
配置命令很简单:
cd ~/nuttx_workspace/nuttx
make distclean # 清理之前的配置
make menuconfig
执行后会弹出一个图形化配置界面。嗯,这个界面虽然看着复古,但功能很强大。我刚开始用的时候也觉得别扭,用习惯了反而觉得比那些花里胡哨的IDE配置工具好用。
配置界面主要分这几块:
| 配置项 | 说明 | 我的建议 |
|---|---|---|
| Board Selection | 选择目标开发板 | 先选官方支持的板子,比如STM32F4Discovery |
| RTOS Features | 内核功能配置 | 关掉不需要的IPC、信号量等 |
| Device Drivers | 设备驱动选择 | 只保留你硬件上有的外设驱动 |
| File Systems | 文件系统配置 | 汽车电子常用PROCFS、SPIFFS |
| Networking | 网络协议栈 | 如果不用网络,直接关掉,能省不少内存 |
具体裁剪时,我一般遵循这个原则:用不到的,坚决不选。比如你的项目只需要CAN通信,那把USB、以太网、SD卡这些驱动统统关掉。别觉得以后可能用到就留着,嵌入式开发不是写PC软件,资源就是生命线。
配置完成后,保存退出。然后执行编译:
make -j4
第一次编译会比较慢,大概5-10分钟。编译成功后,会在nuttx目录下生成nuttx.bin文件,这就是最终的内核镜像。
最后,我建议你把配置保存下来:
# 保存配置到文件
cp .config my_project.config
# 下次直接加载
cp my_project.config .config
make oldconfig
这样,你每次新建项目时,直接加载之前的配置,再微调一下就行,不用从头开始配。我在团队里就是这么做的——维护一个「基础配置库」,不同项目直接复用,效率高很多。
好了,环境搭建这部分就讲到这里。下一章我们聊聊NuttX的任务管理,这可是实时操作系统的核心。你想想看,汽车上那么多任务同时跑,怎么保证它们不打架?嗯,到时候你就知道了。