OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Source/] [include/] [semphr.h] - Blame information for rev 584

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 572 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
#ifndef INC_FREERTOS_H
55
        #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
56
#endif
57
 
58
#ifndef SEMAPHORE_H
59
#define SEMAPHORE_H
60
 
61
#include "queue.h"
62
 
63
typedef xQueueHandle xSemaphoreHandle;
64
 
65
#define semBINARY_SEMAPHORE_QUEUE_LENGTH        ( ( unsigned char ) 1 )
66
#define semSEMAPHORE_QUEUE_ITEM_LENGTH          ( ( unsigned char ) 0 )
67
#define semGIVE_BLOCK_TIME                                      ( ( portTickType ) 0 )
68
 
69
 
70
/**
71
 * semphr. h
72
 * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
73
 *
74
 * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
75
 * The queue length is 1 as this is a binary semaphore.  The data size is 0
76
 * as we don't want to actually store any data - we just want to know if the
77
 * queue is empty or full.
78
 *
79
 * This type of semaphore can be used for pure synchronisation between tasks or
80
 * between an interrupt and a task.  The semaphore need not be given back once
81
 * obtained, so one task/interrupt can continuously 'give' the semaphore while
82
 * another continuously 'takes' the semaphore.  For this reason this type of
83
 * semaphore does not use a priority inheritance mechanism.  For an alternative
84
 * that does use priority inheritance see xSemaphoreCreateMutex().
85
 *
86
 * @param xSemaphore Handle to the created semaphore.  Should be of type xSemaphoreHandle.
87
 *
88
 * Example usage:
89
 <pre>
90
 xSemaphoreHandle xSemaphore;
91
 
92
 void vATask( void * pvParameters )
93
 {
94
    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
95
    // This is a macro so pass the variable in directly.
96
    vSemaphoreCreateBinary( xSemaphore );
97
 
98
    if( xSemaphore != NULL )
99
    {
100
        // The semaphore was created successfully.
101
        // The semaphore can now be used.
102
    }
103
 }
104
 </pre>
105
 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
106
 * \ingroup Semaphores
107
 */
108
#define vSemaphoreCreateBinary( xSemaphore )            {                                                                                                                                                                                               \
109
                                                                                                                xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH );      \
110
                                                                                                                if( xSemaphore != NULL )                                                                                                                                        \
111
                                                                                                                {                                                                                                                                                                                       \
112
                                                                                                                        xSemaphoreGive( xSemaphore );                                                                                                                   \
113
                                                                                                                }                                                                                                                                                                                       \
114
                                                                                                        }
115
 
116
/**
117
 * semphr. h
118
 * <pre>xSemaphoreTake(
119
 *                   xSemaphoreHandle xSemaphore,
120
 *                   portTickType xBlockTime
121
 *               )</pre>
122
 *
123
 * <i>Macro</i> to obtain a semaphore.  The semaphore must have previously been
124
 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
125
 * xSemaphoreCreateCounting().
126
 *
127
 * @param xSemaphore A handle to the semaphore being taken - obtained when
128
 * the semaphore was created.
129
 *
130
 * @param xBlockTime The time in ticks to wait for the semaphore to become
131
 * available.  The macro portTICK_RATE_MS can be used to convert this to a
132
 * real time.  A block time of zero can be used to poll the semaphore.  A block
133
 * time of portMAX_DELAY can be used to block indefinitely (provided
134
 * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
135
 *
136
 * @return pdTRUE if the semaphore was obtained.  pdFALSE
137
 * if xBlockTime expired without the semaphore becoming available.
138
 *
139
 * Example usage:
140
 <pre>
141
 xSemaphoreHandle xSemaphore = NULL;
142
 
143
 // A task that creates a semaphore.
144
 void vATask( void * pvParameters )
145
 {
146
    // Create the semaphore to guard a shared resource.
147
    vSemaphoreCreateBinary( xSemaphore );
148
 }
149
 
150
 // A task that uses the semaphore.
151
 void vAnotherTask( void * pvParameters )
152
 {
153
    // ... Do other things.
154
 
155
    if( xSemaphore != NULL )
156
    {
157
        // See if we can obtain the semaphore.  If the semaphore is not available
158
        // wait 10 ticks to see if it becomes free.
159
        if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
160
        {
161
            // We were able to obtain the semaphore and can now access the
162
            // shared resource.
163
 
164
            // ...
165
 
166
            // We have finished accessing the shared resource.  Release the
167
            // semaphore.
168
            xSemaphoreGive( xSemaphore );
169
        }
170
        else
171
        {
172
            // We could not obtain the semaphore and can therefore not access
173
            // the shared resource safely.
174
        }
175
    }
176
 }
177
 </pre>
178
 * \defgroup xSemaphoreTake xSemaphoreTake
179
 * \ingroup Semaphores
180
 */
