========== Semaphores ========== .. image:: Semaphores.png :width: 600 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 =========== .. code-block:: c 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 ======== .. code-block:: c 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 ========= .. code-block:: c 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 ============== .. code-block:: c INT8U OSSemPendAbort(OS_EVENT *pevent, INT8U opt, INT8U *perr); OSSemPost ========= .. code-block:: c 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 =========== .. code-block:: c 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 ======== .. code-block:: c void OSSemSet(OS_EVENT *pevent, INT16U cnt, INT8U *perr); OSSemQuery ========== .. code-block:: c INT8U OSSemQuery(OS_EVENT *pevent, OS_SEM_DATA *p_sem_data);