Semaphores
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);