181
#define xSemaphoreTake( xSemaphore, xBlockTime )                xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
182
 
183
/**
184
 * semphr. h
185
 * xSemaphoreTakeRecursive(
186
 *                          xSemaphoreHandle xMutex,
187
 *                          portTickType xBlockTime
188
 *                        )
189
 *
190
 * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
191
 * The mutex must have previously been created using a call to
192
 * xSemaphoreCreateRecursiveMutex();
193
 *
194
 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
195
 * macro to be available.
196
 *
197
 * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
198
 *
199
 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
200
 * doesn't become available again until the owner has called
201
 * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
202
 * if a task successfully 'takes' the same mutex 5 times then the mutex will
203
 * not be available to any other task until it has also  'given' the mutex back
204
 * exactly five times.
205
 *
206
 * @param xMutex A handle to the mutex being obtained.  This is the
207
 * handle returned by xSemaphoreCreateRecursiveMutex();
208
 *
209
 * @param xBlockTime The time in ticks to wait for the semaphore to become
210
 * available.  The macro portTICK_RATE_MS can be used to convert this to a
211
 * real time.  A block time of zero can be used to poll the semaphore.  If
212
 * the task already owns the semaphore then xSemaphoreTakeRecursive() will
213
 * return immediately no matter what the value of xBlockTime.
214
 *
215
 * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime
216
 * expired without the semaphore becoming available.
217
 *
218
 * Example usage:
219
 <pre>
220
 xSemaphoreHandle xMutex = NULL;
221
 
222
 // A task that creates a mutex.
223
 void vATask( void * pvParameters )
224
 {
225
    // Create the mutex to guard a shared resource.
226
    xMutex = xSemaphoreCreateRecursiveMutex();
227
 }
228
 
229
 // A task that uses the mutex.
230
 void vAnotherTask( void * pvParameters )
231
 {
232
    // ... Do other things.
233
 
234
    if( xMutex != NULL )
235
    {
236
        // See if we can obtain the mutex.  If the mutex is not available
237
        // wait 10 ticks to see if it becomes free.
238
        if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
239
        {
240
            // We were able to obtain the mutex and can now access the
241
            // shared resource.
242
 
243
            // ...
244
            // For some reason due to the nature of the code further calls to
245
                        // xSemaphoreTakeRecursive() are made on the same mutex.  In real
246
                        // code these would not be just sequential calls as this would make
247
                        // no sense.  Instead the calls are likely to be buried inside
248
                        // a more complex call structure.
249
            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
250
            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
251
 
252
            // The mutex has now been 'taken' three times, so will not be
253
                        // available to another task until it has also been given back
254
                        // three times.  Again it is unlikely that real code would have
255
                        // these calls sequentially, but instead buried in a more complex
256
                        // call structure.  This is just for illustrative purposes.
257
            xSemaphoreGiveRecursive( xMutex );
258
                        xSemaphoreGiveRecursive( xMutex );
259
                        xSemaphoreGiveRecursive( xMutex );
260
 
261
                        // Now the mutex can be taken by other tasks.
262
        }
263
        else
264
        {
265
            // We could not obtain the mutex and can therefore not access
266
            // the shared resource safely.
267
        }
268
    }
269
 }
270
 </pre>
271
 * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
272
 * \ingroup Semaphores
273
 */
274
#define xSemaphoreTakeRecursive( xMutex, xBlockTime )   xQueueTakeMutexRecursive( xMutex, xBlockTime )
275
 
276
 
277
/*
278
 * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
279
 *
280
 * The source code that implements the alternative (Alt) API is much
281
 * simpler      because it executes everything from within a critical section.
282
 * This is      the approach taken by many other RTOSes, but FreeRTOS.org has the
283
 * preferred fully featured API too.  The fully featured API has more
284
 * complex      code that takes longer to execute, but makes much less use of
285
 * critical sections.  Therefore the alternative API sacrifices interrupt
286
 * responsiveness to gain execution speed, whereas the fully featured API
287
 * sacrifices execution speed to ensure better interrupt responsiveness.
288
 */
289
#define xSemaphoreAltTake( xSemaphore, xBlockTime )             xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
290
 
