^

NuttX实时操作系统

起因

近日嵌入式系统实验课,涉及到了Linux的内核编译,然而实验所讲的十分粗浅,仅是一步步复制粘贴,故萌生想法——动手编译一个操作系统内核。

在学习实时操作系统时听说了NuttX,颇感兴趣,便从它下手。

硬件设备

手上有一块闲置的(人手一块的)STM32F03C8T6最小系统板。
STM32F103C8T6,是ARM Cortex-M3的内核,显然在官方的支持平台列表中,有64KB的片上Flash和20KB的片上SRAM,应该可以装得下Nuttx(毕竟是可裁剪系统,最小内核只有约20KB)。

此外,需要一个J-Link/ST-Link下载器,我这边用的是Segger J-Link.

当然,要使用串口的话,还需要一个USB-TTL转换器。

安装

整个操作是在Ubuntu 18.04虚拟机下进行的。
第一步当然是安装相应的系统依赖、GCC工具链、以及NuttX。

系统依赖

安装以下Package:

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

安装KConfig(这个是用来做menuconfig的,在ESP-IDF的开发中也遇到了)

对于Ubuntu 20.04 LTS之后的系统,执行apt install kconfig-frontends即可。

对于Ubuntu 18.04 LTS,执行:

git clone https://bitbucket.org/nuttx/tools.git

cd tools/kconfig-frontends

./configure --enable-mconf --disable-nconf --disable-gconf --disable-qconf

make

make install

GCC工具链

安装交叉编译工具链:

apt install gcc-arm-none-eabi binutils-arm-none-eabi

arm-none-eabi-gcc(ARM architecture,novendor,nottarget an operating system,complies with the ARM EABI)用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel,不适用编译 Linux 应用 Application),一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用,所以不支持那些跟操作系统关系密切的函数。

下载内核源码

通过git下载:

mkdir nuttxspace

cd nuttxspace

git clone https://github.com/apache/incubator-nuttx.git nuttx

git clone https://github.com/apache/incubator-nuttx-apps apps

编译

安装完成后,即可进行内核编译,这里使用menuconfig简单编一个仅有nsh一个功能的系统。

Configuration

NuttX提供一个脚本,让你可以从一个现有的configuration开始,而不是从0开始手撸配置。

查看你的板子有那些已有configuration

cd nuttx

./tools/configure.sh -L | less

通过/ < name >可以快速向下搜索,? < name >可以向上搜索(其中的< name >表示要搜索的字符串)。

这边,搜索stm32f103可以看到,有一项为stm32f103-minimum:nsh,即说明了我们的最小系统板有一个既有配置nsh。也就是只有一个nsh功能的系统。

接着,

./tools/configure.sh -l stm32f103-minimum:nsh

即可导入此配置。

此后,便可通过喜闻乐见的make menuconfig查看并且修改此configuration,你可以在此基础上做些修改,但这里不演示,直接编译。

Build

直接make即可,可以看到当前目录下多出了nuttx文件(ELF)和nuttx.bin文件。
ps:通过make clean可以清除编译输出。

烧写

官方文档用的是ST-Link+OpenOCD烧写,但我手边没有ST-Link,只有J-Link,查看openOCD文档发现其对Segger JLink支持不好(速度很慢),故使用J-Link烧写。

首先,下载J-Link,这是一个deb包,直接双击安装即可。
安装完成后将会在/opt下多出SEGGER/JLink,其中包含了JLink的各种工具:
JLinkExe是一个命令行工具
JLinkFlashExe是一个GUI调试工具
这边,我们通过

/opt/SEGGER/JLink/JLinkExe

打开GUI下载器。

通过J-Link以SWD的方式连接STM32和电脑,程序会让你选择相应的芯片型号——选择STM32F03C8,连接方式——选择SWD,速率——选择4000kHz。随后OK。

之后按以下步骤:

烧写完成。

运行

拔掉下载器,通过TTL-USB转换器连接STM32和电脑(Ubuntu)

STM32的TX(A9)-转换器RX
STM32的RX(A10)-转换器TX

若没有安装picomon,先通过sudo apt install picocom安装

在ubuntu上运行picocom串口工具,连接STM32

sudo picocom -b 115200 /dev/ttyUSB0

可见串口终端打印出了nsh>提示符(若无打印输出,按回车),说明nuttx系统安装成功。

新坑

之后看看NuttX能整出什么花活。