SlideServe
Menu
Préférences
© SlideServe · v2026

Chapter7 Semaphore Management

tess avatar
11 diapositives · 381 Views · Oct 20, 2014

Chapter7 Semaphore Management. Semaphores. Create a semaphore by calling OSSemCreate() The initial count of the semaphore can be 0 to 65535 Use to signal the occurrence of one ore more event, the init value is 0 (flag) Use to access a shared resource, the init value is set to 1 (binary) (key)

Chapter7 Semaphore Management - slide 1
01 / 11Chapter7 Semaphore Management
1 / 17

Télécharger la présentation

Chapter7 Semaphore Management
Une image / un lien ci-dessous est fourni (tel quel) pour télécharger la présentation

Politique de téléchargement : le contenu du site vous est fourni TEL QUEL pour votre information et votre usage personnel ; il ne peut être vendu, concédé sous licence ni partagé sur d’autres sites sans l’accord de son auteur.Le contenu vous est fourni TEL QUEL, pour votre information et votre usage personnel uniquement. Téléchargez la présentation en cliquant sur ce lien. Lors du téléchargement, si vous ne parvenez pas à télécharger une présentation, l’éditeur a peut-être supprimé le fichier de son serveur.Pendant le téléchargement, si vous ne parvenez pas à obtenir une présentation, le fichier a peut-être été supprimé par l’éditeur.

F I N

Plus de contenu associé

Transcription de la présentation
  1. Chapter7 Semaphore Management

  2. Semaphores • Create a semaphore by calling OSSemCreate() • The initial count of the semaphore can be 0 to 65535 • Use to signal the occurrence of one ore more event, the init value is 0 (flag) • Use to access a shared resource, the init value is set to 1 (binary) (key) • Five services will access semaphore: • OSSemCreate(), OSSemPend(), OSSemPost(), OSSemAccept(), OSSemQuery() Figure 7.1 Relationships between tasks, ISRs, and a semaphore

  3. Creating a SemaphoreOSSemCreate() OS_EVENT *OSSemCreate (INT16U cnt) { OS_EVENT *pevent; OS_ENTER_CRITICAL(); pevent = OSEventFreeList; (1) if (OSEventFreeList != (OS_EVENT *)0) { (2) OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; } OS_EXIT_CRITICAL(); if (pevent != (OS_EVENT *)0) { (3) pevent->OSEventType = OS_EVENT_TYPE_SEM; (4) pevent->OSEventCnt = cnt; (5) OSEventWaitListInit(pevent); (6) } return (pevent); //semaphore address or say descriptor (7) }

  4. Figure 7.2 ECB just before OSSemCreate() returns OS_EVENT pevent OSEventType OS_Evnet_Type_SEM OSEventCnt Cnt OSEventPtr (void *)0 OSEvnetGrp=0x00 OSEventGrp 7 6 5 4 3 2 1 0 All initialized to 0x00 63 62 61 60 59 58 57 56

  5. Deleting a Semaphore, OSSemDel() #if OS_SEM_DEL_EN > 0 OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif BOOLEAN tasks_waiting; if (OSIntNesting > 0) { /* See if called from ISR ... */ *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return (pevent); } #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return (pevent); } if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return (pevent); } #endif

  6. OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on semaphore */ tasks_waiting = TRUE; /* Yes */ } else { tasks_waiting = FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ if (tasks_waiting == FALSE) { pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return ((OS_EVENT *)0); /* Semaphore has been deleted */ } else { OS_EXIT_CRITICAL(); *err = OS_ERR_TASK_WAITING; return (pevent); }

  7. case OS_DEL_ALWAYS: /* Always delete the semaphore */ while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for semaphore */ OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); } pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *err = OS_NO_ERR; return ((OS_EVENT *)0); /* Semaphore has been deleted */ default: OS_EXIT_CRITICAL(); *err = OS_ERR_INVALID_OPT; return (pevent); } } #endif

  8. Waiting on a SemaphoreOSSemPend() void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { (1) OS_EXIT_CRITICAL(); *err = OS_ERR_EVENT_TYPE; } if (pevent->OSEventCnt > 0) { (2) pevent->OSEventCnt--; (3) OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return; OSTCBCur->OSTCBStat |= OS_STAT_SEM; (5) OSTCBCur->OSTCBDly = timeout; (6) OSEventTaskWait(pevent); (7) OS_EXIT_CRITICAL(); OSSched(); (8) OS_ENTER_CRITICAL(); if (OSTCBCur->OSTCBStat & OS_STAT_SEM) { (9) OSEventTO(pevent); (10) OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; return; } OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; (11) OS_EXIT_CRITICAL(); *err = OS_NO_ERR; }

  9. Signaling a SemaphoreOSSemPost() INT8U OSSemPost (OS_EVENT *pevent) { OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { (1) OS_EXIT_CRITICAL(); return (OS_ERR_EVENT_TYPE); } if (pevent->OSEventGrp) { (2) OSEventTaskRdy(pevent, (void *)0, OS_STAT_SEM); (3) OS_EXIT_CRITICAL(); OSSched(); (4) return (OS_NO_ERR); } if (pevent->OSEventCnt < 65535) { pevent->OSEventCnt++; (5) OS_EXIT_CRITICAL(); return (OS_NO_ERR); } OS_EXIT_CRITICAL(); return (OS_SEM_OVF); }

  10. Getting a Semaphore without WaitingOSSemAccept() • To obtain a semaphore without putting a task to sleep if the semaphore is not available INT16U OSSemAccept (OS_EVENT *pevent) { INT16U cnt; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { (1) OS_EXIT_CRITICAL(); return (0); } cnt = pevent->OSEventCnt; (2) if (cnt > 0) { (3) pevent->OSEventCnt--; (4) } OS_EXIT_CRITICAL(); return (cnt); //original value (5) }

  11. Obaining the status of a semaphoreOSSemQuery() • Allow APs to take a snapshot of an ECB • Two arguments are required • Pevent: pointer to the semaphore • Pdata pointer to a data structure which will receive the information about the desired semaphore INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata) { INT8U i; INT8U *psrc; INT8U *pdest; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { (1) OS_EXIT_CRITICAL(); return (OS_ERR_EVENT_TYPE); } pdata->OSEventGrp = pevent->OSEventGrp; (2) psrc = &pevent->OSEventTbl[0]; pdest = &pdata->OSEventTbl[0]; for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { *pdest++ = *psrc++; } pdata->OSCnt = pevent->OSEventCnt; (3) OS_EXIT_CRITICAL(); return (OS_NO_ERR); }