嵌入式系统-Chapter6-同步、互斥 与通信_第1页
嵌入式系统-Chapter6-同步、互斥 与通信_第2页
嵌入式系统-Chapter6-同步、互斥 与通信_第3页
嵌入式系统-Chapter6-同步、互斥 与通信_第4页
嵌入式系统-Chapter6-同步、互斥 与通信_第5页
已阅读5页,还剩124页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、嵌入式系统(xtng)及应用共一百二十九页第六章同步(tngb)、互斥与通信共一百二十九页主要(zhyo)内容概述(i sh)信号量邮箱和消息队列事件异步信号*管道*共一百二十九页概述(i sh)多任务系统中任务之间的关系相互独立 仅竞争CPU资源竞争除CPU外的其他资源(互斥)同步 协调彼此运行的步调,保证协同运行的各个任务具有正确的执行(zhxng)次序 通信 彼此间传递数据或信息,以协同完成某项工作共一百二十九页任务能以以下方式与中断处理程序或其他(qt)任务进行同步或通信:单向同步或通信:一个任务与另一个任务或一个ISR同步或通信。 双向同步或通信:两个任务相互同步或通信。双向同步不能

2、在任务与ISR之间进行,因为ISR不能等待。 概述(i sh)共一百二十九页ISR xTask yPOSTPEND任务(rn wu)与ISR之间的同步(单向)Task xTask yPOSTPENDPOSTPEND任务(rn wu)与任务(rn wu)之间的同步(双向)任务与任务之间的同步(单向)Task xTask yPOSTPEND共一百二十九页在嵌入式多任务系统中,任务间的耦合程度是不一样的:耦合程度较高:任务之间需要进行大量的通信,相应(xingyng)的系统开销较大;耦合程度较低:任务之间不存在通信需求,其间的同步关系很弱甚至不需要同步或互斥,系统开销较小。研究任务间耦合程度的高低对

3、于合理地设计应用系统、划分任务有很重要的作用。 概述(i sh)共一百二十九页在单处理器平台上,嵌入式操作系统内核提供的同步、互斥与通信机制(jzh)主要包括:信号量(semaphore),用于互斥与同步事件(组)(event group),用于同步异步信号(asynchronous signal),用于同步邮箱(mailbox)、消息队列(message queue),用于消息通信管道(pipe),提供非结构化数据交换和实现同步 概述(i sh)共一百二十九页以下一些(yxi)机制也可用于同步与通信(在单处理器或多处理器系统中):全局变量共享内存Sockets远程过程调用(Remote Pr

4、ocedure Call)概述(i sh)共一百二十九页第一节信号量信号量的种类及用途互斥信号量二值信号量计数(j sh)信号量信号量机制的主要数据结构典型的信号量操作共一百二十九页信号量用于实现任务与任务之间、任务与中断处理程序之间的同步(tngb)与互斥。信号量一般分为三种:信号量的种类(zhngli)及用途用于解决互斥问题。它比较特殊,可能会引起优先级反转问题。用于解决同步问题用于解决资源计数问题将信号量进行种类细分,可以根据其用途,在具体实现时做专门处理,提高执行效率和可靠性。互斥信号量计数信号量二值信号量共一百二十九页用互斥信号量保护的代码区称作“临界区”,临界区代码通常用于对共享资

5、源的访问(fngwn)。互斥信号量的值被初始化成1,表明目前没有任务进入“临界区”,但最多只有一个任务可以进入“临界区”。第一个试图进入“临界区”的任务将成功获得互斥信号量,而随后试图进入用同一信号量保护的临界区的所有其他任务就必须等待。当任务离开“临界区”时,它将释放信号量并允许正在等待该信号量的任务进入“临界区”。互斥信号量Task1Task2共享资源共一百二十九页互斥信号量共享资源可能是一段存储器空间、一个数据结构或I/O设备,也可能是被两个或多个并发任务共享的任何内容。使用互斥信号量可以实现对共享资源的串行访问,保证只有成功地获取互斥信号量的任务才能够释放它。互斥信号量是一种特殊的二值

6、信号量,一般它支持所有权、递归访问、任务删除(shnch)安全和一些避免优先级反转、饥饿、死锁等互斥所固有问题的协议。 共一百二十九页互斥信号量状态图互斥信号量状态图开启(kiq)锁定(su dn)初始化值为1申请并获得值为0释放值为1申请(递归)并获得锁定数加1释放(递归)锁定数减1共一百二十九页互斥信号量所有权:当一个任务通过获取互斥信号量而将其锁定时,得到该互斥信号量的所有权。相反(xingfn),当一个任务释放信号量时,失去对其的所有权。当一个任务拥有互斥信号量时,其他的任务不能再锁定或释放它,即任务要释放互斥信号量,必须事前先获取该信号量。 共一百二十九页Task1RoutineAR

