Nuttx应该是一个不错的系统,有瓜可挖。小米的澎湃os底层内核使用的就是它。 翻出之前别人送我的imax6ul开发板,在那安安静静的吃灰,有了想动一动的冲动。于是想到给自己定一个小目标,逐步实现Nuttx内核系统在imax6ul的开发板上移植,并开展些有意思的实验。
前言
小米宣布全新自研的操作系统—小米澎湃OS的出炉,这个系统是基于深度改造的Android,加上自研的Vela系统(基于Nuttx内核)合并而成,彻底重建了底层架构。
NuttX是一个成熟的实时操作系统,于07年由Gregory Nutt先生正式开源,2016年被三星选为TizenRT操作系统的内核,2019年在小米的推动下正式进入Apache基金会,经过开源社区多年的不懈努力,NuttX功能丰富,性能稳定,商业化成熟度高,Fitbit最近两代的手环产品和索尼多款消费级产品都是基于NuttX开发的。
即便不用,学习研究也是不错的。它比linux轻量级,除了驱动和各个板子的包,其余代码量也不是很大。用来学习玩一玩也是不错的选择,它还能在esp32和stm32单片机上跑呢。分享下猫哥(熬夜晚上更有精神的猫)的学习方法,其实很简单。就是实战,动手去做项目。
像linux之父Linus大佬说的一句名言 “ Talk is cheap, show me the code ,just read the fucking source code!” 。如果你从事编程领域的工作却没有听过,请自行面壁 3 分钟 :) 。但是哪有那么多项目练?自己给自己找啊,权当是拿来玩的,just for fun。
Linus 在学习Minix操作系统的过程中,对自带的终端仿真程序非常不满,于是自己写了一个。然后他不想在Minix系统里写,想要在无系统的裸硬件上写,来更好的理解计算机的执行原理。于是他需要知道cpu的工作原理,知道如何写入屏幕,如何读取键盘的输入,如何读写modem,这就是操作系统的雏形。Linus 用这个终端程序登入学校的电脑,查阅电子邮件,参加Minix新闻组的讨论,但是他还想上传和下载文件,于是还需要磁盘驱动程序和文件系统驱动,这是巨大的工作量。他的日程从此变成了编程-睡觉-编程-睡觉的循环,在过程中,这个终端越来越像操作系统,于是Linus 干脆决定把这个终端做成操作系统。
要做成操作系统,还有一个巨大的挑战,那就是要实现Posix规范,也就是Unix系统里的系统调用,有了这些系统api,其他Unix的程序就可以在这个操作系统上运行。Linus 在电子邮件新闻组里求助未果后,找到Sun公司Unix系统的用户手册,然后根据基本版的系统调用标准,开始自己实现这些功能。在1991年9月17日,Linus把操作系统上传到FTP上,那个时候的Linux操作系统大概1w行左右,而现在Linux超过1000w行代码。所以,你如今看到的庞然大物,大名鼎鼎的linux系统起初也是源于Linus的《just for fun》. Linus的人生哲学,Linus认为驱动人类的是三点动机:生存,人在社会秩序中的位置,以及娱乐。Linus在那年夏天我做了两件事。第一件是什么都没做。第二件事是读完了七百一十九页的《操作系统:设计和执行》。那本红色的简装本教科书差不多等于睡在了我的床。
在软件世界中,一旦你解决了最根本的的问题,兴趣就容易很快地消失。一旦你遇到了不知道而想要了解的东西,兴趣就很容易上来。nuttx就是一个可以让人产生兴趣的东西。
分享下我的学习三步法:
1.定一个小目标(不是挣它一个亿啊)
2.专注努力达成目标(不轻言放弃)
3.总结分享(学到的写出来也教会别人,费曼学习法)
NuttX官网地址:nuttx.apache.org/
NuttX的优点
在 NuttX 开源社区积极做贡献的,除了小米之外,还有索尼和NXP。很明显,这个系统肯定是有巨大优点,才会吸引大厂持续投入的。小米智能家居系统基于nuttx。
事实确实如此,这个系统最大的优点,就是原生支持对 POSIX 接口的兼容(可商用化RTOS中的唯一)。这也就意味着广受欢迎的 Linux 平台之现有开源库和组件,都可以很方便地移植到 NuttX 系统上。另外由于软件平台对硬件平台作出了隔离和统一,因此厂商的上层应用代码在移植到不同硬件平台时也可以更好地复用。
NuttX对POSIX标准有原生兼容:NuttX是可商用化RTOS中唯一一个对POSIX API有原生支持的实时操作系统,所以很多Linux社区的开源软件可以很方便的移植到NuttX上,这样可以极大的简化开源软件移植,方便代码复用,降低学习曲线,其它RTOS需要适配层把POSIX API转成内部API,而且通常只兼容一小部分的POSIX接口。
- NuttX对POSIX标准有原生兼容:NuttX是可商用化RTOS中唯一一个对POSIX API有原生支持的实时操作系统,所以很多Linux社区的开源软件可以很方便的移植到NuttX上,这样可以极大的简化开源软件移植,方便代码复用,降低学习曲线,其它RTOS需要适配层把POSIX API转成内部API,而且通常只兼容一小部分的POSIX接口。
- 完成度高:NuttX集成了文件系统、网络协议栈、图形库和驱动框架,减少开发成本。
- 模块化设计:所有组件甚至组件内部特性,都可以通过配置Kconfig来调整或关闭,可按需对系统进行裁剪,适用于不同产品形态。
- 代码精简:所有组件都是从头编码,专门对代码和数据做了优化设计。
- 轻量级:虽然NuttX实现了传统操作系统的所有功能,但是最终生成的代码尺寸还是可以很小(最小配置不到32KB,最大配置不超过256KB)。
- 和Linux系统的兼容性:因为NuttX整体设计、代码组织,编译过程和Linux非常接近,将会极大地降低Android/Linux开发者的迁移成本。
- 活跃开放的社区:很多厂商(比如小米、Sony,乐鑫、NXP等)和开源爱好者都在积极回馈社区。
小米基于NuttX内核推出的物联网软件平台小米Vela ,意欲打通IoT应用,基于同一个底层基座,更加利于手机与IoT设备之间的协同。如小米正在重点开发小米妙享功能。小米妙享开放平台即将开放视频投射和应用协同功能。小米Vela可以打通碎片化的IoT应用,支持高性价比的MCU设备,可以原生支持小米妙享功能。手表,手环,音箱,智能家电,相机ISP等设备,通过技术创新,做大生态,让用户受益。
NuttX系统架构
从纵向看,NuttX和传统操作系统一样由调度子系统、文件子系统、网络子系统、图形子系统和驱动子系统组成。从横向看,NuttX向上给应用程序提供了POSIX和ANSI定义的标准C/C++接口。对于没有标准化的组件(比如各种外设),NuttX通常会提供兼容Linux的API。向下NuttX定义了Arch API、块设备驱动接口、网卡驱动接口、display驱动接口,以及各种总线和外设的lower half驱动接口,使得芯片厂商能够规范、快速地完成移植工作。下图中数量众多的蓝色模块就是NuttX实现的各种功能。
移植环境准备
imax6ul的linux开发板交叉编译工具链:
nuttx系统内核源码下载地址:
git clone https://github.com/apache/nuttx.git
#下载快点儿的用这个:
git clone https://gitee.com/nuttx-rtos/nuttx.git
#apps也需下载,放在跟nuttx同级的目录下,目录名为apps
git clone https://github.com/apache/nuttx-apps.git
imx6ul开发板交叉编译工具链下载地址:
https://download.csdn.net/download/qq8864/88117926
以下指令根据需要,非必须。
sudo apt install dos2unix
#非必须,如果没有可执行权限的话执行它
find ./tools -type f -name "*.sh" -exec chmod +x {} \;
#非必须,之前是源码下到windows下,换行变成了回车换行(\r\n) linux下换行只能是\n
find ./tools -type f | xargs dos2unix
#列出支持的板子配置
./tools/configure.sh -L
#过滤,sabre这个是nxp官方的imx6系列的板子(cortex-a9),比较接近imx6ul(32位arm-cortexa7)
./tools/configure.sh -L | grep "sabre"./tools/configure.sh -l sabre-6quad:nsh#source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
安装环境依赖包:
以下最好都安装,根据你的环境不同,可能有的非必须。但为了不中途编译报错,建议全装。因为里面一些确实很有用啊,比如gperf,genromfs,kconfig-frontends等。后面的编译报错多跟少这一步的依赖有关系。
sudo apt install \
bison flex gettext texinfo libncurses5-dev libncursesw5-dev \
gperf automake libtool pkg-config build-essential gperf genromfs \
libgmp-dev libmpc-dev libmpfr-dev libisl-dev binutils-dev libelf-dev \
libexpat-dev gcc-multilib g++-multilib picocom u-boot-tools util-linux
sudo apt install kconfig-frontends
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi
列出支持的板子配置,使用命令:
cd nuttx
./tools/configure.sh -L
模拟器环境使用
NuttX 有个很强大的功能就是它有一个完成的模拟器支持,如果代码和硬件无关,在模拟器运行成功后,无需任何修改可以运行在硬件上。Nuttx 支持在电脑中使用模拟器运行 nuttx。在开发时先在 sim 中调试验证完成后,再使用硬件进行调试,能够提高开发效率和缩短开发时间。
配置模拟器版本编译
在 Nuttx 的代码中默认包含所有支持的芯片驱动,所有无需下载额外的代码,只要根据需要选择你需要使用配置即可:
# 进入 nuttx 目录
cd nuttx
# c查看所有可用的配置
./tools/configure.sh -L
输入命令后会打印非常多配置,以 sim:minibaisc
为例,其中冒号前面的 sim 表示使用芯片,冒号后面的 minibasic 表示具体配置名称。
sim:minibasic 表示在模拟器中运行的最小程序配置,它编译完后它只包含一个 shell 和一个 hello world。
make distclean
# 生成指定配置的配置信息
./tools/configure.sh -l sim:minibasic
# 编译程序
make -j
编译完成后,在 nuttx 目录下(执行 make 的当前目录),会生成一个 ./nuttx 可执行文件。
运行 ./nuttx 后会出现一个新的 shell,这个是 Nuttx 的终端 nsh,输入 help 命令可查看当前可用命令。
输入 hello 后按回车,即执行 hello 的程序,然后打印出 hello world。退出 nsh 需要使用命令 poweroff,而不能使用 Ctrl-C 结束程序。
hello 程序所在位置为:apps/examples/hello/hello_main.c 中,打开文件可以可进行修改然后编译运行。
配置NUTTX系统
编译nuttx系统前,需要先配置下它,即是告诉它你要编译哪个硬件指令体系下的哪个板子配置。
进入NUTTX源码根目录
#需要先清除下,否则可能还是之前的配置信息
sudo make distclean
重新配置系统
以stm32f4discovery开发板举例:
cd nuttx // 进入根目录
带USB调试:
./tools/configure.sh stm32f4discovery:usbnsh
带串口调试:
./tools/configure.sh stm32f4discovery:nsh
常见报错及解决
以下是常见报错及解决办法:
系统无法找到名为 "kconfig-mconf" 的命令,导致在执行 make 命令中的 menuconfig 目标时出现了错误。一般来说,"kconfig-mconf" 命令用于启动 Linux 内核配置工具(通常为基于文本的菜单式界面),允许用户交互式地配置内核选项。缺少依赖导致,需在线安装libncurses5-dev,gperf, flex bison组件。
sudo apt-get install gperf libncurses5-dev flex bison
说明:
Libncurses库用于在终端显示文本界面。典型应用场景为编译linux内核时make menuconfig配置界面,flex与bison在编译和汇编过程中用到,用于读取源代码并且获得程序的结构描述和分析程序结构,并且生成相应的目标代码。
工具kconfig-frontends的安装:
git clone https://bitbucket.org/nuttx/tools.git
$ cd tools/kconfig-frontends
$ # on MacOS do the following:
$ patch < ../kconfig-macos.diff -p 1
$ ./configure --enable-mconf --disable-shared --enable-static --disable-gconf --disable-qconf --disable-nconf
$ # on Linux do the following:
$ ./configure --enable-mconf --disable-nconf --disable-gconf --disable-qconf
$ make
$ make install
更简单的办法,通过以下命令安装:
sudo apt install kconfig-frontends
说明:
如果不安装kconfig-frontends组件,执行make menuconfig会提示kconfig-mconf无法找到的错误,
这是因为本机器上的aclocal版本过高(1.16>1.15),于是想到有两个解决办法:
1.修改configure文件里对aclocal版本的版本号。
2.在本机安装aclocal-1.15
最简单的方法:
首先用aclocal --version命令获取本机版本,然后去改configure文件,用vim打开configure,查找am__api_version,发现版本号如下:
am__api_version='1.15'
把am__api_version改成本机aclocal版本
am__api_version='1.16'
配置运行环境
cd ../ //回到nuttx源码根目录
sudo make menuconfig
报错信息:
报错解决:
提示的很明显,找不到apps目录下的Kconfig文件,那就建一个。内容如下:
config EXAMPLES_TEST_20240414bool "test_program"default n---help---Enable the test example, written by yyz
最后,sudo make menuconfig终于成功的看到如下配置界面:
本以为大功告成,结果编译报错,如下:
这个原因真不好找, 好在在这里找到了答案:Failed to Build with Custom Apps Directory · Issue #11442 · apache/nuttx · GitHub
其实原因是apps里的文件写法或配置有问题。正常的执行是这样:
root@VM-8-2-ubuntu:/home/ubuntu/test/nuttx/src/nuttx# ./tools/configure.sh -l sim:minibasicCopy filesSelect CONFIG_HOST_LINUX=yRefreshing...
CP: arch/dummy/Kconfig to /home/ubuntu/test/nuttx/src/nuttx/arch/dummy/dummy_kconfig
CP: boards/dummy/Kconfig to /home/ubuntu/test/nuttx/src/nuttx/boards/dummy/dummy_kconfig
LN: platform/board to /home/ubuntu/test/nuttx/src/apps/platform/dummy
LN: include/arch to arch/sim/include
LN: include/arch/board to /home/ubuntu/test/nuttx/src/nuttx/boards/sim/sim/sim/include
LN: drivers/platform to /home/ubuntu/test/nuttx/src/nuttx/drivers/dummy
LN: include/arch/chip to /home/ubuntu/test/nuttx/src/nuttx/arch/sim/include/sim
LN: arch/sim/src/chip to /home/ubuntu/test/nuttx/src/nuttx/arch/sim/src/sim
LN: arch/sim/src/board to /home/ubuntu/test/nuttx/src/nuttx/boards/sim/sim/sim/src
mkkconfig in /home/ubuntu/test/nuttx/src/apps/audioutils
mkkconfig in /home/ubuntu/test/nuttx/src/apps/benchmarks
mkkconfig in /home/ubuntu/test/nuttx/src/apps/boot
mkkconfig in /home/ubuntu/test/nuttx/src/apps/canutils
mkkconfig in /home/ubuntu/test/nuttx/src/apps/crypto
mkkconfig in /home/ubuntu/test/nuttx/src/apps/dummy
mkkconfig in /home/ubuntu/test/nuttx/src/apps/examples/mcuboot
mkkconfig in /home/ubuntu/test/nuttx/src/apps/examples
mkkconfig in /home/ubuntu/test/nuttx/src/apps/fsutils
mkkconfig in /home/ubuntu/test/nuttx/src/apps/games
mkkconfig in /home/ubuntu/test/nuttx/src/apps/gpsutils
mkkconfig in /home/ubuntu/test/nuttx/src/apps/graphics
mkkconfig in /home/ubuntu/test/nuttx/src/apps/industry
mkkconfig in /home/ubuntu/test/nuttx/src/apps/interpreters/luamodules
mkkconfig in /home/ubuntu/test/nuttx/src/apps/interpreters
mkkconfig in /home/ubuntu/test/nuttx/src/apps/logging
mkkconfig in /home/ubuntu/test/nuttx/src/apps/lte
mkkconfig in /home/ubuntu/test/nuttx/src/apps/math
mkkconfig in /home/ubuntu/test/nuttx/src/apps/mlearning
mkkconfig in /home/ubuntu/test/nuttx/src/apps/netutils
mkkconfig in /home/ubuntu/test/nuttx/src/apps/sdr
mkkconfig in /home/ubuntu/test/nuttx/src/apps/system
mkkconfig in /home/ubuntu/test/nuttx/src/apps/testing
mkkconfig in /home/ubuntu/test/nuttx/src/apps/wireless/bluetooth
mkkconfig in /home/ubuntu/test/nuttx/src/apps/wireless/ieee802154
mkkconfig in /home/ubuntu/test/nuttx/src/apps/wireless
mkkconfig in /home/ubuntu/test/nuttx/src/libraries
mkkconfig in /home/ubuntu/test/nuttx/src/projects
mkkconfig in /home/ubuntu/test/nuttx/src/apps
#
# configuration written to .config
#
最后成功编译并生成了Nuttx可执行文件。至此,环境准备就绪,且在ubuntu20上的模拟器运行成功,接下来的目标是imx6ul开发板上的移植工作啦。
其他资源
NuttX:如何移植新板件到NuttX/如何修改底层驱动_keil移植nuttx-CSDN博客
NUTTx移植到飞控板_nuttx移植stm32f446-CSDN博客
Compiling with Make — NuttX latest documentation
ubuntu14.04 nuttx开发环境的搭建_kconfig-mconf: not found-CSDN博客
2.2NuttX环境搭建-编译环境安装 - 知乎
Nuttx学习入门-CSDN博客
Nuttx操作系统(四):系统架构 - 知乎
ubuntu下Nuttx OS调试环境搭建--Apple的学习笔记 - 简书
https://blog.51cto.com/u_15899439/5909170
Xiaomi Vela - 小米物联网嵌入式软件平台
百度安全验证
百度安全验证
https://www.techsir.com/a/202011/68424.html
小米澎湃OS的自研Vela系统是何方神圣?相较于鸿蒙系统差距有多大 - 哈喽生活网
对标鸿蒙?小米推出物联网软件平台小米Vela 可打通IoT应用 - 科技先生
https://blog.51cto.com/u_15899439/5909170
Linux之父的自传《Just For Fun》到底说了些什么? - 掘金
《Just for fun》-Linux之父Linus的传奇人生 - 知乎
Nuttx操作系统(三):构建模式 - 知乎
Nuttx操作系统 - 知乎
NuttX学习2 - 简书
nuttx在riscv的qemu上运行体验-腾讯云开发者社区-腾讯云
NuttX 快速上手:在 ESP32 上运行 SQLite_哔哩哔哩_bilibili
GitHub - espressif/crosstool-NG: crosstool-NG with support for Xtensa
GitHub - Gary-Hobson/NXOS: 一个用于简化基于 NuttX 的应用开发的仓库