Files
cosyos/README.md
T
2023-02-28 06:29:05 +00:00

13 KiB
Raw Blame History

CosyOS

温馨舒适的RTOS

纵观天下之RTOS,基本千篇一律、人云亦云,普遍都存在实时性差、缺乏创新等特点,只有极少数RTOS能够一骑绝尘。 实时性差是因为存在关闭总中断的情况。中断才是最需要实时处理的,而不是任务,中断的实时性问题不解决,任务调度的再及时、切换的再快也是白搭。从这个角度来说,Keil RTX是非常优秀的,因为它实现了Cortex-M3以上内核全局不关中断,然而对于其它内核来说却没有这个待遇。
设计一款所有内核全局不关中断的RTOS成为了作者的奋斗目标,否则在如今RTOS烂大街的情况下,再设计一款千篇一律的RTOS还有什么意义呢?

简介

CosyOS始创于2021年,并于2022年底完成kernel的第一个版本V1.0.0。作者以“突破创新”为理念,“简单易用”为原则,经过不懈的努力,终于大获成功。CosyOS的最大亮点是实现了所有内核全局不关中断(零中断延迟)。除此之外,一些传统技术均实现了突破与创新。如消息邮箱,支持随意定义数据类型,丰富了邮件的形式;事件标志组,支持定义标志位,方便了标志组的应用。另外,CosyOS还独创了一些新技术,如私信等,会陆续向大家介绍... ...

下面,让我们来初步体验一下CosyOS的易用性。

CosyOS一步创建任务示例:

任务名称 任务优先级 任务栈大小 安全运行时 私信
demo1_task 1级 128字节 0,无限长 0,无私信
demo2_task 2级 256字节 9个时间片 3个参数

注1安全运行时是CosyOS的安全关键技术之一,是为了当有任务出现代码运行卡死或死循环时,能够及时停止该任务,使得比它优先级低的任务得以正常运行。
注2私信是CosyOS独创的一种任务间通讯方式,可用来实现信号、事件、消息等功能。

# 创建demo1_task
uCreateTask(demo1_task, 1, 128, 0, 0)
{
    ... ...
    uSendDM(demo2_task) "hello", 999, 3.14); // 发送私信至demo2_taskC89Mode
    uSendDM(demo2_task, "hello", 999, 3.14); // 发送私信至demo2_taskC99Mode
    ... ...
    uEndTasking; // 所有任务的最后一句代码
}
# 创建demo2_task
uCreateTask(demo2_task, 2, 256, 9, 3)(char *p, int a, float b)
{
    ... ...
    if(uRecvDM(500)) // 接收私信(超时时间为500个滴答周期,返回值为真则接收成功)
    {
        /* 使用私信(读取p、a、b*/
    }
    ... ...
    uEndTasking;
}
# 启动钩子
void start_hook(void)
{
    uStartTask(demo1_task, 0); // 启动demo1_task并置任务的初始状态为就绪状态
    uStartTask(demo2_task, 1); // 启动demo2_task并置任务的初始状态为挂起状态
}

您有没有眼前一亮呢?CosyOS创建一个任务竟如此简单,通过调用API“uCreateTask”,输入各项参数并直接写任务代码即可。下一步就是在启动钩子中启动任务,任务便可参与调度并运行了。CosyOS还开创性的把任务形参用做私信,私信参数(数量、名称、类型)可随意定义,与普通函数定义形参如出一辙。其它应用也都有着异曲同工之妙,即无论做什么事,都尽可能做到简化流程一步完成,最大程度的降低开发者的工作量,给开发者创造一个温馨舒适的开发环境。