7、outineB互斥信号量嵌套(递归)资源访问如果(rgu)Task1调用RoutineA,而RoutineA又调用RoutineB,并且三者访问相同的共享资源,就发生了递归共享资源的访问同步问题。 共享资源 一个(y )递归的互斥信号量允许嵌套锁定互斥信号量,而不引起死锁。 共一百二十九页互斥信号量嵌套(递归)资源访问每个获取信号量的调用必须与释放(shfng)信号量的调用相匹配。当最外层的获取信号量的调用与释放(shfng)信号量的调用匹配时,该信号量才允许被其它任务访问。 用于同步的信号量不支持嵌套访问,任务如果对同步信号量使用上述操作是错误的,任务会被永久阻塞,并且阻塞条件永远不会解除。

8、 共一百二十九页互斥信号量删除安全:在一个受信号量保护的临界区,经常需要保护在临界区执行的任务(rn wu)不会被意外地删除。删除一个在临界区执行的任务可能引起意想不到的后果,造成保护资源的信号量不可用,可能导致资源处于破坏状态,也就导致了其它所有要访问该资源的任务无法得到满足。 共一百二十九页互斥信号量删除安全:为避免任务在临界区执行时不被意外删除:提供“任务保护”和“解除任务保护”原语对同时,为互斥信号量提供“删除安全”选项。在创建信号量的时候使用这个(zh ge)选项,当应用每次获取信号量时隐含地使能“任务保护”功能,当每次释放信号量时隐含地使用“解除任务保护”功能。 共一百二十九页各种

9、互斥机制(jzh)比较比较项目关中断使用测试并置位指令禁止任务切换使用信号量锁定范围互斥力度最强,锁定所有外部可屏蔽中断,凡是以中断形式到达的外部事件以及与之相关联的任务或处理过程均得不到执行凡是使用该指令访问共享资源的代码所有的任务只影响竞争共享资源的任务对系统响应时间的影响如果关中断的时间较长,对系统的响应性能有很大影响较小如果禁止切换的时间过长,则影响系统的响应性能对系统响应性能有一定影响,可能导致优先级反转实现时的系统开销小小小较大注意事项关中断时间要尽量短不是所有的处理器都具备这种指令,影响可移植性关调度的时间要尽量短需采用一定的策略解决优先级反转问题共一百二十九页二值信号量二值信号

10、量主要用于任务与任务之间、任务与中断(zhngdun)服务程序之间的同步用于同步的二值信号量初始值为0,表示同步事件尚未产生;任务申请信号量以等待该同步事件的发生;另一个任务或ISR到达同步点时,释放信号量(将其值设置为1)表示同步事件已发生,以唤醒等待的任务。Task1Task2二值信号量初值为0共一百二十九页二值信号量二值信号量状态图可获得(hud)不可(bk)获得申请并获得(值为0)释放(值为1)初始化值为0共一百二十九页Task1() 执行一些操作(cozu); 将信号量sem1置1; 申请信号量sem2; Task2() 申请信号量sem1; 执行一些(yxi)操作; 将信号量sem

11、2置1; Task2申请信号量sem1失败,系统切换到Task1sem1被置1后,Task2得到sem1并抢占Task1Task2运行到某处时因某种原因被阻塞,系统切换到Task1用二值信号量实现两个任务之间的双向同步Task2优先级高于Task1sem1和sem2的初始值均为0共一百二十九页计数(j sh)信号量计数信号量用于控制系统中共享资源的多个实例(shl)的使用,允许多个任务同时访问同一种资源的多个实例(shl)计数信号量被初始化为n(非负整数),n为该种共享资源的数目。Task1Task2共享资源实例nTask m共享资源实例1共一百二十九页计数(j sh)信号量计数(j sh)信

12、号量状态图可获得不可获得初始化值大于0申请并获得值为0释放值为1申请并获得值减1释放值加1共一百二十九页计数(j sh)信号量 1 2 3 4 n生产者任务消费者任务计数信号量使用实例(shl):有界缓冲问题共一百二十九页生产者任务(rn wu)do 产生一个数据项申请empty申请mutex将新生成的数据项添加到缓冲中释放mutex释放full while (1);消费者任务do 申请full申请mutex从缓冲中移出一个数据项的内容(nirng)释放mutex释放empty消费新获得的数据项内容 while (1); 计数信号量full:已被填充的数据项数目,取值范围0n,初始值为0计数信

13、号量empty:空闲数据项数目,取值范围为0n,初始值为n;互斥信号量mutex:控制生产者任务和消费者任务对有界缓冲的访问,初始值为1。共一百二十九页信号量机制的主要(zhyo)数据结构SCB1SCB2信号量控制块count信号量名字或IDTask1Task2任务等待列表共一百二十九页信号量机制(jzh)的主要数据结构信号量控制块:管理所有创建的信号量,内核在系统运行(ynxng)时动态分配和回收信号量控制块互斥和二值信号量控制块结构: Binary_Semaphore_Control_Blockwait_queue任务等待队列attributes信号量属性lock_nesting_beha

