请保留:【作者:张佩】 【原文:www.yiiyee.cn/blog】
Zephry是Linux基金会托管的一个嵌入式RTOS系统,主导开发的是Intel。我对这个系统进行了学习之后,得到了下面的5条总体认识。
- Zephyr的内核模式是宏内核,不是微内核;设备驱动都被集成在内核中;内核编译采用Kconfig脚本配置,资源配置也通过它在编译时指定
- Zephyr支持的平台:arm、x86、RISC-v、ARC、NIOS 2、POSIX等
- ARM平台支持不完全:只支持arm 32系列的m/r平台,a平台不支持;同时,也不支持arm64
- Zephyr支持100多种嵌入式开发平台,嵌入式友好;内核size可以小至8kB
- Zephyr只有mpu(内存保护单元)的支持,任务之间的内存是相互隔离的,但不支持虚拟内存;多个用户应用同时运行有一定的困难,目前仅支持单应用的形式
内核实现
Zephyr采用的是标准的宏内核的架构,这对于它面向MCU进行开发是有利的。如果采用微内核的话,需要有稳健的IPC机制,不仅执行效率上有所降低,并且需要更多的代码量。
当前的Zephyr代码结构和Linux十分相似。它有一个架构无关的通用的内核逻辑部分(Kernel目录),架构相关的实现被分离到不同的目录中去了(arch目录),基础的总线和外设的驱动也独立实现(driver目录),并在编译的时候集成在内核中。此外,一些重要的基础能力包括文件系统的支持、网络连接的支持,也是要在编译的时候和内核集成在一起的(ext目录)。
(v)[zhangpei@yunzhu:~/Documents/code/zephyr]$ ls
CMakeLists.txt README.rst dts scripts
CODEOWNERS VERSION ext subsys
CONTRIBUTING.rst arch include tests
Kconfig boards kernel version.h.in
Kconfig.zephyr cmake lib zephyr-env.cmd
LICENSE doc misc zephyr-env.sh
Makefile drivers samples zephyr.log
Zephyr的编译工作也采用Kconfig配置的方式。在进行一个具体的开发板适配的时候,内核配置和裁剪是很重要的工作,它决定了编译出来的内核size可以小到什么程度。比如下面是一个实现了USB HID功能的示例项目,它的基本配置只有聊聊几项内容:
CONFIG_USB=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_HID=y
CONFIG_USB_DEVICE_PRODUCT="Zephyr HID sample"
CONFIG_SYS_LOG=y
CONFIG_SYS_LOG_USB_DRIVER_LEVEL=1
CONFIG_SYS_LOG_USB_DEVICE_LEVEL=1
此外,内核配置中可以包含资源配置。包括CPU、RAM等的信息。这避免了系统起来之后进行动态检索的过程,适合嵌入式平台的精简模式。
平台支持
对于一个嵌入式RTOS系统来说,当前的Zephyr的平台支持是很广泛的,特别是它支持的开发板的类型,多达150种,并且提供了100多种典型的开发示例,可以覆盖各种简单的传感器设备,到一些专用外设或IoT等(如鼠键、摄像头、网关等)。
它所支持的平台包括:arm、x86、RISC-v、ARC。同时,它还支持Linux的POSIX接口,就是它可以通过POSIX接口来模拟一个软件的硬件平台作为CPU、RAM来执行,从而可以把完整的Zephyr项目作为一个POSIX应用运行在Unix/Linux系统上。这对于开发和验证很友好。
但要说明的是,对于嵌入式系统使用很广的arm平台它的支持并不好。目前只支持面向嵌入式和实时应用的R系列、M系列。对于所用的A系列芯片,它不支持。对于新的arm 64平台,当然也不支持。
除了有较多的平台支持外,Zephyr更大的能力体现在驱动栈的成熟。它对于嵌入式常用的总线如I2C、I2S、GPIO、CAN甚至x86平台上的PCI等全都支持,支持fat32、nffs这两个轻量文件系统,有完整的USB驱动栈,完整的网络驱动栈,对包括WIFI、Zigbee、蓝牙等在内的无线连接也全部支持,它对于audio和显示也有一定的支持。这使得嵌入式系统可以通过它进行快速的开发。
同时,它还有一个名为JerryScript的轻量的JavaScript引擎,使得用户可以基于JS这种简单的脚本语言在Zephyr上快速地开发轻量应用,甚至是web应用。
用户应用
先看三个Zephyr的系统特性:
- Zephyr有内存保护,但不支持虚拟内存,亦即只做到MPU的支持,没有做到MMU的支持;
- 支持多线程,不同的线程可以使用独有的内存区域;
- 用户程序的入口地址是全局唯一的main函数。
从上述这3个基本事实出发,同时结合它的众多的sample示例,我们知道Zephyr是一个单应用的操作系统。全局唯一的main函数是用户应用的入口地址,这从设计上就不允许两个独立应用同时存在。但这个应用内部可以创建多个线程。
应用通过ymal文件进行配置,通过它来指定应用的描述信息,配置依赖信息。如果要支持多应用,可以通过一些简单的改造来快速实现。主要的思路是:
- 通过一个通用的init任务对用户空间进行初始化,内核完成初始任务后,将执行权交给init;
- 实现一种用户交互的方式,比如串口方式的terminal shell,以支持用户操作;
- 或者不实现2,而通过静态的用户配置文件,由init进程启动指定的用户进程。
结论
Zephyr是一个更适用于MCU/MPU平台的嵌入式RTOS系统,采用宏内核的开发模式,支持单个应用在上层执行。它本身的价值在于:虽然功能单一,但能力全面,可以在很小的系统上运行。
由于微内核现在很热,很多既有的RTOS在尝试把自己改造成微内核的架构。这样,不仅可以支持多应用的运行模式,也可以让内核更加地安全(驱动移出内核),面向的应用领域也可以更广泛。通过一些手段,Zephyr也可以被改造成微内核的架构。需要做的主要工作包括:
- 建立用户驱动模型,把当前的内核驱动按需移到独立进程中;
- 实现虚拟内存的管理功能,当然必须是在有MMU支持的平台上;
- 根据需要,对内核的基础功能进行一定的拓展,包括系统IPC的实现,如果要支持多应用,则最好有进程或Job的支持。
但考虑到一旦改造之后,可能导致它原有的架构大大变化,反而令其不能很好地适用于MCU/MPU平台,使得它的既有价值削弱。所以并不建议。
5,721 total views, 12 views today