uCos-II中任务的同步与通信
任务的同步与通信
任务间的同步
在多任务合作工作过程中,操作系统要解决两个问题:
- 各任务间应该具有一种互斥关系,即对某些共享资源,如果一个任务正在使用,则其他任务只能等待,等到该任务释放资源后,等待任务之一才能使用它;
- 相关的任务在执行上要有先后次序,一个任务要等其伙伴发来通知,或建立了某个条件后才能继续执行,否则只能等待;
任务之间的这种制约性的合作运行机制叫任务间的同步;
任务中的事件
uCosII使用信号量、消息邮箱和消息队列这些中间环节来实现任务之间的通信,而这些中间环节都统一称为事件;
事件控制块及事件处理
事件控制块
对于事件来说,当其被占用时,会导致其他请求该事件的任务因暂时得不到该事件的服务而处于等待状态;
作为功能完善的事件,应该对这些等待任务有两方面的管理能力:
- 要对等待事件的所有任务进行记录并排序;
- 允许等待任务有一个等待时限,即当等待任务认为等不及时可以退出对事件的请求;
对于等待事件任务的记录,系统定义了一个INT8U类型的数组OSEventTbl[]作为等待事件任务的记录表,即等待任务表;
等待任务表以任务优先级别为顺序为每个任务分配一个二进制位,来表示这一位对应的任务为事件的等待任务,否则不是等待任务;
为了加快该表的访问速度,也定义了一个INT8U类型的变量OSEventGrp来表示等待任务中的任务组;
等待任务的等待时限记录在等待任务的任务控制块TCB的成员OSTCBDly中,并在每个时钟节拍中断服务程序中对该数据进行维护,每当有任务的等待时限到达时,便将该任务从等待任务表中删除,并使它进入就绪状态;
系统为了把描述事件的数据结构统一起来,使用叫做事件控制快ECB的数据结构来描述诸如信号量、消息邮箱和消息队列等事件;
事件控制块的组织是通过事件控制块链表的形式;
事件处理函数
系统中对事件控制块进行基本操作的函数定义在文件os_core.c中;
EventWaitListInit()事件控制块的初始化函数,作用是把变量OSEventGrp及任务等待表中的每一位都清0,即令事件任务等待表中不含有任何等待任务;OS_EventTaskWait()把一个任务置于等待状态;OS_EventTaskRdy()把调用这个函数的任务在任务等待表中的位置清0(解除等待状态)后,再把任务在任务就绪表中对应的位置设置为1,然后引发一次任务调度;OS_EventTO()使一个等待超时的任务进入就绪状态;
信号量及其操作
当事件控制块成员OSEventType的值被设置为OS_EVENT_TYPE_SEM时,这个事件控制块描述的就是一个信号量;
信号量由计数器和等待任务表两部分组成;
操作
OSSemCreate
应用程序在使用信号量之前必须先调用该函数来创建一个信号量;
OSSemPend
请求信号量,为防止任务因得不到信号量而处于长期的等待状态,该函数允许用参数timeout设置一个等待时间的限制,当任务等待时间超过timeout时,可以结束等待状态而进入就绪状态,如果该参数设置为0,则表明任务的等待时间为无限长;
当任务需要访问一个共享资源时,先要请求管理该资源的信号量,这样就可以根据信号量当前是否有效(即信号量计数器的值是否大于0)来决定该任务是否可以继续运行,如果信号量有效,则把信号量计数器减1,然后继续运行任务,如果信号量无效(即信号量计数器的值等于0),则会在等待任务表中把该任务对应的位设置为1而让任务处于等待状态,并把等待时限timeout保存在任务控制块对应的变量中;
如果希望任务在请求信号量,当信号量无效时不进入等待状态而继续运行,则不调用函数OSSemPend(),而是调用函数OSSemAccept()来请求信号量;
OSSemPost
任务获得信号量,在访问共享资源结束以后,必须调用该函数释放信号量,也叫发送信号量;
该函数在对信号量的计数器操作之前,要检查是否还有等待该信号量的任务,如果没有,则将信号量计数器值加1,如果有,则调用调度器OS_Sched()去运行等待任务中优先级最高的任务;
OSSemDel
如果应用程序不需要某个信号,那么可调用该函数来删除该信号;
函数中的参数opt用来指明信号量的删除条件,该参数有两个参数值可以选择:
- OS_DEL_NO_PEND当等待任务表中已没有等待任务时才删除信号量;
- OS_DEL_ALLWAYS在等待任务表中无论是否有等待任务都立即删除信号量;
需要注意,只能在任务中删除信号量,而不能在中断服务程序中删除;
OSSemQuery
任务可以调用该函数随时查询信号量的当前状态;
互斥信号量
互斥信号量时一个二值信号,可以使任务以独占方式使用共享资源;
使用互斥型信号量会出现任务优先级反转的问题,即在可剥夺型内核中,当任务以独占方式使用共享资源时,会出现低优先级任务先于高优先级任务而被运行的现象,这种现象在实时系统中是不允许出现的,因为它破坏了任务执行的预期顺序,可能会导致严重的后果;
解决该现象的办法之一是,使获得信号量任务的优先级别在使用共享资源期间暂时提升到所有任务最高优先级的高一个级别上,以使该任务不被其他任务所打断,从而能尽快地使用完共享资源并释放信号量,然后在释放信号量之后,再恢复该任务原来的优先级别;
OSMutexCreate
创建互斥型信号量,在描述互斥型信号量的事件控制块中,除了成员OSEventType要赋予常数OS_EVENT_TYPE_MUTEX以表明是一个互斥型信号量和仍然没有使用成员OSEventPtr之外,成员OSEventCnt被分成了低8位和高8位两部分,高8位用来存放为了避免出现优先级反转现象而要提升的优先级prio,低8位赋予常数OS_MUTEX_AVAILABLE,表明信号量尚未被任何任务所占用,处于有效状态;
OSMutexPend
请求互斥型信号量;
也可以调用函数OSMutexAccept()无等待地请求一个互斥型信号量;
OSMutexPost
发送一个互斥型信号量;
OSMutexQuery
获取互斥型信号量的当前状态;
OSMutexDel
任务调用该函数可删除一个互斥型信号量;
消息邮箱
OSMboxCreate
创建消息邮箱;
OSMboxPost
向消息邮箱发送消息;
OSMboxPostOpt
向消息邮箱发送消息,可以以广播的方式向事件等待任务表中的所有任务发送消息;
OSMboxPend
请求消息邮箱;
OSMboxAccept
请求消息邮箱失败时,不进行等待而是继续运行;
OSMboxQuery
查询消息邮箱当前状态信息;
OSMboxDel
删除一个消息邮箱;
消息队列
使用消息队列可在任务之间传递多条消息,消息队列由三部分组成:时间控制块、消息队列和消息;
事件控制块成员OSEventPtr指向一个叫做队列控制块(OS_Q)的结构,该结构管理着一个数组MsgTbl[],该数组中的元素都是指向消息的指针;
OSQCreate
创建消息队列,首先需要定义一个指针数组,然后把各个消息数据缓冲区的首地址存入这个数组中,最后调用该函数来创建消息队列;
OSQPend
请求消息队列,即从消息队列中获取消息;
如果希望任务无等待地请求一个消息队列,则可调用函数OSQAccept()函数;
OSQPost/OSQPostFront
向消息队列发送消息;
函数OSQPost()是以FIFO的方式组织消息队列;
函数OSQPostFront()以LIFO的方式组织消息队列;
OSQPostOpt
该函数时任务将以广播的方式通过消息队列发送消息;
OSQFlush
清空消息队列;
OSQDel
删除一个已存在的消息队列;
OSQQuery
查询一个消息队列的状态;
uCos-II中任务的同步与通信的更多相关文章
- ucos ii 百度官方介绍
μC/OS II(Micro-Controller Operating System Two)是一个可以基于ROM运行的.可裁剪的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处 ...
- ucos实时操作系统学习笔记——任务间通信(队列)
ucos操作系统中的queue机制同样使用了event机制来实现,其实和前面的sem,mutex实现类似,所不同的是对sem而言,任务想获得信号量,对mutex而言,任务想获得的是互斥锁.任务间通信的 ...
- DE1-SOC开发板上搭建NIOS II处理器运行UCOS II
DE1-SOC开发板上搭建NIOS II处理器运行UCOS II 今天在DE1-SOC的开发板上搭建NIOS II软核运行了UCOS II,整个开发过程比较繁琐,稍微有一步做的不对,就会导致整个过 ...
- [转]在Windows中配置Rsync同步
在Windows中配置Rsync同步 Rsync是一款不错的文件免费同步软件,可以镜像保存整个目录树和文件系统,同 时保持原来文件的权限.时间.软硬链接.第一次同步时 rsync 会复制全部内容,下次 ...
- Win32多线程编程(3) — 线程同步与通信
一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用.新线程与创建它的线程在相同的进程上下文中运行.因此,新线程可以访问进程内核对象的所有句柄.进程中的所有内存以及同一个进程中其他所有线 ...
- US/OS2之任务同步与通信
嵌入式系统中的各个任务都是以并发的方式来运行的,并为同一个大的任务服务,它们不可避免地要共同使用一些共享资源,并且在处理一些需要多个任务共同协作来完成的工作时,还需要相互的支持和限制.因此,对于一个完 ...
- javaEE开发中使用session同步和token机制来防止并发重复提交
javaEE开发中使用session同步和token机制来防止并发重复提交 通常在普通的操作当中,我们不需要处理重复提交的,而且有很多方法来防止重复提交.比如在登陆过程中,通过使用redirect,可 ...
- Python 多线程、多进程 (二)之 多线程、同步、通信
Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...
- Qt 多线程同步与通信
Qt 多线程同步与通信 1 多线程同步 Qt提供了以下几个类来完成这一点:QMutex.QMutexLocker.QSemphore.QWaitCondition. 当然可能还包含QReadWrite ...
随机推荐
- 如何知道一个EXE使用什么开发语言开发的
一般是看EXE调用哪些DLL,这可以使用VC++中的工具Dependency Walker,它可以列出静态链接的所有DLL. 如果EXE中的DLL包括MSVBVM60.DLL,则是使用VB 6.0开发 ...
- 关于ORACLE数据库名以及数据实例名等几个重要概念
在Oracle中有关数据库和数据库实例的几个重要概念,有时候如果理解不是很深或者对其疏忽.混淆了,还真容易搞错或弄不清其概念,下面就数据库实例名.数据库名.数据库域名.数据库服务名.全局数据库名几个概 ...
- django 问题综合
orm部分 本篇文章我会持续更新,把开发中遇到的一切orm相关的问题都放在这里 mysql索引报错 使用django 的orm,数据库用的mysql,在使用makemigrations和migrate ...
- python3 tkinter报错:_tkinter.TclError: cannot use geometry manager pack inside . which already has slaves managed by grid
报错: _tkinter.TclError: cannot use geometry manager pack inside . which already has slaves managed by ...
- Tomcat调试404错误
开篇附上我找到的部分解决方法摘自:https://blog.csdn.net/psp0001060/article/details/51879232 如不想跳转查看,链接内容如下: 问题一: ...
- LOJ #6043. 「雅礼集训 2017 Day7」蛐蛐国的修墙方案
我可以大喊一声这就是个SB题吗? 首先讲一句如果你像神仙CXR一样精通搜索你就可以得到\(80pts\)(无Subtask)的好成绩 我们考虑挖掘一下题目的性质,首先发现这是一个置换,那么我们发现这的 ...
- 你所不知道的ASP.NET Core MVC/WebApi基础系列(二)
前言 好久没冒泡了,算起来估计有快半年没更新博客了,估计是我第一次停更如此之久,人总有懒惰的时候,时间越长越懒惰,但是呢,不学又不行,持续的惰性是不行dei,要不然会被时光所抛弃,技术所淘汰,好吧,进 ...
- 11 Django RESTful framework 实现缓存
01-安装 pip install drf-extensions 02-导入 from rest_framework_extensions.cache.mixins import CacheRespo ...
- MYSQL Statement violates GTID consistency: Updates to non-transactional tables can only be done in either autocommitted statements or single-statement transactions, and never in the same statement as
[2019-04-21 10:17:20] [ERROR] [org.hibernate.engine.jdbc.spi.SqlExceptionHelper:144] Statement viola ...
- Android 开发之Windows环境下Android Studio安装和使用教程
JDK环境配置: http://www.cnblogs.com/liuhongfeng/archive/2015/12/30/5084896.html Android Studio下载地址:http: ...