Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

A semaphore was originally a mechanical signaling mechanism. The railroad industry used the device to provide a form of mutual exclusion for railroads tracks shared by more than one train. In this form, the semaphore signaled trains by closing a set of mechanical arms to block a train from a section of track that was currently in use. When the track became available, the arm would swing up and the waiting train would then proceed.

The notion of using a semaphore in software as a means of mutual exclusion was invented by the Dutch computer scientist Edgser Dijkstra in 1959. In computer software, a semaphore is a protocol mechanism offered by most multitasking kernels. Semaphores, originally used to control access to shared resources, but now they are used for synchronization as described in Synchronization. However, it is useful to describe how semaphores can be used to share resources. The pitfalls of semaphores will be discussed in a later section.

A semaphore was originally a “lock mechanism” and code acquired the key to this lock to continue execution. Acquiring the key means that the executing task has permission to enter the section of otherwise locked code. Entering a section of locked code causes the task to wait until the key becomes available.

Typically, two types of semaphores exist: binary semaphores and counting semaphores. As its name implies, a binary semaphore can only take two values: 0 or 1. A counting semaphore allows for values between 0 and 255, 65,535, or 4,294,967,295, depending on whether the semaphore mechanism is implemented using 8, 16, or 32 bits, respectively. For µC/OS-III, the maximum value of a semaphore is determined by the data type OS_SEM_CTR (see os_type.h), which can be changed as needed. Along with the semaphore’s value, µC/OS-III also keeps track of tasks waiting for the semaphore’s availability.

Only tasks are allowed to use semaphores when semaphores are used for sharing resources; ISRs are not allowed.

A semaphore is a kernel object defined by the OS_SEM data type, which is defined by the structure os_sem (see os.h). The application can have any number of semaphores (limited only by the amount of RAM available).

There are a number of operations the application is able to perform on semaphores, summarized in Table 13-2. In this chapter, only three functions used most often are discussed: OSSemCreate(), OSSemPend(), and OSSemPost(). Other functions are described in Appendix A, “µC/OS-III API Reference”. When semaphores are used for sharing resources, every semaphore function must be called from a task and never from an ISR. The same limitation does not apply when using semaphores for signaling, as described later in Chapter 13.

Function Name

Operation

OSSemCreate()

Create a semaphore.

OSSemDel()

Delete a semaphore.

OSSemPend()

Wait on a semaphore.

OSSemPendAbort()

Abort the wait on a semaphore.

OSSemPost()

Release or signal a semaphore.

OSSemSet()

Force the semaphore count to a desired value.

...

Include Page
css.Migrating from uC-OS-II to uC-OS-III.css
css.Migrating from uC-OS-II to uC-OS-III.css
Include Page
css.webworks.css
css.webworks.css

Anchor
1080171
1080171
Semaphores

Anchor
1092434
1092434
Table C-13 shows the difference in API for semaphore management.

Anchor
1181591
1181591
 

HTML Table
summary
classPlain_Table
Table Row (tr)
Table Cell (td)

Anchor
1093048
1093048
µC/OS-II (os_sem.c)

Table Cell (td)

Anchor
1093050
1093050
µC/OS-III (os_sem.c)

Table Cell (td)

Anchor
1093052
1093052
Note

Table Row (tr)
Table Cell (td)
rowspan3

Anchor
1093054
1093054
INT16U

Anchor
1093055
1093055
OSSemAccept(

Anchor
1093056
1093056
OS_EVENT *pevent);

Table Cell (td)
rowspan3

Anchor
1093058
1093058
 

Table Cell (td)
rowspan3

Anchor
1093060
1093060
(1)

Table Row (tr)

Table Row (tr)

Table Row (tr)
Table Cell (td)
rowspan4

Anchor
1093074
1093074
OS_EVENT *

Anchor
1093075
1093075
OSSemCreate(

Anchor
1093076
1093076
INT16U cnt);

Table Cell (td)
rowspan4

Anchor
1093078
1093078
void

Anchor
1093079
1093079
OSSemCreate(

Anchor
1093080
1093080
OS_SEM *p_sem,

Anchor
1093081
1093081
CPU_CHAR *p_name,

Anchor
1093082
1093082
OS_SEM_CTR cnt,

Anchor
1093083
1093083
OS_ERR *p_err);

Table Cell (td)
rowspan4

Anchor
1093085
1093085
(2)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)
Table Cell (td)
rowspan10

Anchor
1093105
1093105
OS_EVENT *

Anchor
1093106
1093106
OSSemDel(

Anchor
1093107
1093107
OS_EVENT *pevent,

Anchor
1093108
1093108
INT8U opt,

Anchor
1093109
1093109
INT8U *perr);

Table Cell (td)
rowspan10

Anchor
1093111
1093111
OS_OBJ_QTY,