14、vior试图嵌套获得时的规则 wait_discipline任务等待信号量的方式priority_ceiling优先级天花板值lock是否被占有holder拥有者 nest_count嵌套层数共一百二十九页计数信号量控制结构Counting_Semaphore_Control_Block wait_queue任务等待(dngdi)队列 attributes计数信号量属性 maximum_count 最大计数值 wait_discipline任务等待信号量的方式 count当前计数值信号量机制(jzh)的主要数据结构共一百二十九页信号量内部实现机制(jzh)实例说明C/OS-II事件控制块ECB

15、同步与通信机制的基本数据结构typedef structINT8UOSEventType;/事件类型INT8UOSEventGrp;/等待任务所在的组INT16UOSEventCnt;/计数器(信号量)void*OSEventPtr;/指向消息或消息队列的指针(zhzhn)INT8UOSEventTblOS_EVENT_TBL_SIZE;/等待任务列表OS_EVENT;共一百二十九页信号量内部实现机制(jzh)实例说明C/OS-II当一个事件发生后,等待(dngdi)事件列表中优先级最高的任务(即在.OSEventTbl&OSEventGrp中所有被置1的位中优先级数值最小的任务)得到该事件。

16、共一百二十九页信号量内部实现(shxin)机制实例说明C/OS-II当.OSEventTbln中的任何一位为1时,OSEventGrp中的第n位为1。 与任务就绪列表(li bio)类似!共一百二十九页信号量内部实现机制实例(shl)说明C/OS-II将一个任务插入(ch r)到等待事件的任务列表中:pevent-OSEventGrp |= OSMapTblprio 3;pevent-OSEventTblprio 3 |= OSMapTblprio & 0 x07;与将一个任务插入到就绪列表中的操作类似!Index Bit mask (Binary)0 0 0 0 0 0 0 0 11 0 0

17、 0 0 0 0 1 02 0 0 0 0 0 1 0 03 0 0 0 0 1 0 0 04 0 0 0 1 0 0 0 05 0 0 1 0 0 0 0 06 0 1 0 0 0 0 0 07 1 0 0 0 0 0 0 0共一百二十九页信号量内部实现(shxin)机制实例说明C/OS-II从等待事件的任务(rn wu)列表中使任务(rn wu)脱离等待状态if (pevent-OSEventTblprio 3 &= OSMapTblprio & 0 x07) = 0) pevent-OSEventGrp &= OSMapTblprio 3;与将任务从就绪列表中清除的操作类似!共一百二十九

18、页信号量内部实现机制实例(shl)说明C/OS-II在等待事件的任务(rn wu)列表中查找优先级最高的任务(rn wu)y = OSUnMapTblpevent-OSEventGrp;x = OSUnMapTblpevent-OSEventTbly;prio = (y OSEventPtr;if (pevent != (OS_EVENT *)0) /初始化ECB的各个域pevent-OSEventType = OS_EVENT_TYPE_SEM; /事件类型为信号量pevent-OSEventCnt = cnt; /信号量的初始计数值pevent-OSEventPtr = (void *)0

19、;OS_EventWaitListInit(pevent); /初始化等待任务(rn wu)列表return (pevent); /调用者需检查返回值,如果为NULL则表示建立失败共一百二十九页获取(huq)(申请)信号量功能:试图获得应用指定的信号量。if 信号量的值大于0then 将信号量的值减1else 根据接收信号量的选项,将任务(rn wu)放到等待队列中,或是直接返回共一百二十九页获取(huq)(申请)信号量当所申请的信号量不能被立即获得时,可以有以下几种选择:永远等待 不等待,立即返回,并返回一个错误状态码指定等待时限(可有效避免(bmin)死锁)注意:不允许在ISR中选择等待当

20、任务选择等待时,将被按FIFO或优先级顺序放置在等待队列中共一百二十九页获取(huq)(申请)信号量如果任务等待一个使用优先级继承算法的互斥信号量,且它的优先级高于当前正占有此信号量的任务的优先级,那么占有信号量的任务将继承这个(zh ge)被阻塞的任务的优先级。如果任务成功地获得一个采用优先级天花板算法的互斥信号量,它的优先级又低于优先级天花板,那么它的优先级将被抬升至天花板。 共一百二十九页获取(huq)(等待)一个信号量OSSemPend()void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)if (pevent-OS

21、EventCnt 0) /信号量值大于0,成功获得信号量并返回pevent-OSEventCnt-; *err = OS_NO_ERR;return; OSTCBCur-OSTCBStat |= OS_STAT_SEM; /设置任务状态为等待信号量OSTCBCur-OSTCBDly = timeout; /设置等待时限OS_EventTaskWait(pevent);/将任务放置到信号量的等待列表(li bio)中 OS_Sched(); /内核实施任务调度,系统切换到另一就绪任务执行if (OSTCBCur-OSTCBStat & OS_STAT_SEM) /判断任务恢复执行的原因,如果等待

