Project

General

Profile

Download (9.54 KB) Statistics
| Branch: | Tag: | Revision:
1
/*
2
	FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
3

    
4
	This file is part of the FreeRTOS.org distribution.
5

    
6
	FreeRTOS.org is free software; you can redistribute it and/or modify
7
	it under the terms of the GNU General Public License as published by
8
	the Free Software Foundation; either version 2 of the License, or
9
	(at your option) any later version.
10

    
11
	FreeRTOS.org is distributed in the hope that it will be useful,
12
	but WITHOUT ANY WARRANTY; without even the implied warranty of
13
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
	GNU General Public License for more details.
15

    
16
	You should have received a copy of the GNU General Public License
17
	along with FreeRTOS.org; if not, write to the Free Software
18
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19

    
20
	A special exception to the GPL can be applied should you wish to distribute
21
	a combined work that includes FreeRTOS.org, without being obliged to provide
22
	the source code for any proprietary components.  See the licensing section 
23
	of http://www.FreeRTOS.org for full details of how and when the exception
24
	can be applied.
25

    
26
	***************************************************************************
27
	See http://www.FreeRTOS.org for documentation, latest information, license 
28
	and contact details.  Please ensure to read the configuration and relevant 
29
	port sections of the online documentation.
30

    
31
	Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
32
	with commercial development and support options.
33
	***************************************************************************
34
*/
35

    
36
#include "queue.h"
37

    
38
#ifndef SEMAPHORE_H
39
#define SEMAPHORE_H
40

    
41
typedef xQueueHandle xSemaphoreHandle;
42

    
43
#define semBINARY_SEMAPHORE_QUEUE_LENGTH	( ( unsigned portCHAR ) 1 )
44
#define semSEMAPHORE_QUEUE_ITEM_LENGTH		( ( unsigned portCHAR ) 0 )
45
#define semGIVE_BLOCK_TIME					( ( portTickType ) 0 )
46

    
47

    
48
/**
49
 * semphr. h
50
 * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
51
 *
52
 * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
53
 * The queue length is 1 as this is a binary semaphore.  The data size is 0
54
 * as we don't want to actually store any data - we just want to know if the
55
 * queue is empty or full.
56
 *
57
 * @param xSemaphore Handle to the created semaphore.  Should be of type xSemaphoreHandle.
58
 *
59
 * Example usage:
60
 <pre>
61
 xSemaphoreHandle xSemaphore;
62

    
63
 void vATask( void * pvParameters )
64
 {
65
    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
66
    // This is a macro so pass the variable in directly.
67
    vSemaphoreCreateBinary( xSemaphore );
68

    
69
    if( xSemaphore != NULL )
70
    {
71
        // The semaphore was created successfully.
72
        // The semaphore can now be used.  
73
    }
74
 }
75
 </pre>
76
 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
77
 * \ingroup Semaphores
78
 */
79
#define vSemaphoreCreateBinary( xSemaphore )		{																							\
80
														xSemaphore = xQueueCreate( ( unsigned portCHAR ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH );	\
81
														if( xSemaphore != NULL )																\
82
														{																						\
83
															xSemaphoreGive( xSemaphore );														\
84
														}																						\
85
													}
86

    
87
/**
88
 * semphr. h
89
 * xSemaphoreTake( 
90
 *                   xSemaphoreHandle xSemaphore, 
91
 *                   portTickType xBlockTime 
92
 *               )</pre>
93
 *
94
 * <i>Macro</i> to obtain a semaphore.  The semaphore must of been created using 
95
 * vSemaphoreCreateBinary ().
96
 *
97
 * @param xSemaphore A handle to the semaphore being obtained.  This is the
98
 * handle returned by vSemaphoreCreateBinary ();
99
 *
100
 * @param xBlockTime The time in ticks to wait for the semaphore to become
101
 * available.  The macro portTICK_RATE_MS can be used to convert this to a
102
 * real time.  A block time of zero can be used to poll the semaphore.
103
 *
104
 * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime
105
 * expired without the semaphore becoming available.
106
 *
107
 * Example usage:
108
 <pre>
109
 xSemaphoreHandle xSemaphore = NULL;
110

    
111
 // A task that creates a semaphore.
112
 void vATask( void * pvParameters )
113
 {
114
    // Create the semaphore to guard a shared resource.
115
    vSemaphoreCreateBinary( xSemaphore );
116
 }
117

    
118
 // A task that uses the semaphore.
119
 void vAnotherTask( void * pvParameters )
120
 {
121
    // ... Do other things.
122

    
123
    if( xSemaphore != NULL )
124
    {
125
        // See if we can obtain the semaphore.  If the semaphore is not available
126
        // wait 10 ticks to see if it becomes free.	
127
        if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
128
        {
129
            // We were able to obtain the semaphore and can now access the
130
            // shared resource.
131

    
132
            // ...
133

    
134
            // We have finished accessing the shared resource.  Release the 
135
            // semaphore.
136
            xSemaphoreGive( xSemaphore );
137
        }
138
        else
139
        {
140
            // We could not obtain the semaphore and can therefore not access
141
            // the shared resource safely.
142
        }
143
    }
144
 }
145
 </pre>
146
 * \defgroup xSemaphoreTake xSemaphoreTake
147
 * \ingroup Semaphores
148
 */
