信号量
OSSemCreate
Description
Initializes a semaphore. Semaphores are used when a task wants exclusive access to a resource,
needs to synchronize its activities with an ISR or a task, or is waiting until an event occurs.
You would use a semaphore to signal the occurrence of an event to one or multiple tasks, and
use mutexes to guard share resources. However, technically, semaphores allow for both.
void OSSemCreate (OS_SEM *p_sem,
CPU_CHAR *p_name,
OS_SEM_CTR cnt,
OS_ERR *p_err)
Arguments
p_sem
is a pointer to the semaphore control block. It is assumed that storage for the semaphore
will be allocated in the application. In other words, you need to declare a “global”
variable as follows, and pass a pointer to this variable to OSSemCreate():
OS_SEM MySem;
p_name
is a pointer to an ASCII string used to assign a name to the semaphore. The name can be
displayed by debuggers or µC/Probe.
cnt
specifies the initial value of the semaphore.
If the semaphore is used for resource sharing, you would set the initial value of the
semaphore to the number of identical resources guarded by the semaphore. If there is only
one resource, the value should be set to 1 (this is called a binary semaphore). For multiple
resources, set the value to the number of resources (this is called a counting semaphore).
If using a semaphore as a signaling mechanism, you should set the initial value to 0.
/* ----------------------------- SEMAPHORES ---------------------------- */
#define OS_CFG_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */
#define OS_CFG_SEM_DEL_EN 1u /* Include code for OSSemDel() */
#define OS_CFG_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */
#define OS_CFG_SEM_SET_EN 1u /* Include code for OSSemSet() */
OSSemPend(消耗信号量)
Description
Used when a task wants exclusive access to a resource, needs to synchronize its activities with
an ISR or task, or is waiting until an event occurs.
When the semaphore is used for resource sharing, if a task calls OSSemPend() and the value of
the semaphore is greater than 0, OSSemPend() decrements the semaphore and returns to its
caller. However, if the value of the semaphore is 0, OSSemPend() places the calling task in the
waiting list for the semaphore. The task waits until the owner of the semaphore releases the
semaphore by calling OSSemPost(), or the specified timeout expires. If the semaphore is
signaled before the timeout expires, µC/OS-III resumes the highest-priority task waiting for the
semaphore.
When the semaphore is used as a signaling mechanism, the calling task waits until a task or an
ISR signals the semaphore by calling OSSemPost(), or the specified timeout expires.
A pended task that has been suspended with OSTaskSuspend() can obtain the semaphore.
However, the task remains suspended until it is resumed by calling OSTaskResume().
OSSemPend() also returns if the pend is aborted or, the semaphore is deleted.
OS_SEM_CTR OSSemPend (OS_SEM *p_sem,
OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err)
timeout
allows the task to resume execution if a semaphore is not posted within the specified
number of clock ticks. A timeout value of 0 indicates that the task waits forever for the
semaphore. The timeout value is not synchronized with the clock tick. The timeout count
begins decrementing on the next clock tick, which could potentially occur immediately.
opt
specifies whether the call is to block if the semaphore is not available, or not block.
OS_OPT_PEND_BLOCKING
to block the caller until the semaphore is available or a timeout occurs.
OS_OPT_PEND_NON_BLOCKING
If the semaphore is not available, OSSemPend() will not block but return to the caller
with an appropriate error code.
p_ts 时间戳
is a pointer to a variable that will receive a timestamp of when the semaphore was posted,
pend aborted, or deleted. Passing a NULL pointer is valid and indicates that a timestamp is
not required.
A timestamp is useful when the task must know when the semaphore was posted or, how
long it took for the task to resume after the semaphore was posted. In the latter case, call
OS_TS_GET() and compute the difference between the current value of the timestamp and
*p_ts. In other words:
delta = OS_TS_GET() - *p_ts;
OSSemPost(增加信号量)
Description
A semaphore is signaled by calling OSSemPost(). If the semaphore value is 0 or more, it is
incremented, and OSSemPost() returns to its caller. If tasks are waiting for the semaphore to be
signaled, OSSemPost() removes the highest-priority task pending for the semaphore from the
waiting list and makes this task ready-to-run. The scheduler is then called to determine if the
awakened task is now the highest-priority task that is ready-to-run.
OS_SEM_CTR OSSemPost (OS_SEM *p_sem,
OS_OPT opt,
OS_ERR *p_err)
Arguments
p_sem
is a pointer to the semaphore.
opt
determines the type of post performed.
OS_OPT_POST_1(发给优先级最高的)
Post and ready only the highest-priority task waiting on the semaphore.
OS_OPT_POST_ALL(发给所有任务)
Post to all tasks waiting on the semaphore. You should only use this option if the
semaphore is used as a signaling mechanism and never when the semaphore is used
to guard a shared resource. It does not make sense to tell all tasks that are sharing a
resource that they can all access the resource.