22、时限超时但仍然未获得信号量,则返回超时信息OSEventTO(pevent); *err = OS_TIMEOUT;return;OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0; *err = OS_NO_ERR; /任务由于获得信号量而恢复执行,本调用成功返回共一百二十九页获取(无等待地请求(qngqi))一个信号量OSSemAccept()INT16U OSSemAccept (OS_EVENT *pevent)INT16U cnt;cnt = pevent-OSEventCnt; if (cnt 0) pevent-OSEventCnt-; return (

23、cnt); 注意:即使(jsh)不能成功获得信号量(返回值为0),调用者也不会被阻塞。此函数可以在中断处理程序中使用。共一百二十九页释放(shfng)信号量功能:释放一个应用指定的信号量。 if 没有任务等待这个信号量then 信号量的值加1 else 将信号量分配给一个等待任务(将相应的任务移出等待队列,使其就绪) 如果使用了优先级继承或优先级天花板算法,那么执行该功能(系统(xtng)调用)的任务的优先级将恢复到原来的高度。 共一百二十九页释放(shfng)一个信号量OSSemPost()INT8U OSSemPost (OS_EVENT *pevent)if (pevent-OSEven

24、tGrp!=0 x00) /如果有任务在等待该信号量OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /使等待任务列表中优先级最高的任务就绪OS_Sched(); /内核实施任务调度return (OS_NO_ERR);/成功返回(fnhu) if (pevent-OSEventCnt OSEventCnt+; /信号量的值加1return (OS_NO_ERR);/成功返回 return (OS_SEM_OVF);/信号量溢出共一百二十九页删除(shnch)信号量功能:从系统中删除应用指定的一个(y )信号量内核动作:将信号量控制块返还给系统删

25、除信号量的不一定是创建信号量的任务如果有任务正在等待获得该信号量,执行此功能将使所有等待这个信号量的任务回到就绪队列中,且返回一个状态码指示该信号量已被删除共一百二十九页删除(shnch)信号量企图获取已删除的信号量将返回一个错误;在互斥信号量正被使用(shyng)时(已经被某任务获取),不能删除它。因为该信号量正在保护一个共享资源或临界代码段,该动作可能造成数据崩溃或其他严重问题。 共一百二十九页删除(shnch)一个信号量OSSemDel()OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U *err)BOOLEAN tasks_wa

26、iting;if(pevent-OSEventGrp!=0 x00/根据(gnj)是否有任务在等待信号量设置等待标志tasks_waiting=TRUE;elsetasks_waiting=FALSE;switch(opt)case OS_DEL_NO_PEND:/如果有任务等待信号量则不删除信号量if(task_waiting=FALSE/没有任务等待,释放ECB回空闲链pevent-OSEventType=OS_EVENT_TYPE_UNUSED;pevent-OSEventPtr=OSEventFreeList; OSEventFreeList=pevent;/调整空闲ECB链头指针*e

27、rr=OS_NO_ERR;return(OS_EVENT)0);else*err=OS_ERR_TASK_WAITING;/有任务等待,删除信号量失败return(pevent);共一百二十九页删除(shnch)一个信号量OSSemDel()case OS_DEL_ALWAYS:/无论有无任务等待都删除信号量 /将等待列表(li bio)中的每个任务都设置成就绪while(pevent-OSEventGrp!=0 x00)OS_EventTaskRdy(pevent,(void *)0, OS_STAT_SEM);/释放该信号量的ECB回空闲控制块链pevent-OSEventType=OS_

28、EVENT_TYPE_UNUSED;pevent-OSEventFreeList; OSEventFreeList=pevent;/如果之前有任务等待信号量,内核实施任务调度if(tasks_waiting=TRUE)OS_Sched();*err=OS_NO_ERR;return(OS_EVENT *)0);default:*err=OS_ERR_INVALID_OPT;return(pevent);共一百二十九页清除信号量的任务(rn wu)等待列表为了清除等待一个信号量的所有任务,某些内核支持Flush操作,以便(ybin)释放信号量等待任务列表中的所有任务。当多个任务的执行必须在某些点

29、相遇时,需要这样的机制。 SignalTaskTask2 二值信号量初值为0FlushTask1Task3共一百二十九页第二节邮箱和消息(xio xi)队列通信方式(fngsh)概述消息队列机制的主要数据结构典型的消息队列操作消息队列的其他典型使用共一百二十九页任务间的通信方式直接通信。在通信过程中双方必须明确地知道(命名)彼此:Send (P,message) 发送一个消息到任务PReceive(Q,message) 从任务Q接收(jishu)一个消息 间接通信。通信双方不需要指出消息的来源或去向,而通过中间机制来通信。如:send(A,message) 发送一个消息给邮箱Areceive(

30、A,message) 从邮箱A接收一个消息通信(tng xn)方式概述共一百二十九页消息队列:属于间接通信方式消息:内存空间中一段长度可变的缓冲区,其长度和内容均可以由用户定义,其内容可以是实际的数据、数据块的指针或空。对消息内容的解释由应用完成。从操作系统观点看,消息没有定义的格式,所有的消息都是字节流,没有特定的含义。从应用观点看,根据应用定义的消息格式,消息被解释成特定的含义。应用可以只把消息当成(dn chn)一个标志,这时消息机制用于实现同步概述(i sh)共一百二十九页一些操作系统内核把消息进一步分为:邮箱和消息队列邮箱仅能存放单条消息,它提供了一种低开销的机制(jzh)来传送信息

