
嵌入式系统Chapter同步互斥与通信.ppt
128页电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心嵌入式系统及应用嵌入式系统及应用电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心第六章第六章同步、互斥与通信同步、互斥与通信电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心主要内容主要内容•概述概述•信号量信号量•邮箱和消息队列邮箱和消息队列•事件事件•异步信号异步信号* *•管道管道* *电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心概述概述•多任务系统中任务之间的关系多任务系统中任务之间的关系•相互独立相互独立 仅竞争仅竞争CPUCPU资源资源•竞争除竞争除CPUCPU外的其他资源〔互斥〕外的其他资源〔互斥〕•同步同步 协调彼此运行的步调,保证协同运协调彼此运行的步调,保证协同运行的各个任务具有正确的执行次序行的各个任务具有正确的执行次序 •通信通信 彼此间传递数据或信息,以协同完彼此间传递数据或信息,以协同完成某项工作成某项工作电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•任务能以以下方式与中断处理程序或其任务能以以下方式与中断处理程序或其他任务进行同步或通信:他任务进行同步或通信:–单向同步或通信:一个任务与另一个任务或一个ISR同步或通信。
–双向同步或通信:两个任务相互同步或通信双向同步不能在任务与ISR之间进行,因为ISR不能等待 概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心ISR xTask yPOSTPEND任务与任务与任务与任务与ISRISR之间的同步之间的同步之间的同步之间的同步〔单向〕〔单向〕〔单向〕〔单向〕Task xTask yPOSTPENDPOSTPEND任务与任务任务与任务任务与任务任务与任务之间的同步之间的同步之间的同步之间的同步〔双向〕〔双向〕〔双向〕〔双向〕任务与任务任务与任务任务与任务任务与任务之间的同步之间的同步之间的同步之间的同步〔单向〕〔单向〕〔单向〕〔单向〕Task xTask yPOSTPEND电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•在嵌入式多任务系统中,任务间的耦合在嵌入式多任务系统中,任务间的耦合程度是不一样的:程度是不一样的:•耦合程度较高:任务之间需要进行大量耦合程度较高:任务之间需要进行大量的通信,相应的系统开销较大;的通信,相应的系统开销较大;•耦合程度较低:任务之间不存在通信需耦合程度较低:任务之间不存在通信需求,其间的同步关系很弱甚至不需要同求,其间的同步关系很弱甚至不需要同步或互斥,系统开销较小。
步或互斥,系统开销较小•研究任务间耦合程度的上下对于合理地研究任务间耦合程度的上下对于合理地设计应用系统、划分任务有很重要的作设计应用系统、划分任务有很重要的作用 概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•在单处理器平台上,嵌入式操作系统内在单处理器平台上,嵌入式操作系统内核提供的同步、互斥与通信机制主要包核提供的同步、互斥与通信机制主要包括:括:•信号量〔信号量〔semaphoresemaphore〕,用于互斥与同步〕,用于互斥与同步•事件〔组〕〔事件〔组〕〔event groupevent group〕,用于同步〕,用于同步•异步信号〔异步信号〔asynchronous signalasynchronous signal〕,用〕,用于同步于同步•邮箱〔邮箱〔mailboxmailbox〕、消息队列〔〕、消息队列〔message message queuequeue〕,用于消息通信〕,用于消息通信•管道〔管道〔pipepipe〕,提供非结构化数据交换〕,提供非结构化数据交换和实现同步和实现同步 概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•以下一些机制也可用于同步与通信〔在以下一些机制也可用于同步与通信〔在单处理器或多处理器系统中〕:单处理器或多处理器系统中〕:•全局变量全局变量•共享内存共享内存•SocketsSockets•远程过程调用〔远程过程调用〔Remote Procedure CallRemote Procedure Call〕〕概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心第一节第一节信号量信号量信号量的种类及用途信号量的种类及用途互斥信号量互斥信号量二值信号量二值信号量计数信号量计数信号量信号量机制的主要数据结构信号量机制的主要数据结构典型的信号量操作典型的信号量操作电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•信号量用于实现任务与任务之间、任务信号量用于实现任务与任务之间、任务与中断处理程序之间的与中断处理程序之间的同步同步与与互斥互斥。
•信号量一般分为三种:信号量一般分为三种:信号量的种类及用途信号量的种类及用途用于解决互斥问题它比较特殊,可能用于解决互斥问题它比较特殊,可能会引起优先级反转问题会引起优先级反转问题用于解决同步问题用于解决同步问题用于解决资源计数问题用于解决资源计数问题将信号量进行种类细分,可以根据其用途,在具体将信号量进行种类细分,可以根据其用途,在具体实现时做专门处理,提高执行效率和可靠性实现时做专门处理,提高执行效率和可靠性电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•用互斥信号量保护的代码区称作用互斥信号量保护的代码区称作““临界区临界区〞〞,临界区,临界区代码通常用于对共享资源的访问代码通常用于对共享资源的访问•互斥信号量的值被初始化成互斥信号量的值被初始化成1 1,说明目前没有任务进入,说明目前没有任务进入““临界区临界区〞〞,但最多只有一个任务可以进入,但最多只有一个任务可以进入““临界区临界区〞〞•第一个试图进入第一个试图进入““临界区临界区〞〞的任务将成功获得互斥信的任务将成功获得互斥信号量,而随后试图进入用同一信号量保护的临界区的号量,而随后试图进入用同一信号量保护的临界区的所有其他任务就必须等待。
所有其他任务就必须等待•当任务离开当任务离开““临界区临界区〞〞时,它将释放信号量并允许正时,它将释放信号量并允许正在等待该信号量的任务进入在等待该信号量的任务进入““临界区临界区〞〞互斥信号量互斥信号量Task1Task2共享资源共享资源电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心互斥信号量互斥信号量•共享资源可能是一段存储器空间、一个数据结构共享资源可能是一段存储器空间、一个数据结构或或I/OI/O设备,也可能是被两个或多个并发任务共享设备,也可能是被两个或多个并发任务共享的任何内容的任何内容•使用互斥信号量可以实现对共享资源的串行访问,使用互斥信号量可以实现对共享资源的串行访问,保证只有成功地获取互斥信号量的任务才能够释保证只有成功地获取互斥信号量的任务才能够释放它•互斥信号量是一种特殊的二值信号量,一般它支互斥信号量是一种特殊的二值信号量,一般它支持所有权、递归访问、任务删除平安和一些防止持所有权、递归访问、任务删除平安和一些防止优先级反转、饥饿、死锁等互斥所固有问题的协优先级反转、饥饿、死锁等互斥所固有问题的协议 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心互斥信号量状态图互斥信号量状态图互斥信号量状态图互斥信号量状态图开启开启锁定锁定初始化初始化值为值为1申请并获得申请并获得值为值为0释放释放值为值为1申请申请(递归递归)并获得并获得锁定数加锁定数加1释放释放(递归递归)锁定数减锁定数减1电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心互斥信号量互斥信号量•所有权:当一个任务通过获取互斥信号量所有权:当一个任务通过获取互斥信号量而将其锁定时,得到该互斥信号量的所有而将其锁定时,得到该互斥信号量的所有权。
相反,当一个任务释放信号量时,失权相反,当一个任务释放信号量时,失去对其的所有权去对其的所有权•当一个任务拥有互斥信号量时,其他的任当一个任务拥有互斥信号量时,其他的任务不能再锁定或释放它,即任务要释放互务不能再锁定或释放它,即任务要释放互斥信号量,必须事前先获取该信号量斥信号量,必须事前先获取该信号量 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心Task1RoutineARoutineB互斥信号量互斥信号量•嵌套〔递归〕资源访问嵌套〔递归〕资源访问•如果如果Task1Task1调用调用RoutineARoutineA,而,而RoutineARoutineA又调又调用用RoutineBRoutineB,并且三者访问相同的共享资,并且三者访问相同的共享资源,就发生了递归共享资源的访问同步问源,就发生了递归共享资源的访问同步问题 共享资源共享资源 一个递归的互斥信一个递归的互斥信号量允许嵌套锁定号量允许嵌套锁定互斥信号量,而不互斥信号量,而不引起死锁引起死锁 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心互斥信号量互斥信号量•嵌套〔递归〕资源访问嵌套〔递归〕资源访问•每个获取信号量的调用必须与释放信号量每个获取信号量的调用必须与释放信号量的调用相匹配。
当最外层的获取信号量的的调用相匹配当最外层的获取信号量的调用与释放信号量的调用匹配时,该信号调用与释放信号量的调用匹配时,该信号量才允许被其它任务访问量才允许被其它任务访问 •用于同步的信号量不支持嵌套访问,任务用于同步的信号量不支持嵌套访问,任务如果对同步信号量使用上述操作是错误的,如果对同步信号量使用上述操作是错误的,任务会被永久阻塞,并且阻塞条件永远不任务会被永久阻塞,并且阻塞条件永远不会解除 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心互斥信号量互斥信号量•删除平安:删除平安:•在一个受信号量保护的临界区,经常需要在一个受信号量保护的临界区,经常需要保护在临界区执行的任务不会被意外地删保护在临界区执行的任务不会被意外地删除•删除一个在临界区执行的任务可能引起意删除一个在临界区执行的任务可能引起意想不到的后果,造成保护资源的信号量不想不到的后果,造成保护资源的信号量不可用,可能导致资源处于破坏状态,也就可用,可能导致资源处于破坏状态,也就导致了其它所有要访问该资源的任务无法导致了其它所有要访问该资源的任务无法得到满足得到满足 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心互斥信号量互斥信号量•删除平安:删除平安:•为防止任务在临界区执行时不被意外删除:为防止任务在临界区执行时不被意外删除:•提供提供““任务保护任务保护〞〞和和““解除任务保护解除任务保护〞〞原原语对语对•同时,为互斥信号量提供同时,为互斥信号量提供““删除平安删除平安〞〞选选项。
在创立信号量的时候使用这个选项,项在创立信号量的时候使用这个选项,当应用每次获取信号量时隐含地使能当应用每次获取信号量时隐含地使能““任任务保护务保护〞〞功能,当每次释放信号量时隐含功能,当每次释放信号量时隐含地使用地使用““解除任务保护解除任务保护〞〞功能 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心二值信号量二值信号量•二值信号量主要用于任务与任务之间、任务与中二值信号量主要用于任务与任务之间、任务与中断效劳程序之间的同步断效劳程序之间的同步•用于同步的二值信号量初始值为用于同步的二值信号量初始值为0 0,表示同步事件,表示同步事件尚未产生;尚未产生;•任务申请信号量以等待该同步事件的发生;任务申请信号量以等待该同步事件的发生;•另一个任务或另一个任务或ISRISR到达同步点时,释放信号量〔将到达同步点时,释放信号量〔将其值设置为其值设置为1 1〕表示同步事件已发生,以唤醒等待〕表示同步事件已发生,以唤醒等待的任务Task1Task2二二值值信号量信号量初初值为值为0电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心二值信号量二值信号量二值信号量状态图二值信号量状态图可获得可获得不可获得不可获得申请并获得申请并获得(值为值为0)释放释放(值为值为1)初始化初始化值为值为0电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心Task1(){ …… 执行一些操作执行一些操作; 将信号量将信号量sem1置置1; 申请信号量申请信号量sem2; …… ……}Task2(){ …… 申请信号量申请信号量sem1; 执行一些操作执行一些操作; 将信号量将信号量sem2置置1; …… ……}Task2申申请请信信号号量量sem1失失败败,,系系统统切换到切换到Task1sem1被被 置置 1后后 ,,Task2得得 到到 sem1并并抢占抢占Task1Task2运运行行到到某某处处时时因因某某种种原原因因被被阻阻塞塞,,系系统统切切换换到到Task1用二值信号量实现两个任务之间的双向同步用二值信号量实现两个任务之间的双向同步用二值信号量实现两个任务之间的双向同步用二值信号量实现两个任务之间的双向同步• •Task2Task2优先级高于优先级高于优先级高于优先级高于Task1Task1• •sem1sem1和和和和sem2sem2的初始值均为的初始值均为的初始值均为的初始值均为0 0电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心计数信号量计数信号量计数信号量用于控制系统中共享资源的多计数信号量用于控制系统中共享资源的多个实例的使用,允许多个任务同时访问同个实例的使用,允许多个任务同时访问同一种资源的多个实例一种资源的多个实例计数信号量被初始化为计数信号量被初始化为n〔非负整数〕,〔非负整数〕,n为该种共享资源的数目。
为该种共享资源的数目Task1Task2共享资源实例共享资源实例nTask m共享资源实例共享资源实例1…………电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心计数信号量计数信号量计数信号量状态图计数信号量状态图可可获获得得不可不可获获得得初始化初始化值值大于大于0申申请请并并获获得得值为值为0释释放放值为值为1申申请请并并获获得得值值减减1释释放放值值加加1电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量机制的主要数据结构信号量机制的主要数据结构SCB1SCB2…………信号量控制信号量控制块块count信号量名字或信号量名字或IDTask1Task2……任任务务等待列表等待列表电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量机制的主要数据结构信号量机制的主要数据结构•信号量控制块:管理所有创立的信号量,内核信号量控制块:管理所有创立的信号量,内核在系统运行时动态分配和回收信号量控制块在系统运行时动态分配和回收信号量控制块•互斥和二值信号量控制块结构互斥和二值信号量控制块结构: : Binary_Semaphore_Control_BlockBinary_Semaphore_Control_Blockwait_queue任务等待队列任务等待队列attributes信号量属性信号量属性lock_nesting_behavior试图嵌套获得时的规那么试图嵌套获得时的规那么 wait_discipline任务等待信号量的方式任务等待信号量的方式priority_ceiling优先级天花板值优先级天花板值lock是否被占有是否被占有holder拥有者拥有者 nest_count嵌套层数嵌套层数电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•计数信号量控制结构计数信号量控制结构Counting_Semaphore_Control_BlockCounting_Semaphore_Control_Block wait_queuewait_queue 任务等待队列任务等待队列 attributes attributes 计数信号量属性计数信号量属性 maximum_countmaximum_count 最大计数值最大计数值 wait_discipline wait_discipline任务等待信号量的方式任务等待信号量的方式 count count当前计数值当前计数值信号量机制的主要数据结构信号量机制的主要数据结构电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量内部实现机制实例说明信号量内部实现机制实例说明--µC/OS-II•事件控制块事件控制块ECBECB-同步与通信机制的根本数据结构-同步与通信机制的根本数据结构•typedef struct{typedef struct{•INT8UINT8UOSEventType;//OSEventType;//事件类型事件类型•INT8UINT8UOSEventGrp;//OSEventGrp;//等待任务所在的组等待任务所在的组•INT16UINT16UOSEventCnt;//OSEventCnt;//计数器〔信号量〕计数器〔信号量〕•voidvoid*OSEventPtr;//*OSEventPtr;//指向消息或消息队列的指向消息或消息队列的指针指针•INT8UINT8UOSEventTbl[OS_EVENT_TBL_SIZE];//OSEventTbl[OS_EVENT_TBL_SIZE];//等等待任务列表待任务列表•}OS_EVENT;}OS_EVENT;电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量内部实现机制实例说明信号量内部实现机制实例说明--µC/OS-II•当一个事件发生当一个事件发生后,等待事件列后,等待事件列表中优先级最高表中优先级最高的任务〔即在的任务〔即在.OSEventTbl[]&O.OSEventTbl[]&OSEventGrpSEventGrp中所有中所有被置被置1 1的位中优先的位中优先级数值最小的任级数值最小的任务〕得到该事件。
务〕得到该事件电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量内部实现机制实例说明信号量内部实现机制实例说明--µC/OS-II•当当.OSEventTbl[n].OSEventTbl[n]中的任何一位为中的任何一位为1 1时,时,OSEventGrpOSEventGrp中的第中的第n n位为位为1 1 与任务就绪列与任务就绪列表类似!表类似!电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量内部实现机制实例说明信号量内部实现机制实例说明--µC/OS-II•将一个任务插入到等待事件将一个任务插入到等待事件的任务列表中:的任务列表中:pevent->OSEventGrp |= OSMapTbl[prio >> 3];pevent->OSEventTbl[prio >> 3] |= OSMapTbl[prio & 0x07];与将一个任务插入到就绪列表中的操作类似!Index Bit mask (Binary)0 0 0 0 0 0 0 0 11 0 0 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电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量内部实现机制实例说明信号量内部实现机制实例说明--µC/OS-II•从等待事件的任务列表中使任务脱离等待从等待事件的任务列表中使任务脱离等待状态状态•if ((pevent->OSEventTbl[prio >> 3] &= if ((pevent->OSEventTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) {~OSMapTbl[prio & 0x07]) == 0) {•pevent->OSEventGrp &= ~OSMapTbl[prio pevent->OSEventGrp &= ~OSMapTbl[prio >> 3];>> 3];•} }•与将任务从就绪列表中去除的操作类似!与将任务从就绪列表中去除的操作类似!电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量内部实现机制实例说明信号量内部实现机制实例说明--µC/OS-II•在等待事件的任务列表中查找优先级最高在等待事件的任务列表中查找优先级最高的任务的任务y = OSUnMapTbl[pevent->OSEventGrp];x = OSUnMapTbl[pevent->OSEventTbl[y]];prio = (y << 3) + x;与查找优先级最高的就绪任务的操作类似!电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心信号量内部实现机制实例说明信号量内部实现机制实例说明--µC/OS-II•空闲事件控制块链表空闲事件控制块链表电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的信号量操作典型的信号量操作•创立信号量创立信号量•获取〔申请〕信号量获取〔申请〕信号量•释放信号量释放信号量•删除信号量删除信号量•去除信号量的任务等待列表去除信号量的任务等待列表 •获取有关信号量的各种信息获取有关信号量的各种信息 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心创立信号量创立信号量•功能:根据应用传递的参数创立一个信号量功能:根据应用传递的参数创立一个信号量•参数:信号量的名字、属性和初始值等。
参数:信号量的名字、属性和初始值等•内核动作:内核动作:•从空闲信号量控制块链中分配一个信号量控制块,从空闲信号量控制块链中分配一个信号量控制块,并初始化信号量属性并初始化信号量属性•创立成功时,为其分配唯一的创立成功时,为其分配唯一的IDID号返回给应用号返回给应用•如果已创立信号量数量已到达用户配置的最大数如果已创立信号量数量已到达用户配置的最大数量,就返回错误量,就返回错误电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心创立信号量创立信号量信号量的属性包括:信号量的属性包括:类型类型任务等待信号量的方式〔即排列的顺序〕任务等待信号量的方式〔即排列的顺序〕与任务删除平安、递归访问以及解决优先级与任务删除平安、递归访问以及解决优先级反转的策略相关的参数〔只针对互斥信号反转的策略相关的参数〔只针对互斥信号量〕 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心创立信号量创立信号量信信号号量量的的属属性性信号量的类型互斥信号量〔互斥信号量〔MUTEX_SEMAPHORE〕〕计数信号量〔计数信号量〔COUNTING_SEMAPHORE〕〕二值信号量〔二值信号量〔BINARY_SEMAPHORE〕〕任务等待信号量的方式先进先出〔先进先出〔FIFO〕顺序〕顺序优先级〔优先级〔PRIORITY〕顺序〕顺序优先级反转问题的解决方法〔只适用于互斥信号量〕优先级继承算法〔优先级继承算法〔INHERIT_PRIORITY〕〕优先级天花板算法优先级天花板算法(PRIORITY_CEILING) ,需给,需给出所有可能获得此信号量的任务中优先级最高出所有可能获得此信号量的任务中优先级最高的任务的优先级。
的任务的优先级电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心创立一个信号量创立一个信号量OSSemCreate()OS_EVENT *OSSemCreate (INT16U cnt)OS_EVENT *OSSemCreate (INT16U cnt){ {OS_EVENT *pevent;OS_EVENT *pevent;pevent = OSEventFreeList;//pevent = OSEventFreeList;//从空闲事件控制块链中取得一个从空闲事件控制块链中取得一个ECBECBif (OSEventFreeList != (OS_EVENT *)0) { if (OSEventFreeList != (OS_EVENT *)0) { OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;} }if (pevent != (OS_EVENT *)0) { //if (pevent != (OS_EVENT *)0) { //初始化初始化ECBECB的各个域的各个域pevent->OSEventType = OS_EVENT_TYPE_SEM; //pevent->OSEventType = OS_EVENT_TYPE_SEM; //事件类型为事件类型为信号量信号量pevent->OSEventCnt = cnt; //pevent->OSEventCnt = cnt; //信号量的初始计数值信号量的初始计数值pevent->OSEventPtr = (void *)0;pevent->OSEventPtr = (void *)0;OS_EventWaitListInit(pevent); //OS_EventWaitListInit(pevent); //初始化等待任务列表初始化等待任务列表} }return (pevent); //return (pevent); //调用者需检查返回值,如果为调用者需检查返回值,如果为NULLNULL那么表示建那么表示建立失败立失败} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心获取〔申请〕信号量获取〔申请〕信号量•功能:试图获得应用指定的信号量。
功能:试图获得应用指定的信号量if 信号量的值大于0then 将信号量的值减1else 根据接收信号量的选项,将任务放到等待队列中,或是直接返回电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心获取〔申请〕信号量获取〔申请〕信号量•当所申请的信号量不能被立即获得时,可当所申请的信号量不能被立即获得时,可以有以下几种选择:以有以下几种选择:•永远等待永远等待 •不等待,立即返回,并返回一个错误状态不等待,立即返回,并返回一个错误状态码码•指定等待时限〔可有效防止死锁〕指定等待时限〔可有效防止死锁〕•注意:注意:•不允许在不允许在ISRISR中选择等待中选择等待•当任务选择等待时,将被按当任务选择等待时,将被按FIFOFIFO或优先级或优先级顺序放置在等待队列中顺序放置在等待队列中电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心获取〔申请〕信号量获取〔申请〕信号量•如果任务等待一个使用如果任务等待一个使用优先级继承算法优先级继承算法的互斥的互斥信号量,且它的优先级高于当前正占有此信号信号量,且它的优先级高于当前正占有此信号量的任务的优先级,那么占有信号量的任务将量的任务的优先级,那么占有信号量的任务将继承这个被阻塞的任务的优先级。
继承这个被阻塞的任务的优先级•如果任务成功地获得一个采用如果任务成功地获得一个采用优先级天花板算优先级天花板算法法的互斥信号量,它的优先级又低于优先级天的互斥信号量,它的优先级又低于优先级天花板,那么它的优先级将被抬升至天花板花板,那么它的优先级将被抬升至天花板 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心获取〔等待〕一个信号量获取〔等待〕一个信号量OSSemPend()void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err){ {if (pevent->OSEventCnt > 0) { //if (pevent->OSEventCnt > 0) { //信号量值大于信号量值大于0 0,成功获得信号量并返回,成功获得信号量并返回pevent->OSEventCnt--; pevent->OSEventCnt--; *err = OS_NO_ERR;*err = OS_NO_ERR;return;} return;} OSTCBCur->OSTCBStat |= OS_STAT_SEM; //OSTCBCur->OSTCBStat |= OS_STAT_SEM; //设置任务状态为等待信号量设置任务状态为等待信号量OSTCBCur->OSTCBDly = timeout; //OSTCBCur->OSTCBDly = timeout; //设置等待时限设置等待时限OS_EventTaskWait(pevent);//OS_EventTaskWait(pevent);//将任务放置到信号量的等待列表中将任务放置到信号量的等待列表中 OS_Sched(); //OS_Sched(); //内核实施任务调度,系统切换到另一就绪任务执行内核实施任务调度,系统切换到另一就绪任务执行if (OSTCBCur->OSTCBStat & OS_STAT_SEM) { //if (OSTCBCur->OSTCBStat & OS_STAT_SEM) { //判断任务恢复执行的原因,判断任务恢复执行的原因,如果等待时限超时但仍然未获得信号量,那么返回超时信息如果等待时限超时但仍然未获得信号量,那么返回超时信息OSEventTO(pevent); OSEventTO(pevent); *err = OS_TIMEOUT;*err = OS_TIMEOUT;return;}return;}OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; *err = OS_NO_ERR; //*err = OS_NO_ERR; //任务由于获得信号量而恢复执行,本调用成功返回任务由于获得信号量而恢复执行,本调用成功返回} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心获取〔无等待地请求〕一个信号量获取〔无等待地请求〕一个信号量OSSemAccept()INT16U OSSemAccept (OS_EVENT *pevent)INT16U OSSemAccept (OS_EVENT *pevent){ {INT16U cnt;INT16U cnt;cnt = pevent->OSEventCnt; cnt = pevent->OSEventCnt; if (cnt > 0) { if (cnt > 0) { pevent->OSEventCnt--; pevent->OSEventCnt--; } }return (cnt); return (cnt); } }注意:即使不能成功获得信号量〔返回值为注意:即使不能成功获得信号量〔返回值为0 0〕,调用者〕,调用者也不会被阻塞。
此函数可以在中断处理程序中使用也不会被阻塞此函数可以在中断处理程序中使用电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心释放信号量释放信号量•功能:释放一个应用指定的信号量功能:释放一个应用指定的信号量 •if if 没有任务等待这个信号量没有任务等待这个信号量•then then 信号量的值加信号量的值加1 1 •else else 将信号量分配给一个等待任务〔将将信号量分配给一个等待任务〔将相应的任务移出等待队列,使其就绪〕相应的任务移出等待队列,使其就绪〕 •如果使用了优先级继承或优先级天花板算如果使用了优先级继承或优先级天花板算法,那么执行该功能〔系统调用〕的任务法,那么执行该功能〔系统调用〕的任务的优先级将恢复到原来的高度的优先级将恢复到原来的高度 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心释放一个信号量释放一个信号量OSSemPost()INT8U OSSemPost (OS_EVENT *pevent)INT8U OSSemPost (OS_EVENT *pevent){ {if (pevent->OSEventGrp!=0x00) { if (pevent->OSEventGrp!=0x00) { ////如果有任务在等待该信号量如果有任务在等待该信号量OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); ////使等使等待任务列表中优先级最高的任务就绪待任务列表中优先级最高的任务就绪OS_Sched(); OS_Sched(); ////内核实施任务调度内核实施任务调度return (OS_NO_ERR);return (OS_NO_ERR);////成功返回成功返回} } if (pevent->OSEventCnt < 65535) {if (pevent->OSEventCnt < 65535) {////如果没有任务等待该信号量,如果没有任务等待该信号量,并且信号量的值未溢出并且信号量的值未溢出pevent->OSEventCnt++; pevent->OSEventCnt++; ////信号量的值加信号量的值加1 1return (OS_NO_ERR);return (OS_NO_ERR);////成功返回成功返回} } return (OS_SEM_OVF);return (OS_SEM_OVF);////信号量溢出信号量溢出} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除信号量删除信号量•功能:从系统中删除应用指定的一个信号功能:从系统中删除应用指定的一个信号量量•内核动作:将信号量控制块返还给系统内核动作:将信号量控制块返还给系统•删除信号量的不一定是创立信号量的任务删除信号量的不一定是创立信号量的任务•如果有任务正在等待获得该信号量,执行如果有任务正在等待获得该信号量,执行此功能将使所有等待这个信号量的任务回此功能将使所有等待这个信号量的任务回到就绪队列中,且返回一个状态码指示该到就绪队列中,且返回一个状态码指示该信号量已被删除信号量已被删除电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除信号量删除信号量•企图获取已删除的信号量将返回一个错误;企图获取已删除的信号量将返回一个错误;•在互斥信号量正被使用时〔已经被某任务在互斥信号量正被使用时〔已经被某任务获取〕,不能删除它。
因为该信号量正在获取〕,不能删除它因为该信号量正在保护一个共享资源或临界代码段,该动作保护一个共享资源或临界代码段,该动作可能造成数据崩溃或其他严重问题可能造成数据崩溃或其他严重问题 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除一个信号量删除一个信号量OSSemDel()OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U *err)OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U *err){ {BOOLEAN tasks_waiting;BOOLEAN tasks_waiting;if(pevent->OSEventGrp!=0x00{//if(pevent->OSEventGrp!=0x00{//根据是否有任务在等待信号量设置等待标志根据是否有任务在等待信号量设置等待标志tasks_waiting=TRUE;tasks_waiting=TRUE;}else{}else{tasks_waiting=FALSE;tasks_waiting=FALSE;} }switch(opt){switch(opt){case OS_DEL_NO_PEND://case OS_DEL_NO_PEND://如果有任务等待信号量那么不删除信号量如果有任务等待信号量那么不删除信号量if(task_waiting==FALSE{//if(task_waiting==FALSE{//没有任务等待,释放没有任务等待,释放ECBECB回空闲链回空闲链pevent->OSEventType=OS_EVENT_TYPE_UNUSED;pevent->OSEventType=OS_EVENT_TYPE_UNUSED;pevent->OSEventPtr=OSEventFreeList;pevent->OSEventPtr=OSEventFreeList; OSEventFreeList=pevent;// OSEventFreeList=pevent;//调整空闲调整空闲ECBECB链头指针链头指针*err=OS_NO_ERR;*err=OS_NO_ERR;return((OS_EVENT)0);return((OS_EVENT)0);}else{}else{*err=OS_ERR_TASK_WAITING;//*err=OS_ERR_TASK_WAITING;//有任务等待,删除信号有任务等待,删除信号量失败量失败return(pevent);return(pevent);} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除一个信号量删除一个信号量OSSemDel()case OS_DEL_ALWAYS:case OS_DEL_ALWAYS:////无论有无任务等待都删除信号量无论有无任务等待都删除信号量 ////将等待列表中的每个任务都设置成就绪将等待列表中的每个任务都设置成就绪while(pevent->OSEventGrp!=0x00){while(pevent->OSEventGrp!=0x00){OS_EventTaskRdy(pevent,(void *)0, OS_STAT_SEM);}OS_EventTaskRdy(pevent,(void *)0, OS_STAT_SEM);}////释放该信号量的释放该信号量的ECBECB回空闲控制块链回空闲控制块链pevent->OSEventType=OS_EVENT_TYPE_UNUSED;pevent->OSEventType=OS_EVENT_TYPE_UNUSED;pevent->OSEventFreeList;pevent->OSEventFreeList; OSEventFreeList=pevent; OSEventFreeList=pevent;////如果之前有任务等待信号量,内核实施任务调度如果之前有任务等待信号量,内核实施任务调度if(tasks_waiting==TRUE){OS_Sched();}if(tasks_waiting==TRUE){OS_Sched();}*err=OS_NO_ERR;*err=OS_NO_ERR;return((OS_EVENT *)0);return((OS_EVENT *)0);default:default:*err=OS_ERR_INVALID_OPT;*err=OS_ERR_INVALID_OPT;return(pevent);return(pevent);} }} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心去除信号量的任务等待列表去除信号量的任务等待列表•为了去除等待一个信号量的所有任务,某为了去除等待一个信号量的所有任务,某些内核支持些内核支持FlushFlush操作,以便释放信号量等操作,以便释放信号量等待任务列表中的所有任务。
当多个任务的待任务列表中的所有任务当多个任务的执行必须在某些点相遇时,需要这样的机执行必须在某些点相遇时,需要这样的机制 SignalTaskTask2 二值信号量二值信号量初值为初值为0FlushTask1Task3电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心第二节第二节邮箱和消息队列邮箱和消息队列通信方式概述通信方式概述消息队列机制的主要数据结构消息队列机制的主要数据结构典型的消息队列操作典型的消息队列操作消息队列的其他典型使用消息队列的其他典型使用电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•任务间的通信方式任务间的通信方式•直接通信在通信过程中双方必须明确直接通信在通信过程中双方必须明确地知道〔命名〕彼此:地知道〔命名〕彼此:•Send (PSend (P,,message) message) – 发送一个消息到发送一个消息到任务任务P P•Receive(QReceive(Q,,message) message) – 从任务从任务Q Q接收一接收一个消息个消息 •间接通信通信双方不需要指出消息的间接通信通信双方不需要指出消息的来源或去向,而通过中间机制来通信。
来源或去向,而通过中间机制来通信如:如:•send(Asend(A,,message) message) – 发送一个消息给邮发送一个消息给邮箱箱A A•receive(Areceive(A,,message) message) – 从邮箱从邮箱A A接收一接收一个消息个消息通信方式概述通信方式概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•消息队列:消息队列:属于间接通信方式属于间接通信方式•消息:消息:内存空间中一段长度可变的缓冲区,其内存空间中一段长度可变的缓冲区,其长度和内容均可以由用户定义,其内容可以是长度和内容均可以由用户定义,其内容可以是实际的数据、数据块的指针或空实际的数据、数据块的指针或空•对消息内容的解释由应用完成对消息内容的解释由应用完成–从操作系统操作系统观点看,消息没有定义的格式,所有的消息都是字节流,没有特定的含义–从应用应用观点看,根据应用定义的消息格式,消息被解释成特定的含义–应用可以只把消息当成一个标志,这时消息机制用于实现同步同步概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•一些操作系统内核把消息进一步分为:邮箱和一些操作系统内核把消息进一步分为:邮箱和消息队列消息队列•邮箱仅能存放单条消息,它提供了一种低开销邮箱仅能存放单条消息,它提供了一种低开销的机制来传送信息。
每个邮箱可以保存一条大的机制来传送信息每个邮箱可以保存一条大小为假设干个字节的消息小为假设干个字节的消息•消息队列可存放假设干消息,提供了一种任务消息队列可存放假设干消息,提供了一种任务间缓冲通信的方法间缓冲通信的方法•消息机制可支持定长与可变长度两种模式的消消息机制可支持定长与可变长度两种模式的消息,可变长度的消息队列需要对队列中的每一息,可变长度的消息队列需要对队列中的每一条消息增加额外的存储开销条消息增加额外的存储开销概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心消息队列机制的主要数据结构消息队列机制的主要数据结构队队列控制列控制块块队队列列长长度度QCB1队队列名或列名或IDTask3Task4……接收任接收任务务等待列等待列表表Task1Task2……发发送任送任务务等待列等待列表表最大最大消息消息长长度度QCB2……消息队列及其相关的参数和支持数据结构消息队列及其相关的参数和支持数据结构 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心消息队列状态图消息队列状态图非空非空满满队列创立队列创立消息数为消息数为0消息队列状态图消息队列状态图消息发送消息发送消息数加消息数加1空空消息发送消息发送消息数为消息数为1消息接收消息接收消息数为消息数为0消息接收消息接收消息数减消息数减1消息接收消息接收消息数减消息数减1消息发送消息发送消息数等于队列长度消息数等于队列长度电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心消息队列机制的主要数据结构消息队列机制的主要数据结构•消息队列控制块消息队列控制块•管理所有创立的消息队列,系统运行时动态分配管理所有创立的消息队列,系统运行时动态分配和回收消息队列控制块和回收消息队列控制块•消息队列缓冲区消息队列缓冲区•存放发送到该队列的消息,接收者从缓冲区中取存放发送到该队列的消息,接收者从缓冲区中取出消息。
出消息•消息的发送或接收有两种方法〔影响消息缓冲区消息的发送或接收有两种方法〔影响消息缓冲区结构〕:结构〕:•将数据从发送任务的空间完全拷贝到接收任务的将数据从发送任务的空间完全拷贝到接收任务的空间中〔效率较低,执行时间与消息大小有关〕空间中〔效率较低,执行时间与消息大小有关〕•只传递指向数据存储空间的指针〔提高系统性能只传递指向数据存储空间的指针〔提高系统性能〕〕电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心Sending TaskReceiving TaskMessage1Message1Message1发送任务的发送任务的内存区域内存区域消息队列的消息队列的内存区域内存区域接收任务的接收任务的内存区域内存区域1st copy2nd copy发送和接收消息的消息拷贝和内存使用发送和接收消息的消息拷贝和内存使用发送和接收消息的消息拷贝和内存使用发送和接收消息的消息拷贝和内存使用• •这种消息传递方法效率低、占用空间大这种消息传递方法效率低、占用空间大这种消息传递方法效率低、占用空间大这种消息传递方法效率低、占用空间大• •一种效率更高的方式是传递消息指针一种效率更高的方式是传递消息指针一种效率更高的方式是传递消息指针一种效率更高的方式是传递消息指针电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心number_of_messagemax_message_countnumber_of_messagemax_message_sizewait_disciplinewait_queuequeue_startqueue_inqueue_outqueue_endmessagemessagemessagemessagemessagemessagemessagemessagemessagemax_message_count消息队列消息队列控制块控制块消息队列消息队列缓冲区缓冲区消息队列机制的主要数据结构消息队列机制的主要数据结构电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心消息队列的环形缓冲消息队列的环形缓冲消息队列的环形缓冲消息队列的环形缓冲消息队列机制的主要数据结构消息队列机制的主要数据结构max_message_countqueue_endqueue_startqueue_outnumber_of_messagequeue_in消息指针消息指针电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的消息队列操作典型的消息队列操作•创立消息队列创立消息队列•发送普通消息发送普通消息•发送紧急消息发送紧急消息•发送播送消息发送播送消息•接收消息接收消息•删除消息队列删除消息队列•获取有关消息队列的各种信息获取有关消息队列的各种信息 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心创立消息队列创立消息队列•创立消息队列时,调用者可以指定如下参创立消息队列时,调用者可以指定如下参数:数:•消息的最大长度消息的最大长度•每个消息队列中最多的消息数每个消息队列中最多的消息数•消息队列的属性消息队列的属性•任务等待消息时的排队方式:任务等待消息时的排队方式:FIFOFIFO或或PRIORITYPRIORITY•系统为新创立的消息队列分配唯一的系统为新创立的消息队列分配唯一的ID ID 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心发送消息发送消息•根据紧急程度的不同,消息通常可分为根据紧急程度的不同,消息通常可分为普通消息与紧急消息。
普通消息与紧急消息•如果有任务正在等待消息〔即消息队列如果有任务正在等待消息〔即消息队列为空〕,那么普通消息发送和紧急消息为空〕,那么普通消息发送和紧急消息发送的执行效果是一样的任务从等待发送的执行效果是一样的任务从等待队列移到就绪队列中,消息被拷贝到任队列移到就绪队列中,消息被拷贝到任务提供的缓冲区中〔或者由接收任务得务提供的缓冲区中〔或者由接收任务得到指向消息的指针〕到指向消息的指针〕•如果没有任务等待,发送普通消息将消如果没有任务等待,发送普通消息将消息放在队列尾,而发送紧急消息将消息息放在队列尾,而发送紧急消息将消息放在队列头放在队列头电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心发送消息发送消息Msg 3接收任务接收任务等待列表等待列表Msg 2Msg 1消息队列消息队列发送普通消息-先进先出发送普通消息-先进先出((FIFO)次序)次序Msg 3接收任务接收任务等待列表等待列表Msg 2Msg 1消息队列消息队列发送紧急消息-后进先出发送紧急消息-后进先出((LIFO)次序)次序电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心发送消息发送消息•如果发送消息时队列已被填满,那么不同的操如果发送消息时队列已被填满,那么不同的操作系统可能采取不同的处理方法:作系统可能采取不同的处理方法:•挂起试图向已满的消息队列中发送消息的任务挂起试图向已满的消息队列中发送消息的任务〔不适用于中断效劳程序〕〔不适用于中断效劳程序〕•简单地丢弃该条消息并向调用者返回错误信息简单地丢弃该条消息并向调用者返回错误信息•播送消息。
在此之前所有试图从队列中接收消播送消息在此之前所有试图从队列中接收消息的任务此时都将获得相同的消息该功能拷息的任务此时都将获得相同的消息该功能拷贝消息到各任务的消息缓冲中〔或者让所有的贝消息到各任务的消息缓冲中〔或者让所有的等待任务得到指向消息的指针〕,并唤醒所有等待任务得到指向消息的指针〕,并唤醒所有的等待任务的等待任务电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收消息接收消息•如果指定的消息队列中有消息,那么将如果指定的消息队列中有消息,那么将其中的第一条消息拷贝到调用者的缓冲其中的第一条消息拷贝到调用者的缓冲区〔或者将第一条消息指针传递给调用区〔或者将第一条消息指针传递给调用者〕,并从消息队列中删除它者〕,并从消息队列中删除它•如果此时消息队列中没有消息,那么可如果此时消息队列中没有消息,那么可能出现以下几种情况:能出现以下几种情况:•永远等待消息的到达:等待消息的任务永远等待消息的到达:等待消息的任务按按FIFOFIFO或优先级上下顺序排列在等待队或优先级上下顺序排列在等待队列中列中 •等待消息且指定等待时限:等待消息的等待消息且指定等待时限:等待消息的任务按任务按FIFOFIFO或优先级上下顺序排列在等或优先级上下顺序排列在等待队列中待队列中•不等待,强制立即返回不等待,强制立即返回电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收消息接收消息•限时等待可有效预防死锁限时等待可有效预防死锁•中断效劳程序接收消息时必须选择不等待,因为中断效劳程序接收消息时必须选择不等待,因为中断效劳程序是不能被阻塞的。
中断效劳程序是不能被阻塞的•如果消息队列被应用删除,那么所有等待该消息如果消息队列被应用删除,那么所有等待该消息队列的任务都被返回一个错误信息,并回复到就队列的任务都被返回一个错误信息,并回复到就绪状态电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收消息接收消息Task 4High消息队列消息队列接收任务等待列表接收任务等待列表任务等待列表-基于任务等待列表-基于优先级的次序优先级的次序Task 2mediumTask 3mediumTask 1LowTask 4High消息队列消息队列接收任务等待列表接收任务等待列表任务等待列表-先进先出任务等待列表-先进先出((FIFO)次序)次序Task 2mediumTask 3mediumTask 1Low电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除消息队列删除消息队列•从系统中删除指定的消息队列,释放消息队列控从系统中删除指定的消息队列,释放消息队列控制块及消息队列缓冲区制块及消息队列缓冲区•任何知道此消息队列任何知道此消息队列IDID号的代码都可以删除它号的代码都可以删除它•消息队列被删除后,所有等待从这个消息队列接消息队列被删除后,所有等待从这个消息队列接收消息的任务都回到就绪态,并得到一个错误信收消息的任务都回到就绪态,并得到一个错误信息说明消息队列已被删除。
息说明消息队列已被删除电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心消息队列的其他典型使用消息队列的其他典型使用•紧耦合的单向数据通信:发送任务发送消紧耦合的单向数据通信:发送任务发送消息后要求一个响应信号,说明接收任务已息后要求一个响应信号,说明接收任务已经成功接收到消息经成功接收到消息 Task1Task2 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心消息队列的其他典型使用消息队列的其他典型使用•紧耦合的双向数据通信紧耦合的双向数据通信 :如果数据需要在:如果数据需要在任务之间双向流动,那么可以采用紧耦合任务之间双向流动,那么可以采用紧耦合的双向数据通信模式〔也称为全双工通信的双向数据通信模式〔也称为全双工通信〕 Task1Task2电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心第三节第三节事事 件件概述概述事件机制的主要数据结构事件机制的主要数据结构典型的事件操作典型的事件操作事件机制的典型应用事件机制的典型应用电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•在嵌入式实时内核中,事件是指一种说明预先在嵌入式实时内核中,事件是指一种说明预先定义的系统事件已经发生的机制。
定义的系统事件已经发生的机制•事件机制用于任务与任务之间、任务与事件机制用于任务与任务之间、任务与ISRISR之之间的同步其主要的特点是可实现一对多的同间的同步其主要的特点是可实现一对多的同步 •一个事件就是一个标志,不具备其它信息一个事件就是一个标志,不具备其它信息•一个或多个事件构成一个事件集事件集可以一个或多个事件构成一个事件集事件集可以用一个指定长度的变量〔比方一个用一个指定长度的变量〔比方一个8bit, 8bit, 16bit16bit或或32bit32bit的无符号整型变量,不同的操作的无符号整型变量,不同的操作系统其具体实现不一样〕来表示,而每个事件系统其具体实现不一样〕来表示,而每个事件由在事件集变量中的某一位来代表由在事件集变量中的某一位来代表 概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•事件及事件集有以下特点:事件及事件集有以下特点: •事件间相互独立事件间相互独立•事件仅用于同步,不提供数据传输功能事件仅用于同步,不提供数据传输功能•事件无队列,即屡次发送同一事件,在未经过事件无队列,即屡次发送同一事件,在未经过任何处理的情况下,其效果等同于只发送一次。
任何处理的情况下,其效果等同于只发送一次•提供事件机制的意义在于:提供事件机制的意义在于:•当某任务要与多个任务或中断效劳同步时,就当某任务要与多个任务或中断效劳同步时,就需要使用事件机制需要使用事件机制•假设任务需要与一组事件中的任意一个发生同假设任务需要与一组事件中的任意一个发生同步,可称为独立型同步〔逻辑步,可称为独立型同步〔逻辑““或或〞〞关系〕•任务也可以等待假设干事件都发生时才同步,任务也可以等待假设干事件都发生时才同步,称为关联型同步〔逻辑称为关联型同步〔逻辑““与与〞〞关系〕 概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心“ “或〞同步和或〞同步和或〞同步和或〞同步和“ “与〞同步与〞同步与〞同步与〞同步概述概述任务任务任务任务任务任务任务任务ISRISRORAND“与〞型同步与〞型同步“或〞型同步或〞型同步事件集事件集事件集事件集POSTPOSTPENDPEND电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心用多个事件的组合发信号给多个任务用多个事件的组合发信号给多个任务用多个事件的组合发信号给多个任务用多个事件的组合发信号给多个任务概述概述任务任务任务任务任务任务ISRORAND事件集事件集事件集事件集事件集事件集〔〔8,,16或或32位〕位〕POSTPENDPEND电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•术语:术语:•发送事件集发送事件集 。
指在一次发送过程中发往指在一次发送过程中发往接收者〔比方任务〕的一个或多个事件接收者〔比方任务〕的一个或多个事件的组合 •待处理事件集指已被发送到一个接收待处理事件集指已被发送到一个接收者但还没有被接收〔即正在等待处理〕者但还没有被接收〔即正在等待处理〕的所有事件的集合的所有事件的集合 •事件条件指事件接收者在一次接收过事件条件指事件接收者在一次接收过程中期待接收的一个或多个事件的集合程中期待接收的一个或多个事件的集合•““或或〞〞同步:待处理事件集只要包括事同步:待处理事件集只要包括事件条件中的任一事件即可满足要求;件条件中的任一事件即可满足要求;•““与与〞〞同步:其二是待处理事件集必须同步:其二是待处理事件集必须包括事件条件中的全部事件方可满足要包括事件条件中的全部事件方可满足要求 概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心事件机制的主要数据结构事件机制的主要数据结构•事件集控制块:管理所有创立的事件集事件集控制块:管理所有创立的事件集•或者或者•事件集附属于任务,不需创立,其相关参事件集附属于任务,不需创立,其相关参数成为任务控制块的一局部数成为任务控制块的一局部电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心事件的内部实现机制实例说明事件的内部实现机制实例说明--µC/OS-II•事件标志组数据结构事件标志组数据结构•typedef struct{typedef struct{•INT8UINT8UOSFlagType;//OSFlagType;//指示本数据结构的类型指示本数据结构的类型•voidvoid*OSFlagWaitList;//*OSFlagWaitList;//等待事件标志的任务链表等待事件标志的任务链表•OS_FLAGSOS_FLAGSOSFlagFlags;//OSFlagFlags;//各事件标志的当前状态各事件标志的当前状态•}OS_FLAG_GRP;}OS_FLAG_GRP;•事件标志节点数据结构事件标志节点数据结构•typedef struct{typedef struct{•voidvoid*OSFlagNodeNext;//*OSFlagNodeNext;//后驱指针后驱指针•voidvoid*OSFlagNodePrev;//*OSFlagNodePrev;//前驱指针前驱指针•voidvoid*OSFlagNodeTCB;//*OSFlagNodeTCB;//任务控制块指针任务控制块指针•voidvoid*OSFlagNodeFlagGrp;//*OSFlagNodeFlagGrp;//指回指回OS_FLAG_GRPOS_FLAG_GRP结结构构•OS_FLAGSOS_FLAGSOSFlagNodeFlags;//OSFlagNodeFlags;//所等待的事件标志组合所等待的事件标志组合•INT8UINT8UOSFlagNodeWaitType;//OSFlagNodeWaitType;//等待类型〔与、或〕等待类型〔与、或〕•}OS_FLAG_NODE;}OS_FLAG_NODE;电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心事件标志组、事件标志节点及事件标志组、事件标志节点及任务控制块之间的关系任务控制块之间的关系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电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的事件操作典型的事件操作•创立事件集创立事件集•删除事件集删除事件集•发送事件〔集〕发送事件〔集〕•接收事件〔集〕接收事件〔集〕•获取有关事件集的各种信息获取有关事件集的各种信息 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心创立事件集创立事件集•申请空闲事件集控制块,设置事件集属申请空闲事件集控制块,设置事件集属性,初始化控制块中的域,分配性,初始化控制块中的域,分配IDID号号电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心创立一个事件标志组创立一个事件标志组OSFlagCreate()OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags, INT8U *err)OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags, INT8U *err){ {OS_FLAG_GRP *pgrp;OS_FLAG_GRP *pgrp;pgrp=OSFlagFreeList;pgrp=OSFlagFreeList;////获取一个空闲事件标志组结构获取一个空闲事件标志组结构if(pgrp!=(OS_FLAG_GRP *)0){if(pgrp!=(OS_FLAG_GRP *)0){////获取成功,初始化该结构中的域获取成功,初始化该结构中的域OSFlagFreeList=(OS_FLAG_GRP *)OSFlagFreeList-OSFlagFreeList=(OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList;>OSFlagWaitList;////调整空闲结构链头指针调整空闲结构链头指针pgrp->OSFlagType=OS_EVENT_TYPE_FLAG;pgrp->OSFlagType=OS_EVENT_TYPE_FLAG;pgrp->OSFlagFlags=flags;pgrp->OSFlagFlags=flags;////初始化当前各事件标志的状态初始化当前各事件标志的状态pgrp->OSFlagWaitList=(void *)0;pgrp->OSFlagWaitList=(void *)0;////尚无任务等待事件标志尚无任务等待事件标志*err=OS_NO_ERR;*err=OS_NO_ERR;}else{*err=OS_FLAG_GRP_DEPLETED;}}else{*err=OS_FLAG_GRP_DEPLETED;}return(pgrp);return(pgrp);} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收事件〔集〕接收事件〔集〕在接收事件〔集〕时可以有如下选项在接收事件〔集〕时可以有如下选项WAITNO_WAIT接收事件(集)时可等待接收事件(集)时可等待接收事件(集)时不等待接收事件(集)时不等待•接收者永远等待,直到事件接收者永远等待,直到事件条件被满足后成功返回;条件被满足后成功返回; •接收者根据指定的时限等待。
接收者根据指定的时限等待EVENT_ALLEVENT_ANY待处理事件集必须包含事件条件中的全部事件方可满足要求,待处理事件集必须包含事件条件中的全部事件方可满足要求,即按照即按照“与与”条件接收事件条件接收事件待处理事件集只要包含事件条件中的任一事件即可满足要求,待处理事件集只要包含事件条件中的任一事件即可满足要求,即按照即按照“或或”条件接收事件条件接收事件电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收〔等待〕事件标志组的事件标志位接收〔等待〕事件标志组的事件标志位OSFlagPend()OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err)INT16U timeout, INT8U *err){ {OS_FLAG_NODE node;// OS_FLAG_NODEOS_FLAG_NODE node;// OS_FLAG_NODE作为局部变量存在于调用该函数的任务堆栈中作为局部变量存在于调用该函数的任务堆栈中OS_FLAGS flags_cur;OS_FLAGS flags_cur;OS_FLAGS flags_rdy;OS_FLAGS flags_rdy;switch(wait_type){switch(wait_type){case OS_FLAG_WAIT_SET_ALL://case OS_FLAG_WAIT_SET_ALL://任务以任务以““与与〞〞方式等待事件标志方式等待事件标志flags_rdy=pgrp->OSFlagFlags&flags;flags_rdy=pgrp->OSFlagFlags&flags;if(flags_rdy==flags){//if(flags_rdy==flags){//事件标志当前状态与等待条件相符事件标志当前状态与等待条件相符pgrp->OSFlagFlags&=~flags_rdy;//pgrp->OSFlagFlags&=~flags_rdy;//去除〔即去除〔即““消费消费〞〞〕满足〕满足条件的事件标志条件的事件标志flags_cur=pgrp->OSFlagFlags;flags_cur=pgrp->OSFlagFlags;*err=OS_NO_ERR;*err=OS_NO_ERR;return(flags_cur);//return(flags_cur);//返回处理后的事件标志组返回处理后的事件标志组}else{OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);}}else{OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);}////事件标志当前状态与等待条件不相符,任务被阻塞事件标志当前状态与等待条件不相符,任务被阻塞break;break;电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收〔等待〕事件标志组的事件标志位接收〔等待〕事件标志组的事件标志位OSFlagPend()case OS_FLAG_WAIT_SET_ANY: //case OS_FLAG_WAIT_SET_ANY: //任务以任务以““或或〞〞方式等待事件标志方式等待事件标志 flags_rdy=pgrp->OSFlagFlags&flags; flags_rdy=pgrp->OSFlagFlags&flags;if(flags_rdy!=(OS_FLAGS)0){//if(flags_rdy!=(OS_FLAGS)0){//有满足条件的事件标志有满足条件的事件标志 pgrp->OSFlagFlags&=~flags_rdy; // pgrp->OSFlagFlags&=~flags_rdy; //去除〔即去除〔即““消费消费〞〞〕满〕满足条件的事件标志足条件的事件标志 flags_cur=pgrp->OSFlagFlags; flags_cur=pgrp->OSFlagFlags; *err=OS_NO_ERR; *err=OS_NO_ERR; return(flags_cur); // return(flags_cur); //返回处理后的事件标志组返回处理后的事件标志组}else{OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);}}else{OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);}////事件标志当前状态与等待条件不相符,任务被阻塞事件标志当前状态与等待条件不相符,任务被阻塞break;break;default:default:flags_cur=(OS_FLAGS)0;flags_cur=(OS_FLAGS)0;*err=OS_FLAG_ERR_WAIT_TYPE;*err=OS_FLAG_ERR_WAIT_TYPE;return(flags_cur);return(flags_cur);} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心OS_Sched();//OS_Sched();//当前任务被放到事件标志等待链后,内核实施任务调度当前任务被放到事件标志等待链后,内核实施任务调度if(OSTCBCur->OSTCBStat & OS_STAT_FLAG){//if(OSTCBCur->OSTCBStat & OS_STAT_FLAG){//判断任务重新就绪的原因,如判断任务重新就绪的原因,如果是等待超时果是等待超时OS_FlagUnlink(&node);//OS_FlagUnlink(&node);//将任务从事件标志等待链中解除下来将任务从事件标志等待链中解除下来OSTCBCur->OSTCBStat=OS_STAT_RDY;//OSTCBCur->OSTCBStat=OS_STAT_RDY;//设置当前任务状态为就绪设置当前任务状态为就绪flags_cur=(OS_FLAGS)0;//flags_cur=(OS_FLAGS)0;//无效的事件标志状态无效的事件标志状态*err=OS_TIMEOUT;//*err=OS_TIMEOUT;//超时信号超时信号}else{//}else{//任务重新就绪的原因是在限定时间得到了满足条件的事件标志任务重新就绪的原因是在限定时间得到了满足条件的事件标志pgrp->OSFlagFlags&=~OSTCBCur->OSTCBFlagsRdy; //pgrp->OSFlagFlags&=~OSTCBCur->OSTCBFlagsRdy; //去除〔即去除〔即““消费消费〞〞〕满足条件的事件标志〕满足条件的事件标志flags_cur=pgrp->OSFlagFlags;flags_cur=pgrp->OSFlagFlags;*err=OS_NO_ERR;*err=OS_NO_ERR;} }return(flags_cur);return(flags_cur);} }接收〔等待〕事件标志组的事件标志位接收〔等待〕事件标志组的事件标志位OSFlagPend()电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心添加一个任务到事件标志组等待任务链表中添加一个任务到事件标志组等待任务链表中OS_FlagBlock()OS_FLAG_GRPOS_EVENT_TYPE_FLAGAND or ORAND or OR00OS_TCBOS_TCBOSTCBCurAND or OROS_FLAG_NODEOS_FLAG_NODE0电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收〔无等待地获取〕事件标志接收〔无等待地获取〕事件标志OSFlagAccept()OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags, OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *err)INT8U wait_type, INT8U *err){ {OS_FLAGS flags_cur, flags_rdy;OS_FLAGS flags_cur, flags_rdy;*err = OS_NO_ERR;*err = OS_NO_ERR;switch (wait_type) {//switch (wait_type) {//判断等待事件标志的方式判断等待事件标志的方式 case OS_FLAG_WAIT_SET_ALL:// case OS_FLAG_WAIT_SET_ALL://〞〞与与〞〞方式等待方式等待flags_rdy = pgrp->OSFlagFlags & flags;flags_rdy = pgrp->OSFlagFlags & flags;if (flags_rdy == flags) pgrp->OSFlagFlags &= if (flags_rdy == flags) pgrp->OSFlagFlags &= ~flags_rdy;//~flags_rdy;//事件标志当前状态与等待条件相符,去除〔即事件标志当前状态与等待条件相符,去除〔即““消费消费〞〞〕相应的事件标志〕相应的事件标志else *err = OS_FLAG_ERR_NOT_RDY;//else *err = OS_FLAG_ERR_NOT_RDY;//不符合条件,返回错不符合条件,返回错误信息误信息flags_cur = pgrp->OSFlagFlags;flags_cur = pgrp->OSFlagFlags;break;break;电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心接收〔无等待地获取〕事件标志接收〔无等待地获取〕事件标志OSFlagAccept() case OS_FLAG_WAIT_SET_ANY:// case OS_FLAG_WAIT_SET_ANY://〞〞或或〞〞方式等待方式等待flags_rdy = pgrp->OSFlagFlags & flags;flags_rdy = pgrp->OSFlagFlags & flags;if (flags_rdy != (OS_FLAGS)0) if (flags_rdy != (OS_FLAGS)0) pgrp->OSFlagFlags &= ~flags_rdy;//pgrp->OSFlagFlags &= ~flags_rdy;//事件标志当前事件标志当前状态与等待条件相符,去除〔即状态与等待条件相符,去除〔即““消费消费〞〞〕相应的事件标志〕相应的事件标志else *err = OS_FLAG_ERR_NOT_RDY; //else *err = OS_FLAG_ERR_NOT_RDY; //不符合条件,返回不符合条件,返回错误信息错误信息flags_cur = pgrp->OSFlagFlags;flags_cur = pgrp->OSFlagFlags;break;break; default: default:flags_cur = (OS_FLAGS)0;//0flags_cur = (OS_FLAGS)0;//0表示无效的事件标志组表示无效的事件标志组*err = OS_FLAG_ERR_WAIT_TYPE;//*err = OS_FLAG_ERR_WAIT_TYPE;//错误的等待类型错误的等待类型break;break; } } return (flags_cur); return (flags_cur);} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心发送事件〔集〕发送事件〔集〕•调用者〔任务或中断〕构造一个事件〔集调用者〔任务或中断〕构造一个事件〔集〕,将其发往接收者〔比方目标任务〕。
〕,将其发往接收者〔比方目标任务〕可能会出现以下几种情况之一:可能会出现以下几种情况之一:•目标任务正在等待的事件条件得到满足,目标任务正在等待的事件条件得到满足,任务就绪;任务就绪;•目标任务正在等待的事件条件没有得到满目标任务正在等待的事件条件没有得到满足,该事件〔集〕被按足,该事件〔集〕被按““或或〞〞操作,保存操作,保存到目标任务的待处理事件集中,目标任务到目标任务的待处理事件集中,目标任务继续等待;继续等待;•目标任务未等待事件〔集〕,该事件〔集目标任务未等待事件〔集〕,该事件〔集〕被按〕被按““或或〞〞操作,保存到目标任务的待操作,保存到目标任务的待处理事件集中处理事件集中 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心发送〔置位〕事件标志组中的事件标志发送〔置位〕事件标志组中的事件标志OSFlagPost()OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U *err)OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U *err){ {OS_FLAG_NODE *pnode;OS_FLAG_NODE *pnode;BOOLEAN sched= FALSE;//BOOLEAN sched= FALSE;//初始化调度标志初始化调度标志OS_FLAGS flags_cur, flags_rdy;OS_FLAGS flags_cur, flags_rdy;pgrp->OSFlagFlags |= flags;//pgrp->OSFlagFlags |= flags;//置位事件标志置位事件标志pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;//pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;//获取任务等待链头节点获取任务等待链头节点while (pnode != (OS_FLAG_NODE *)0) {//while (pnode != (OS_FLAG_NODE *)0) {//如果有任务等待,遍历等待链如果有任务等待,遍历等待链switch (pnode->OSFlagNodeWaitType) {switch (pnode->OSFlagNodeWaitType) { case OS_FLAG_WAIT_SET_ALL://case OS_FLAG_WAIT_SET_ALL://〞〞与与〞〞方式等待方式等待 flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; if (flags_rdy == pnode->OSFlagNodeFlags) {// if (flags_rdy == pnode->OSFlagNodeFlags) {//符合等待条件符合等待条件 if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) sched = TRUE;//sched = TRUE;//如果任务就绪,设置调度标志如果任务就绪,设置调度标志 } } break; break;电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心case OS_FLAG_WAIT_SET_ANY://case OS_FLAG_WAIT_SET_ANY://〞〞或或〞〞方式等待方式等待 flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; if (flags_rdy != (OS_FLAGS)0) {// if (flags_rdy != (OS_FLAGS)0) {//有满足条件的事件标有满足条件的事件标志志 if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) sched = TRUE; //sched = TRUE; //如果任务就绪,设置调度标志如果任务就绪,设置调度标志 } } break; break;} } pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;//pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;//下一个下一个等待事件标志的节点等待事件标志的节点} }if (sched == TRUE) OS_Sched();//if (sched == TRUE) OS_Sched();//如果设置了调度标志,那么实施如果设置了调度标志,那么实施调度调度*err = OS_NO_ERR;*err = OS_NO_ERR; return (pgrp->OSFlagFlags); return (pgrp->OSFlagFlags);} }发送〔置位〕事件标志组中的事件标志发送〔置位〕事件标志组中的事件标志OSFlagPost()电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除事件集删除事件集•回收事件集控制块到空闲链中,等待接回收事件集控制块到空闲链中,等待接收该事件集的任务被恢复就绪收该事件集的任务被恢复就绪电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除事件标志组删除事件标志组OSFlagDel()OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, INT8U opt, INT8U *err)OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, INT8U opt, INT8U *err){ BOOLEAN tasks_waiting;{ BOOLEAN tasks_waiting; OS_FLAG_NODE *pnode; OS_FLAG_NODE *pnode;if (pgrp->OSFlagWaitList != (void *)0) tasks_waiting = TRUE;if (pgrp->OSFlagWaitList != (void *)0) tasks_waiting = TRUE;////有任务等有任务等待待else tasks_waiting = FALSE;else tasks_waiting = FALSE;////无任务等待无任务等待switch (opt) {switch (opt) { case OS_DEL_NO_PEND: case OS_DEL_NO_PEND:////在无任务等待时才删除事件标志组在无任务等待时才删除事件标志组if (tasks_waiting == FALSE) {if (tasks_waiting == FALSE) {////无任务等待,释放控制块到空闲链中无任务等待,释放控制块到空闲链中 pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; pgrp->OSFlagWaitList = (void *)OSFlagFreeList; pgrp->OSFlagWaitList = (void *)OSFlagFreeList; OSFlagFreeList = pgrp; OSFlagFreeList = pgrp; *err = OS_NO_ERR; *err = OS_NO_ERR; return ((OS_FLAG_GRP *)0); return ((OS_FLAG_GRP *)0);} else {} else {////有任务等待,删除失败有任务等待,删除失败 *err = OS_ERR_TASK_WAITING; *err = OS_ERR_TASK_WAITING; return (pgrp); return (pgrp); } }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心删除事件标志组删除事件标志组OSFlagDel() case OS_DEL_ALWAYS: case OS_DEL_ALWAYS:////无论是否有任务等待,都删除事件标志组无论是否有任务等待,都删除事件标志组pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;////获取等待头节点获取等待头节点 while (pnode != (OS_FLAG_NODE *)0) { while (pnode != (OS_FLAG_NODE *)0) {////遍历整个等待任务遍历整个等待任务链,使每个等待任务就绪链,使每个等待任务就绪 OS_FlagTaskRdy(pnode, (OS_FLAGS)0); OS_FlagTaskRdy(pnode, (OS_FLAGS)0); pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; } }pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; pgrp->OSFlagWaitList = (void *)OSFlagFreeList; pgrp->OSFlagWaitList = (void *)OSFlagFreeList;OSFlagFreeList = pgrp;OSFlagFreeList = pgrp;////释放控制块回空闲链释放控制块回空闲链if (tasks_waiting == TRUE) OS_Sched();if (tasks_waiting == TRUE) OS_Sched();////如果之前有任务等待,如果之前有任务等待, *err = OS_NO_ERR; *err = OS_NO_ERR;内核实施调度内核实施调度 return ((OS_FLAG_GRP *)0); return ((OS_FLAG_GRP *)0); default: default:*err = OS_ERR_INVALID_OPT;*err = OS_ERR_INVALID_OPT; return (pgrp); return (pgrp); } }} }电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心设设置事件置事件②②设设置事件置事件②②Task1ISR来自某设备的来自某设备的中断中断Task2消息队列消息队列Q事件标志集事件标志集信号量信号量S01000100发发送消息送消息①①释释放信号量放信号量①①接收消息接收消息④④获获取信号取信号量量④④③③事件机制的典型应用事件机制的典型应用•解决复杂的应用设计问题解决复杂的应用设计问题①①发送方〔发送方〔Task1Task1或或ISRISR〕发送信息〔消息或信〕发送信息〔消息或信号量〕;号量〕;②②发送方〔发送方〔Task1Task1或或ISRISR〕设置相应的事件标志〕设置相应的事件标志〔指示消息或信号量的〔指示消息或信号量的发送〕;发送〕;③③接收方〔接收方〔Task2Task2〕检〕检测事件标志集,判断是测事件标志集,判断是否满足其接收条件〔否满足其接收条件〔““与与〞〞条件接收或条件接收或““或或〞〞条件接收〕;条件接收〕;④④接收方〔接收方〔Task2Task2〕根〕根据事件标志集的指示定据事件标志集的指示定向接收信息〔消息或信向接收信息〔消息或信号量〕,到达和不同发号量〕,到达和不同发送方〔送方〔Task1Task1或或ISRISR〕同〕同步或通信的目的。
步或通信的目的 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心第四节第四节异步信号异步信号概述概述异步信号机制与中断机制的比较异步信号机制与中断机制的比较异步信号机制与事件机制的比较异步信号机制与事件机制的比较异步信号机制的主要数据结构异步信号机制的主要数据结构典型的异步信号操作典型的异步信号操作电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心•异步信号机制用于任务与任务之间、任务与异步信号机制用于任务与任务之间、任务与ISRISR之间的异步操作,它被任务〔或之间的异步操作,它被任务〔或ISRISR〕用来通知〕用来通知其它任务某个事件的出现其它任务某个事件的出现•异步信号标志可以依附于任务需要处理异步异步信号标志可以依附于任务需要处理异步信号的任务由两局部组成,一个是与异步信号信号的任务由两局部组成,一个是与异步信号无关的任务主体,另一个是无关的任务主体,另一个是ASRASR〔异步信号效劳〔异步信号效劳例程〕•一个一个ASRASR对应于一个任务当向任务发送一个异对应于一个任务当向任务发送一个异步信号,如果该任务正在运行那么中止其自身步信号,如果该任务正在运行那么中止其自身代码的运行,转而运行与该异步信号相关的效代码的运行,转而运行与该异步信号相关的效劳例程;或者当该任务被激活时,在投入运行劳例程;或者当该任务被激活时,在投入运行前执行前执行ASRASR。
•异步信号机制也可以称作软中断机制,异步信异步信号机制也可以称作软中断机制,异步信号又被称为软中断信号号又被称为软中断信号概述概述电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心概述概述Task1ISRTask2 ( ){使能异步信号;使能异步信号;……………………}Signal_routine ( ){……Return();}100000异步信号异步信号标标志志电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心异步信号机制与中断机制的比较异步信号机制与中断机制的比较•相同点相同点•具有中断性对中断的处理和对异步信号具有中断性对中断的处理和对异步信号的处理都要先暂时地中断当前任务的运行的处理都要先暂时地中断当前任务的运行•有相应的效劳程序有相应的效劳程序•根据中断向量,有一段与中断信号对应的根据中断向量,有一段与中断信号对应的效劳程序,称为效劳程序,称为ISRISR〔〔Interrupt Service Interrupt Service RoutineRoutine〕〕•根据异步信号的编号,有一段与之对应的根据异步信号的编号,有一段与之对应的效劳程序,称为效劳程序,称为ASRASR〔〔Asynchronious Asynchronious Service RoutineService Routine〕〕•可以屏蔽其响应可以屏蔽其响应•外部硬件中断可以通过相应的存放器操作外部硬件中断可以通过相应的存放器操作被屏蔽被屏蔽•任务也可屏蔽对异步信号的响应任务也可屏蔽对异步信号的响应电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心异步信号机制与中断机制的比较异步信号机制与中断机制的比较•不同点不同点•实质不同实质不同•中断由硬件或者特定的指令产生,不受任务中断由硬件或者特定的指令产生,不受任务调度的控制调度的控制•异步信号由系统调用〔使用发送异步信号功异步信号由系统调用〔使用发送异步信号功能〕产生,受到任务调度的控制能〕产生,受到任务调度的控制–处理时机〔或响应时间〕不同处理时机〔或响应时间〕不同–中断触发后,硬件根据中断向量找到相应的效劳中断触发后,硬件根据中断向量找到相应的效劳程序执行。
在退出中断效劳程序之前会进行重调程序执行在退出中断效劳程序之前会进行重调度,所以中断结束后运行的任务不一定是先前被度,所以中断结束后运行的任务不一定是先前被中断的任务中断的任务–异步信号通过发送异步信号的系统调用触发,但异步信号通过发送异步信号的系统调用触发,但是系统不一定马上开始对它的处理:是系统不一定马上开始对它的处理:–如果接收异步信号的不是当前任务,那么如果接收异步信号的不是当前任务,那么ASR要要等到接收任务被调度、完成上下文切换后才能执等到接收任务被调度、完成上下文切换后才能执行,之后再执行任务自身的代码行,之后再执行任务自身的代码–任务也可以给自己发送异步信号,在这种情况下,任务也可以给自己发送异步信号,在这种情况下,其其ASR将马上执行将马上执行–执行的环境不同执行的环境不同–一般地,一般地,ISR在独立的上下文中运行,操作系统在独立的上下文中运行,操作系统为之提供专门的堆栈空间为之提供专门的堆栈空间–ASR在相关任务的上下文中运行,所以在相关任务的上下文中运行,所以ASR也是也是任务的一个组成局部任务的一个组成局部电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心异步信号机制与事件机制的比较异步信号机制与事件机制的比较•同样是标志着某个事件的发生,事件机同样是标志着某个事件的发生,事件机制的使用是同步的,而异步信号机制是制的使用是同步的,而异步信号机制是异步的。
异步的•对一个任务来说,什么时候会接收到事对一个任务来说,什么时候会接收到事件是的,因为接收事件的功能是它自己件是的,因为接收事件的功能是它自己在运行过程中调用的在运行过程中调用的•任务不能预知何时会收到一个异步信号,任务不能预知何时会收到一个异步信号,并且一旦接收到了异步信号,在允许响并且一旦接收到了异步信号,在允许响应的情况下,它会中断正在运行的代码应的情况下,它会中断正在运行的代码而去执行异步信号处理程序而去执行异步信号处理程序电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心异步信号机制的主要数据结构异步信号机制的主要数据结构•一种异步信号控制结构一种异步信号控制结构Asynchronous_Signal_Control_Block Asynchronous_Signal_Control_Block –enabled 是否使能对异步信号的响应–handler 处理例程–attribute_set ASR的执行属性–signals_posted 使能响应时,已发送但尚未处理的信号–signals_pending 屏蔽响应时,已发送但尚未处理的信号–nest_level ASR中异步信号的嵌套层数电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心异步信号机制的主要数据结构异步信号机制的主要数据结构•ASRASR的执行属性的执行属性–是否允许任务在执行ASR过程中被抢占–是否允许时间片切换–是否支持ASR嵌套–是否允许在执行ASR过程中响应中断电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的异步信号操作典型的异步信号操作•安装异步信号处理例程安装异步信号处理例程•发送异步信号到任务发送异步信号到任务 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心安装异步信号处理例程安装异步信号处理例程•为任务安装一个异步信号处理例程〔为任务安装一个异步信号处理例程〔ASRASR〕。
〕仅当任务已建立了仅当任务已建立了ASRASR,才允许向该任务发,才允许向该任务发送异步信号,否那么发送的异步信号无效送异步信号,否那么发送的异步信号无效当任务的当任务的ASRASR无效时,发送到任务的异步信无效时,发送到任务的异步信号将被丢弃号将被丢弃•调用者需指定调用者需指定ASRASR的入口地址和执行属性的入口地址和执行属性电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心异步信号处理例程的一般形式异步信号处理例程的一般形式void handler(signal_set){switch(signal_set){CASE SIGNAL_1:动作动作1;;break; CASE SIGNAL_2:动作动作2;;break;……}}signal_set参数为任务接收到的异步信号集参数为任务接收到的异步信号集电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心发送异步信号到任务发送异步信号到任务•任务或任务或ISRISR可以调用该功能发送异步信号到目可以调用该功能发送异步信号到目标任务,发送者指定目标任务和要发送的异步标任务,发送者指定目标任务和要发送的异步信号〔集〕。
信号〔集〕•发送异步信号给任务对接收任务的执行状态没发送异步信号给任务对接收任务的执行状态没有任何影响有任何影响•在目标任务已经安装了异步信号处理例程的情在目标任务已经安装了异步信号处理例程的情况下,如果目标任务不是当前执行任务,那么况下,如果目标任务不是当前执行任务,那么发送给它的异步信号就会等下一次该任务占有发送给它的异步信号就会等下一次该任务占有处理器时再由相应的处理器时再由相应的ASRASR处理,任务获得处理处理,任务获得处理器后,将首先执行器后,将首先执行ASRASR•如果当前运行的任务发送异步信号给自己或收如果当前运行的任务发送异步信号给自己或收到来自中断的异步信号,在允许到来自中断的异步信号,在允许ASRASR处理的前处理的前提下,它的提下,它的ASRASR会立即执行会立即执行电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心第五节第五节管道管道概述概述管道机制的主要数据结构管道机制的主要数据结构典型的管道操作典型的管道操作管道机制的典型应用管道机制的典型应用电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制概述管道机制概述•管道〔管道〔pipepipe〕是提供非结构化数据交换和〕是提供非结构化数据交换和实现任务间同步的内核对象。
在传统的实实现任务间同步的内核对象在传统的实现中,管道是单向数据交换设施现中,管道是单向数据交换设施 Task1Task2管道管道管道中的数据管道中的数据写描述符写描述符读读描述符描述符向管道向管道写数据写数据从管道从管道读读数据数据数据在管道内像一个非结构字节流,按数据在管道内像一个非结构字节流,按FIFOFIFO的次序从管道的次序从管道中读出当管道空时,阻塞读者,当管道满时,阻塞写者当管道空时,阻塞读者,当管道满时,阻塞写者 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制概述管道机制概述•管道允许有多个读者和写者管道允许有多个读者和写者 Task1Task5管道管道Task2Task3Task4Task6ISR1ISR2ISR3公共管道操作公共管道操作电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制概述管道机制概述•管道与消息队列的区别管道与消息队列的区别•管道不存储多个消息,它存储的数据是非管道不存储多个消息,它存储的数据是非结构化的字节流;结构化的字节流;•管道中的数据严格地遵循先进先出的顺序;管道中的数据严格地遵循先进先出的顺序;•管道支持选择〔管道支持选择〔selectselect〕操作,而消息队〕操作,而消息队列不支持。
列不支持电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制概述管道机制概述•管道的状态管道的状态非空非空满满创创立管道立管道无写入数无写入数据据读读数据,有数据,有剩余数据剩余数据空空写数据写数据读读数据,数据,无数据留无数据留下下写数据,有写数据,有剩余空剩余空间间读读数据数据写数据,无写数据,无剩余空剩余空间间电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制概述管道机制概述•命名管道和无名管道:命名管道和无名管道:•一个命名管道具有一个类似于文件名的名一个命名管道具有一个类似于文件名的名字,并像一个文件或设备出现在文件中字,并像一个文件或设备出现在文件中任务或任务或ISRISR可以用名字对其进行引用可以用名字对其进行引用•无名管道没有名字且不在文件系统中出现,无名管道没有名字且不在文件系统中出现,它必须使用创立管道时系统返回调用者的它必须使用创立管道时系统返回调用者的描述符才能引用描述符才能引用 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制的主要数据结构管道机制的主要数据结构管道控制管道控制块块Byte countData bufferBuffer sizeOutput positionInput positionTask3Task4……接收任接收任务务等待列表等待列表Task1Task2……发发送任送任务务等待列表等待列表电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的管道操作典型的管道操作•创立和删除一个管道;创立和删除一个管道;•读或写管道;读或写管道;•管道上的选择操作;管道上的选择操作;•FlushFlush操作。
操作电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的管道操作典型的管道操作•管道创立和删除管道创立和删除•创立管道的操作给调用者返回两个描述符,创立管道的操作给调用者返回两个描述符,后续的调用引用这些描述符一个描述符后续的调用引用这些描述符一个描述符只能用于写,而另一个只能用于读只能用于写,而另一个只能用于读•创立一个命名管道与创立文件类似,在命创立一个命名管道与创立文件类似,在命名管道建立之后,在文件系统中有一个可名管道建立之后,在文件系统中有一个可识别的名字,可以使用识别的名字,可以使用openopen操作翻开它操作翻开它因此,调用者也必须说明是采用读方式翻因此,调用者也必须说明是采用读方式翻开还是写方式翻开开还是写方式翻开•与与openopen操作相对应,操作相对应,closeclose操作用于关闭并操作用于关闭并删除一个命名管道删除一个命名管道电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的管道操作典型的管道操作•管道读和写管道读和写•读操作把管道中的数据返回给调用者〔任读操作把管道中的数据返回给调用者〔任务〕任务应指定读多少数据如果指定务〕。
任务应指定读多少数据如果指定的大小超过管道中可以得到的数据量,那的大小超过管道中可以得到的数据量,那么任务可以选择阻塞,等待剩余的数据到么任务可以选择阻塞,等待剩余的数据到达 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的管道操作典型的管道操作•选择〔选择〔SelectSelect〕操作〕操作 •SelectSelect操作允许一个任务阻塞并等待一个操作允许一个任务阻塞并等待一个或多个管道上的一个指定条件的发生或多个管道上的一个指定条件的发生 Task1ISRTask2Task3Pipe1Pipe2Pipe3任务任务Task3Task3等待从等待从Pipe1Pipe1和和Pipe2Pipe2这两个管道读数这两个管道读数据并写到第三个管道据并写到第三个管道Pipe3Pipe3上在这种情况下,上在这种情况下,当头两个管道中的任意当头两个管道中的任意一个有数据时,一个有数据时,SelectSelect调用返回调用返回 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心典型的管道操作典型的管道操作•FlushFlush操作操作 •FlushFlush操作将所有的数据从管道中去除,使操作将所有的数据从管道中去除,使管道回到最初创立的状态。
管道回到最初创立的状态 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制的典型应用管道机制的典型应用•主要用于任务到任务或主要用于任务到任务或ISRISR到任务的数据传到任务的数据传输输 •也可用于任务之间的同步也可用于任务之间的同步 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心管道机制的典型应用管道机制的典型应用Task ATask BSelect操作操作Select操作操作管道管道C管道管道D任务任务A A和任务和任务B B翻开两个翻开两个管道作为任务间的通信管道作为任务间的通信方式:翻开管道方式:翻开管道C C作为从作为从任务任务A A到任务到任务B B的数据传的数据传输,翻开管道输,翻开管道D D作为从任作为从任务务B B到任务到任务A A的回应 电子科技大学嵌入式软件工程中心电子科技大学嵌入式软件工程中心谢谢!。
