aboutsummaryrefslogtreecommitdiffstats
path: root/src/FreeRTOS-Sim-master/Demo/Common/Full/semtest.c
diff options
context:
space:
mode:
authorMaximilien Cuony <maximilien@theglu.org>2016-05-31 21:58:17 +0200
committerMaximilien Cuony <maximilien@theglu.org>2016-05-31 21:58:17 +0200
commit9069fc127e4f73041fbd1f66e4506fcf12418315 (patch)
tree902aa478c6e9d47cde89eaa996b5f7f662070518 /src/FreeRTOS-Sim-master/Demo/Common/Full/semtest.c
parent4803231e214fbd19eab4ba2289583859ee07183f (diff)
downloadglutte-o-matic-9069fc127e4f73041fbd1f66e4506fcf12418315.tar.gz
glutte-o-matic-9069fc127e4f73041fbd1f66e4506fcf12418315.tar.bz2
glutte-o-matic-9069fc127e4f73041fbd1f66e4506fcf12418315.zip
Simuator - Work in progress
Diffstat (limited to 'src/FreeRTOS-Sim-master/Demo/Common/Full/semtest.c')
-rw-r--r--src/FreeRTOS-Sim-master/Demo/Common/Full/semtest.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/src/FreeRTOS-Sim-master/Demo/Common/Full/semtest.c b/src/FreeRTOS-Sim-master/Demo/Common/Full/semtest.c
new file mode 100644
index 0000000..bcd1e9a
--- /dev/null
+++ b/src/FreeRTOS-Sim-master/Demo/Common/Full/semtest.c
@@ -0,0 +1,327 @@
+/*
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
+
+ ***************************************************************************
+ >>! NOTE: The modification to the GPL is included to allow you to !<<
+ >>! distribute a combined work that includes FreeRTOS without being !<<
+ >>! obliged to provide the source code for proprietary components !<<
+ >>! outside of the FreeRTOS kernel. !<<
+ ***************************************************************************
+
+ FreeRTOS 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. Full license text is available on the following
+ link: http://www.freertos.org/a00114.html
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that is more than just the market leader, it *
+ * is the industry's de facto standard. *
+ * *
+ * Help yourself get started quickly while simultaneously helping *
+ * to support the FreeRTOS project by purchasing a FreeRTOS *
+ * tutorial book, reference manual, or both: *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
+ the FAQ page "My application does not run, what could be wrong?". Have you
+ defined configASSERT()?
+
+ http://www.FreeRTOS.org/support - In return for receiving this top quality
+ embedded software for free we request you assist our global community by
+ participating in the support forum.
+
+ http://www.FreeRTOS.org/training - Investing in training allows your team to
+ be as productive as possible as early as possible. Now you can receive
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+ Ltd, and the world's leading authority on the world's leading RTOS.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and commercial middleware.
+
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+ engineered and independently SIL3 certified version for use in safety and
+ mission critical applications that require provable dependability.
+
+ 1 tab == 4 spaces!
+*/
+
+/**
+ * Creates two sets of two tasks. The tasks within a set share a variable, access
+ * to which is guarded by a semaphore.
+ *
+ * Each task starts by attempting to obtain the semaphore. On obtaining a
+ * semaphore a task checks to ensure that the guarded variable has an expected
+ * value. It then clears the variable to zero before counting it back up to the
+ * expected value in increments of 1. After each increment the variable is checked
+ * to ensure it contains the value to which it was just set. When the starting
+ * value is again reached the task releases the semaphore giving the other task in
+ * the set a chance to do exactly the same thing. The starting value is high
+ * enough to ensure that a tick is likely to occur during the incrementing loop.
+ *
+ * An error is flagged if at any time during the process a shared variable is
+ * found to have a value other than that expected. Such an occurrence would
+ * suggest an error in the mutual exclusion mechanism by which access to the
+ * variable is restricted.
+ *
+ * The first set of two tasks poll their semaphore. The second set use blocking
+ * calls.
+ *
+ * \page SemTestC semtest.c
+ * \ingroup DemoFiles
+ * <HR>
+ */
+
+/*
+Changes from V1.2.0:
+
+ + The tasks that operate at the idle priority now use a lower expected
+ count than those running at a higher priority. This prevents the low
+ priority tasks from signaling an error because they have not been
+ scheduled enough time for each of them to count the shared variable to
+ the high value.
+
+Changes from V2.0.0
+
+ + Delay periods are now specified using variables and constants of
+ TickType_t rather than unsigned long.
+
+Changes from V2.1.1
+
+ + The stack size now uses configMINIMAL_STACK_SIZE.
+ + String constants made file scope to decrease stack depth on 8051 port.
+*/
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* Demo app include files. */
+#include "semtest.h"
+#include "print.h"
+
+/* The value to which the shared variables are counted. */
+#define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xfff )
+#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xff )
+
+#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE
+
+#define semtstNUM_TASKS ( 4 )
+
+#define semtstDELAY_FACTOR ( ( TickType_t ) 10 )
+
+/* The task function as described at the top of the file. */
+static void prvSemaphoreTest( void *pvParameters );
+
+/* Structure used to pass parameters to each task. */
+typedef struct SEMAPHORE_PARAMETERS
+{
+ SemaphoreHandle_t xSemaphore;
+ volatile unsigned long *pulSharedVariable;
+ TickType_t xBlockTime;
+} xSemaphoreParameters;
+
+/* Variables used to check that all the tasks are still running without errors. */
+static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 };
+static volatile short sNextCheckVariable = 0;
+
+/* Strings to print if USE_STDIO is defined. */
+const char * const pcPollingSemaphoreTaskError = "Guarded shared variable in unexpected state.\r\n";
+const char * const pcSemaphoreTaskStart = "Guarded shared variable task started.\r\n";
+
+/*-----------------------------------------------------------*/
+
+void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority )
+{
+xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters;
+const TickType_t xBlockTime = ( TickType_t ) 100;
+
+ /* Create the structure used to pass parameters to the first two tasks. */
+ pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
+
+ if( pxFirstSemaphoreParameters != NULL )
+ {
+ /* Create the semaphore used by the first two tasks. */
+ vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore );
+
+ if( pxFirstSemaphoreParameters->xSemaphore != NULL )
+ {
+ /* Create the variable which is to be shared by the first two tasks. */
+ pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
+
+ /* Initialise the share variable to the value the tasks expect. */
+ *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE;
+
+ /* The first two tasks do not block on semaphore calls. */
+ pxFirstSemaphoreParameters->xBlockTime = ( TickType_t ) 0;
+
+ /* Spawn the first two tasks. As they poll they operate at the idle priority. */
+ xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
+ xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
+ }
+ }
+
+ /* Do exactly the same to create the second set of tasks, only this time
+ provide a block time for the semaphore calls. */
+ pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
+ if( pxSecondSemaphoreParameters != NULL )
+ {
+ vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore );
+
+ if( pxSecondSemaphoreParameters->xSemaphore != NULL )
+ {
+ pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
+ *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE;
+ pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS;
+
+ xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
+ xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvSemaphoreTest( void *pvParameters )
+{
+xSemaphoreParameters *pxParameters;
+volatile unsigned long *pulSharedVariable, ulExpectedValue;
+unsigned long ulCounter;
+short sError = pdFALSE, sCheckVariableToUse;
+
+ /* See which check variable to use. sNextCheckVariable is not semaphore
+ protected! */
+ portENTER_CRITICAL();
+ sCheckVariableToUse = sNextCheckVariable;
+ sNextCheckVariable++;
+ portEXIT_CRITICAL();
+
+ /* Queue a message for printing to say the task has started. */
+ vPrintDisplayMessage( &pcSemaphoreTaskStart );
+
+ /* A structure is passed in as the parameter. This contains the shared
+ variable being guarded. */
+ pxParameters = ( xSemaphoreParameters * ) pvParameters;
+ pulSharedVariable = pxParameters->pulSharedVariable;
+
+ /* If we are blocking we use a much higher count to ensure loads of context
+ switches occur during the count. */
+ if( pxParameters->xBlockTime > ( TickType_t ) 0 )
+ {
+ ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;
+ }
+ else
+ {
+ ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;
+ }
+
+ for( ;; )
+ {
+ /* Try to obtain the semaphore. */
+ if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS )
+ {
+ /* We have the semaphore and so expect any other tasks using the
+ shared variable to have left it in the state we expect to find
+ it. */
+ if( *pulSharedVariable != ulExpectedValue )
+ {
+ vPrintDisplayMessage( &pcPollingSemaphoreTaskError );
+ sError = pdTRUE;
+ }
+
+ /* Clear the variable, then count it back up to the expected value
+ before releasing the semaphore. Would expect a context switch or
+ two during this time. */
+ for( ulCounter = ( unsigned long ) 0; ulCounter <= ulExpectedValue; ulCounter++ )
+ {
+ *pulSharedVariable = ulCounter;
+ if( *pulSharedVariable != ulCounter )
+ {
+ if( sError == pdFALSE )
+ {
+ vPrintDisplayMessage( &pcPollingSemaphoreTaskError );
+ }
+ sError = pdTRUE;
+ }
+ }
+
+ /* Release the semaphore, and if no errors have occurred increment the check
+ variable. */
+ if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE )
+ {
+ vPrintDisplayMessage( &pcPollingSemaphoreTaskError );
+ sError = pdTRUE;
+ }
+
+ if( sError == pdFALSE )
+ {
+ if( sCheckVariableToUse < semtstNUM_TASKS )
+ {
+ ( sCheckVariables[ sCheckVariableToUse ] )++;
+ }
+ }
+
+ /* If we have a block time then we are running at a priority higher
+ than the idle priority. This task takes a long time to complete
+ a cycle (deliberately so to test the guarding) so will be starving
+ out lower priority tasks. Block for some time to allow give lower
+ priority tasks some processor time. */
+ vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR );
+ }
+ else
+ {
+ if( pxParameters->xBlockTime == ( TickType_t ) 0 )
+ {
+ /* We have not got the semaphore yet, so no point using the
+ processor. We are not blocking when attempting to obtain the
+ semaphore. */
+ taskYIELD();
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreSemaphoreTasksStillRunning( void )
+{
+static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 };
+portBASE_TYPE xTask, xReturn = pdTRUE;
+
+ for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ )
+ {
+ if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] )
+ {
+ xReturn = pdFALSE;
+ }
+
+ sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ];
+ }
+
+ return xReturn;
+}
+
+