Chapter 6: Event Control Block (ECB)
Synchronization & Communication Semaphore (counting semaphore) Mutual Exclusion Semaphore (binary semaphore + PCP) Event Flag Communication Message Mailbox Message Queue
General operations OSXxxCreate OSXxxDel OSXxxPend OSXxxAccept Wait for Xxx OSXxxAccept A non-blocking version of OSXxxPend OSXxxPost Release Xxx OSXxxQuery
Blocking System call TaskA TaskB “Device Not Ready”
Nonblocking System call TaskA return -1 “Device Not Ready”
Asynchronous System call TaskA TaskA return 0 “Device Not Ready”
Semantics of ECB ECB (Event Control Block) An ISR or a task can signal an ECB Only a task can wait for an ECB (error!!!) An optional timeout can be specified in case the ECB is not signaled within the specified time period
Semantics of ECB Multiple tasks can wait for an ECB. Only the highest priority task (HPT) is made ready to run when the ECB is signaled. When a ECB is used as a semaphore, tasks can both wait and signal the ECB.
The use of ECB A building block to implement services such as Semaphore Mutual Exclusion Semaphore Message Mailbox Message Queue All ECB functions only consider how to manipulate data structures. Caller must consider synchronization issues
ECB data structure
Type of event control block Pointer to message or queue structure ECB data structure Type of event control block .OSEventType .OSEventGrp .OSEventCnt .OSEventPtr 7 6 5 4 3 2 1 15 14 13 12 11 10 9 8 . 55 54 53 52 51 50 49 48 63 62 61 60 59 58 57 56 ~ OSRdyGrp Semaphore Count… Pointer to message or queue structure ~ OSRdyTbl “red” fields are Initialized by OS_EventWaitListInit ~: is “similar to”
OSEventType OSEventGrp OSEventCnt OSEventPtr OSEventTbl[] OS_EVENT_TYPE_SEM OS_EVENT_TYPE_MUTEX 0x00 0x00 cnt prio OS_MUTEX_AVAILABLE NULL NULL 0x00 … 0x00 0x00 … 0x00 OS_EVENT_TYPE_QM Point to msg 0x00 OS_EVENT_TYPE_MBOX 0x00 … 0x00 0x00 cnt Point to Q 0x00 … 0x00
ECB Functions OS_EventWaitListInit() OS_EventTaskRdy() Initialize an ECB OS_EventTaskRdy() Make a task ready OS_EventTaskWait() Put the task to sleep OS_EventTO()
5 Task A ECB Task B ready queue (waiting queue) 2. OS_XXX_Post 1 ready queue 2. OS_XXX_Post (OS_Event_TaskRdy) 1. OS_XXX_Pend (OS_Event_TaskWait) Task A ECB (waiting queue) Task B 5
5 Task A ECB Task B ready queue (waiting queue) OS_XXX_Post 1 ready queue 2. OS_EventTO 1. OS_XXX_Pend (OS_Event_TaskWait) Task A OS_XXX_Post (OS_Event_TaskRdy) ECB (waiting queue) Task B 5
OS_EventWaitListInit() "loop unrolling"
OS_EventTaskRdy() This function is called by the POST functions for a semaphore, a mutex, a message mailbox or a message queue when the ECB is signaled. OS_EventTaskRdy() removes the highest priority task from the wait list of the ECB and makes this task ready to run.
OS_EventTaskRdy() - 1 EventGrp EventTbl Waiting Queue Ready Queue 1 1 OSRdyGrp EventGrp 1 1 1 EventTbl OSRdyTbl 1 1 1 1 1
OS_EventTaskRdy() - 2 EventGrp EventTbl Waiting Queue Ready Queue 1 1 OSRdyGrp EventGrp 1 EventTbl OSRdyTbl 1 1 1 1 1
OS_EventTaskRdy() - 3 EventGrp EventTbl Waiting Queue Ready Queue 1 1 OSRdyGrp EventGrp 1 1 EventTbl OSRdyTbl 1 1 1 1 1
OS_EventTaskRdy() - 4 Task Control Block (TCB) Event Control Block OSTCBDly=? 1 OSTCBEventPtr OSTCBStat 1 1 Task Control Block (TCB) Event Control Block (ECB)
OS_EventTaskRdy() - 5 Task Control Block (TCB) Event Control Block OSTCBDly=? 1 OSTCBEventPtr OSTCBStat 1 1 Task Control Block (TCB) Event Control Block (ECB)
OS_EventTaskRdy() - 6 Task Control Block (TCB) Event Control Block OSTCBDly=0 1 OSTCBEventPtr OSTCBStat ≒ Rdy 1 1 Task Control Block (TCB) Event Control Block (ECB)
OS_EventTaskRdy() INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk) { OS_TCB *ptcb; INT8U x, y, bitx, bity, prio; y = OSUnMapTbl[pevent->OSEventGrp]; bity = OSMapTbl[y]; x = OSUnMapTbl[pevent->OSEventTbl[y]]; bitx = OSMapTbl[x]; prio = (INT8U)((y << 3) + x); if ((pevent->OSEventTbl[y] &= ~bitx) == 0x00) pevent->OSEventGrp &= ~bity; ptcb = OSTCBPrioTbl[prio]; ptcb->OSTCBDly = 0; ptcb->OSTCBEventPtr = (OS_EVENT *)0; ptcb->OSTCBMsg = msg; ptcb->OSTCBStat &= ~msk; if (ptcb->OSTCBStat == OS_STAT_RDY) { OSRdyGrp |= bity; OSRdyTbl[y] |= bitx; } return (prio); Find highest priority task waiting for message Remove this task from the waiting list Prevent OSTimeTick() from readying task Unlink ECB from this task Clear bit associated with event type Set the task ready to run if the task is not suspended
OS_EventTaskWait() This function is called by the PEND functions for a semaphore, a mutex, a message mailbox or a message queue when a task must wait on an ECB. It removes the current task from the ready list and places it in the wait list of the ECB.
OS_EventTaskWait() - 1 EventGrp EventTbl Waiting Queue Ready Queue 1 1 OSRdyGrp EventGrp 1 1 EventTbl OSRdyTbl 1 1 1 1 1
OS_EventTaskWait() - 2 EventGrp EventTbl Waiting Queue Ready Queue 1 1 OSRdyGrp EventGrp 1 EventTbl OSRdyTbl 1 1 1 1 1
OS_EventTaskWait() - 3 EventGrp EventTbl Waiting Queue Ready Queue 1 1 OSRdyGrp EventGrp 1 1 1 EventTbl OSRdyTbl 1 1 1 1 1
Put task in waiting list OS_EventTaskWait() void OS_EventTaskWait (OS_EVENT *pevent) { OSTCBCur->OSTCBEventPtr = pevent; if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0x00) { OSRdyGrp &= ~OSTCBCur->OSTCBBitY; } pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; Task no longer ready Put task in waiting list
OS_EventTO() OS_EventTO = OS-Event-Time-Out This function is called by the PEND functions for a semaphore, a mutex, a message mailbox or a message queue when the ECB is not signaled within the specified timeout period.
Usage: OS_EventTaskRdy() Taski Taskj xxx_post() xxx_pend( 0 ) xxx_post() xxx_pend( 0 )
Usage: OS_EventTO() 1 3 2 Taski Taskj Taskj xxx_post() xxx_pend( 3 ) Waiting queue Ready queue xxx_post() xxx_pend( 3 ) xxx_post() xxx_pend( 0 ) 1 3 2
Remove the task from the waiting list of the ECB OS_EventTO() void OS_EventTO (OS_EVENT *pevent) { if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0x00) { pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; } OSTCBCur->OSTCBStat = OS_STAT_RDY; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; Remove the task from the waiting list of the ECB