]> begriffs open source - cmsis/blob - CMSIS/DoxyGen/RTOS2/src/cmsis_os2_Sema.txt
Doxygen: Fixed references from mq_size to mq_mem in osMessageQueueAttr_t description.
[cmsis] / CMSIS / DoxyGen / RTOS2 / src / cmsis_os2_Sema.txt
1 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2 //  ==== Semaphore Management ====
3 /** 
4 \addtogroup CMSIS_RTOS_SemaphoreMgmt Semaphores
5 \ingroup CMSIS_RTOS
6 \brief Access shared resources simultaneously from different threads.
7 \details 
8 Semaphores are used to manage and protect access to shared resources. Semaphores are very similar to
9 \ref CMSIS_RTOS_MutexMgmt "Mutexes". Whereas a Mutex permits just one thread to access a shared resource at a
10 time, a semaphore can be used to permit a fixed number of threads/ISRs to access a pool of shared resources. Using
11 semaphores, access to a group of identical peripherals can be managed (for example multiple DMA channels).
12
13 \image html "Semaphore.png" "CMSIS-RTOS Semaphore"
14
15 A semaphore object should be initialized to the maximum number of available tokens. This number of available resources is
16 specified as parameter of the \ref osSemaphoreNew function. Each time a semaphore token is obtained with \ref osSemaphoreAcquire
17 (in \em available state), the semaphore count is decremented. When the semaphore count is 0 (i.e. \em depleted state), no
18 more semaphore tokens can be obtained. The thread/ISR that tries to obtain the semaphore token needs to wait until the next
19 token is free. Semaphores are released with \ref osSemaphoreRelease incrementing the semaphore count.
20
21 \image html "semaphore_states.png" "CMSIS-RTOS Semaphore States"
22
23 \note The functions \ref osSemaphoreAcquire, \ref osSemaphoreGetCount, and \ref osSemaphoreRelease can be called from
24 \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
25
26 \note Refer to \ref semaphoreConfig for RTX5 configuration options.
27
28 Semaphore Use Cases
29 -------------------
30 Due to their flexibility, semaphores cover a wide range of synchronizing applications. At the same time, they are perhaps the
31 most challenging RTOS object to understand. The following explains a use case for semaphores, taken from the book
32 <a href="http://www.greenteapress.com/semaphores/" target="_blank">The Little Book Of Semaphores</a> by Allen B. Downey which
33 is available for free download.
34
35 <b>Non-binary Semaphore (Multiplex)</b>
36
37 A multiplex limits the number of threads that can access a critical section of code. For example, this could be a function
38 accessing DMA resources which can only support a limited number of calls.
39
40 To allow multiple threads to run the function, initialize a semaphore to the maximum number of threads that can be allowed.
41 The number of tokens in the semaphore represents the number of additional threads that may enter. If this number is zero,
42 then the next thread trying to access the function will have to wait until one of the other threads exits and releases its
43 token. When all threads have exited the token number is back to n. The following example shows the code for one of the
44 threads that might access the resource:
45
46 \code
47 osSemaphoreId_t multiplex_id;
48  
49 void thread_n (void)
50 {
51   multiplex_id = osSemaphoreNew(3, 3, NULL);
52   while(1)
53     {
54       osSemaphoreAcquire(multiplex_id, osWaitForever);
55       // do something
56       osSemaphoreRelease(multiplex_id);
57     }
58 }
59 \endcode
60
61 <b>Producer/Consumer Semaphore</b>
62
63 The producer-consumer problem can be solved using two semaphores.
64
65 A first semaphore (\token{empty_id}) counts down the available (empty) buffers, i.e.
66 the producer thread can wait for available buffer slots by acquiring from this one.
67
68 A second semaphore (\token{filled_id}) counts up the used (filled) buffers, i.e.
69 the consumer thread can wait for available data by acquiring from this one.
70
71 It is crucial for the correct behaviour that the threads acquire and release on both
72 semaphores in the given sequence. According to this example one can have multiple
73 producer and/or consumer threads running concurrently.
74
75 \code
76 #define BUFFER_SIZE 10
77 osSemaphoreId_t empty_id = osSemaphoreNew(BUFFER_SIZE, BUFFER_SIZE, NULL);
78 osSemaphoreId_t filled_id = osSemaphoreNew(BUFFER_SIZE, 0, NULL);
79
80 void producer_thread (void)
81 {
82   while(1)
83   {
84     osSemaphoreAcquire(empty_id, osWaitForever);
85     // produce data
86     osSemaphoreRelease(filled_id);
87   }
88 }
89
90 void consumer_thread (void)
91 {
92   while(1)
93   {
94     osSemaphoreAcquire(filled_id, osWaitForever);
95     // consume data
96     osSemaphoreRelease(empty_id);
97   }
98 }
99 \endcode
100
101 @{
102 */
103
104 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
105 /**
106 \typedef  osSemaphoreId_t
107 \details
108 Returned by:
109 - \ref osSemaphoreNew
110 */
111
112 /**
113 \struct osSemaphoreAttr_t
114 \details
115 Specifies the following attributes for the \ref osSemaphoreNew function.
116 */
117
118 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
119 /**
120 \fn osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
121 \details
122 The function \b osSemaphoreNew creates and initializes a semaphore object that is used to manage access to shared resources
123 and returns the pointer to the semaphore object identifier or \token{NULL} in case of an error. It can be safely called
124 before the RTOS is started (call to \ref osKernelStart), but not before it is initialized (call to \ref osKernelInitialize).
125
126 The parameter \em max_count specifies the maximum number of available tokens. A \em max_count value of 1 creates a binary
127 semaphore.
128
129 The parameter \em initial_count sets the initial number of available tokens.
130
131 The parameter \em attr specifies additional semaphore attributes. Default attributes will be used if set to \token{NULL}.
132 /*
133 New definition:
134 */
135 Possible \ref osSemaphoreId_t return values:
136 - pointer to the created semaphore object
137 - \em NULL, if (\em max_count == 0U)
138 - \em NULL, if  (\em max_count > \em MAX_SEMAPHORE_CNT)
139 - \em NULL, if  (\em initial_count > \em max_count)
140 - \em NULL, if the control block memory (\em attr->cb_mem) is not \em NULL and the memory is not 4 byte aligned 
141 - \em NULL, if the control block memory (\em attr->cb_mem) is not \em NULL but the size (\em attr->cb_size) is not big enough to store a \em semaphore object
142 - \em NULL, if the control block memory (\em attr->cb_mem) is \em NULL but the size (\em attr->cb_size) is not 0
143 - \em NULL, if the maximum number of semaphores have been created already
144 - \em NULL, if IRQ is masked
145 - \em NULL, if in IRQ mode.
146
147
148
149 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
150
151 <b>Code Example</b>
152 \code
153 #include "cmsis_os2.h"                                     // CMSIS RTOS header file
154  
155 void Thread_Semaphore (void *argument);                    // thread function
156 osThreadId_t tid_Thread_Semaphore;                         // thread id
157  
158 osSemaphoreId_t sid_Thread_Semaphore;                      // semaphore id
159  
160 int Init_Semaphore (void)
161 {
162  
163   sid_Thread_Semaphore = osSemaphoreNew(2, 2, NULL);
164   if (!sid_Thread_Semaphore) {
165     ; // Semaphore object not created, handle failure
166   }
167  
168   tid_Thread_Semaphore = osThreadNew (Thread_Semaphore, NULL, NULL);
169   if (!tid_Thread_Semaphore) {
170     return(-1);
171   }
172  
173   return(0);
174 }
175   
176 void Thread_Semaphore (void *argument)
177 {
178   osStatus_t val;
179  
180   while (1) {
181     ; // Insert thread code here...
182  
183     val = osSemaphoreAcquire (sid_Thread_Semaphore, 10);   // wait for max. 10 ticks for semaphore token to get available
184     switch (val) {
185     case osOK:
186       ; // Use protected code here...
187       osSemaphoreRelease (sid_Thread_Semaphore);           // Return a token back to a semaphore
188       break;
189     case osErrorResource:
190       break;
191     case osErrorParameter:
192       break;
193     default:
194       break;
195     }
196  
197     osThreadYield ();                                      // suspend thread
198   }
199 }
200 \endcode
201 */
202
203 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
204 /**
205 \fn const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id)
206 \details
207 The function \b osSemaphoreGetName returns the pointer to the name string of the semaphore identified by parameter \a
208 semaphore_id or \token{NULL} in case of an error.
209 /*
210 New definition:
211 */
212 Possible return values:
213 - pointer to the name string of the semaphore identified by parameter \a semaphore_id
214 - \em NULL, if the semaphore specified by \a semaphore_id  is \em NULL
215 - \em NULL, if a semaphore specified by \a semaphore_id does not exist
216 - \em NULL, if the semaphore is in state \em 'osRtxObjectInactive'
217 - \em NULL, if IRQ is masked
218 - \em NULL, if in IRQ mode.
219
220
221 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
222 */
223
224 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
225 /**
226 \fn osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout)
227 \details
228 The blocking function \b osSemaphoreAcquire waits until a token of the semaphore object specified by parameter
229 \a semaphore_id becomes available. If a token is available, the function instantly returns and decrements the token count. 
230
231 The parameter \a timeout specifies how long the system waits to acquire the token. While the system waits, the thread
232 that is calling this function is put into the \ref ThreadStates "BLOCKED" state. The parameter \ref CMSIS_RTOS_TimeOutValue
233 "timeout" can have the following values:
234  - when \a timeout is \token{0}, the function returns instantly (i.e. try semantics).
235  - when \a timeout is set to \b osWaitForever the function will wait for an infinite time until the semaphore becomes
236    available (i.e. wait semantics).
237  - all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics).
238
239 Possible \ref osStatus_t return values:
240 - \em 'osOK', if the token has been obtained
241 - \em 'osErrorResource', if the semaphore specified by \a semaphore_id is in state \em 'osRtxObjectInactive'
242 - \em 'osErrorTimeout', if the token is not available and \em timeout > 0
243 - \em 'osErrorResource', if the token is not available and \em timeout == 0 
244 - \em 'osErrorParameter',  if a semaphore specified by \a semaphore_id does not exist 
245 - \em 'osErrorParameter', if semaphore_id equals \em NULL.
246
247
248
249 \note May be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" if the parameter \a timeout is set to
250 \token{0}.
251  
252 <b>Code Example</b>
253
254 Refer to \ref osSemaphoreNew.
255 */
256
257 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
258 /**
259 \fn osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id)
260 \details
261 The function \b osSemaphoreRelease releases a token of the semaphore object specified by parameter \a semaphore_id. Tokens
262 can only be released up to the maximum count specified at creation time, see \ref osSemaphoreNew. Other threads that
263 currently wait for a token of this semaphore object will be put into the \ref ThreadStates "READY" state.
264
265 Possible \ref osStatus_t return values:
266 - \em 'osOK', if the token has been correctly released and the count increased
267 - \em 'osErrorParameter', if a semaphore specified by \a semaphore_id does not exist
268 - \em 'osErrorParameter', if the semaphore specified by \a semaphore_id is \em NULL
269 - \em 'osErrorResource', if the semaphore specified by \a semaphore_id is in state \em 'osRtxObjectInactive'.
270 - \em 'osErrorResource', if no semaphore specified by \a semaphore_id has been taken.
271
272 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
273
274 <b>Code Example</b>
275
276 Refer to \ref osSemaphoreNew.
277 */
278
279 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
280 /**
281 \fn uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id)
282 \details
283 The function \b osSemaphoreGetCount returns the number of available tokens of the semaphore object specified by parameter
284 \a semaphore_id. In case of an error it returns \token{0}.
285
286 Possible \ref osStatus_t return values:
287 - \em the number of available tokens, in case of success
288 - \em 0, if a semaphore specified by \a semaphore_id does not exist
289 - \em 0, if the semaphore is \em NULL
290 - \em 0, the semaphore is in state \em 'osRtxObjectInactive'.
291
292 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
293 */
294
295 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
296 /**
297 \fn osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id)
298 \details
299 The function \b osSemaphoreDelete deletes a semaphore object specified by parameter \a semaphore_id. It releases internal
300 memory obtained for semaphore handling. After this call, the \a semaphore_id is no longer valid and cannot be used. The
301 semaphore may be created again using the function \ref osSemaphoreNew.
302
303 Possible \ref osStatus_t return values:
304  - \em 'osOK', if the semaphore specified by \a semaphore_id has been deleted
305  - \em 'osErrorResource', if the state of semaphore specified by \a semaphore_id is \em 'osRtxObjectInactive'
306  - \em 'osErrorParameter', if a semaphore specified by \a semaphore_id does not exist
307  - \em 'osErrorParameter', if the semaphore is \em NULL
308  - \em 'osErrorISR', if IRQ is masked
309  - \em 'osErrorISR', if in IRQ mode.
310
311 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
312 */
313 /// @}
314
315 // these struct members must stay outside the group to avoid double entries in documentation
316 /**
317 \var osSemaphoreAttr_t::attr_bits
318 \details
319 Reserved for future use (must be set to '0' for future compatibility).
320
321 \var osSemaphoreAttr_t::cb_mem
322 \details
323 Pointer to a memory for the semaphore control block object. Refer to \ref StaticObjectMemory for more information.
324
325 Default: \token{NULL} to use \ref CMSIS_RTOS_MemoryMgmt_Automatic for the semaphore control block.
326
327 \var osSemaphoreAttr_t::cb_size
328 \details
329 The size (in bytes) of memory block passed with \ref cb_mem. For RTX, the minimum value is defined with \ref osRtxSemaphoreCbSize (higher values are permitted).
330
331 Default: \token{0} as the default is no memory provided with \ref cb_mem.
332
333 \var osSemaphoreAttr_t::name
334 \details
335 Pointer to a constant string with a human readable name (displayed during debugging) of the semaphore object.
336
337 Default: \token{NULL} no name specified.
338 */