Counting semaphore demo added.

This commit is contained in:
Richard Barry 2007-12-01 20:28:04 +00:00
parent a8eabeabbb
commit d69d2df8d6
11 changed files with 581 additions and 202 deletions

View file

@ -0,0 +1,275 @@
/*
FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
See http://www.FreeRTOS.org for documentation, latest information, license
and contact details. Please ensure to read the configuration and relevant
port sections of the online documentation.
Also see http://www.SafeRTOS.com a version that has been certified for use
in safety critical systems, plus commercial licensing, development and
support options.
***************************************************************************
*/
/*
* Simple demonstration of the usage of counting semaphore.
*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* Demo program include files. */
#include "countsem.h"
/* The maximum count value that the semaphore used for the demo can hold. */
#define countMAX_COUNT_VALUE ( 200 )
/* Constants used to indicate whether or not the semaphore should have been
created with its maximum count value, or its minimum count value. These
numbers are used to ensure that the pointers passed in as the task parameters
are valid. */
#define countSTART_AT_MAX_COUNT ( 0xaa )
#define countSTART_AT_ZERO ( 0x55 )
/* Two tasks are created for the test. One uses a semaphore created with its
count value set to the maximum, and one with the count value set to zero. */
#define countNUM_TEST_TASKS ( 2 )
#define countDONT_BLOCK ( 0 )
/*-----------------------------------------------------------*/
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
detected in any of the tasks. */
static portBASE_TYPE xErrorDetected = pdFALSE;
/*-----------------------------------------------------------*/
/*
* The demo task. This simply counts the semaphore up to its maximum value,
* the counts it back down again. The result of each semaphore 'give' and
* 'take' is inspected, with an error being flagged if it is found not to be
* the expected result.
*/
static void prvCountingSemaphoreTask( void *pvParameters );
/*
* Utility function to increment the semaphore count value up from zero to
* countMAX_COUNT_VALUE.
*/
static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter );
/*
* Utility function to decrement the semaphore count value up from
* countMAX_COUNT_VALUE to zero.
*/
static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter );
/*-----------------------------------------------------------*/
/* The structure that is passed into the task as the task parameter. */
typedef struct COUNT_SEM_STRUCT
{
/* The semaphore to be used for the demo. */
xSemaphoreHandle xSemaphore;
/* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with
its count value set to its max count value, or countSTART_AT_ZERO if it
should have been created with its count value set to 0. */
unsigned portBASE_TYPE uxExpectedStartCount;
/* Incremented on each cycle of the demo task. Used to detect a stalled
task. */
unsigned portBASE_TYPE uxLoopCounter;
} xCountSemStruct;
/* Two structures are defined, one is passed to each test task. */
static xCountSemStruct xParameters[ countNUM_TEST_TASKS ];
/*-----------------------------------------------------------*/
void vStartCountingSemaphoreTasks( void )
{
/* Create the semaphores that we are going to use for the test/demo. The
first should be created such that it starts at its maximum count value,
the second should be created such that it starts with a count value of zero. */
xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE );
xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT;
xParameters[ 0 ].uxLoopCounter = 0;
xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 );
xParameters[ 1 ].uxExpectedStartCount = 0;
xParameters[ 1 ].uxLoopCounter = 0;
/* Were the semaphores created? */
if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) )
{
/* Create the demo tasks, passing in the semaphore to use as the parameter. */
xTaskCreate( prvCountingSemaphoreTask, "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL );
xTaskCreate( prvCountingSemaphoreTask, "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL );
}
}
/*-----------------------------------------------------------*/
static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter )
{
unsigned portBASE_TYPE ux;
/* If the semaphore count is at its maximum then we should not be able to
'give' the semaphore. */
if( xSemaphoreGive( xSemaphore ) == pdPASS )
{
xErrorDetected = pdTRUE;
}
/* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
{
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS )
{
/* We expected to be able to take the semaphore. */
xErrorDetected = pdTRUE;
}
( *puxLoopCounter )++;
}
/* If the semaphore count is zero then we should not be able to 'take'
the semaphore. */
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
{
xErrorDetected = pdTRUE;
}
}
/*-----------------------------------------------------------*/
static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter )
{
unsigned portBASE_TYPE ux;
/* If the semaphore count is zero then we should not be able to 'take'
the semaphore. */
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
{
xErrorDetected = pdTRUE;
}
/* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
{
if( xSemaphoreGive( xSemaphore ) != pdPASS )
{
/* We expected to be able to take the semaphore. */
xErrorDetected = pdTRUE;
}
( *puxLoopCounter )++;
}
/* If the semaphore count is at its maximum then we should not be able to
'give' the semaphore. */
if( xSemaphoreGive( xSemaphore ) == pdPASS )
{
xErrorDetected = pdTRUE;
}
}
/*-----------------------------------------------------------*/
static void prvCountingSemaphoreTask( void *pvParameters )
{
xCountSemStruct *pxParameter;
#ifdef USE_STDIO
void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
const portCHAR * const pcTaskStartMsg = "Counting semaphore demo started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
/* The semaphore to be used was passed as the parameter. */
pxParameter = ( xCountSemStruct * ) pvParameters;
/* Did we expect to find the semaphore already at its max count value, or
at zero? */
if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT )
{
prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );
}
/* Now we expect the semaphore count to be 0, so this time there is an
error if we can take the semaphore. */
if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS )
{
xErrorDetected = pdTRUE;
}
for( ;; )
{
prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );
prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );
}
}
/*-----------------------------------------------------------*/
portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void )
{
static unsigned portBASE_TYPE uxLastCount0 = 0, uxLastCount1 = 0;
portBASE_TYPE xReturn = pdPASS;
/* Return fail if any 'give' or 'take' did not result in the expected
behaviour. */
if( xErrorDetected != pdFALSE )
{
xReturn = pdFAIL;
}
/* Return fail if either task is not still incrementing its loop counter. */
if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter )
{
xReturn = pdFAIL;
}
else
{
uxLastCount0 = xParameters[ 0 ].uxLoopCounter;
}
if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter )
{
xReturn = pdFAIL;
}
else
{
uxLastCount1 = xParameters[ 1 ].uxLoopCounter;
}
return xReturn;
}