Anchor
1093112
1093112
OSSemDel(

Anchor
1093113
1093113
OS_SEM *p_sem,

Anchor
1093114
1093114
OS_OPT opt,

Anchor
1093115
1093115
OS_ERR *p_err);

Table Cell (td)
rowspan10

Anchor
1093117
1093117
 

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)
Table Cell (td)
rowspan5

Anchor
1093197
1093197
void

Anchor
1093198
1093198
OSSemPend(

Anchor
1093199
1093199
OS_EVENT *pevent,

Anchor
1093200
1093200
INT32U timeout,

Anchor
1093201
1093201
INT8U *perr);

Table Cell (td)
rowspan5

Anchor
1093203
1093203
OS_SEM_CTR

Anchor
1093204
1093204
OSSemPend(

Anchor
1093205
1093205
OS_SEM *p_sem,

Anchor
1093206
1093206
OS_TICK timeout,

Anchor
1093207
1093207
OS_OPT opt,

Anchor
1093208
1093208
CPU_TS *p_ts,

Anchor
1093209
1093209
OS_ERR *p_err);

Table Cell (td)
rowspan5

Anchor
1093483
1093483
(3)

Anchor
1093484
1093484
 

Anchor
1093485
1093485
 

Anchor
1093486
1093486
 

Anchor
1093487
1093487
 

Anchor
1093488
1093488
 

Anchor
1093211
1093211
 

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)
Table Cell (td)
rowspan5

Anchor
1093273
1093273
INT8U

Anchor
1093274
1093274
OSSemPendAbort(

Anchor
1093275
1093275
OS_EVENT *pevent,

Anchor
1093276
1093276
INT8U opt,

Anchor
1093277
1093277
INT8U *perr);

Table Cell (td)
rowspan5

Anchor
1093279
1093279
OS_OBJ_QTY

Anchor
1093508
1093508
OSSemPendAbort(

Anchor
1093509
1093509
OS_SEM *p_sem,

Anchor
1093510
1093510
OS_OPT opt,

Anchor
1093511
1093511
OS_ERR *p_err);

Table Cell (td)
rowspan5

Anchor
1093281
1093281
 

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)
Table Cell (td)
rowspan4

Anchor
1093334
1093334
void

Anchor
1093335
1093335
OSSemPost(

Anchor
1093336
1093336
OS_EVENT *pevent);

Table Cell (td)
rowspan4

Anchor
1093338
1093338
void

Anchor
1093547
1093547
OSSemPost(

Anchor
1093548
1093548
OS_SEM *p_sem,

Anchor
1093549
1093549
OS_OPT opt,

Anchor
1093539
1093539
OS_ERR *p_err);

Table Cell (td)
rowspan4

Anchor
1093340
1093340
 

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)
Table Cell (td)
rowspan4

Anchor
1093387
1093387
INT8U

Anchor
1093388
1093388
OSSemQuery(

Anchor
1093389
1093389
OS_EVENT *pevent,

Anchor
1093390
1093390
OS_SEM_DATA *p_sem_data);

Table Cell (td)
rowspan4

Anchor
1093392
1093392
 

Table Cell (td)
rowspan4

Anchor
1093394
1093394
(4)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)
Table Cell (td)
rowspan6

Anchor
1093414
1093414
void

Anchor
1093415
1093415
OSSemSet(

Anchor
1093416
1093416
OS_EVENT *pevent,

Anchor
1093417
1093417
INT16U cnt,

Anchor
1093418
1093418
INT8U *perr);

Table Cell (td)
rowspan6

Anchor
1093420
1093420
void

Anchor
1093571
1093571
OSSemSet(

Anchor
1093572
1093572
OS_SEM *p_sem,

Anchor
1093573
1093573
OS_SEM_CTR cnt,

Anchor
1093563
1093563
OS_ERR *p_err);

Table Cell (td)
rowspan6

Anchor
1093422
1093422
 

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Table Row (tr)

Anchor
1159612
1159612
 

    1. Anchor
      1092499
      1092499
      Semaphore Management API
      1. Anchor
        1080238
        1080238
        In µC/OS-III, there is no “accept” API since this feature is built into the OSSemPend() by specifying the OS_OPT_PEND_NON_BLOCKING option.
      2. Anchor
        1080239
        1080239
        In µC/OS-II, OSSemCreate() returns the address of an OS_EVENT, which is used as the “handle” to the semaphore. In µC/OS-III, the application must allocate storage for an OS_SEM object, which serves the same purpose as the OS_EVENT. The benefit in µC/OS-III is that it is not necessary to predetermine the number of semaphores at compile time.
      3. Anchor
        1080240
        1080240
        µC/OS-III returns additional information when a semaphore is signaled. The ISR or task that signals the semaphore takes a snapshot of the current timestamp and stores this in the OS_SEM object signaled. The receiver of the signal therefore knows when the signal was sent.
      4. Anchor
        1080241
        1080241
        µC/OS-III does not provide query services, as they were rarely used.