突破与创新

  • 开创性的实现了所有内核全局不关中断(零中断延迟),保证了中断中用户代码的实时性
  • 独创的私信(任务形参),参数可随意定义,使用极为灵活,是任务间通讯的利器
  • 独创的软件RTC,支持设置时间和获取时间,可替代硬件RTC
  • 80251内核支持独创的虚拟双栈指针技术,使任务的切换效率等同于Cortex-M
  • 定时中断任务/钩子定时查询任务/钩子,针对于嵌入式开发中最典型的应用
  • 消息邮箱,每个邮箱在创建时,都可定义属于自己的数据类型,极大的丰富了邮件的形式,方便了任务间消息的传递
  • 消息队列,采用FIFO机制,支持常量和变量类型的字符串和数组。常量类型采用指针引用方式,变量类型同时支持指针引用和数据拷贝两种方式
  • 事件标志组,声明标志组的同时定义标志位,不同标志组的标志位可以重名,对标志组和标志位的访问通过组名和位名来实现,极大的方便了标志组的应用
  • 全局变量访问,通过调用API可实现在任意任务和中断中对全局变量的安全访问,而不必担心重入的发生

因循守旧

  • 完全开源的免版税、确定性的RTOS
  • 任务调度支持抢占式调度、时间片轮转调度
  • 用户任务数量不限,且每个任务都可以有255级优先级(0~254)
  • 简洁高效的代码,极低的硬件资源占用,使CosyOS可轻松应用于各种小型MCU
  • 任务管理器,可实时监控各任务的运行,便于开发者急时发现设计中存在的潜在问题

任务调度

CosyOS的任务调度类型包括抢占式调度、时间片轮转调度,不同优先级采用抢占式调度,相同优先级采用时间片轮转调度。
CosyOS的任务调度时机分为定时调度与临时调度。

定时调度

  • 在每个系统滴答周期,SysTick_Handler都会触发一次任务调度。

临时调度

  • 启动任务时,会立即触发任务调度;
  • 当前任务被阻塞、挂起、停止、删除、设置优先级时,会立即触发任务调度;
  • 恢复任务时,如果恢复后该任务可以运行并且它的优先级高于当前任务的优先级,会立即触发任务调度;
  • 设置其它任务优先级时,如果该任务可以运行并且它的新优先级高于当前任务的优先级,会立即触发任务调度。

CosyOS的任务调度机制可最大程度的实现尽可能实时高效的任务切换,使任务的切换效率无与伦比。

任务优先级分组

您可在系统配置文件中配置任务优先级分组。共有六个分组可供选择,8级、16级、32级、64级、128级、256级。
如您配置的分组为8级,则最高优先级为7级,最低优先级为0级;如您配置的分组为256级,则最高优先级为255级,最低优先级为0级。

时间片模式

CosyOS有三种时间片的定义模式,全局时间片、算法时间片、自定义时间片,需在系统配置文件中定义。
1. 全局时间片 所有任务采用统一的时间片。
2. 算法时间片 不同优先级任务的时间片不同,采用一个算法公式来描述,优先级越高时间片应越短。
3. 自定义时间片 不同优先级任务的时间片不同,用户自定义各优先级的时间片,优先级越高时间片应越短。

时间片的取值范围:1~65535,单位为滴答周期。

安全运行时

安全运行时是CosyOS的安全关键技术之一,是为了当有任务出现代码运行卡死或死循环时,能够及时停止该任务,使得比它优先级低的任务得以正常运行。当任务累计运行时间超过安全运行时,仍不能被比它优先级低的任务所切换,则SF为软fault,该任务停止运行。安全运行时的取值范围:0~65535,单位为时间片,0为无限长。

支持任务/钩子