View file

@ -0,0 +1,44 @@
/*
FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
See http://www.FreeRTOS.org for documentation, latest information, license
and contact details. Please ensure to read the configuration and relevant
port sections of the online documentation.
Also see http://www.SafeRTOS.com a version that has been certified for use
in safety critical systems, plus commercial licensing, development and
support options.
***************************************************************************
*/
#ifndef COUNT_SEMAPHORE_TEST_H
#define COUNT_SEMAPHORE_TEST_H
void vStartCountingSemaphoreTasks( void );
portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void );
#endif

View file

@ -62,6 +62,7 @@
#define configIDLE_SHOULD_YIELD 1 #define configIDLE_SHOULD_YIELD 1
#define configUSE_CO_ROUTINES 1 #define configUSE_CO_ROUTINES 1
#define configUSE_MUTEXES 1 #define configUSE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 10 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 10 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

View file

@ -65,38 +65,6 @@
* <HR> * <HR>
*/ */
/*
Changes from V1.00:
+ Prevent the call to kbhit() for debug builds as the debugger seems to
have problems stepping over the call.
Changes from V1.2.3
+ The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive
scheduler.
Changes from V1.2.6
+ Create new tasks as defined by the new demo application file dynamic.c.
Changes from V2.0.0
+ Delay periods are now specified using variables and constants of
portTickType rather than unsigned portLONG.
Changes from V3.1.1
+ The tasks defined in the new file "events.c" are now created and
monitored for errors.
Changes from V3.2.4
+ Now includes the flash co-routine demo rather than the flash task demo.
This is to demonstrate the co-routine functionality.
*/
#include <stdlib.h> #include <stdlib.h>
#include <conio.h> #include <conio.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -122,6 +90,7 @@ Changes from V3.2.4
#include "blocktim.h" #include "blocktim.h"
#include "GenQTest.h" #include "GenQTest.h"
#include "QPeek.h" #include "QPeek.h"
#include "countsem.h"
/* Priority definitions for the tasks in the demo application. */ /* Priority definitions for the tasks in the demo application. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
@ -185,6 +154,7 @@ portSHORT main( void )
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartMultiEventTasks(); vStartMultiEventTasks();
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartCountingSemaphoreTasks();
/* Create the "Print" task as described at the top of the file. */ /* Create the "Print" task as described at the top of the file. */
xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL );
@ -408,6 +378,12 @@ static portSHORT sErrorHasOccurred = pdFALSE;
sErrorHasOccurred = pdTRUE; sErrorHasOccurred = pdTRUE;
} }
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
vDisplayMessage( "Error in counting semaphore demo task!\r\n" );
sErrorHasOccurred = pdTRUE;
}
if( sErrorHasOccurred == pdFALSE ) if( sErrorHasOccurred == pdFALSE )
{ {
vDisplayMessage( "OK " ); vDisplayMessage( "OK " );

View file

@ -75,7 +75,7 @@ WVList
0 0
19 19
WPickList WPickList
53 55
20 20
MItem MItem
3 3
@ -724,8 +724,8 @@ WVList
0 0
172 172
MItem MItem
27 28
..\COMMON\MINIMAL\crflash.c ..\COMMON\MINIMAL\countsem.c
173 173
WString WString
4 4
@ -742,8 +742,8 @@ WVList
0 0
176 176
MItem MItem
26 27
..\COMMON\MINIMAL\crhook.c ..\COMMON\MINIMAL\crflash.c
177 177
WString WString
4 4
@ -760,8 +760,8 @@ WVList
0 0
180 180
MItem MItem
28 26
..\COMMON\MINIMAL\GenQTest.c ..\COMMON\MINIMAL\crhook.c
181 181
WString WString
4 4
@ -778,8 +778,8 @@ WVList
0 0
184 184
MItem MItem
25 28
..\COMMON\MINIMAL\QPeek.c ..\COMMON\MINIMAL\GenQTest.c
185 185
WString WString
4 4
@ -796,8 +796,8 @@ WVList
0 0
188 188
MItem MItem
15 25
fileio\fileio.c ..\COMMON\MINIMAL\QPeek.c
189 189
WString WString
4 4
@ -814,8 +814,8 @@ WVList
0 0
192 192
MItem MItem
6 15
main.c fileio\fileio.c
193 193
WString WString
4 4
@ -832,8 +832,8 @@ WVList
0 0
196 196
MItem MItem
17 6
partest\partest.c main.c
197 197
WString WString
4 4
@ -850,8 +850,8 @@ WVList
0 0
200 200
MItem MItem
15 17
serial\serial.c partest\partest.c
201 201
WString WString
4 4
@ -868,26 +868,26 @@ WVList
0 0
204 204
MItem MItem
3 15
*.h serial\serial.c
205 205
WString WString
3 4
NIL COBJ
206 206
WVList WVList
0 0
207 207
WVList WVList
0 0
-1 20
1
1 1
0
0 0
208 208
MItem MItem
31 3
..\..\SOURCE\INCLUDE\croutine.h *.h
209 209
WString WString
3 3
@ -898,14 +898,14 @@ WVList
211 211
WVList WVList
0 0
204 -1
1
1 1
0 0
0
212 212
MItem MItem
27 31
..\..\source\include\list.h ..\..\SOURCE\INCLUDE\croutine.h
213 213
WString WString
3 3
@ -916,14 +916,14 @@ WVList
215 215
WVList WVList
0 0
204 208
1 1
1 1
0 0
216 216
MItem MItem
31 27
..\..\source\include\portable.h ..\..\source\include\list.h
217 217
WString WString
3 3
@ -934,14 +934,14 @@ WVList
219 219
WVList WVList
0 0
204 208
1 1
1 1
0 0
220 220
MItem MItem
31 31
..\..\source\include\projdefs.h ..\..\source\include\portable.h
221 221
WString WString
3 3
@ -952,14 +952,14 @@ WVList
223 223
WVList WVList
0 0
204 208
1 1
1 1
0 0
224 224
MItem MItem
28 31
..\..\source\include\queue.h ..\..\source\include\projdefs.h
225 225
WString WString
3 3
@ -970,14 +970,14 @@ WVList
227 227
WVList WVList
0 0
204 208
1 1
1 1
0 0
228 228
MItem MItem
29 28
..\..\source\include\semphr.h ..\..\source\include\queue.h
229 229
WString WString
3 3
@ -988,14 +988,14 @@ WVList
231 231
WVList WVList
0 0
204 208
1 1
1 1
0 0
232 232
MItem MItem
27 29
..\..\source\include\task.h ..\..\source\include\semphr.h
233 233
WString WString
3 3
@ -1006,14 +1006,14 @@ WVList
235 235
WVList WVList
0 0
204 208
1 1
1 1
0 0
236 236
MItem MItem
55 27
..\..\source\portable\owatcom\16bitdos\common\portasm.h ..\..\source\include\task.h
237 237
WString WString
3 3
@ -1024,14 +1024,14 @@ WVList
239 239
WVList WVList
0 0
204 208
1 1
1 1
0 0
240 240
MItem MItem
53 55
..\..\source\portable\owatcom\16bitdos\pc\portmacro.h ..\..\source\portable\owatcom\16bitdos\common\portasm.h
241 241
WString WString
3 3
@ -1042,14 +1042,14 @@ WVList
243 243
WVList WVList
0 0
204 208
1 1
1 1
0 0
244 244
MItem MItem
26 53
..\common\include\blockq.h ..\..\source\portable\owatcom\16bitdos\pc\portmacro.h
245 245
WString WString
3 3
@ -1060,14 +1060,14 @@ WVList
247 247
WVList WVList
0 0
204 208
1 1
1 1
0 0
248 248
MItem MItem
28 26
..\COMMON\INCLUDE\blocktim.h ..\common\include\blockq.h
249 249
WString WString
3 3
@ -1078,14 +1078,14 @@ WVList
251 251
WVList WVList
0 0
204 208
1 1
1 1
0 0
252 252
MItem MItem
27 28
..\common\include\comtest.h ..\COMMON\INCLUDE\blocktim.h
253 253
WString WString
3 3
@ -1096,14 +1096,14 @@ WVList
255 255
WVList WVList
0 0
204 208
1 1
1 1
0 0
256 256
MItem MItem
26 27
..\COMMON\INCLUDE\crhook.h ..\common\include\comtest.h
257 257
WString WString
3 3
@ -1114,14 +1114,14 @@ WVList
259 259
WVList WVList
0 0
204 208
1 1
1 1
0 0
260 260
MItem MItem
25 28
..\common\include\death.h ..\COMMON\INCLUDE\countsem.h
261 261
WString WString
3 3
@ -1132,14 +1132,14 @@ WVList
263 263
WVList WVList
0 0
204 208
1 1
1 1
0 0
264 264
MItem MItem
27 26
..\COMMON\INCLUDE\dynamic.h ..\COMMON\INCLUDE\crhook.h
265 265
WString WString
3 3
@ -1150,14 +1150,14 @@ WVList
267 267
WVList WVList
0 0
204 208
1 1
1 1
0 0
268 268
MItem MItem
26 25
..\common\include\fileio.h ..\common\include\death.h
269 269
WString WString
3 3
@ -1168,14 +1168,14 @@ WVList
271 271
WVList WVList
0 0
204 208
1 1
1 1
0 0
272 272
MItem MItem
25 27
..\common\include\flash.h ..\COMMON\INCLUDE\dynamic.h
273 273
WString WString
3 3
@ -1186,14 +1186,14 @@ WVList
275 275
WVList WVList
0 0
204 208
1 1
1 1
0 0
276 276
MItem MItem
24 26
..\common\include\flop.h ..\common\include\fileio.h
277 277
WString WString
3 3
@ -1204,14 +1204,14 @@ WVList
279 279
WVList WVList
0 0
204 208
1 1
1 1
0 0
280 280
MItem MItem
28 25
..\COMMON\INCLUDE\GenQTest.h ..\common\include\flash.h
281 281
WString WString
3 3
@ -1222,14 +1222,14 @@ WVList
283 283
WVList WVList
0 0
204 208
1 1
1 1
0 0
284 284
MItem MItem
27 24
..\common\include\partest.h ..\common\include\flop.h
285 285
WString WString
3 3
@ -1240,14 +1240,14 @@ WVList
287 287
WVList WVList
0 0
204 208
1 1
1 1
0 0
288 288
MItem MItem
25 28
..\common\include\pollq.h ..\COMMON\INCLUDE\GenQTest.h
289 289
WString WString
3 3
@ -1258,14 +1258,14 @@ WVList
291 291
WVList WVList
0 0
204 208
1 1
1 1
0 0
292 292
MItem MItem
25 27
..\common\include\print.h ..\common\include\partest.h
293 293
WString WString
3 3
@ -1276,14 +1276,14 @@ WVList
295 295
WVList WVList
0 0
204 208
1 1
1 1
0 0
296 296
MItem MItem
27 25
..\common\include\semtest.h ..\common\include\pollq.h
297 297
WString WString
3 3
@ -1294,14 +1294,14 @@ WVList
299 299
WVList WVList
0 0
204 208
1 1
1 1
0 0
300 300
MItem MItem
26 25
..\common\include\serial.h ..\common\include\print.h
301 301
WString WString
3 3
@ -1312,14 +1312,14 @@ WVList
303 303
WVList WVList
0 0
204 208
1 1
1 1
0 0
304 304
MItem MItem
16 27
FreeRTOSConfig.h ..\common\include\semtest.h
305 305
WString WString
3 3
@ -1330,7 +1330,43 @@ WVList
307 307
WVList WVList
0 0
204 208
1
1
0
308
MItem
26
..\common\include\serial.h
309
WString
3
NIL
310
WVList
0
311
WVList
0
208
1
1
0
312
MItem
16
FreeRTOSConfig.h
313
WString
3
NIL
314
WVList
0
315
WVList
0
208
1 1
1 1
0 0

View file

@ -4,10 +4,10 @@ projectIdent
VpeMain VpeMain
1 1
WRect WRect
0 6
0 9
7680 6229
9216 7197
2 2
MProject MProject
3 3
@ -31,7 +31,7 @@ WRect
0 0
0 0
7168 7168
8474 8270
0 0
0 0
9 9
@ -39,5 +39,5 @@ WFileName
12 12
rtosdemo.tgt rtosdemo.tgt
0 0
24 25
7 7

View file

@ -116,6 +116,10 @@
#define configUSE_MUTEXES 0 #define configUSE_MUTEXES 0
#endif #endif
#ifndef configUSE_COUNTING_SEMAPHORES
#define configUSE_COUNTING_SEMAPHORES 0
#endif
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
/* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism /* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism
within the mutex implementation so must be available if mutexes are used. */ within the mutex implementation so must be available if mutexes are used. */

View file

@ -1175,10 +1175,11 @@ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQue
signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ); signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
/* /*
* For internal use only. Use xSemaphoreCreateMutex() instead of calling * For internal use only. Use xSemaphoreCreateMutex() or
* this function directly. * xSemaphoreCreateCounting() instead of calling these functions directly.
*/ */
xQueueHandle xQueueCreateMutex( void ); xQueueHandle xQueueCreateMutex( void );
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -34,11 +34,11 @@
*************************************************************************** ***************************************************************************
*/ */
#include "queue.h"
#ifndef SEMAPHORE_H #ifndef SEMAPHORE_H
#define SEMAPHORE_H #define SEMAPHORE_H
#include "queue.h"
typedef xQueueHandle xSemaphoreHandle; typedef xQueueHandle xSemaphoreHandle;
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned portCHAR ) 1 ) #define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned portCHAR ) 1 )
@ -85,7 +85,7 @@ typedef xQueueHandle xSemaphoreHandle;
* \ingroup Semaphores * \ingroup Semaphores
*/ */
#define vSemaphoreCreateBinary( xSemaphore ) { \ #define vSemaphoreCreateBinary( xSemaphore ) { \
xSemaphore = xQueueCreate( ( unsigned portCHAR ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \ xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( xSemaphore != NULL ) \ if( xSemaphore != NULL ) \
{ \ { \
xSemaphoreGive( xSemaphore ); \ xSemaphoreGive( xSemaphore ); \
@ -341,6 +341,66 @@ typedef xQueueHandle xSemaphoreHandle;
*/ */
#define xSemaphoreCreateMutex() xQueueCreateMutex() #define xSemaphoreCreateMutex() xQueueCreateMutex()
/**
* semphr. h
* <pre>vSemaphoreCreateCounting( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE uxMaxCount )</pre>
*
* <i>Macro</i> that creates a counting semaphore by using the existing
* queue mechanism. The queue length is used as the maximum count. The data
* size is 0 as we don't want to actually store any data - we just want to
* know if the queue is empty or full.
*
* Counting semaphores are typically used for two things:
*
* 1) Counting events.
*
* In this usage scenario an event handler will 'give' a semphore each time
* an event occurs (incrementing the semaphore count value), and a handler
* task will 'take' a semaphore each time it processes an event
* (decrementing the semaphore count value). The count value is therefore
* the difference between the number of events that have occurred and the
* number that have been processed. In this case it is desirable for the
* initial count value to be zero.
*
* 2) Resource management.
*
* In this usage scenario the count value indicates the number of resources
* available. To obtain control of a resource a task must first obtain a
* semphoare - decrementing the semaphore count value. When the count value
* reaches zero there are no free resources. When a task finishes with the
* resource it 'gives' the semahore back - incrementing the semaphore count
* value. In this case it is desirable for the initial count value to be
* equal to the maximum count value, indicating that all resources are free.
*
* @param uxMaxCount The maximum count value that can be reached. When the
* semaphore reaches this value it can nolonger be 'given'.
* @param uxInitialCount
*
* @return Handle to the created semaphore. Should be of type xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
xSemaphoreHandle xSemaphore = NULL;
// Semaphore cannot be used before a call to vSemaphoreCreateCounting().
// This is a macro so pass the variable in directly.
vSemaphoreCreateBinary( xSemaphore, );
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
* \ingroup Semaphores
*/
#define xSemaphoreCreateCounting( uxCountValue, uxInitialCount ) xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount )
#endif /* SEMAPHORE_H */ #endif /* SEMAPHORE_H */

View file

@ -114,7 +114,7 @@ portSTACK_TYPE *pxOriginalTOS;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; *pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */ *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ *pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--; pxTopOfStack--;

View file

@ -34,49 +34,6 @@
*************************************************************************** ***************************************************************************
*/ */
/*
Changes from V1.01
+ More use of 8bit data types.
+ Function name prefixes changed where the data type returned has changed.
Changed from V2.0.0
+ Added the queue locking mechanism and make more use of the scheduler
suspension feature to minimise the time interrupts have to be disabled
when accessing a queue.
Changed from V2.2.0
+ Explicit use of 'signed' qualifier on portCHAR types added.
Changes from V3.0.0
+ API changes as described on the FreeRTOS.org WEB site.
Changes from V3.2.3
+ Added the queue functions that can be used from co-routines.
Changes from V4.0.5
+ Added a loop within xQueueSend() and xQueueReceive() to prevent the
functions exiting when a block time remains and the function has
not completed.
Changes from V4.1.2:
+ BUG FIX: Removed the call to prvIsQueueEmpty from within xQueueCRReceive
as it exited with interrupts enabled. Thanks Paul Katz.
Changes from V4.1.3:
+ Modified xQueueSend() and xQueueReceive() to handle the (very unlikely)
case whereby a task unblocking due to a temporal event can remove/send an
item from/to a queue when a higher priority task is still blocked on the
queue. This modification is a result of the SafeRTOS testing.
*/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -100,6 +57,11 @@ Changes from V4.1.3:
#define uxQueueType pcHead #define uxQueueType pcHead
#define queueQUEUE_IS_MUTEX NULL #define queueQUEUE_IS_MUTEX NULL
/* Semaphores do not actually store or copy data, so have an items size of
zero. */
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )
#define queueDONT_BLOCK ( ( portTickType ) 0 )
/* /*
* Definition of the queue used by the scheduler. * Definition of the queue used by the scheduler.
* Items are queued by copy, not reference. * Items are queued by copy, not reference.
@ -144,6 +106,7 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ); signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
xQueueHandle xQueueCreateMutex( void ); xQueueHandle xQueueCreateMutex( void );
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
#if configUSE_CO_ROUTINES == 1 #if configUSE_CO_ROUTINES == 1
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ); signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
@ -296,6 +259,25 @@ size_t xQueueSizeInBytes;
#endif /* configUSE_MUTEXES */ #endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if configUSE_COUNTING_SEMAPHORES == 1
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
{
xQueueHandle pxHandle;
pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );
if( pxHandle != NULL )
{
pxHandle->uxMessagesWaiting = uxInitialCount;
}
return pxHandle;
}
#endif /* configUSE_COUNTING_SEMAPHORES */
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
{ {
signed portBASE_TYPE xReturn = pdPASS; signed portBASE_TYPE xReturn = pdPASS;