Semaphores

../_images/Semaphores.png

Semaphores can be used as flags or as counters.

  • To use as a flag create with count = 0.
  • To use as a counter create with count = n.

Used as flags, semaphores can signal an event or coordinate the action between two tasks, or between an ISR and a task.

Used as counters, semaphores can be used to keep track of resources.

OSSemCreate

OS_EVENT *OSSemCreate(INT16U cnt);
  • Creates a semaphore
  • Returns a pointer to its OS_EVENT structure
  • Sets the initial value to between 0 to 65,535
  • The Event Control Block or ECB is essentially the semaphore’s handle.

OSSemDel

OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U *perr);
  • Deletes a semaphore
  • Frees the ECB or event control block that was used for the semaphore
  • Requires an option
    • OS_DEL_NO_PEND - don’t delete if tasks are waiting on the semaphore
    • OS_DEL_ALWAYS - always delete
  • If called with OS_DEL_ALWAYS, the semaphore will be deleted even if tasks are waiting on it.
    • All the waiting tasks will become ready
    • All those tasks will think they have the semaphore, which is bad!
  • Best practice is to first delete all tasks that use the semaphore before deleting the semaphore.

OSSemPend

void OSSemPend(OS_EVENT *pevent, INT16U timeout, INT8U *perr);
  • Acquire a semaphore or wait
  • Returns with error OS_ERR_PEND_ISR if called from an ISR
  • If semaphore is nozero it decrements the count and returns immediately with OS_NO_ERR
  • If semaphore is zero
    • Sets timeout if given, 0 means infinite wait
    • Set the status flag
    • Moves the task to the wait list
    • Calls the scheduler
  • If the timeout expires it returns the error OS_TIMEOUT
  • On return the ECB is unlinked

OSSemPendAbort

INT8U OSSemPendAbort(OS_EVENT *pevent, INT8U opt, INT8U *perr);

OSSemPost

INT8U OSSemPost(OS_EVENT *pevent);
  • First checks to see if there are any waiting tasks
    • If there is it removes the highest waiting task
    • Set that task to ready
    • Calls the scheduler
  • If there are no waiting tasks
    • It increments the semaphore’s count
    • If the count is over 65,535 it returns an overflow error, OS_SEM_OVF
    • Else it returns no error, OS_NO_ERR

OSSemAccept

INT16U OSSemAccept(OS_EVENT *pevent);
  • Tries to acquire a semaphore without waiting
  • If the count is nonzero
    • Saves the count as return value
    • Decrements the count
    • Returns the saved count

OSSemSet

void OSSemSet(OS_EVENT *pevent, INT16U cnt, INT8U *perr);

OSSemQuery

INT8U OSSemQuery(OS_EVENT *pevent, OS_SEM_DATA *p_sem_data);

Table Of Contents

Previous topic

Time

Next topic

Mutexes

This Page