1 / 17

Chapter 6 Event Control Blocks

Chapter 6 Event Control Blocks. Figure 6.1 use of event control blocks (ECB) how tasks and ISRs can interact with each other. Event Control Blocks. typedef struct { INT8U OSEventType; /* Event type */

shyla
Télécharger la présentation

Chapter 6 Event Control Blocks

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 6Event Control Blocks

  2. Figure 6.1 use of event control blocks (ECB)how tasks and ISRs can interact with each other

  3. Event Control Blocks typedef struct { INT8U OSEventType; /* Event type */ INT8U OSEventGrp; /* Group for wait list */ INT16U OSEventCnt; /* Count (when event is a semaphore) */ void *OSEventPtr; /* Ptr to message or queue structure */ INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* Wait list for event to occur */ } OS_EVENT; • Each semaphore, mailbox, and queue is assigned an ECB • OSEventType: contains the type associated with the ECB • OS_EVENT_SEM, OS_EVENT_TYPE_MUTEX, OS_EVENT_TYPE_MBOX, OS_EVENT_TYPE_Q • OSEventPtr: only used when the ECB is assigned to a mailbox or a queue • OSEventTbl[] and OSEventGrp • similar to OSRdyTbl[ and OSRdyGrp • Contain a list of tasks waiting on the event instead of a list of tasks ready to run • OSEventCnt: used to hold the semaphore count

  4. Event Control Block (ECB) • Each task that needs to wait for the event to occur is placed in the wait list • Consist of the two variables: OSEventGrp and OSEventTbl[ ] OS_EVENT pevent OSEvnetType OSEvnetCnt OSEvnetPtr OSEvnetGrp 7 6 5 4 3 2 1 0 OSEventTbl[ ] 63 62 61 60 59 58 57 56

  5. Figure 6.3 Wait list for task waiting for an event to occur

  6. pevent->OSEventGrp |= OSMapTbl[prio >> 3]; pevent->OSEventTbl[prio >> 3] |= OSMapTbl[prio & 0x07]; Making a task wait for an event Removing a task from a wait list if ((pevent->OSEventTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) { pevent->OSEventGrp &= ~OSMapTbl[prio >> 3]; } Finding the highest priority task waiting for the event y = OSUnMapTbl[pevent->OSEventGrp]; x = OSUnMapTbl[pevent->OSEventTbl[y]]; prio = (y << 3) + x;

  7. Contents of OSMapTbl[ ]

  8. OSUnMapTbl[ ] INT8U const OSUnMapTbl[] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };

  9. Example of ECB wait list • OSEventGrp = 11001000 => OSUnMapTbl[OSEventGrp] = 3 • OSEventTbl[3] = 00010000  OSUnMapTbl[OSEventTbl[3] ] = 4 • The priority of the task waiting is 3*8+4 = 28

  10. OS_EVENT pevent OSEvnetType OSEvnetCnt OSEvnetPtr OSEvnetGrp 7 6 5 4 3 2 1 0 63 62 61 60 59 58 57 56 Figure 6.3 List of free ECBs • The number of ECBs to allocate depends on the number of semaphores, mailboxes, and queues needed for your application • When OSInit() is called, all ECBs are linked in a singly linked list • The list of free ECBs

  11. Four common operations can be performed on ECBs • Initialize an ECB • Make a task ready • Make a task wait for an event • Make a task ready because a timeout occurred while waiting for an event • Four functions have been created to performs these operations • OSEventWaitListInit(): called when a semaphore, mutex, message mailbos, or message queue is created • OSEventTaskRdy() • OSEventWait() • OSEventTO()

  12. Initializing an ECBOSEventWaitListInit() • Is called by OSSemCreate(), OSMutexCreate() OSMboxCreate (), OSQCreate () • No task is waiting on the ECB new version void OSEventWaitListInit (OS_EVENT *pevent) { INT8U *ptbl; pevent->OSEventGrp = 0x00; ptlb = & pevent->OSEventTbl[0]; #if OS_EVENT_TBL_SIZE > 0 *ptbl++ = 0x00; #endif #if OS_EVENT_TBL_SIZE > 1 *ptbl++ = 0x00; #endif . . . } Old version void OSEventWaitListInit (OS_EVENT *pevent) { INT8U i; pevent->OSEventGrp = 0x00; for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { pevent->OSEventTbl[i] = 0x00; } } The code is implemented inline to avoid the overhead of a for loop

  13. Making a task readyOSEventTaskRdy() • This function is called by • OSSemPost(), OSMutexPost(), OSMbosPost(), OSQPost(), and OSQPostFront() • Removes the highest priority task (HPT) from the wait list of the ECB and makes this task ready to run void OSEventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk) { OS_TCB *ptcb; INT8U x; INT8U y; INT8U bitx; INT8U bity; INT8U prio;

  14. y = OSUnMapTbl[pevent->OSEventGrp]; (1) bity = OSMapTbl[y]; (2) x = OSUnMapTbl[pevent->OSEventTbl[y]]; (3) bitx = OSMapTbl[x]; (4) prio = (INT8U)((y << 3) + x); (5) if ((pevent->OSEventTbl[y] &= ~bitx) == 0) { (6) pevent->OSEventGrp &= ~bity; } ptcb = OSTCBPrioTbl[prio]; (7) ptcb->OSTCBDly = 0; (8) ptcb->OSTCBEventPtr = (OS_EVENT *)0; (9) #if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN ptcb->OSTCBMsg = msg; (10) #else msg = msg; //avoid a warning message in compiler #endif ptcb->OSTCBStat &= ~msk; //OS_STAT_SEM, OS_STAT_MUTEX, OS_STAT_MBOX, OS_STAT_Q (11) if (ptcb->OSTCBStat == OS_STAT_RDY) { (12) OSRdyGrp |= bity; (13) OSRdyTbl[y] |= bitx; } } OSEventTaskRdy (cont’d)

  15. Figure 6.4 Making a task ready to run

  16. Making a task wait for an eventOSEventTaskWait() • Called by OSSemPend(), OSMutexPend(), OSMboxPend, and OSQPend() when a task must wait on an ECB • OSEventTaskWait() removes the current task from the ready list and places it in the wait list of the ECB void OSEventTaskWait (OS_EVENT *pevent) { OSTCBCur->OSTCBEventPtr = pevent; (1) if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { (2) OSRdyGrp &= ~OSTCBCur->OSTCBBitY; } pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; (3) pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; }

  17. Making a task ready because of a timeoutOSEventTO() • Called by OSSemPend(), OSMboxPend(), OSQPend() when a task has been made ready to run by OSTimeTick() • OSEventTO() must remove the task from the wait list of the ECB and mark the task as being ready void OSEventTO (OS_EVENT *pevent) { if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { (1) pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; } OSTCBCur->OSTCBStat = OS_STAT_RDY; (2) OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; (3) }

More Related