291
/**
292
 * semphr. h
293
 * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
294
 *
295
 * <i>Macro</i> to release a semaphore.  The semaphore must have previously been
296
 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
297
 * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
298
 *
299
 * This macro must not be used from an ISR.  See xSemaphoreGiveFromISR () for
300
 * an alternative which can be used from an ISR.
301
 *
302
 * This macro must also not be used on semaphores created using
303
 * xSemaphoreCreateRecursiveMutex().
304
 *
305
 * @param xSemaphore A handle to the semaphore being released.  This is the
306
 * handle returned when the semaphore was created.
307
 *
308
 * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.
309
 * Semaphores are implemented using queues.  An error can occur if there is
310
 * no space on the queue to post a message - indicating that the
311
 * semaphore was not first obtained correctly.
312
 *
313
 * Example usage:
314
 <pre>
315
 xSemaphoreHandle xSemaphore = NULL;
316
 
317
 void vATask( void * pvParameters )
318
 {
319
    // Create the semaphore to guard a shared resource.
320
    vSemaphoreCreateBinary( xSemaphore );
321
 
322
    if( xSemaphore != NULL )
323
    {
324
        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
325
        {
326
            // We would expect this call to fail because we cannot give
327
            // a semaphore without first "taking" it!
328
        }
329
 
330
        // Obtain the semaphore - don't block if the semaphore is not
331
        // immediately available.
332
        if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
333
        {
334
            // We now have the semaphore and can access the shared resource.
335
 
336
            // ...
337
 
338
            // We have finished accessing the shared resource so can free the
339
            // semaphore.
340
            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
341
            {
342
                // We would not expect this call to fail because we must have
343
                // obtained the semaphore to get here.
344
            }
345
        }
346
    }
347
 }
348
 </pre>
349
 * \defgroup xSemaphoreGive xSemaphoreGive
350
 * \ingroup Semaphores
351
 */
352
#define xSemaphoreGive( xSemaphore )            xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
353
 
354
/**
355
 * semphr. h
356
 * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
357
 *
358
 * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
359
 * The mutex must have previously been created using a call to
360
 * xSemaphoreCreateRecursiveMutex();
361
 *
362
 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
363
 * macro to be available.
364
 *
365
 * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
366
 *
367
 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
368
 * doesn't become available again until the owner has called
369
 * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
370
 * if a task successfully 'takes' the same mutex 5 times then the mutex will
371
 * not be available to any other task until it has also  'given' the mutex back
372
 * exactly five times.
373
 *
374
 * @param xMutex A handle to the mutex being released, or 'given'.  This is the
375
 * handle returned by xSemaphoreCreateMutex();
376
 *
377
 * @return pdTRUE if the semaphore was given.
378
 *
379
 * Example usage:
380
 <pre>
381
 xSemaphoreHandle xMutex = NULL;
382
 
383
 // A task that creates a mutex.
384
 void vATask( void * pvParameters )
385
 {
386
    // Create the mutex to guard a shared resource.
387
    xMutex = xSemaphoreCreateRecursiveMutex();
388
 }
389
 
390
 // A task that uses the mutex.
391
 void vAnotherTask( void * pvParameters )
392
 {
393
    // ... Do other things.
394
 
395
    if( xMutex != NULL )
396
    {
397
        // See if we can obtain the mutex.  If the mutex is not available
398
        // wait 10 ticks to see if it becomes free.
399
        if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
400
        {
401
            // We were able to obtain the mutex and can now access the
402
            // shared resource.
403
 
404
            // ...
405
            // For some reason due to the nature of the code further calls to
406
                        // xSemaphoreTakeRecursive() are made on the same mutex.  In real
407
                        // code these would not be just sequential calls as this would make
408
                        // no sense.  Instead the calls are likely to be buried inside
409
                        // a more complex call structure.
410
            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
411
            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
412
 
413
            // The mutex has now been 'taken' three times, so will not be
414
                        // available to another task until it has also been given back
415
                        // three times.  Again it is unlikely that real code would have
416
                        // these calls sequentially, it would be more likely that the calls
417
                        // to xSemaphoreGiveRecursive() would be called as a call stack
418
                        // unwound.  This is just for demonstrative purposes.
419
            xSemaphoreGiveRecursive( xMutex );
420
                        xSemaphoreGiveRecursive( xMutex );
421
                        xSemaphoreGiveRecursive( xMutex );
422
 
423
                        // Now the mutex can be taken by other tasks.
424
        }
425
        else
426
        {
427
            // We could not obtain the mutex and can therefore not access
428
            // the shared resource safely.
429
        }
430
    }
431
 }
432
 </pre>
433
 * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
434
 * \ingroup Semaphores
435
 */
436
#define xSemaphoreGiveRecursive( xMutex )       xQueueGiveMutexRecursive( xMutex )
437
 