一、系统任务
由操作系统自主创建并自动启动的任务。
1. 任务管理器(Taskmgr 优先级固定为最高级。
2. 调试任务(Debugger 优先级固定为最高级,用做命令行和任务管理器的串口接收解析。
3. 启动任务(Starter 优先级固定为比最高级低一级,通过调用启动钩子来启动用户任务,而后删除自身。
4. 系统空闲任务(Sysidle 优先级固定为最低级0级,是系统级的空闲任务。

二、系统钩子
由操作系统自主创建并自动调用的函数,并由用户来写代码。
1. 初始化钩子(init_hook 在主函数中首先被调用,适用于初始化时钟、IO、寄存器等工作。
2. 启动钩子(start_hook 在启动任务中被调用,用于启动用户任务。用户可在启动钩子内调用API“uStartTask”来启动用户任务。
3. 滴答钩子(tick_hook 每个滴答周期,在SysTick_Handler中都会被调用一次,适用于每滴答周期/秒/分/时/...做一次的工作。
4. 空闲钩子(idle_hook 在系统空闲任务中被调用,用户可添加自己的代码做一些没有实时性要求的工作。

三、定时任务/钩子
包括定时中断任务/钩子和定时查询任务/钩子,其实质都是软件定时器中断。
1. 定时中断任务/钩子 由用户设定定时时间,当定时器溢出时,系统将自动恢复/调用对应的任务/钩子。支持定时器的自动重装载,可实现自动重复定时。
2. 定时查询任务/钩子 由用户设定定时时间,当定时器溢出后,系统在每个滴答周期都会查询用户定义的事件,若事件为真,系统将自动恢复/调用对应的任务/钩子。支持定时器的自动重装载,可实现自动重复定时。

四、一般用户任务
对于一般用户任务,只要优先级为0级,就是空闲任务。用户空闲任务内都要有阻塞事件,以保证所有空闲任务都有机会被运行。

最高优先级固定分配给任务管理器和调试任务,用户任务不要使用。

任务状态

CosyOS的任务状态较传统RTOS划分更为详细,以便用户在使用任务管理器监控任务时,能够更加准确的判断各任务的运行情况。
具体划分如下:

注:[]为在任务管理器中显示的任务状态

  • 运行状态[RDY] 任务正在运行。
  • 就绪状态[RDY] 任务已经准备就绪,可以参与任务调度并运行。
  • 延时阻塞状态[DLY] 由延时而导致任务进入阻塞状态,直到延时时间结束转为就绪状态。
  • 非延时阻塞状态
    1. 二值信号量阻塞状态[BIN] 由二值信号量等待或获取而导致任务进入阻塞状态,直到成功或超时转为就绪状态。
    2. 互斥信号量阻塞状态[MUT] 由互斥信号量获取而导致任务进入阻塞状态,直到成功或超时转为就绪状态。
    3. 计数信号量阻塞状态[SEM] 由计数信号量获取而导致任务进入阻塞状态,直到成功或超时转为就绪状态。
    4. 等待标志组阻塞状态[GRP] 由事件标志组等待而导致任务进入阻塞状态,直到成功或超时转为就绪状态。
    5. 接收消息阻塞状态[MSG] 由接收消息而导致任务进入阻塞状态,直到收到消息或超时转为就绪状态。
    6. 接收邮件阻塞状态[MAL] 由接收邮件而导致任务进入阻塞状态,直到收到邮件或超时转为就绪状态。
    7. 接收私信阻塞状态[DM] 由接收私信而导致任务进入阻塞状态,直到收到私信或超时转为就绪状态。
  • 浮动状态[RDY] 浮动状态是临时的就绪状态,在特定条件下可再次转为刚才的阻塞状态。当任务进入非延时阻塞状态后,终将转为浮动状态。在任务管理器中显示为就绪状态。
  • 挂起状态[SPD] 任务暂停运行,除任务状态变为挂起外,任务的其它相关信息和数据均保持不变。当恢复任务后,可继续挂起时的断点运行。 运行状态的任务被挂起,恢复后为就绪状态;其它状态的任务被挂起,恢复后为原状态。
  • 停止状态 任务停止运行,不可恢复。
    1. 任务栈溢出停止[!OF] 由任务栈溢出而导致任务停止运行。
    2. 任务栈重分配失败停止[!RF] 由任务栈重分配失败而导致任务停止运行。
    3. 安全运行时溢出停止[!SR] 由安全运行时溢出而导致任务停止运行。
  • 删除状态(Deleted 任务被删除,若想再次运行该任务,必须重新启动该任务。

任务状态
—————————— CosyOS-任务状态图 ——————————

任务管理器
—————————— CosyOS-任务管理器 ——————————

线程优先级

线程优先级

支持内核

CosyOS现支持8051、80251、Cortex-M等内核,未来会陆续添加对其它内核的支持。

开发流程

补充说明

API用户参考手册

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request