曾今只是使用过移植好的RTOS进行任务开发,对其实现的底层原理一直一知半解,正好接触到了李述桐老师的课程以及一些网上的资料,让我对实时操作系统的原理有了更深的理解,特此把一些原理和思考记录下来和大家一起分享,同时若有理解上的错误还恳请大家能够及时指正。
RTOS中有很多的事件包括计数信号量、互斥量、邮箱、消息队列等,几乎所有的事件都是基于事件控制块所完成,在事件控制块的基础上增加一些不同的功能就能变成各类事件。所有的事件都需要完成一个最基本的功能:若无事件发生,让任务停下来等待,等待事件发生后再继续运行,若事件已经发生,则继续运行。这也是事件控制块所需要完成的核心功能,为此事件控制块上需要有一个等待链表,将任务挂载在上面。
typedef struct _tEvent{
tEventType type; //事件类型 计数信号量、互斥量、邮箱、消息队列等
tList waitList; //等待链表
}tEvent; //事件控制块结构体
计数信号量:在事件控制块的基础上增加一个计数值,当事件发生且无等待任务时,计数值++,只要任务获取计数信号量时,计数值--,当计数值为0时任务就在等待链表上等待,直到新的事件发生。比如:一个按钮按下去,触发一个任务,当按钮没按的时候,任务就等待执行,当按钮快速按10下,任务也会连续执行10下后再停止。计数信号量能够记录事件发生的次数。
互斥量与二值信号量:互斥量与二值信号量非常相似,就是将计数信号量的计数值最大只能为1,比如:一个按钮按下去,触发一个任务,当按钮没按的时候,任务就等待执行,当按钮快速按10下后停止,任务可能只会再执行一下就停止。互斥量比二值信号量多了一个优先级继承。
消息队列:在事件控制块的基础上增加一个消息队列,当事件发生且无等待任务时,消息的指针就被挂载到消息队列上,只要任务获取消息队列时,消息就被取出,当消息队列为空时任务就在等待链表上等待,直到新的事件发生。
邮箱:只能存放一个消息的消息队列。