149
#define xSemaphoreTake( xSemaphore, xBlockTime )	xQueueReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime )
150

    
151
/**
152
 * semphr. h
153
 * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
154
 *
155
 * <i>Macro</i> to release a semaphore.  The semaphore must of been created using 
156
 * vSemaphoreCreateBinary (), and obtained using sSemaphoreTake ().
157
 *
158
 * This must not be used from an ISR.  See xSemaphoreGiveFromISR () for
159
 * an alternative which can be used from an ISR.
160
 *
161
 * @param xSemaphore A handle to the semaphore being released.  This is the
162
 * handle returned by vSemaphoreCreateBinary ();
163
 *
164
 * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.
165
 * Semaphores are implemented using queues.  An error can occur if there is
166
 * no space on the queue to post a message - indicating that the 
167
 * semaphore was not first obtained correctly.
168
 *
169
 * Example usage:
170
 <pre>
171
 xSemaphoreHandle xSemaphore = NULL;
172

    
173
 void vATask( void * pvParameters )
174
 {
175
    // Create the semaphore to guard a shared resource.
176
    vSemaphoreCreateBinary( xSemaphore );
177

    
178
    if( xSemaphore != NULL )
179
    {
180
        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
181
        {
182
            // We would expect this call to fail because we cannot give
183
            // a semaphore without first "taking" it!
184
        }
185

    
186
        // Obtain the semaphore - don't block if the semaphore is not
187
        // immediately available.
188
        if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
189
        {
190
            // We now have the semaphore and can access the shared resource.
191

    
192
            // ...
193

    
194
            // We have finished accessing the shared resource so can free the
195
            // semaphore.
196
            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
197
            {
198
                // We would not expect this call to fail because we must have
199
                // obtained the semaphore to get here.
200
            }
201
        }
202
    }
203
 }
204
 </pre>
205
 * \defgroup xSemaphoreGive xSemaphoreGive
206
 * \ingroup Semaphores
207
 */
208
#define xSemaphoreGive( xSemaphore )				xQueueSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME )
209

    
210
/**
211
 * semphr. h
212
 * <pre>
213
 xSemaphoreGiveFromISR( 
214
                          xSemaphoreHandle xSemaphore, 
215
                          portSHORT sTaskPreviouslyWoken 
216
                      )</pre>
217
 *
218
 * <i>Macro</i> to  release a semaphore.  The semaphore must of been created using 
219
 * vSemaphoreCreateBinary (), and obtained using xSemaphoreTake ().
220
 *
221
 * This macro can be used from an ISR.
222
 *
223
 * @param xSemaphore A handle to the semaphore being released.  This is the
224
 * handle returned by vSemaphoreCreateBinary ();
225
 *
226
 * @param sTaskPreviouslyWoken This is included so an ISR can make multiple calls
227
 * to xSemaphoreGiveFromISR () from a single interrupt.  The first call
228
 * should always pass in pdFALSE.  Subsequent calls should pass in
229
 * the value returned from the previous call.  See the file serial .c in the
230
 * PC port for a good example of using xSemaphoreGiveFromISR ().
231
 *
232
 * @return pdTRUE if a task was woken by releasing the semaphore.  This is 
233
 * used by the ISR to determine if a context switch may be required following
234
 * the ISR.
235
 *
236
 * Example usage:
237
 <pre>
238
 #define LONG_TIME 0xffff
239
 #define TICKS_TO_WAIT	10
240
 xSemaphoreHandle xSemaphore = NULL;
241

    
242
 // Repetitive task.
243
 void vATask( void * pvParameters )
244
 {
245
    for( ;; )
246
    {
247
        // We want this task to run every 10 ticks or a timer.  The semaphore 
248
        // was created before this task was started
249

    
250
        // Block waiting for the semaphore to become available.
251
        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
252
        {
253
            // It is time to execute.
254

    
255
            // ...
256

    
257
            // We have finished our task.  Return to the top of the loop where
258
            // we will block on the semaphore until it is time to execute 
259
            // again.
260
        }
261
    }
262
 }
263

    
264
 // Timer ISR
265
 void vTimerISR( void * pvParameters )
266
 {
267
 static unsigned portCHAR ucLocalTickCount = 0;
268

    
269
    // A timer tick has occurred.
270

    
271
    // ... Do other time functions.
272

    
273
    // Is it time for vATask () to run?
274
    ucLocalTickCount++;
275
    if( ucLocalTickCount >= TICKS_TO_WAIT )
276
    {
277
        // Unblock the task by releasing the semaphore.
278
        xSemaphoreGive( xSemaphore );
279

    
280
        // Reset the count so we release the semaphore again in 10 ticks time.
281
        ucLocalTickCount = 0;
282
    }
283
 }
284
 </pre>
285
 * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
286
 * \ingroup Semaphores
287
 */
288
#define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken )			xQueueSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken )
289

    
290

    
291
#endif
(16-16/18)
Add picture from clipboard (Maximum size: 48.8 MB)