438
/*
439
 * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
440
 *
441
 * The source code that implements the alternative (Alt) API is much
442
 * simpler      because it executes everything from within a critical section.
443
 * This is      the approach taken by many other RTOSes, but FreeRTOS.org has the
444
 * preferred fully featured API too.  The fully featured API has more
445
 * complex      code that takes longer to execute, but makes much less use of
446
 * critical sections.  Therefore the alternative API sacrifices interrupt
447
 * responsiveness to gain execution speed, whereas the fully featured API
448
 * sacrifices execution speed to ensure better interrupt responsiveness.
449
 */
450
#define xSemaphoreAltGive( xSemaphore )         xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
451
 
452
/**
453
 * semphr. h
454
 * <pre>
455
 xSemaphoreGiveFromISR(
456
                          xSemaphoreHandle xSemaphore,
457
                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
458
                      )</pre>
459
 *
460
 * <i>Macro</i> to  release a semaphore.  The semaphore must have previously been
461
 * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
462
 *
463
 * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
464
 * must not be used with this macro.
465
 *
466
 * This macro can be used from an ISR.
467
 *
468
 * @param xSemaphore A handle to the semaphore being released.  This is the
469
 * handle returned when the semaphore was created.
470
 *
471
 * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
472
 * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
473
 * to unblock, and the unblocked task has a priority higher than the currently
474
 * running task.  If xSemaphoreGiveFromISR() sets this value to pdTRUE then
475
 * a context switch should be requested before the interrupt is exited.
476
 *
477
 * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
478
 *
479
 * Example usage:
480
 <pre>
481
 \#define LONG_TIME 0xffff
482
 \#define TICKS_TO_WAIT 10
483
 xSemaphoreHandle xSemaphore = NULL;
484
 
485
 // Repetitive task.
486
 void vATask( void * pvParameters )
487
 {
488
    for( ;; )
489
    {
490
        // We want this task to run every 10 ticks of a timer.  The semaphore
491
        // was created before this task was started.
492
 
493
        // Block waiting for the semaphore to become available.
494
        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
495
        {
496
            // It is time to execute.
497
 
498
            // ...
499
 
500
            // We have finished our task.  Return to the top of the loop where
501
            // we will block on the semaphore until it is time to execute
502
            // again.  Note when using the semaphore for synchronisation with an
503
                        // ISR in this manner there is no need to 'give' the semaphore back.
504
        }
505
    }
506
 }
507
 
508
 // Timer ISR
509
 void vTimerISR( void * pvParameters )
510
 {
511
 static unsigned char ucLocalTickCount = 0;
512
 static signed portBASE_TYPE xHigherPriorityTaskWoken;
513
 
514
    // A timer tick has occurred.
515
 
516
    // ... Do other time functions.
517
 
518
    // Is it time for vATask () to run?
519
        xHigherPriorityTaskWoken = pdFALSE;
520
    ucLocalTickCount++;
521
    if( ucLocalTickCount >= TICKS_TO_WAIT )
522
    {
523
        // Unblock the task by releasing the semaphore.
524
        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
525
 
526
        // Reset the count so we release the semaphore again in 10 ticks time.
527
        ucLocalTickCount = 0;
528
    }
529
 
530
    if( xHigherPriorityTaskWoken != pdFALSE )
531
    {
532
        // We can force a context switch here.  Context switching from an
533
        // ISR uses port specific syntax.  Check the demo task for your port
534
        // to find the syntax required.
535
    }
536
 }
537
 </pre>
538
 * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
539
 * \ingroup Semaphores
540
 */
541
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )                  xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
542
 
543
/**
544
 * semphr. h
545
 * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
546
 *
547
 * <i>Macro</i> that implements a mutex semaphore by using the existing queue
548
 * mechanism.
549
 *
550
 * Mutexes created using this macro can be accessed using the xSemaphoreTake()
551
 * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and
552
 * xSemaphoreGiveRecursive() macros should not be used.
553
 *
554
 * This type of semaphore uses a priority inheritance mechanism so a task
555
 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
556
 * semaphore it is no longer required.
557
 *
558
 * Mutex type semaphores cannot be used from within interrupt service routines.
559
 *
560
 * See vSemaphoreCreateBinary() for an alternative implementation that can be
561
 * used for pure synchronisation (where one task or interrupt always 'gives' the
562
 * semaphore and another always 'takes' the semaphore) and from within interrupt
563
 * service routines.
564
 *
565
 * @return xSemaphore Handle to the created mutex semaphore.  Should be of type
566
 *              xSemaphoreHandle.
567
 *
568
 * Example usage:
569
 <pre>
570
 xSemaphoreHandle xSemaphore;
571
 
572
 void vATask( void * pvParameters )
573
 {
574
    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
575
    // This is a macro so pass the variable in directly.
576
    xSemaphore = xSemaphoreCreateMutex();
577
 
578
    if( xSemaphore != NULL )
579
    {
580
        // The semaphore was created successfully.
581
        // The semaphore can now be used.
582
    }
583
 }
584
 </pre>
585
 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
586
 * \ingroup Semaphores
587
 */
