一,前言
最近看技术blog,发现好多免费的OS,其中nuttx引起了我的注意,主要原因是它是RTOS,但是用的API是posix的,我简单理解就是在linux和rtos的结合体。这样在linux上的应用code要移植到单片机,那么就可以用nuttx。然后看到nuttx被国产某家买断后变成apache nuttx一直在维护,它拥有开源飞控系统PX4中。除了图形图形,os也是我感兴趣的内容。所以近期又会开展一轮os相关的复习和再学习。我还看到鸿蒙os的虚拟文件系统借用的就是nuttx的虚拟文件系统,不过说此文件系统性能不太好。
二,nuttx交叉编译调试环境搭建
nuttx最适配的是linux环境,我也在window安装了cygwin去编译,貌似不太好用。所以在虚拟机上安装了ubuntu20.04,然后按nuttx官网help搭建了编译调试环境。但是最后一步OpenOCD出错,最后自己研究了下,连接完stlink后需要使用命令
openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f target/stm32f4x.cfg
然后就可以看到串口输出"nsh>"了。参考官网的具体步骤如下:
A,ubuntu20.04环境创建
我先安装了ubuntu20.04在虚拟机中。然后mnt中为空,无法共享文件。网上查了解决方案。
在进入mnt目录,mkdir hgfs创建文件夹,执行vmhgfs-fuse /mnt/hgfs。然后cd hgfs就可以看到设置的共享文件夹咯~
B,安装编译工具链
按nuttx.apache.org官网的help,安装需要的工具。
1.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
2.apt install kconfig-frontends
3.apt install gcc-arm-none-eabi binutils-arm-none-eabi
C,编译
cd nuttx
./tools/configure.sh -l stm32f4discovery:nsh
make menuconfig(需要自定义配置可使用)
make
make clean(要clean后重新编译需要使用)
问题记录:
make: “-C”选项需要非空字符串参数
make: *** [tools/Makefile.unix:326:dirlinks] 错误 2
网上搜索到CONFIG_APPS_DIR在预设的 .config 文件中定义,如果没有定义,默认为 ../apps。目标 menuconfig 调用命令 kconfig-mconf 进行配置。所以我漏下载了app文件夹。我理解只要下载nuttx文件夹即可。原来2个都要下载的。
D,连接stlink调试
apt install openocd
openocd -f interface/st-link-v2.cfg -f target/stm32f1x.cfg -c 'init' -c 'program nuttx/nuttx.bin verify reset' -c 'shutdown'
结果没有用,原来是路径无法识别,把路径补全了。我是stm32F407芯片不是f1,所以修改了cfg名字如下。
openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f target/stm32f4x.cfg
能正常连接咯~
三,ubuntu下基于codeblocks的交叉编译stm32调试环境搭建
虽然配合上jlink可以在ubuntu环境下使用ozone,但是我在网上视频看了codeblocks来调试,另外help中也用了codeblocks sim进行nuttx调试,我以前只知道eclipse进行交叉编译及调试,没有想到codeblocks也可以,所以按网上的老外的视频教程操作了下,一开始没有成功,但是我没有放弃,仔细对比了下,codeblocks创建工程的路径需要在源码nuttx路径。而不能仅通过外部导入nuttx路径的code,否则Makefile找不到路径。具体方法我做了记录。
先安装codeblacks
sudo apt install codeblocks
安装教程编译的gdb
sudo apt-get install gdb-arm-none-eabi
然后在命令窗口,root权限登录,然后输入codeblocks,就是按root权限打开codeblocks,否则编译过程会提示没有权限。
-
Settings->Debugger
image.png -
点击Create Config创建OpenOCD
image.png -
修改gdb文件路径后点击ok关闭窗口
image.png -
修改Compiler
image.png
image.png
点击右边三角,选择编译工具页进行修改,最后set as default。
image.png -
创建空白工程
image.png
点击next,然后清空输出物,仅设置Debug为all。来支持make all命令。然后点击finish。
image.png -
修改属性,This is customer Makefile打钩。
image.png
转入最后的debug页修改。
image.png
monitor reset init和load nuttx和b nx_start
image.png -
导入code,然后选择select all进行全部文件的导入,点击ok
image.png -
进行编译
在用codeblocks的build前,其实已经按照nuttx官网的help用make命令编译成功过,并且修改过配置项。用codeblocks的build主要是用来验证codeblocks环境的。
image.png
编译成功截图
image.png - 插入Stlink,通过openOCD连接上
openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f target/stm32f4x.cfg -
在codeblocks中使用调试
Debug->start就会停止在nx_start
image.png
四,nuttx 10.0.1框架分析
- 文件夹目录,按document中的help已经了解了。
- 然后我去看代码,找第一句入口函数。
boards\arm\stm32\stm32f4discovery\scripts\ld.script中ENTRY(_stext)说明入口是_stext,但是它是一个参数。而这个参数是在arch\arm\src\Makefile文件的$(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS)
中可以看出,传入了--entry为__start,所以__start就是第一句入口函数。
找到入口函数后,看code的框架就比较简单了。先初始化board相关,然后初始化os相关,最后启动os。每一段都有注释,而且有showprogress的log,容易看的code都是设计的好的code。
stm32_clockconfig();
stm32_fpuconfig();
stm32_lowsetup();
stm32_gpioinit();
showprogress('A');
nx_start()就是初始化os,然后调用nx_bringup()->nx_create_initthread->nx_start_application->nxtask_create
创建第一个task并启动。这个task函数为CONFIG_USER_ENTRYPOINT配置的值为nsh_main,这个具体在app文件夹中。等于进入APP code。APP code中若要创建task,依然可以调用nxtask_create。
五,小结
RTOS方面我最感兴趣的就是调度机制,其它关于虚拟文件系统,网络模块等只是大概了解下框架和主要的数据流。现在编译调试环境搭建完成了,之后可以进行源码的深入理解阶段了。