31、。每个邮箱可以保存一条大小为若干个字节的消息。消息队列可存放若干消息,提供了一种任务间缓冲通信的方法。消息机制可支持定长与可变长度两种模式的消息,可变长度的消息队列需要对队列中的每一条消息增加额外的存储开销。概述(i sh)共一百二十九页消息(xio xi)队列机制的主要数据结构队列控制块队列长度QCB1队列名或IDTask3Task4接收任务等待列表Task1Task2发送任务等待列表最大消息长度QCB2消息队列及其相关的参数和支持(zhch)数据结构 共一百二十九页消息(xio xi)队列状态图非空满队列创建(chungjin)消息数为0消息队列状态图消息发送消息数加1空消息发送消息数为1

32、消息接收消息数为0消息接收消息数减1消息接收消息数减1消息发送消息数等于队列长度共一百二十九页消息队列(duli)机制的主要数据结构消息队列控制块管理所有创建(chungjin)的消息队列,系统运行时动态分配和回收消息队列控制块消息队列缓冲区存放发送到该队列的消息,接收者从缓冲区中取出消息。消息的发送或接收有两种方法(影响消息缓冲区结构):将数据从发送任务的空间完全拷贝到接收任务的空间中(效率较低,执行时间与消息大小有关)只传递指向数据存储空间的指针(提高系统性能)共一百二十九页Sending TaskReceiving TaskMessage1Message1Message1发送任务的内存区

33、域消息队列的内存区域接收任务的内存区域1st copy2nd copy发送和接收消息的消息拷贝和内存使用这种消息传递方法效率低、占用空间大一种效率更高的方式(fngsh)是传递消息指针共一百二十九页number_of_messagemax_message_countnumber_of_messagemax_message_sizewait_disciplinewait_queuequeue_startqueue_inqueue_outqueue_endmessagemessagemessagemessagemessagemessagemessagemessagemessagemax_messa

34、ge_count消息队列(duli)控制块消息(xio xi)队列缓冲区消息队列机制的主要数据结构共一百二十九页消息队列(duli)的环形缓冲消息队列(duli)机制的主要数据结构max_message_countqueue_endqueue_startqueue_outnumber_of_messagequeue_in消息指针共一百二十九页典型的消息(xio xi)队列操作创建消息队列发送普通(ptng)消息发送紧急消息发送广播消息接收消息删除消息队列获取有关消息队列的各种信息 共一百二十九页创建消息(xio xi)队列创建消息队列时,调用者可以指定如下参数(cnsh):消息的最大长度每个消

35、息队列中最多的消息数消息队列的属性任务等待消息时的排队方式:FIFO或PRIORITY系统为新创建的消息队列分配唯一的ID 共一百二十九页发送(f sn)消息根据紧急程度(chngd)的不同,消息通常可分为普通消息与紧急消息。如果有任务正在等待消息(即消息队列为空),则普通消息发送和紧急消息发送的执行效果是一样的。任务从等待队列移到就绪队列中,消息被拷贝到任务提供的缓冲区中(或者由接收任务得到指向消息的指针)。如果没有任务等待,发送普通消息将消息放在队列尾,而发送紧急消息将消息放在队列头。共一百二十九页发送(f sn)消息Msg 3接收任务等待列表Msg 2Msg 1消息队列发送普通消息先进先

36、出(FIFO)次序Msg 3接收任务等待列表Msg 2Msg 1消息队列发送紧急消息后进先出(LIFO)次序共一百二十九页发送(f sn)消息如果发送消息时队列已被填满,则不同的操作系统可能采取不同的处理(chl)办法:挂起试图向已满的消息队列中发送消息的任务(不适用于中断服务程序)简单地丢弃该条消息并向调用者返回错误信息广播消息。在此之前所有试图从队列中接收消息的任务此时都将获得相同的消息。该功能拷贝消息到各任务的消息缓冲中(或者让所有的等待任务得到指向消息的指针),并唤醒所有的等待任务。共一百二十九页接收(jishu)消息如果指定的消息队列中有消息,则将其中的第一条消息拷贝到调用者的缓冲区

