Click HERE for English version.
RMP 是一个专注于形式化验证和简易可用的小型实时系统。它通过采取形式化方法来确保系统的可靠性(当前验证工作还未完成;不过,100%的白盒测试分支覆盖率已经达到。目前的内核可以被看作IEC 61508 SIL2预认证等级,或者EAL 4)。所有的实时操作系统必备的功能它都具备,但是并不在此基础上提供更多可选组件以确保内核的精炼性。这样,得到的内核就是一个最小化的内核,可以很方便地对它进行形式化验证。同时,它还可以作为客户操作系统运行在虚拟机监视器上。
本系统比以 FreeRTOS 和 RT-Thread 为代表的全功能系统相比要小得多,而且理解起来应该也相对容易得多。即便本系统仅仅包含了一个.C文件,它仍然提供了高效的内存管理,抗锯齿图形界面库和其他实用函数,并且这些功能的实现都不消耗任何额外的RAM!
本系统的手册可以在 这里 找到。
如果想要参与开发,请阅读 参与 和 规范 两个指导文档。如果要提交拉取请求,请使用 拉取请求模板 。 本软件采用 三种不同的授权 :你可以选择 LGPL v3 ,也可以选择 经修改的MIT协议 。 如果有特殊需求, 也可以联系我们请求商业授权。 LGPLv3协议是有例外的 :如果内核本身未经修改,即便它和应用程序或驱动静态链接或被包含进了工程之内,那么这种用法被看作是正常使用,而且应用程序本身仍然可以是私有的。给内核增加一个移植 是 对内核本身的修改,但增加一个驱动则 不是 。
对于那些由微控制器厂商提供的硬件抽象层软件包,请到 M0P0_Library 软件仓库自行下载。
从 这里 下载预编译的x86-32位Linux系统上可运行的二进制,观察性能测试的运行结果!
创建一个线程
RMP_Thd_Crt(&Thd_1 /* 线程控制块 */,
Func_1 /* 线程入口 */,
&Stack_1[238] /* 线程栈地址 */,
(void*)0x12345678 /* 参数 */,
1 /* 优先级 */,
5 /* 时间片 */);
删除一个线程
RMP_Thd_Del(&Thd_1 /* 线程控制块 */);
悬起一个线程
RMP_Thd_Suspend(&Thd_1 /* 线程控制块 */);
解除线程悬起
RMP_Thd_Resume(&Thd_1 /* 线程控制块 */);
void Func_1(void* Param)
{
RMP_PRINTK_S("Parameter passed is ");
RMP_PRINTK_U((ptr_t)Param);
RMP_PRINTK_S("\r\n");
while(1)
{
RMP_Thd_Delay(30000);
RMP_PRINTK_S("Delayed 30000 cycles\r\n\r\n");
};
}
void RMP_Init_Hook(void)
{
RMP_Thd_Crt(&Thd_1, Func_1, &Stack_1[238], (void*)0x12345678, 1, 5);
}
void Func_1(void* Param)
{
ptr_t Time=0;
while(1)
{
RMP_Thd_Delay(30000);
RMP_Thd_Snd(&Thd_2, Time, RMP_MAX_SLICES);
Time++;
};
}
void Func_2(void* Param)
{
ptr_t Data;
while(1)
{
RMP_Thd_Rcv(&Data, RMP_MAX_SLICES);
RMP_PRINTK_S("Received ");
RMP_PRINTK_I(Data);
RMP_PRINTK_S("\n");
};
}
void RMP_Init_Hook(void)
{
RMP_Thd_Crt(&Thd_1, Func_1, &Stack_1[238], (void*)0x12345678, 1, 5);
RMP_Thd_Crt(&Thd_2, Func_2, &Stack_2[238], (void*)0x87654321, 1, 5);
}
void Func_1(void* Param)
{
while(1)
{
RMP_Thd_Delay(30000);
RMP_Sem_Post(&Sem_1, 1);
};
}
void Func_2(void* Param)
{
ptr_t Data;
while(1)
{
RMP_Sem_Pend(&Sem_1, RMP_MAX_SLICES);
RMP_PRINTK_S("Semaphore successfully acquired!\r\n\r\n");
};
}
void RMP_Init_Hook(void)
{
RMP_Sem_Crt(&Sem_1,0);
RMP_Thd_Crt(&Thd_1, Func_1, &Stack_1[238], (void*)0x12345678, 1, 5);
RMP_Thd_Crt(&Thd_2, Func_2, &Stack_2[238], (void*)0x87654321, 1, 5);
}
/* Initialize memory pool */
RMP_Mem_Init(Pool, Pool_Size);
/* Allocate from the pool */
Mem=RMP_Malloc(Pool, Alloc_Size);
/* Free allocated memory */
RMP_Free(Pool, Mem);
Flash和SRAM消耗以kB计,其他数据以CPU指令周期计。下表列出的所有值都是典型(有意义的系统配置)值而非绝对意义上的最小值,因为纯技术层面的最小配置在实际工程中很少是真正有用的。HAL库所造成的额外存储器消耗也被计算在内。
本系统的绝对最小值在1.6k ROM和432Byte RAM左右,这个大小是在HC32L136K8TA(Cortex-M0+)的移植上达到的,并包括了第一个线程的60Byte的线程控制块和256Byte的线程栈,以及64Byte的内核中断响应用栈。操作系统内核和最精简的HAL库一共仅占用了52Byte存储。如果你对这个数字还有不满意,那么可以不使用厂商提供的HAL库而自己写一个版本。
架构 | 工具链 | Flash | SRAM | Yield | Sem | Mail/Int | Sem/Int | Mem | |
---|---|---|---|---|---|---|---|---|---|
DSPIC33E | XC16-GCC | 4.46 | 1.15 | 526 | 828 | 750 | 914 | 884 | 579 |
MSP430 | TI CCS7 | 2.90 | 0.64 | 495 | 906 | 786 | 830 | 736 | 1575 |
Cortex-M0 | Keil uVision 5 | 4.94 | 1.65 | 374 | 663 | 616 | 659 | 617 | N/A |
Cortex-M0+ | Keil uVision 5 | 6.25 | 1.65 | 334 | 607 | 544 | 588 | 552 | N/A |
Cortex-M3 | Keil uVision 5 | 5.31 | 1.65 | 252 | 513 | 448 | 465 | 418 | 311 |
Cortex-M4 | Keil uVision 5 | 5.46 | 1.66 | 188 | 386 | 353 | 361 | 329 | 233 |
Cortex-M7 | Keil uVision 5 | 6.66 | 1.65 | 196 | 288 | 277 | 296 | 296 | 183 |
Cortex-M7 | GCC | 7.71 | 1.98 | 176 | 313 | 276 | 290 | 268 | 193 |
Cortex-M7-RVM | Keil uVision 5 | 2.09 | 2.29 | 1068 | 1256 | 1195 | 884 | 866 | 176 |
Cortex-M7-RVM | GCC | 2.15 | 2.10 | 1103 | 1277 | 1225 | 907 | 866 | 177 |
Cortex-R4 | TI CCS7 | 15.1 | 1.42 | 281 | 458 | 406 | 424 | 368 | 274 |
Cortex-R5 | TI CCS7 | 18.2 | 3.72 | 305 | 471 | 426 | 472 | 432 | 267 |
MIPS M14k | XC32-GCC | 17.2 | 2.46 | 263 | 378 | 358 | 430 | 420 | 211 |
RV32IMAC | GCC | 2.24 | 2.89 | 261 | 585 | 506 | ~800** | ~800** | N/A |
X86-LINUX | GCC | N/A | N/A | 33000 | 35000 | 33000 | 35000 | 33000 | 136 |
*作为对比,RT-Linux 4.12在Cortex-M7上的最好线程切换时间是25000时钟周期。这是使用futex测得的;如使用其他IPC如管道等,则结果更差。
**该值仅供参考;评估所使用的器件依赖于SPI Flash来运行代码,有时候一个指令缓存落空就会导致45000周期的延迟。传统上,依赖于外部SPI Flash的器件在做测量时需要很大的内部内存来运行这些代码,但是该器件没有如此多的内存可供使用。
- DSPIC33E平台使用DSPIC33EP512MU810进行评估。
- MSP430平台使用MSP430FR5994进行评估。
- Cortex-M0平台使用STM32F030F4P6进行评估。
- Cortex-M0+平台使用STM32L053C8T6进行评估。
- Cortex-M3平台使用STM32F103RET6进行评估。
- Cortex-M4平台使用STM32F405RGT6进行评估。
- Cortex-M7平台使用STM32F767IGT6进行评估。
- Cortex-M7-RVM平台使用STM32F767IGT6进行评估,而且RMP此时是作为客户机运行在 RVM 嵌入式虚拟机监视器上.
- Cortex-R4平台使用TMS570LS0432进行评估。
- Cortex-R5平台使用TMS570LC4357进行评估。
- MIPS M14k平台使用PIC32MZ2048EFM100进行评估。
- RV32IMAC平台使用FE310-G000进行评估。
- X86 Linux平台使用Ubuntu 16.04和i7-4820k @ 3.7GHz进行评估。
所有的编译器优化选项都被设为最高(通常是-O3),而且时间优化选项也被打开。
- Yield :两线程间进行切换所用的时间。
- Mail :两线程间使用邮箱进行发送-接收操作的耗时。
- Sem :两线程间使用计数信号量进行发布-获取操作的耗时。
- Mail/Int:从中断发送到某线程邮箱的耗时。
- Sem/Int :从中断发布信号量的耗时。
- Mem :进行一次内存操作(比如分配或释放)的用时。
架构 | 原因 | 支持优先度 |
---|---|---|
RL78 | 常用16位单片机 | ⭐⭐⭐⭐⭐ |
TI C2000 | 常用DSP架构 | ⭐⭐⭐⭐ |
MicroBlaze | 常用软核 | ⭐⭐ |
NIOS II | 常用软核 | ⭐ |
架构 | 原因 | 替代方案 |
---|---|---|
PIC18 | 硬件堆栈 | 使用RMS状态机操作系统 |
AVR32 | 正在消亡 | 使用大众化的Cortex-M和Cortex-R |
ARMv5 | 被替代 | 使用更新的Cortex-M和Cortex-R |
x86-64 | 高级系统 | 使用RME微内核操作系统 |
Cortex-A | 高级系统 | 使用RME微内核操作系统 |
Coldfire | 正在消亡 | 使用大众化的Cortex-M和Cortex-R |
PowerPC | 正在消亡 | 使用大众化的Cortex-M和Cortex-R |
RX100/600/600S | 小众架构 | 使用大众化的Cortex-M和Cortex-R |
Tricore | 小众架构 | 使用大众化的Cortex-M和Cortex-R |
MB91460 | 小众架构 | 使用大众化的Cortex-M和Cortex-R |
下面的说明会帮助你在本地快速建立一个可用来评估测试本系统的工程。请参看系统的中文文档以获取更多信息。
要运行测试,你需要一块基于 Cortex-M或Cortex-R或MIPS或MSP430 的开发板。本RTOS主要面向资源受限的MCU,不提供对高端MCU,MPU和CPU的特别支持。不要使用QEMU模拟器来测试本系统,因为QEMU有很多不完善之处,与真正的硬件行为并不一致。
如果你没有开发板,那么RMP也有一个 基于x86处理器的Linux移植 。然而,该移植使用了ptrace系统调用和信号系统,因此并不很快,这一点可以从性能测试的数据看出。
对于其他平台的支持应该也是容易实现的,但是当前并没有支持计划。对于那些Cortex-A和具备内存管理单元(MMU)的其他处理器,可以使用M7M1_MuEukaron 实时多核心微内核;M7M1也支持一部分的Cortex-M和全部的Cortex-R。
在 Project 文件夹下能够找到多种微控制器的移植好的 厂商集成开发环境 或 Eclipse 的工程样板。参看各个工程文件夹下的自述文件以获取更多关于如何编译和运行该工程的信息。某些工程需要额外的厂商硬件抽象层库的支持,它们可以在 M0P0_Library 软件仓库被找到。
要运行测试,只要将测试下载到对应的开发板并开始单步调试即可。某些例子会采用两个LED来指示系统当前的状态,此时要填充LED的点亮和熄灭函数来运行该示例。
要使用本系统内建的图形库,请参考用户手册的相关章节。
当部署本系统到生产环境时,请仔细阅读本系统自带的手册,以确保各项配置正确。本系统的手册可以在 Documents 文件夹下找到。
- Keil uVision 5 (armcc)
- Code composer studio
- MPLAB X XC32
- GCC/Clang-LLVM
其他的工具链现在不推荐或者当前不受支持,虽然要增加新的支持应该也很简单。
请阅读CONTRIBUTING.md文档来获得关于行为规范和提交代码的相关信息。
演进 - 远古 - 原核 (M5P1 R4T1)
宋磊锋 - ARM Cortex M3/4/7的GCC汇编支持。