00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #include <stdlib.h>
00079
00080
00081 #include "FreeRTOS.h"
00082 #include "task.h"
00083 #include "semphr.h"
00084
00085
00086 #include "semtest.h"
00087
00088
00089 #define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xfff )
00090 #define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xff )
00091
00092 #define semtstSTACK_SIZE configMINIMAL_STACK_SIZE
00093
00094 #define semtstNUM_TASKS ( 4 )
00095
00096 #define semtstDELAY_FACTOR ( ( portTickType ) 10 )
00097
00098
00099 static portTASK_FUNCTION_PROTO( prvSemaphoreTest, pvParameters );
00100
00101
00102 typedef struct SEMAPHORE_PARAMETERS
00103 {
00104 xSemaphoreHandle xSemaphore;
00105 volatile unsigned long *pulSharedVariable;
00106 portTickType xBlockTime;
00107 } xSemaphoreParameters;
00108
00109
00110 static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 };
00111 static volatile short sNextCheckVariable = 0;
00112
00113
00114
00115 void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority )
00116 {
00117 xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters;
00118 const portTickType xBlockTime = ( portTickType ) 100;
00119
00120
00121 pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
00122
00123 if( pxFirstSemaphoreParameters != NULL )
00124 {
00125
00126 vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore );
00127
00128 if( pxFirstSemaphoreParameters->xSemaphore != NULL )
00129 {
00130
00131 pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
00132
00133
00134 *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE;
00135
00136
00137 pxFirstSemaphoreParameters->xBlockTime = ( portTickType ) 0;
00138
00139
00140 xTaskCreate( prvSemaphoreTest, ( signed char * ) "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
00141 xTaskCreate( prvSemaphoreTest, ( signed char * ) "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
00142 }
00143 }
00144
00145
00146
00147 pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
00148 if( pxSecondSemaphoreParameters != NULL )
00149 {
00150 vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore );
00151
00152 if( pxSecondSemaphoreParameters->xSemaphore != NULL )
00153 {
00154 pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
00155 *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE;
00156 pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_RATE_MS;
00157
00158 xTaskCreate( prvSemaphoreTest, ( signed char * ) "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL );
00159 xTaskCreate( prvSemaphoreTest, ( signed char * ) "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL );
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 vQueueAddToRegistry( ( xQueueHandle ) pxFirstSemaphoreParameters->xSemaphore, ( signed char * ) "Counting_Sem_1" );
00170 vQueueAddToRegistry( ( xQueueHandle ) pxSecondSemaphoreParameters->xSemaphore, ( signed char * ) "Counting_Sem_2" );
00171 }
00172
00173
00174 static portTASK_FUNCTION( prvSemaphoreTest, pvParameters )
00175 {
00176 xSemaphoreParameters *pxParameters;
00177 volatile unsigned long *pulSharedVariable, ulExpectedValue;
00178 unsigned long ulCounter;
00179 short sError = pdFALSE, sCheckVariableToUse;
00180
00181
00182
00183 portENTER_CRITICAL();
00184 sCheckVariableToUse = sNextCheckVariable;
00185 sNextCheckVariable++;
00186 portEXIT_CRITICAL();
00187
00188
00189
00190 pxParameters = ( xSemaphoreParameters * ) pvParameters;
00191 pulSharedVariable = pxParameters->pulSharedVariable;
00192
00193
00194
00195 if( pxParameters->xBlockTime > ( portTickType ) 0 )
00196 {
00197 ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;
00198 }
00199 else
00200 {
00201 ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;
00202 }
00203
00204 for( ;; )
00205 {
00206
00207 if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS )
00208 {
00209
00210
00211
00212 if( *pulSharedVariable != ulExpectedValue )
00213 {
00214 sError = pdTRUE;
00215 }
00216
00217
00218
00219
00220 for( ulCounter = ( unsigned long ) 0; ulCounter <= ulExpectedValue; ulCounter++ )
00221 {
00222 *pulSharedVariable = ulCounter;
00223 if( *pulSharedVariable != ulCounter )
00224 {
00225 sError = pdTRUE;
00226 }
00227 }
00228
00229
00230
00231 if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE )
00232 {
00233 sError = pdTRUE;
00234 }
00235
00236 if( sError == pdFALSE )
00237 {
00238 if( sCheckVariableToUse < semtstNUM_TASKS )
00239 {
00240 ( sCheckVariables[ sCheckVariableToUse ] )++;
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249 vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR );
00250 }
00251 else
00252 {
00253 if( pxParameters->xBlockTime == ( portTickType ) 0 )
00254 {
00255
00256
00257
00258 taskYIELD();
00259 }
00260 }
00261 }
00262 }
00263
00264
00265
00266 portBASE_TYPE xAreSemaphoreTasksStillRunning( void )
00267 {
00268 static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 };
00269 portBASE_TYPE xTask, xReturn = pdTRUE;
00270
00271 for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ )
00272 {
00273 if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] )
00274 {
00275 xReturn = pdFALSE;
00276 }
00277
00278 sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ];
00279 }
00280
00281 return xReturn;
00282 }
00283
00284