37、(或者将第一条消息指针传递给调用者),并从消息队列中删除它。如果此时消息队列中没有消息,则可能出现以下几种情况:永远等待消息的到达:等待消息的任务按FIFO或优先级高低顺序排列在等待队列中 等待消息且指定等待时限(shxin):等待消息的任务按FIFO或优先级高低顺序排列在等待队列中不等待,强制立即返回共一百二十九页接收(jishu)消息限时等待可有效预防死锁中断服务程序接收消息时必须选择不等待,因为中断服务程序是不能被阻塞(zs)的。如果消息队列被应用删除,则所有等待该消息队列的任务都被返回一个错误信息,并回复到就绪状态。共一百二十九页接收(jishu)消息Task 4High消息队列接收任

38、务等待列表任务等待列表基于优先级的次序Task 2mediumTask 3mediumTask 1LowTask 4High消息队列接收任务等待列表任务等待列表先进先出(FIFO)次序Task 2mediumTask 3mediumTask 1Low共一百二十九页删除(shnch)消息队列从系统中删除指定的消息(xio xi)队列,释放消息队列控制块及消息队列缓冲区。任何知道此消息队列ID号的代码都可以删除它。消息队列被删除后,所有等待从这个消息队列接收消息的任务都回到就绪态,并得到一个错误信息表明消息队列已被删除。共一百二十九页消息队列(duli)的其他典型使用紧耦合的单向数据通信:发送(f

39、 sn)任务发送(f sn)消息后要求一个响应信号,表明接收任务已经成功接收到消息。 Task1Task2 共一百二十九页消息队列的其他(qt)典型使用紧耦合的双向数据通信 :如果数据需要在任务之间双向流动,则可以(ky)采用紧耦合的双向数据通信模式(也称为全双工通信)。 Task1Task2共一百二十九页第三节事 件概述事件(shjin)机制的主要数据结构典型的事件操作事件机制的典型应用共一百二十九页在嵌入式实时内核中,事件是指一种表明预先定义的系统事件已经发生的机制。事件机制用于任务与任务之间、任务与ISR之间的同步。其主要的特点是可实现一对多的同步。 一个事件就是一个标志,不具备其它信息

40、。一个或多个事件构成一个事件集。事件集可以用一个指定长度的变量(比如(br)一个8bit, 16bit或32bit的无符号整型变量,不同的操作系统其具体实现不一样)来表示,而每个事件由在事件集变量中的某一位来代表。 概述(i sh)共一百二十九页事件及事件集有以下特点: 事件间相互独立事件仅用于同步,不提供数据传输功能事件无队列,即多次发送同一事件,在未经过任何处理的情况下,其效果等同于只发送一次。提供事件机制的意义在于:当某任务要与多个任务或中断服务同步时,就需要使用事件机制。若任务需要与一组事件中的任意一个(y )发生同步,可称为独立型同步(逻辑“或”关系)。任务也可以等待若干事件都发生时

41、才同步,称为关联型同步(逻辑“与”关系)。 概述(i sh)共一百二十九页“或”同步(tngb)和“与”同步(tngb)概述(i sh)任务任务任务任务ISRISRORAND“与”型同步“或”型同步事件集事件集POSTPOSTPENDPEND共一百二十九页用多个事件的组合(zh)发信号给多个任务概述(i sh)任务任务任务ISRORAND事件集事件集事件集(8,16或32位)POSTPENDPEND共一百二十九页术语:发送事件集 。指在一次发送过程中发往接收者(比如任务)的一个或多个事件的组合。 待处理事件集。指已被发送到一个接收者但还没有(mi yu)被接收(即正在等待处理)的所有事件的集合

42、。 事件条件。指事件接收者在一次接收过程中期待接收的一个或多个事件的集合。“或”同步:待处理事件集只要包括事件条件中的任一事件即可满足要求;“与”同步:其二是待处理事件集必须包括事件条件中的全部事件方可满足要求。 概述(i sh)共一百二十九页事件机制的主要(zhyo)数据结构事件集控制块:管理所有创建的事件集或者事件集附属(fsh)于任务,不需创建,其相关参数成为任务控制块的一部分共一百二十九页事件的内部实现机制实例(shl)说明C/OS-II事件标志(biozh)组数据结构typedef structINT8UOSFlagType;/指示本数据结构的类型void*OSFlagWaitLis

43、t;/等待事件标志的任务链表OS_FLAGSOSFlagFlags;/各事件标志的当前状态OS_FLAG_GRP;事件标志节点数据结构typedef structvoid*OSFlagNodeNext;/后驱指针void*OSFlagNodePrev;/前驱指针void*OSFlagNodeTCB;/任务控制块指针void*OSFlagNodeFlagGrp;/指回OS_FLAG_GRP结构OS_FLAGSOSFlagNodeFlags;/所等待的事件标志组合INT8UOSFlagNodeWaitType;/等待类型(与、或)OS_FLAG_NODE;共一百二十九页事件(shjin)标志组、事

