Please see my note book http://mbed.org/users/kenjiArai/notebook/freertos-on-mbed-board-with-mbed-cloud-ide--never-/

This is too old.
Below is another FreeRTOS on mbed.
http://developer.mbed.org/users/rgrover1/code/FreeRTOS/
I don't know it works well or not.
I have not evaluated it.

Committer:
kenjiArai
Date:
Sat Jan 01 11:17:45 2011 +0000
Revision:
0:d4960fcea8ff

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:d4960fcea8ff 1 /*
kenjiArai 0:d4960fcea8ff 2 FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
kenjiArai 0:d4960fcea8ff 3
kenjiArai 0:d4960fcea8ff 4 ***************************************************************************
kenjiArai 0:d4960fcea8ff 5 * *
kenjiArai 0:d4960fcea8ff 6 * If you are: *
kenjiArai 0:d4960fcea8ff 7 * *
kenjiArai 0:d4960fcea8ff 8 * + New to FreeRTOS, *
kenjiArai 0:d4960fcea8ff 9 * + Wanting to learn FreeRTOS or multitasking in general quickly *
kenjiArai 0:d4960fcea8ff 10 * + Looking for basic training, *
kenjiArai 0:d4960fcea8ff 11 * + Wanting to improve your FreeRTOS skills and productivity *
kenjiArai 0:d4960fcea8ff 12 * *
kenjiArai 0:d4960fcea8ff 13 * then take a look at the FreeRTOS eBook *
kenjiArai 0:d4960fcea8ff 14 * *
kenjiArai 0:d4960fcea8ff 15 * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
kenjiArai 0:d4960fcea8ff 16 * http://www.FreeRTOS.org/Documentation *
kenjiArai 0:d4960fcea8ff 17 * *
kenjiArai 0:d4960fcea8ff 18 * A pdf reference manual is also available. Both are usually delivered *
kenjiArai 0:d4960fcea8ff 19 * to your inbox within 20 minutes to two hours when purchased between 8am *
kenjiArai 0:d4960fcea8ff 20 * and 8pm GMT (although please allow up to 24 hours in case of *
kenjiArai 0:d4960fcea8ff 21 * exceptional circumstances). Thank you for your support! *
kenjiArai 0:d4960fcea8ff 22 * *
kenjiArai 0:d4960fcea8ff 23 ***************************************************************************
kenjiArai 0:d4960fcea8ff 24
kenjiArai 0:d4960fcea8ff 25 This file is part of the FreeRTOS distribution.
kenjiArai 0:d4960fcea8ff 26
kenjiArai 0:d4960fcea8ff 27 FreeRTOS is free software; you can redistribute it and/or modify it under
kenjiArai 0:d4960fcea8ff 28 the terms of the GNU General Public License (version 2) as published by the
kenjiArai 0:d4960fcea8ff 29 Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
kenjiArai 0:d4960fcea8ff 30 ***NOTE*** The exception to the GPL is included to allow you to distribute
kenjiArai 0:d4960fcea8ff 31 a combined work that includes FreeRTOS without being obliged to provide the
kenjiArai 0:d4960fcea8ff 32 source code for proprietary components outside of the FreeRTOS kernel.
kenjiArai 0:d4960fcea8ff 33 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
kenjiArai 0:d4960fcea8ff 34 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kenjiArai 0:d4960fcea8ff 35 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kenjiArai 0:d4960fcea8ff 36 more details. You should have received a copy of the GNU General Public
kenjiArai 0:d4960fcea8ff 37 License and the FreeRTOS license exception along with FreeRTOS; if not it
kenjiArai 0:d4960fcea8ff 38 can be viewed here: http://www.freertos.org/a00114.html and also obtained
kenjiArai 0:d4960fcea8ff 39 by writing to Richard Barry, contact details for whom are available on the
kenjiArai 0:d4960fcea8ff 40 FreeRTOS WEB site.
kenjiArai 0:d4960fcea8ff 41
kenjiArai 0:d4960fcea8ff 42 1 tab == 4 spaces!
kenjiArai 0:d4960fcea8ff 43
kenjiArai 0:d4960fcea8ff 44 http://www.FreeRTOS.org - Documentation, latest information, license and
kenjiArai 0:d4960fcea8ff 45 contact details.
kenjiArai 0:d4960fcea8ff 46
kenjiArai 0:d4960fcea8ff 47 http://www.SafeRTOS.com - A version that is certified for use in safety
kenjiArai 0:d4960fcea8ff 48 critical systems.
kenjiArai 0:d4960fcea8ff 49
kenjiArai 0:d4960fcea8ff 50 http://www.OpenRTOS.com - Commercial support, development, porting,
kenjiArai 0:d4960fcea8ff 51 licensing and training services.
kenjiArai 0:d4960fcea8ff 52 */
kenjiArai 0:d4960fcea8ff 53
kenjiArai 0:d4960fcea8ff 54
kenjiArai 0:d4960fcea8ff 55 /*
kenjiArai 0:d4960fcea8ff 56 * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 -
kenjiArai 0:d4960fcea8ff 57 * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and
kenjiArai 0:d4960fcea8ff 58 * mutex behaviour.
kenjiArai 0:d4960fcea8ff 59 *
kenjiArai 0:d4960fcea8ff 60 * See the comments above the prvSendFrontAndBackTest() and
kenjiArai 0:d4960fcea8ff 61 * prvLowPriorityMutexTask() prototypes below for more information.
kenjiArai 0:d4960fcea8ff 62 */
kenjiArai 0:d4960fcea8ff 63
kenjiArai 0:d4960fcea8ff 64
kenjiArai 0:d4960fcea8ff 65 #include <stdlib.h>
kenjiArai 0:d4960fcea8ff 66
kenjiArai 0:d4960fcea8ff 67 /* Scheduler include files. */
kenjiArai 0:d4960fcea8ff 68 #include "FreeRTOS.h"
kenjiArai 0:d4960fcea8ff 69 #include "task.h"
kenjiArai 0:d4960fcea8ff 70 #include "queue.h"
kenjiArai 0:d4960fcea8ff 71 #include "semphr.h"
kenjiArai 0:d4960fcea8ff 72
kenjiArai 0:d4960fcea8ff 73 /* Demo program include files. */
kenjiArai 0:d4960fcea8ff 74 #include "GenQTest.h"
kenjiArai 0:d4960fcea8ff 75
kenjiArai 0:d4960fcea8ff 76 #define genqQUEUE_LENGTH ( 5 )
kenjiArai 0:d4960fcea8ff 77 #define genqNO_BLOCK ( 0 )
kenjiArai 0:d4960fcea8ff 78
kenjiArai 0:d4960fcea8ff 79 #define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY )
kenjiArai 0:d4960fcea8ff 80 #define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
kenjiArai 0:d4960fcea8ff 81 #define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 )
kenjiArai 0:d4960fcea8ff 82 #define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 )
kenjiArai 0:d4960fcea8ff 83
kenjiArai 0:d4960fcea8ff 84 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 85
kenjiArai 0:d4960fcea8ff 86 /*
kenjiArai 0:d4960fcea8ff 87 * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack()
kenjiArai 0:d4960fcea8ff 88 * macros by using both to fill a queue, then reading from the queue to
kenjiArai 0:d4960fcea8ff 89 * check the resultant queue order is as expected. Queue data is also
kenjiArai 0:d4960fcea8ff 90 * peeked.
kenjiArai 0:d4960fcea8ff 91 */
kenjiArai 0:d4960fcea8ff 92 static void prvSendFrontAndBackTest( void *pvParameters );
kenjiArai 0:d4960fcea8ff 93
kenjiArai 0:d4960fcea8ff 94 /*
kenjiArai 0:d4960fcea8ff 95 * The following three tasks are used to demonstrate the mutex behaviour.
kenjiArai 0:d4960fcea8ff 96 * Each task is given a different priority to demonstrate the priority
kenjiArai 0:d4960fcea8ff 97 * inheritance mechanism.
kenjiArai 0:d4960fcea8ff 98 *
kenjiArai 0:d4960fcea8ff 99 * The low priority task obtains a mutex. After this a high priority task
kenjiArai 0:d4960fcea8ff 100 * attempts to obtain the same mutex, causing its priority to be inherited
kenjiArai 0:d4960fcea8ff 101 * by the low priority task. The task with the inherited high priority then
kenjiArai 0:d4960fcea8ff 102 * resumes a medium priority task to ensure it is not blocked by the medium
kenjiArai 0:d4960fcea8ff 103 * priority task while it holds the inherited high priority. Once the mutex
kenjiArai 0:d4960fcea8ff 104 * is returned the task with the inherited priority returns to its original
kenjiArai 0:d4960fcea8ff 105 * low priority, and is therefore immediately preempted by first the high
kenjiArai 0:d4960fcea8ff 106 * priority task and then the medium prioroity task before it can continue.
kenjiArai 0:d4960fcea8ff 107 */
kenjiArai 0:d4960fcea8ff 108 static void prvLowPriorityMutexTask( void *pvParameters );
kenjiArai 0:d4960fcea8ff 109 static void prvMediumPriorityMutexTask( void *pvParameters );
kenjiArai 0:d4960fcea8ff 110 static void prvHighPriorityMutexTask( void *pvParameters );
kenjiArai 0:d4960fcea8ff 111
kenjiArai 0:d4960fcea8ff 112 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 113
kenjiArai 0:d4960fcea8ff 114 /* Flag that will be latched to pdTRUE should any unexpected behaviour be
kenjiArai 0:d4960fcea8ff 115 detected in any of the tasks. */
kenjiArai 0:d4960fcea8ff 116 static portBASE_TYPE xErrorDetected = pdFALSE;
kenjiArai 0:d4960fcea8ff 117
kenjiArai 0:d4960fcea8ff 118 /* Counters that are incremented on each cycle of a test. This is used to
kenjiArai 0:d4960fcea8ff 119 detect a stalled task - a test that is no longer running. */
kenjiArai 0:d4960fcea8ff 120 static volatile unsigned portLONG ulLoopCounter = 0;
kenjiArai 0:d4960fcea8ff 121 static volatile unsigned portLONG ulLoopCounter2 = 0;
kenjiArai 0:d4960fcea8ff 122
kenjiArai 0:d4960fcea8ff 123 /* The variable that is guarded by the mutex in the mutex demo tasks. */
kenjiArai 0:d4960fcea8ff 124 static volatile unsigned portLONG ulGuardedVariable = 0;
kenjiArai 0:d4960fcea8ff 125
kenjiArai 0:d4960fcea8ff 126 /* Handles used in the mutext test to suspend and resume the high and medium
kenjiArai 0:d4960fcea8ff 127 priority mutex test tasks. */
kenjiArai 0:d4960fcea8ff 128 static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;
kenjiArai 0:d4960fcea8ff 129
kenjiArai 0:d4960fcea8ff 130 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 131
kenjiArai 0:d4960fcea8ff 132 void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority )
kenjiArai 0:d4960fcea8ff 133 {
kenjiArai 0:d4960fcea8ff 134 xQueueHandle xQueue;
kenjiArai 0:d4960fcea8ff 135 xSemaphoreHandle xMutex;
kenjiArai 0:d4960fcea8ff 136
kenjiArai 0:d4960fcea8ff 137 /* Create the queue that we are going to use for the
kenjiArai 0:d4960fcea8ff 138 prvSendFrontAndBackTest demo. */
kenjiArai 0:d4960fcea8ff 139 xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) );
kenjiArai 0:d4960fcea8ff 140
kenjiArai 0:d4960fcea8ff 141 /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
kenjiArai 0:d4960fcea8ff 142 in use. The queue registry is provided as a means for kernel aware
kenjiArai 0:d4960fcea8ff 143 debuggers to locate queues and has no purpose if a kernel aware debugger
kenjiArai 0:d4960fcea8ff 144 is not being used. The call to vQueueAddToRegistry() will be removed
kenjiArai 0:d4960fcea8ff 145 by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
kenjiArai 0:d4960fcea8ff 146 defined to be less than 1. */
kenjiArai 0:d4960fcea8ff 147 vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "Gen_Queue_Test" );
kenjiArai 0:d4960fcea8ff 148
kenjiArai 0:d4960fcea8ff 149 /* Create the demo task and pass it the queue just created. We are
kenjiArai 0:d4960fcea8ff 150 passing the queue handle by value so it does not matter that it is
kenjiArai 0:d4960fcea8ff 151 declared on the stack here. */
kenjiArai 0:d4960fcea8ff 152 xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * )"GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );
kenjiArai 0:d4960fcea8ff 153
kenjiArai 0:d4960fcea8ff 154 /* Create the mutex used by the prvMutexTest task. */
kenjiArai 0:d4960fcea8ff 155 xMutex = xSemaphoreCreateMutex();
kenjiArai 0:d4960fcea8ff 156
kenjiArai 0:d4960fcea8ff 157 /* vQueueAddToRegistry() adds the mutex to the registry, if one is
kenjiArai 0:d4960fcea8ff 158 in use. The registry is provided as a means for kernel aware
kenjiArai 0:d4960fcea8ff 159 debuggers to locate mutexes and has no purpose if a kernel aware debugger
kenjiArai 0:d4960fcea8ff 160 is not being used. The call to vQueueAddToRegistry() will be removed
kenjiArai 0:d4960fcea8ff 161 by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
kenjiArai 0:d4960fcea8ff 162 defined to be less than 1. */
kenjiArai 0:d4960fcea8ff 163 vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Gen_Queue_Mutex" );
kenjiArai 0:d4960fcea8ff 164
kenjiArai 0:d4960fcea8ff 165 /* Create the mutex demo tasks and pass it the mutex just created. We are
kenjiArai 0:d4960fcea8ff 166 passing the mutex handle by value so it does not matter that it is declared
kenjiArai 0:d4960fcea8ff 167 on the stack here. */
kenjiArai 0:d4960fcea8ff 168 xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * )"MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
kenjiArai 0:d4960fcea8ff 169 xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * )"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
kenjiArai 0:d4960fcea8ff 170 xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * )"MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
kenjiArai 0:d4960fcea8ff 171 }
kenjiArai 0:d4960fcea8ff 172 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 173
kenjiArai 0:d4960fcea8ff 174 static void prvSendFrontAndBackTest( void *pvParameters )
kenjiArai 0:d4960fcea8ff 175 {
kenjiArai 0:d4960fcea8ff 176 unsigned portLONG ulData, ulData2;
kenjiArai 0:d4960fcea8ff 177 xQueueHandle xQueue;
kenjiArai 0:d4960fcea8ff 178
kenjiArai 0:d4960fcea8ff 179 #ifdef USE_STDIO
kenjiArai 0:d4960fcea8ff 180 void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
kenjiArai 0:d4960fcea8ff 181
kenjiArai 0:d4960fcea8ff 182 const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n";
kenjiArai 0:d4960fcea8ff 183
kenjiArai 0:d4960fcea8ff 184 /* Queue a message for printing to say the task has started. */
kenjiArai 0:d4960fcea8ff 185 vPrintDisplayMessage( &pcTaskStartMsg );
kenjiArai 0:d4960fcea8ff 186 #endif
kenjiArai 0:d4960fcea8ff 187
kenjiArai 0:d4960fcea8ff 188 xQueue = ( xQueueHandle ) pvParameters;
kenjiArai 0:d4960fcea8ff 189
kenjiArai 0:d4960fcea8ff 190 for( ;; )
kenjiArai 0:d4960fcea8ff 191 {
kenjiArai 0:d4960fcea8ff 192 /* The queue is empty, so sending an item to the back of the queue
kenjiArai 0:d4960fcea8ff 193 should have the same efect as sending it to the front of the queue.
kenjiArai 0:d4960fcea8ff 194
kenjiArai 0:d4960fcea8ff 195 First send to the front and check everything is as expected. */
kenjiArai 0:d4960fcea8ff 196 xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
kenjiArai 0:d4960fcea8ff 197
kenjiArai 0:d4960fcea8ff 198 if( uxQueueMessagesWaiting( xQueue ) != 1 )
kenjiArai 0:d4960fcea8ff 199 {
kenjiArai 0:d4960fcea8ff 200 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 201 }
kenjiArai 0:d4960fcea8ff 202
kenjiArai 0:d4960fcea8ff 203 if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 204 {
kenjiArai 0:d4960fcea8ff 205 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 206 }
kenjiArai 0:d4960fcea8ff 207
kenjiArai 0:d4960fcea8ff 208 /* The data we sent to the queue should equal the data we just received
kenjiArai 0:d4960fcea8ff 209 from the queue. */
kenjiArai 0:d4960fcea8ff 210 if( ulLoopCounter != ulData )
kenjiArai 0:d4960fcea8ff 211 {
kenjiArai 0:d4960fcea8ff 212 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 213 }
kenjiArai 0:d4960fcea8ff 214
kenjiArai 0:d4960fcea8ff 215 /* Then do the same, sending the data to the back, checking everything
kenjiArai 0:d4960fcea8ff 216 is as expected. */
kenjiArai 0:d4960fcea8ff 217 if( uxQueueMessagesWaiting( xQueue ) != 0 )
kenjiArai 0:d4960fcea8ff 218 {
kenjiArai 0:d4960fcea8ff 219 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 220 }
kenjiArai 0:d4960fcea8ff 221
kenjiArai 0:d4960fcea8ff 222 xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
kenjiArai 0:d4960fcea8ff 223
kenjiArai 0:d4960fcea8ff 224 if( uxQueueMessagesWaiting( xQueue ) != 1 )
kenjiArai 0:d4960fcea8ff 225 {
kenjiArai 0:d4960fcea8ff 226 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 227 }
kenjiArai 0:d4960fcea8ff 228
kenjiArai 0:d4960fcea8ff 229 if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 230 {
kenjiArai 0:d4960fcea8ff 231 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 232 }
kenjiArai 0:d4960fcea8ff 233
kenjiArai 0:d4960fcea8ff 234 if( uxQueueMessagesWaiting( xQueue ) != 0 )
kenjiArai 0:d4960fcea8ff 235 {
kenjiArai 0:d4960fcea8ff 236 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 237 }
kenjiArai 0:d4960fcea8ff 238
kenjiArai 0:d4960fcea8ff 239 /* The data we sent to the queue should equal the data we just received
kenjiArai 0:d4960fcea8ff 240 from the queue. */
kenjiArai 0:d4960fcea8ff 241 if( ulLoopCounter != ulData )
kenjiArai 0:d4960fcea8ff 242 {
kenjiArai 0:d4960fcea8ff 243 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 244 }
kenjiArai 0:d4960fcea8ff 245
kenjiArai 0:d4960fcea8ff 246 #if configUSE_PREEMPTION == 0
kenjiArai 0:d4960fcea8ff 247 taskYIELD();
kenjiArai 0:d4960fcea8ff 248 #endif
kenjiArai 0:d4960fcea8ff 249
kenjiArai 0:d4960fcea8ff 250
kenjiArai 0:d4960fcea8ff 251
kenjiArai 0:d4960fcea8ff 252 /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */
kenjiArai 0:d4960fcea8ff 253 for( ulData = 2; ulData < 5; ulData++ )
kenjiArai 0:d4960fcea8ff 254 {
kenjiArai 0:d4960fcea8ff 255 xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );
kenjiArai 0:d4960fcea8ff 256 }
kenjiArai 0:d4960fcea8ff 257
kenjiArai 0:d4960fcea8ff 258 /* Now the order in the queue should be 2, 3, 4, with 2 being the first
kenjiArai 0:d4960fcea8ff 259 thing to be read out. Now add 1 then 0 to the front of the queue. */
kenjiArai 0:d4960fcea8ff 260 if( uxQueueMessagesWaiting( xQueue ) != 3 )
kenjiArai 0:d4960fcea8ff 261 {
kenjiArai 0:d4960fcea8ff 262 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 263 }
kenjiArai 0:d4960fcea8ff 264 ulData = 1;
kenjiArai 0:d4960fcea8ff 265 xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
kenjiArai 0:d4960fcea8ff 266 ulData = 0;
kenjiArai 0:d4960fcea8ff 267 xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
kenjiArai 0:d4960fcea8ff 268
kenjiArai 0:d4960fcea8ff 269 /* Now the queue should be full, and when we read the data out we
kenjiArai 0:d4960fcea8ff 270 should receive 0, 1, 2, 3, 4. */
kenjiArai 0:d4960fcea8ff 271 if( uxQueueMessagesWaiting( xQueue ) != 5 )
kenjiArai 0:d4960fcea8ff 272 {
kenjiArai 0:d4960fcea8ff 273 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 274 }
kenjiArai 0:d4960fcea8ff 275
kenjiArai 0:d4960fcea8ff 276 if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
kenjiArai 0:d4960fcea8ff 277 {
kenjiArai 0:d4960fcea8ff 278 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 279 }
kenjiArai 0:d4960fcea8ff 280
kenjiArai 0:d4960fcea8ff 281 if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
kenjiArai 0:d4960fcea8ff 282 {
kenjiArai 0:d4960fcea8ff 283 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 284 }
kenjiArai 0:d4960fcea8ff 285
kenjiArai 0:d4960fcea8ff 286 #if configUSE_PREEMPTION == 0
kenjiArai 0:d4960fcea8ff 287 taskYIELD();
kenjiArai 0:d4960fcea8ff 288 #endif
kenjiArai 0:d4960fcea8ff 289
kenjiArai 0:d4960fcea8ff 290 /* Check the data we read out is in the expected order. */
kenjiArai 0:d4960fcea8ff 291 for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )
kenjiArai 0:d4960fcea8ff 292 {
kenjiArai 0:d4960fcea8ff 293 /* Try peeking the data first. */
kenjiArai 0:d4960fcea8ff 294 if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 295 {
kenjiArai 0:d4960fcea8ff 296 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 297 }
kenjiArai 0:d4960fcea8ff 298
kenjiArai 0:d4960fcea8ff 299 if( ulData != ulData2 )
kenjiArai 0:d4960fcea8ff 300 {
kenjiArai 0:d4960fcea8ff 301 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 302 }
kenjiArai 0:d4960fcea8ff 303
kenjiArai 0:d4960fcea8ff 304
kenjiArai 0:d4960fcea8ff 305 /* Now try receiving the data for real. The value should be the
kenjiArai 0:d4960fcea8ff 306 same. Clobber the value first so we know we really received it. */
kenjiArai 0:d4960fcea8ff 307 ulData2 = ~ulData2;
kenjiArai 0:d4960fcea8ff 308 if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 309 {
kenjiArai 0:d4960fcea8ff 310 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 311 }
kenjiArai 0:d4960fcea8ff 312
kenjiArai 0:d4960fcea8ff 313 if( ulData != ulData2 )
kenjiArai 0:d4960fcea8ff 314 {
kenjiArai 0:d4960fcea8ff 315 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 316 }
kenjiArai 0:d4960fcea8ff 317 }
kenjiArai 0:d4960fcea8ff 318
kenjiArai 0:d4960fcea8ff 319 /* The queue should now be empty again. */
kenjiArai 0:d4960fcea8ff 320 if( uxQueueMessagesWaiting( xQueue ) != 0 )
kenjiArai 0:d4960fcea8ff 321 {
kenjiArai 0:d4960fcea8ff 322 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 323 }
kenjiArai 0:d4960fcea8ff 324
kenjiArai 0:d4960fcea8ff 325 #if configUSE_PREEMPTION == 0
kenjiArai 0:d4960fcea8ff 326 taskYIELD();
kenjiArai 0:d4960fcea8ff 327 #endif
kenjiArai 0:d4960fcea8ff 328
kenjiArai 0:d4960fcea8ff 329
kenjiArai 0:d4960fcea8ff 330 /* Our queue is empty once more, add 10, 11 to the back. */
kenjiArai 0:d4960fcea8ff 331 ulData = 10;
kenjiArai 0:d4960fcea8ff 332 if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 333 {
kenjiArai 0:d4960fcea8ff 334 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 335 }
kenjiArai 0:d4960fcea8ff 336 ulData = 11;
kenjiArai 0:d4960fcea8ff 337 if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 338 {
kenjiArai 0:d4960fcea8ff 339 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 340 }
kenjiArai 0:d4960fcea8ff 341
kenjiArai 0:d4960fcea8ff 342 if( uxQueueMessagesWaiting( xQueue ) != 2 )
kenjiArai 0:d4960fcea8ff 343 {
kenjiArai 0:d4960fcea8ff 344 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 345 }
kenjiArai 0:d4960fcea8ff 346
kenjiArai 0:d4960fcea8ff 347 /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the
kenjiArai 0:d4960fcea8ff 348 front. */
kenjiArai 0:d4960fcea8ff 349 for( ulData = 9; ulData >= 7; ulData-- )
kenjiArai 0:d4960fcea8ff 350 {
kenjiArai 0:d4960fcea8ff 351 if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 352 {
kenjiArai 0:d4960fcea8ff 353 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 354 }
kenjiArai 0:d4960fcea8ff 355 }
kenjiArai 0:d4960fcea8ff 356
kenjiArai 0:d4960fcea8ff 357 /* Now check that the queue is full, and that receiving data provides
kenjiArai 0:d4960fcea8ff 358 the expected sequence of 7, 8, 9, 10, 11. */
kenjiArai 0:d4960fcea8ff 359 if( uxQueueMessagesWaiting( xQueue ) != 5 )
kenjiArai 0:d4960fcea8ff 360 {
kenjiArai 0:d4960fcea8ff 361 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 362 }
kenjiArai 0:d4960fcea8ff 363
kenjiArai 0:d4960fcea8ff 364 if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
kenjiArai 0:d4960fcea8ff 365 {
kenjiArai 0:d4960fcea8ff 366 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 367 }
kenjiArai 0:d4960fcea8ff 368
kenjiArai 0:d4960fcea8ff 369 if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
kenjiArai 0:d4960fcea8ff 370 {
kenjiArai 0:d4960fcea8ff 371 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 372 }
kenjiArai 0:d4960fcea8ff 373
kenjiArai 0:d4960fcea8ff 374 #if configUSE_PREEMPTION == 0
kenjiArai 0:d4960fcea8ff 375 taskYIELD();
kenjiArai 0:d4960fcea8ff 376 #endif
kenjiArai 0:d4960fcea8ff 377
kenjiArai 0:d4960fcea8ff 378 /* Check the data we read out is in the expected order. */
kenjiArai 0:d4960fcea8ff 379 for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )
kenjiArai 0:d4960fcea8ff 380 {
kenjiArai 0:d4960fcea8ff 381 if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 382 {
kenjiArai 0:d4960fcea8ff 383 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 384 }
kenjiArai 0:d4960fcea8ff 385
kenjiArai 0:d4960fcea8ff 386 if( ulData != ulData2 )
kenjiArai 0:d4960fcea8ff 387 {
kenjiArai 0:d4960fcea8ff 388 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 389 }
kenjiArai 0:d4960fcea8ff 390 }
kenjiArai 0:d4960fcea8ff 391
kenjiArai 0:d4960fcea8ff 392 if( uxQueueMessagesWaiting( xQueue ) != 0 )
kenjiArai 0:d4960fcea8ff 393 {
kenjiArai 0:d4960fcea8ff 394 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 395 }
kenjiArai 0:d4960fcea8ff 396
kenjiArai 0:d4960fcea8ff 397 ulLoopCounter++;
kenjiArai 0:d4960fcea8ff 398 }
kenjiArai 0:d4960fcea8ff 399 }
kenjiArai 0:d4960fcea8ff 400 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 401
kenjiArai 0:d4960fcea8ff 402 static void prvLowPriorityMutexTask( void *pvParameters )
kenjiArai 0:d4960fcea8ff 403 {
kenjiArai 0:d4960fcea8ff 404 xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;
kenjiArai 0:d4960fcea8ff 405
kenjiArai 0:d4960fcea8ff 406 #ifdef USE_STDIO
kenjiArai 0:d4960fcea8ff 407 void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
kenjiArai 0:d4960fcea8ff 408
kenjiArai 0:d4960fcea8ff 409 const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n";
kenjiArai 0:d4960fcea8ff 410
kenjiArai 0:d4960fcea8ff 411 /* Queue a message for printing to say the task has started. */
kenjiArai 0:d4960fcea8ff 412 vPrintDisplayMessage( &pcTaskStartMsg );
kenjiArai 0:d4960fcea8ff 413 #endif
kenjiArai 0:d4960fcea8ff 414
kenjiArai 0:d4960fcea8ff 415 for( ;; )
kenjiArai 0:d4960fcea8ff 416 {
kenjiArai 0:d4960fcea8ff 417 /* Take the mutex. It should be available now. */
kenjiArai 0:d4960fcea8ff 418 if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )
kenjiArai 0:d4960fcea8ff 419 {
kenjiArai 0:d4960fcea8ff 420 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 421 }
kenjiArai 0:d4960fcea8ff 422
kenjiArai 0:d4960fcea8ff 423 /* Set our guarded variable to a known start value. */
kenjiArai 0:d4960fcea8ff 424 ulGuardedVariable = 0;
kenjiArai 0:d4960fcea8ff 425
kenjiArai 0:d4960fcea8ff 426 /* Our priority should be as per that assigned when the task was
kenjiArai 0:d4960fcea8ff 427 created. */
kenjiArai 0:d4960fcea8ff 428 if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
kenjiArai 0:d4960fcea8ff 429 {
kenjiArai 0:d4960fcea8ff 430 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 431 }
kenjiArai 0:d4960fcea8ff 432
kenjiArai 0:d4960fcea8ff 433 /* Now unsuspend the high priority task. This will attempt to take the
kenjiArai 0:d4960fcea8ff 434 mutex, and block when it finds it cannot obtain it. */
kenjiArai 0:d4960fcea8ff 435 vTaskResume( xHighPriorityMutexTask );
kenjiArai 0:d4960fcea8ff 436
kenjiArai 0:d4960fcea8ff 437 /* We should now have inherited the prioritoy of the high priority task,
kenjiArai 0:d4960fcea8ff 438 as by now it will have attempted to get the mutex. */
kenjiArai 0:d4960fcea8ff 439 if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
kenjiArai 0:d4960fcea8ff 440 {
kenjiArai 0:d4960fcea8ff 441 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 442 }
kenjiArai 0:d4960fcea8ff 443
kenjiArai 0:d4960fcea8ff 444 /* We can attempt to set our priority to the test priority - between the
kenjiArai 0:d4960fcea8ff 445 idle priority and the medium/high test priorities, but our actual
kenjiArai 0:d4960fcea8ff 446 prioroity should remain at the high priority. */
kenjiArai 0:d4960fcea8ff 447 vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
kenjiArai 0:d4960fcea8ff 448 if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
kenjiArai 0:d4960fcea8ff 449 {
kenjiArai 0:d4960fcea8ff 450 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 451 }
kenjiArai 0:d4960fcea8ff 452
kenjiArai 0:d4960fcea8ff 453 /* Now unsuspend the medium priority task. This should not run as our
kenjiArai 0:d4960fcea8ff 454 inherited priority is above that of the medium priority task. */
kenjiArai 0:d4960fcea8ff 455 vTaskResume( xMediumPriorityMutexTask );
kenjiArai 0:d4960fcea8ff 456
kenjiArai 0:d4960fcea8ff 457 /* If the did run then it will have incremented our guarded variable. */
kenjiArai 0:d4960fcea8ff 458 if( ulGuardedVariable != 0 )
kenjiArai 0:d4960fcea8ff 459 {
kenjiArai 0:d4960fcea8ff 460 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 461 }
kenjiArai 0:d4960fcea8ff 462
kenjiArai 0:d4960fcea8ff 463 /* When we give back the semaphore our priority should be disinherited
kenjiArai 0:d4960fcea8ff 464 back to the priority to which we attempted to set ourselves. This means
kenjiArai 0:d4960fcea8ff 465 that when the high priority task next blocks, the medium priority task
kenjiArai 0:d4960fcea8ff 466 should execute and increment the guarded variable. When we next run
kenjiArai 0:d4960fcea8ff 467 both the high and medium priority tasks will have been suspended again. */
kenjiArai 0:d4960fcea8ff 468 if( xSemaphoreGive( xMutex ) != pdPASS )
kenjiArai 0:d4960fcea8ff 469 {
kenjiArai 0:d4960fcea8ff 470 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 471 }
kenjiArai 0:d4960fcea8ff 472
kenjiArai 0:d4960fcea8ff 473 /* Check that the guarded variable did indeed increment... */
kenjiArai 0:d4960fcea8ff 474 if( ulGuardedVariable != 1 )
kenjiArai 0:d4960fcea8ff 475 {
kenjiArai 0:d4960fcea8ff 476 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 477 }
kenjiArai 0:d4960fcea8ff 478
kenjiArai 0:d4960fcea8ff 479 /* ... and that our priority has been disinherited to
kenjiArai 0:d4960fcea8ff 480 genqMUTEX_TEST_PRIORITY. */
kenjiArai 0:d4960fcea8ff 481 if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
kenjiArai 0:d4960fcea8ff 482 {
kenjiArai 0:d4960fcea8ff 483 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 484 }
kenjiArai 0:d4960fcea8ff 485
kenjiArai 0:d4960fcea8ff 486 /* Set our priority back to our original priority ready for the next
kenjiArai 0:d4960fcea8ff 487 loop around this test. */
kenjiArai 0:d4960fcea8ff 488 vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );
kenjiArai 0:d4960fcea8ff 489
kenjiArai 0:d4960fcea8ff 490 /* Just to show we are still running. */
kenjiArai 0:d4960fcea8ff 491 ulLoopCounter2++;
kenjiArai 0:d4960fcea8ff 492
kenjiArai 0:d4960fcea8ff 493 #if configUSE_PREEMPTION == 0
kenjiArai 0:d4960fcea8ff 494 taskYIELD();
kenjiArai 0:d4960fcea8ff 495 #endif
kenjiArai 0:d4960fcea8ff 496 }
kenjiArai 0:d4960fcea8ff 497 }
kenjiArai 0:d4960fcea8ff 498 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 499
kenjiArai 0:d4960fcea8ff 500 static void prvMediumPriorityMutexTask( void *pvParameters )
kenjiArai 0:d4960fcea8ff 501 {
kenjiArai 0:d4960fcea8ff 502 ( void ) pvParameters;
kenjiArai 0:d4960fcea8ff 503
kenjiArai 0:d4960fcea8ff 504 for( ;; )
kenjiArai 0:d4960fcea8ff 505 {
kenjiArai 0:d4960fcea8ff 506 /* The medium priority task starts by suspending itself. The low
kenjiArai 0:d4960fcea8ff 507 priority task will unsuspend this task when required. */
kenjiArai 0:d4960fcea8ff 508 vTaskSuspend( NULL );
kenjiArai 0:d4960fcea8ff 509
kenjiArai 0:d4960fcea8ff 510 /* When this task unsuspends all it does is increment the guarded
kenjiArai 0:d4960fcea8ff 511 variable, this is so the low priority task knows that it has
kenjiArai 0:d4960fcea8ff 512 executed. */
kenjiArai 0:d4960fcea8ff 513 ulGuardedVariable++;
kenjiArai 0:d4960fcea8ff 514 }
kenjiArai 0:d4960fcea8ff 515 }
kenjiArai 0:d4960fcea8ff 516 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 517
kenjiArai 0:d4960fcea8ff 518 static void prvHighPriorityMutexTask( void *pvParameters )
kenjiArai 0:d4960fcea8ff 519 {
kenjiArai 0:d4960fcea8ff 520 xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;
kenjiArai 0:d4960fcea8ff 521
kenjiArai 0:d4960fcea8ff 522 for( ;; )
kenjiArai 0:d4960fcea8ff 523 {
kenjiArai 0:d4960fcea8ff 524 /* The high priority task starts by suspending itself. The low
kenjiArai 0:d4960fcea8ff 525 priority task will unsuspend this task when required. */
kenjiArai 0:d4960fcea8ff 526 vTaskSuspend( NULL );
kenjiArai 0:d4960fcea8ff 527
kenjiArai 0:d4960fcea8ff 528 /* When this task unsuspends all it does is attempt to obtain
kenjiArai 0:d4960fcea8ff 529 the mutex. It should find the mutex is not available so a
kenjiArai 0:d4960fcea8ff 530 block time is specified. */
kenjiArai 0:d4960fcea8ff 531 if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS )
kenjiArai 0:d4960fcea8ff 532 {
kenjiArai 0:d4960fcea8ff 533 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 534 }
kenjiArai 0:d4960fcea8ff 535
kenjiArai 0:d4960fcea8ff 536 /* When we eventually obtain the mutex we just give it back then
kenjiArai 0:d4960fcea8ff 537 return to suspend ready for the next test. */
kenjiArai 0:d4960fcea8ff 538 if( xSemaphoreGive( xMutex ) != pdPASS )
kenjiArai 0:d4960fcea8ff 539 {
kenjiArai 0:d4960fcea8ff 540 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 541 }
kenjiArai 0:d4960fcea8ff 542 }
kenjiArai 0:d4960fcea8ff 543 }
kenjiArai 0:d4960fcea8ff 544 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 545
kenjiArai 0:d4960fcea8ff 546 /* This is called to check that all the created tasks are still running. */
kenjiArai 0:d4960fcea8ff 547 portBASE_TYPE xAreGenericQueueTasksStillRunning( void )
kenjiArai 0:d4960fcea8ff 548 {
kenjiArai 0:d4960fcea8ff 549 static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;
kenjiArai 0:d4960fcea8ff 550
kenjiArai 0:d4960fcea8ff 551 /* If the demo task is still running then we expect the loopcounters to
kenjiArai 0:d4960fcea8ff 552 have incremented since this function was last called. */
kenjiArai 0:d4960fcea8ff 553 if( ulLastLoopCounter == ulLoopCounter )
kenjiArai 0:d4960fcea8ff 554 {
kenjiArai 0:d4960fcea8ff 555 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 556 }
kenjiArai 0:d4960fcea8ff 557
kenjiArai 0:d4960fcea8ff 558 if( ulLastLoopCounter2 == ulLoopCounter2 )
kenjiArai 0:d4960fcea8ff 559 {
kenjiArai 0:d4960fcea8ff 560 xErrorDetected = pdTRUE;
kenjiArai 0:d4960fcea8ff 561 }
kenjiArai 0:d4960fcea8ff 562
kenjiArai 0:d4960fcea8ff 563 ulLastLoopCounter = ulLoopCounter;
kenjiArai 0:d4960fcea8ff 564 ulLastLoopCounter2 = ulLoopCounter2;
kenjiArai 0:d4960fcea8ff 565
kenjiArai 0:d4960fcea8ff 566 /* Errors detected in the task itself will have latched xErrorDetected
kenjiArai 0:d4960fcea8ff 567 to true. */
kenjiArai 0:d4960fcea8ff 568
kenjiArai 0:d4960fcea8ff 569 return !xErrorDetected;
kenjiArai 0:d4960fcea8ff 570 }
kenjiArai 0:d4960fcea8ff 571
kenjiArai 0:d4960fcea8ff 572