Counting semaphore demo added.

pull/4/head
Richard Barry 17 years ago
parent a8eabeabbb
commit d69d2df8d6

@ -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;
}

@ -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

@ -50,18 +50,19 @@
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 256 ) /* This can be made smaller if required. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 1
#define configIDLE_SHOULD_YIELD 1
#define configUSE_CO_ROUTINES 1
#define configUSE_MUTEXES 1
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 256 ) /* This can be made smaller if required. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 1
#define configIDLE_SHOULD_YIELD 1
#define configUSE_CO_ROUTINES 1
#define configUSE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 10 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

@ -65,38 +65,6 @@
* <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 <conio.h>
#include "FreeRTOS.h"
@ -122,6 +90,7 @@ Changes from V3.2.4
#include "blocktim.h"
#include "GenQTest.h"
#include "QPeek.h"
#include "countsem.h"
/* Priority definitions for the tasks in the demo application. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
@ -185,6 +154,7 @@ portSHORT main( void )
vStartDynamicPriorityTasks();
vStartMultiEventTasks();
vStartQueuePeekTasks();
vStartCountingSemaphoreTasks();
/* Create the "Print" task as described at the top of the file. */
xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL );
@ -408,6 +378,12 @@ static portSHORT sErrorHasOccurred = pdFALSE;
sErrorHasOccurred = pdTRUE;
}
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
vDisplayMessage( "Error in counting semaphore demo task!\r\n" );
sErrorHasOccurred = pdTRUE;
}
if( sErrorHasOccurred == pdFALSE )
{
vDisplayMessage( "OK " );

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

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

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

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

@ -34,11 +34,11 @@
***************************************************************************
*/
#include "queue.h"
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include "queue.h"
typedef xQueueHandle xSemaphoreHandle;
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned portCHAR ) 1 )
@ -84,12 +84,12 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores
*/
#define vSemaphoreCreateBinary( xSemaphore ) { \
xSemaphore = xQueueCreate( ( unsigned portCHAR ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( xSemaphore != NULL ) \
{ \
xSemaphoreGive( xSemaphore ); \
} \
#define vSemaphoreCreateBinary( xSemaphore ) { \
xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( xSemaphore != NULL ) \
{ \
xSemaphoreGive( xSemaphore ); \
} \
}
/**
@ -341,6 +341,66 @@ typedef xQueueHandle xSemaphoreHandle;
*/
#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 */

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

@ -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 <string.h>
#include "FreeRTOS.h"
@ -100,6 +57,11 @@ Changes from V4.1.3:
#define uxQueueType pcHead
#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.
* 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 xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
xQueueHandle xQueueCreateMutex( void );
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
#if configUSE_CO_ROUTINES == 1
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
@ -296,6 +259,25 @@ size_t xQueueSizeInBytes;
#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 xReturn = pdPASS;

Loading…
Cancel
Save