44、件(shjin)标志节点及任务控制块之间的关系OS_FLAG_GRPOS_FLAG_NODE.OSTCBFlagNode.OSFlagNodeFlags.OSFlagNodeWaitType.OSFlagNodeNext.OSFlagNodePrev.OSFlagNodeTCB.OSFlagWaitList.OSFlagFlags.OSFlagTypeAND or ORAND or ORAND or OROS_EVENT_TYPE_FLAG00.OSTCBFlagNodeOS_TCB共一百二十九页典型的事件(shjin)操作创建事件集删除事件集发送事件(集)接收事件(集)获取(huq)有关事件

45、集的各种信息 共一百二十九页创建(chungjin)事件集申请空闲(kngxin)事件集控制块,设置事件集属性,初始化控制块中的域,分配ID号共一百二十九页创建(chungjin)一个事件标志组OSFlagCreate()OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags, INT8U *err)OS_FLAG_GRP *pgrp;pgrp=OSFlagFreeList;/获取一个空闲事件标志组结构if(pgrp!=(OS_FLAG_GRP *)0)/获取成功,初始化该结构中的域OSFlagFreeList=(OS_FLAG_GRP *)OSFlagFreeLis

46、t-OSFlagWaitList;/调整空闲结构链头指针pgrp-OSFlagType=OS_EVENT_TYPE_FLAG;pgrp-OSFlagFlags=flags;/初始化当前(dngqin)各事件标志的状态pgrp-OSFlagWaitList=(void *)0;/尚无任务等待事件标志*err=OS_NO_ERR;else*err=OS_FLAG_GRP_DEPLETED;return(pgrp);共一百二十九页接收(jishu)事件(集)在接收事件(shjin)(集)时可以有如下选项WAITNO_WAIT接收事件(集)时可等待接收事件(集)时不等待接收者永远等待,直到事件条件被满

47、足后成功返回; 接收者根据指定的时限等待。EVENT_ALLEVENT_ANY待处理事件集必须包含事件条件中的全部事件方可满足要求,即按照“与”条件接收事件待处理事件集只要包含事件条件中的任一事件即可满足要求,即按照“或”条件接收事件共一百二十九页接收(jishu)(等待)事件标志组的事件标志位OSFlagPend()OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err)OS_FLAG_NODE node;/ OS_FLAG_NODE作为局部变量存在于

48、调用该函数的任务(rn wu)堆栈中OS_FLAGS flags_cur;OS_FLAGS flags_rdy;switch(wait_type)case OS_FLAG_WAIT_SET_ALL:/任务以“与”方式等待事件标志flags_rdy=pgrp-OSFlagFlags&flags;if(flags_rdy=flags)/事件标志当前状态与等待条件相符pgrp-OSFlagFlags&=flags_rdy;/清除(即“消费”)满足条件的事件标志flags_cur=pgrp-OSFlagFlags;*err=OS_NO_ERR;return(flags_cur);/返回处理后的事件标志

49、组elseOS_FlagBlock(pgrp, &node, flags, wait_type, timeout);/事件标志当前状态与等待条件不相符,任务被阻塞break;共一百二十九页接收(jishu)(等待)事件标志组的事件标志位OSFlagPend()case OS_FLAG_WAIT_SET_ANY: /任务以“或”方式等待事件标志 flags_rdy=pgrp-OSFlagFlags&flags;if(flags_rdy!=(OS_FLAGS)0)/有满足条件的事件标志 pgrp-OSFlagFlags&=flags_rdy; /清除(即“消费”)满足条件的事件标志 flags_c

50、ur=pgrp-OSFlagFlags; *err=OS_NO_ERR; return(flags_cur); /返回处理后的事件标志组elseOS_FlagBlock(pgrp, &node, flags, wait_type, timeout);/事件标志当前状态(zhungti)与等待条件不相符,任务被阻塞break;default:flags_cur=(OS_FLAGS)0;*err=OS_FLAG_ERR_WAIT_TYPE;return(flags_cur);共一百二十九页OS_Sched();/当前任务被放到事件标志等待链后,内核实施任务调度if(OSTCBCur-OSTCBSt

51、at & OS_STAT_FLAG)/判断(pndun)任务重新就绪的原因,如果是等待超时OS_FlagUnlink(&node);/将任务从事件标志等待链中解除下来OSTCBCur-OSTCBStat=OS_STAT_RDY;/设置当前任务状态为就绪flags_cur=(OS_FLAGS)0;/无效的事件标志状态*err=OS_TIMEOUT;/超时信号else/任务重新就绪的原因是在限定时间得到了满足条件的事件标志pgrp-OSFlagFlags&=OSTCBCur-OSTCBFlagsRdy; /清除(即“消费”)满足条件的事件标志flags_cur=pgrp-OSFlagFlags;*