588
#define xSemaphoreCreateMutex() xQueueCreateMutex()
589
 
590
 
591
/**
592
 * semphr. h
593
 * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
594
 *
595
 * <i>Macro</i> that implements a recursive mutex by using the existing queue
596
 * mechanism.
597
 *
598
 * Mutexes created using this macro can be accessed using the
599
 * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The
600
 * xSemaphoreTake() and xSemaphoreGive() macros should not be used.
601
 *
602
 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
603
 * doesn't become available again until the owner has called
604
 * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
605
 * if a task successfully 'takes' the same mutex 5 times then the mutex will
606
 * not be available to any other task until it has also  'given' the mutex back
607
 * exactly five times.
608
 *
609
 * This type of semaphore uses a priority inheritance mechanism so a task
610
 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
611
 * semaphore it is no longer required.
612
 *
613
 * Mutex type semaphores cannot be used from within interrupt service routines.
614
 *
615
 * See vSemaphoreCreateBinary() for an alternative implementation that can be
616
 * used for pure synchronisation (where one task or interrupt always 'gives' the
617
 * semaphore and another always 'takes' the semaphore) and from within interrupt
618
 * service routines.
619
 *
620
 * @return xSemaphore Handle to the created mutex semaphore.  Should be of type
621
 *              xSemaphoreHandle.
622
 *
623
 * Example usage:
624
 <pre>
625
 xSemaphoreHandle xSemaphore;
626
 
627
 void vATask( void * pvParameters )
628
 {
629
    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
630
    // This is a macro so pass the variable in directly.
631
    xSemaphore = xSemaphoreCreateRecursiveMutex();
632
 
633
    if( xSemaphore != NULL )
634
    {
635
        // The semaphore was created successfully.
636
        // The semaphore can now be used.
637
    }
638
 }
639
 </pre>
640
 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
641
 * \ingroup Semaphores
642
 */
643
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
644
 
645
/**
646
 * semphr. h
647
 * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
648
 *
649
 * <i>Macro</i> that creates a counting semaphore by using the existing
650
 * queue mechanism.
651
 *
652
 * Counting semaphores are typically used for two things:
653
 *
654
 * 1) Counting events.
655
 *
656
 *    In this usage scenario an event handler will 'give' a semaphore each time
657
 *    an event occurs (incrementing the semaphore count value), and a handler
658
 *    task will 'take' a semaphore each time it processes an event
659
 *    (decrementing the semaphore count value).  The count value is therefore
660
 *    the difference between the number of events that have occurred and the
661
 *    number that have been processed.  In this case it is desirable for the
662
 *    initial count value to be zero.
663
 *
664
 * 2) Resource management.
665
 *
666
 *    In this usage scenario the count value indicates the number of resources
667
 *    available.  To obtain control of a resource a task must first obtain a
668
 *    semaphore - decrementing the semaphore count value.  When the count value
669
 *    reaches zero there are no free resources.  When a task finishes with the
670
 *    resource it 'gives' the semaphore back - incrementing the semaphore count
671
 *    value.  In this case it is desirable for the initial count value to be
672
 *    equal to the maximum count value, indicating that all resources are free.
673
 *
674
 * @param uxMaxCount The maximum count value that can be reached.  When the
675
 *        semaphore reaches this value it can no longer be 'given'.
676
 *
677
 * @param uxInitialCount The count value assigned to the semaphore when it is
678
 *        created.
679
 *
680
 * @return Handle to the created semaphore.  Null if the semaphore could not be
681
 *         created.
682
 *
683
 * Example usage:
684
 <pre>
685
 xSemaphoreHandle xSemaphore;
686
 
687
 void vATask( void * pvParameters )
688
 {
689
 xSemaphoreHandle xSemaphore = NULL;
690
 
691
    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
692
    // The max value to which the semaphore can count should be 10, and the
693
    // initial value assigned to the count should be 0.
694
    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
695
 
696
    if( xSemaphore != NULL )
697
    {
698
        // The semaphore was created successfully.
699
        // The semaphore can now be used.
700
    }
701
 }
702
 </pre>
703
 * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
704
 * \ingroup Semaphores
705
 */
706
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
707
 
708
 
709
#endif /* SEMAPHORE_H */
710
 
711
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.