52、err=OS_NO_ERR;return(flags_cur);接收(jishu)(等待)事件标志组的事件标志位OSFlagPend()共一百二十九页添加一个任务(rn wu)到事件标志组等待任务(rn wu)链表中OS_FlagBlock()OS_FLAG_GRPOS_EVENT_TYPE_FLAGAND or ORAND or OR00OS_TCBOS_TCBOSTCBCurAND or OROS_FLAG_NODEOS_FLAG_NODE0共一百二十九页接收(无等待(dngdi)地获取)事件标志OSFlagAccept()OS_FLAGS OSFlagAccept (OS_FLAG_GR

53、P *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *err)OS_FLAGS flags_cur, flags_rdy;*err = OS_NO_ERR;switch (wait_type) /判断等待事件标志的方式 case OS_FLAG_WAIT_SET_ALL:/”与”方式等待flags_rdy = pgrp-OSFlagFlags & flags;if (flags_rdy = flags) pgrp-OSFlagFlags &= flags_rdy;/事件标志当前状态与等待条件(tiojin)相符,清除(即“消费”)相应的事件标志els

54、e *err = OS_FLAG_ERR_NOT_RDY;/不符合条件,返回错误信息flags_cur = pgrp-OSFlagFlags;break;共一百二十九页接收(无等待地获取(huq))事件标志OSFlagAccept() case OS_FLAG_WAIT_SET_ANY:/”或”方式等待flags_rdy = pgrp-OSFlagFlags & flags;if (flags_rdy != (OS_FLAGS)0) pgrp-OSFlagFlags &= flags_rdy;/事件(shjin)标志当前状态与等待条件相符,清除(即“消费”)相应的事件(shjin)标志else

55、 *err = OS_FLAG_ERR_NOT_RDY; /不符合条件,返回错误信息flags_cur = pgrp-OSFlagFlags;break; default:flags_cur = (OS_FLAGS)0;/0表示无效的事件标志组*err = OS_FLAG_ERR_WAIT_TYPE;/错误的等待类型break; return (flags_cur);共一百二十九页发送(f sn)事件(集)调用者(任务或中断)构造一个事件(集),将其发往接收者(比如目标任务)。可能会出现(chxin)以下几种情况之一:目标任务正在等待的事件条件得到满足,任务就绪;目标任务正在等待的事件条件没有

56、得到满足,该事件(集)被按“或”操作,保存到目标任务的待处理事件集中,目标任务继续等待;目标任务未等待事件(集),该事件(集)被按“或”操作,保存到目标任务的待处理事件集中。 共一百二十九页发送(置位)事件(shjin)标志组中的事件(shjin)标志OSFlagPost()OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U *err)OS_FLAG_NODE *pnode;BOOLEAN sched= FALSE;/初始化调度标志OS_FLAGS flags_cur, flags_rdy;pgrp-OSFlagFlags

57、 |= flags;/置位事件标志pnode = (OS_FLAG_NODE *)pgrp-OSFlagWaitList;/获取(huq)任务等待链头节点while (pnode != (OS_FLAG_NODE *)0) /如果有任务等待,遍历等待链switch (pnode-OSFlagNodeWaitType) case OS_FLAG_WAIT_SET_ALL:/”与”方式等待 flags_rdy = pgrp-OSFlagFlags & pnode-OSFlagNodeFlags; if (flags_rdy = pnode-OSFlagNodeFlags) /符合等待条件 if (

58、OS_FlagTaskRdy(pnode, flags_rdy) = TRUE) sched = TRUE;/如果任务就绪,设置调度标志 break;共一百二十九页case OS_FLAG_WAIT_SET_ANY:/”或”方式等待(dngdi) flags_rdy = pgrp-OSFlagFlags & pnode-OSFlagNodeFlags; if (flags_rdy != (OS_FLAGS)0) /有满足条件的事件标志 if (OS_FlagTaskRdy(pnode, flags_rdy) = TRUE) sched = TRUE; /如果任务就绪,设置调度标志 break;

59、 pnode = (OS_FLAG_NODE *)pnode-OSFlagNodeNext;/下一个等待事件标志的节点if (sched = TRUE) OS_Sched();/如果设置了调度标志,则实施调度*err = OS_NO_ERR; return (pgrp-OSFlagFlags);发送(f sn)(置位)事件标志组中的事件标志OSFlagPost()共一百二十九页删除(shnch)事件集回收事件集控制块到空闲(kngxin)链中,等待接收该事件集的任务被恢复就绪共一百二十九页删除事件(shjin)标志组OSFlagDel()OS_FLAG_GRP *OSFlagDel (OS_F

60、LAG_GRP *pgrp, INT8U opt, INT8U *err) BOOLEAN tasks_waiting; OS_FLAG_NODE *pnode;if (pgrp-OSFlagWaitList != (void *)0) tasks_waiting = TRUE;/有任务等待else tasks_waiting = FALSE;/无任务等待switch (opt) case OS_DEL_NO_PEND:/在无任务等待时才删除事件标志组if (tasks_waiting = FALSE) /无任务等待,释放控制块到空闲(kngxin)链中 pgrp-OSFlagType = O

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论