Prepare for a FreeRTOS V9 release candidate:

- Remove the standard demo files that used the [long since deprecated] alternative API.
- Add standard demo task that tests the new xTaskAbortDelay() function.
- Update the Win32 Visual Studio project to use Visual Studio 2015 Community Edition.
- Rename the xGenericListItem TCB member to xStateListItem as it better describes the member's purpose.
This commit is contained in:
Richard Barry 2016-02-18 10:07:42 +00:00
parent c7b7b90cc9
commit d7253324cd
58 changed files with 984 additions and 2490 deletions

View file

@ -0,0 +1,650 @@
/*
FreeRTOS V8.2.3 - 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!
*/
/*
* This file contains some test scenarios that ensure tasks respond correctly
* to xTaskAbortDelay() calls.
*/
/* Standard includes. */
#include "limits.h"
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "event_groups.h"
/* Demo includes. */
#include "AbortDelay.h"
/* This file can only be used if the functionality it tests is included in the
build. Remove the whole file if this is not the case. */
#if( INCLUDE_xTaskAbortDelay == 1 )
#if( INCLUDE_xTaskGetTaskHandle != 1 )
#error This test file uses the xTaskGetTaskHandle() API function so INCLUDE_xTaskGetTaskHandle must be set to 1 in FreeRTOSConfig.h.
#endif
/* Task priorities. Allow these to be overridden. */
#ifndef abtCONTROLLING_PRIORITY
#define abtCONTROLLING_PRIORITY ( configMAX_PRIORITIES - 3 )
#endif
#ifndef abtBLOCKING_PRIORITY
#define abtBLOCKING_PRIORITY ( configMAX_PRIORITIES - 2 )
#endif
/* The tests that are performed. */
#define abtNOTIFY_WAIT_ABORTS 0
#define abtNOTIFY_TAKE_ABORTS 1
#define abtDELAY_ABORTS 2
#define abtDELAY_UNTIL_ABORTS 3
#define abtSEMAPHORE_TAKE_ABORTS 4
#define abtEVENT_GROUP_ABORTS 5
#define abtQUEUE_SEND_ABORTS 6
#define abtMAX_TESTS 7
/*-----------------------------------------------------------*/
/*
* The two test tasks. The controlling task specifies which test to executed.
* More information is provided in the comments within the tasks.
*/
static void prvControllingTask( void *pvParameters );
static void prvBlockingTask( void *pvParameters );
/*
* Test functions called by the blocking task. Each function follows the same
* pattern, but the way the task blocks is different in each case.
*
* In each function three blocking calls are made. The first and third
* blocking call is expected to time out, while the middle blocking call is
* expected to be aborted by the controlling task half way through the block
* time.
*/
static void prvTestAbortingTaskNotifyWait( void );
static void prvTestAbortingTaskNotifyTake( void );
static void prvTestAbortingTaskDelay( void );
static void prvTestAbortingTaskDelayUntil( void );
static void prvTestAbortingSemaphoreTake( void );
static void prvTestAbortingEventGroupWait( void );
static void prvTestAbortingQueueSend( void );
/*
* Checks the amount of time a task spent in the Blocked state is within the
* expected bounds.
*/
static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime );
/*-----------------------------------------------------------*/
/* Used to ensure that tasks are still executing without error. */
static volatile BaseType_t xControllingCycles = 0, xBlockingCycles = 0;
static volatile BaseType_t xErrorOccurred = pdFALSE;
/* Each task needs to know the other tasks handle so they can send signals to
each other. The handle is obtained from the task's name. */
static const char *pcControllingTaskName = "AbtCtrl", *pcBlockingTaskName = "AbtBlk";
/* The maximum amount of time a task will block for. */
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 100 );
const TickType_t xHalfMaxBlockTime = pdMS_TO_TICKS( 50 );
/* The actual block time is dependent on the priority of other tasks in the
system so the actual block time might be greater than that expected, but it
should be within an acceptable upper bound. */
const TickType_t xAllowableMargin = pdMS_TO_TICKS( 7 );
/*-----------------------------------------------------------*/
void vCreateAbortDelayTasks( void )
{
/* Create the two test tasks described above. */
xTaskCreate( prvControllingTask, pcControllingTaskName, configMINIMAL_STACK_SIZE, NULL, abtCONTROLLING_PRIORITY, NULL );
xTaskCreate( prvBlockingTask, pcBlockingTaskName, configMINIMAL_STACK_SIZE, NULL, abtBLOCKING_PRIORITY, NULL );
}
/*-----------------------------------------------------------*/
static void prvControllingTask( void *pvParameters )
{
TaskHandle_t xBlockingTask;
uint32_t ulTestToPerform = abtNOTIFY_WAIT_ABORTS;
TickType_t xTimeAtStart;
const TickType_t xStartMargin = 2UL;
/* Just to remove compiler warnings. */
( void ) pvParameters;
xBlockingTask = xTaskGetTaskHandle( pcBlockingTaskName );
configASSERT( xBlockingTask );
for( ;; )
{
/* Tell the secondary task to perform the next test. */
xTimeAtStart = xTaskGetTickCount();
xTaskNotify( xBlockingTask, ulTestToPerform, eSetValueWithOverwrite );
/* The secondary task has a higher priority, so will now be in the
Blocked state to wait for a maximum of xMaxBlockTime. It expects that
period to complete with a timeout. It will then block for
xMaxBlockTimeAgain, but this time it expects to the block time to abort
half way through. Block until it is time to send the abort to the
secondary task. xStartMargin is used because this task takes timing
from the beginning of the test, whereas the blocking task takes timing
from the entry into the Blocked state - and as the tasks run at
different priorities, there may be some discrepancy. Also, temporarily
raise the priority of the controlling task to that of the blocking
task to minimise discrepancies. */
vTaskPrioritySet( NULL, abtBLOCKING_PRIORITY );
vTaskDelay( xMaxBlockTime + xHalfMaxBlockTime + xStartMargin );
xTaskAbortDelay( xBlockingTask );
/* Reset the priority to the normal controlling priority. */
vTaskPrioritySet( NULL, abtCONTROLLING_PRIORITY );
/* Now wait to be notified that the secondary task has completed its
test. */
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
/* Did the entire test run for the expected time, which is two full
block times plus the half block time caused by calling
xTaskAbortDelay()? */
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, ( xMaxBlockTime + xMaxBlockTime + xHalfMaxBlockTime ) );
/* Move onto the next test. */
ulTestToPerform++;
if( ulTestToPerform >= abtMAX_TESTS )
{
ulTestToPerform = 0;
}
/* To indicate this task is still executing. */
xControllingCycles++;
}
}
/*-----------------------------------------------------------*/
static void prvBlockingTask( void *pvParameters )
{
TaskHandle_t xControllingTask;
uint32_t ulNotificationValue;
/* Just to remove compiler warnings. */
( void ) pvParameters;
xControllingTask = xTaskGetTaskHandle( pcControllingTaskName );
configASSERT( xControllingTask );
for( ;; )
{
/* Wait to be notified of the test that is to be performed next. */
xTaskNotifyWait( 0, ULONG_MAX, &ulNotificationValue, portMAX_DELAY );
switch( ulNotificationValue )
{
case abtNOTIFY_WAIT_ABORTS:
prvTestAbortingTaskNotifyWait();
break;
case abtNOTIFY_TAKE_ABORTS:
prvTestAbortingTaskNotifyTake();
break;
case abtDELAY_ABORTS:
prvTestAbortingTaskDelay();
break;
case abtDELAY_UNTIL_ABORTS:
prvTestAbortingTaskDelayUntil();
break;
case abtSEMAPHORE_TAKE_ABORTS:
prvTestAbortingSemaphoreTake();
break;
case abtEVENT_GROUP_ABORTS:
prvTestAbortingEventGroupWait();
break;
case abtQUEUE_SEND_ABORTS:
prvTestAbortingQueueSend();
break;
default:
/* Should not get here. */
break;
}
/* Let the primary task know the test is complete. */
xTaskNotifyGive( xControllingTask );
/* To indicate this task is still executing. */
xBlockingCycles++;
}
}
/*-----------------------------------------------------------*/
static void prvTestAbortingTaskDelayUntil( void )
{
TickType_t xTimeAtStart, xLastBlockTime;
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* Take a copy of the time as it is updated in the call to
vTaskDelayUntil() but its original value is needed to determine the actual
time spend in the Blocked state. */
xLastBlockTime = xTimeAtStart;
/* This first delay should just time out. */
vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* This second delay should be aborted by the primary task half way
through. Again take a copy of the time as it is updated in the call to
vTaskDelayUntil() buts its original value is needed to determine the amount
of time actually spent in the Blocked state. */
xTimeAtStart = xTaskGetTickCount();
xLastBlockTime = xTimeAtStart;
vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* As with the other tests, the third block period should not time out. */
xTimeAtStart = xTaskGetTickCount();
xLastBlockTime = xTimeAtStart;
vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
}
/*-----------------------------------------------------------*/
static void prvTestAbortingTaskDelay( void )
{
TickType_t xTimeAtStart;
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This first delay should just time out. */
vTaskDelay( xMaxBlockTime );
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way
through. */
vTaskDelay( xMaxBlockTime );
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This third delay should just time out again. */
vTaskDelay( xMaxBlockTime );
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
}
/*-----------------------------------------------------------*/
static void prvTestAbortingTaskNotifyTake( void )
{
TickType_t xTimeAtStart;
uint32_t ulReturn;
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This first delay should just time out. */
ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
if( ulReturn != 0 )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way
through. */
ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
if( ulReturn != 0 )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This third delay should just time out again. */
ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
if( ulReturn != 0 )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
}
/*-----------------------------------------------------------*/
static void prvTestAbortingEventGroupWait( void )
{
TickType_t xTimeAtStart;
static StaticEventGroup_t xEventGroupBuffer;
EventGroupHandle_t xEventGroup;
EventBits_t xBitsToWaitFor = ( EventBits_t ) 0x01, xReturn;
/* Create the event group. Statically allocated memory is used so the
creation cannot fail. */
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This first delay should just time out. */
xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
if( xReturn != 0x00 )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way
through. */
xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
if( xReturn != 0x00 )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This third delay should just time out again. */
xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
if( xReturn != 0x00 )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Not really necessary in this case, but for completeness. */
vEventGroupDelete( xEventGroup );
}
/*-----------------------------------------------------------*/
static void prvTestAbortingQueueSend( void )
{
TickType_t xTimeAtStart;
BaseType_t xReturn;
static StaticQueue_t xQueueBuffer;
static uint8_t ucQueueStorage[ sizeof( uint8_t ) ], ucItemToQueue;
const UBaseType_t xQueueLength = ( UBaseType_t ) 1;
QueueHandle_t xQueue;
/* Create the queue. Statically allocated memory is used so the
creation cannot fail. */
xQueue = xQueueCreateStatic( xQueueLength, sizeof( uint8_t ), ucQueueStorage, &xQueueBuffer );
/* This function tests aborting when in the blocked state waiting to send,
so the queue must be full. There is only one space in the queue. */
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
if( xReturn != pdPASS )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This first delay should just time out. */
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way
through. */
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This third delay should just time out again. */
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Not really necessary in this case, but for completeness. */
vQueueDelete( xQueue );
}
/*-----------------------------------------------------------*/
static void prvTestAbortingSemaphoreTake( void )
{
TickType_t xTimeAtStart;
BaseType_t xReturn;
static StaticSemaphore_t xSemaphoreBuffer;
SemaphoreHandle_t xSemaphore;
/* Create the semaphore. Statically allocated memory is used so the
creation cannot fail. */
xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This first delay should just time out. */
xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way
through. */
xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This third delay should just time out again. */
xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Not really necessary in this case, but for completeness. */
vSemaphoreDelete( xSemaphore );
}
/*-----------------------------------------------------------*/
static void prvTestAbortingTaskNotifyWait( void )
{
TickType_t xTimeAtStart;
BaseType_t xReturn;
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This first delay should just time out. */
xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way
through. */
xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This third delay should just time out again. */
xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
if( xReturn != pdFALSE )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
}
/*-----------------------------------------------------------*/
static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime )
{
TickType_t xTimeNow, xActualBlockTime;
xTimeNow = xTaskGetTickCount();
xActualBlockTime = xTimeNow - xStartTime;
/* The actual block time should not be less than the expected block time. */
if( xActualBlockTime < xExpectedBlockTime )
{
xErrorOccurred = pdTRUE; printf( "Line %d, actual block time %d, expected %d", __LINE__, xActualBlockTime, xExpectedBlockTime );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
/* The actual block time can be greater than the expected block time, as it
depends on the priority of the other tasks, but it should be within an
acceptable margin. */
if( xActualBlockTime > ( xExpectedBlockTime + xAllowableMargin ) )
{
xErrorOccurred = pdTRUE; printf( "Line %d", __LINE__ );taskDISABLE_INTERRUPTS();for(;;){Sleep( 1000 );}
}
}
/*-----------------------------------------------------------*/
BaseType_t xAreAbortDelayTestTasksStillRunning( void )
{
static BaseType_t xLastControllingCycleCount = 0, xLastBlockingCycleCount = 0;
BaseType_t xReturn = pdPASS;
/* Have both tasks performed at least one cycle since this function was
last called? */
if( xControllingCycles == xLastControllingCycleCount )
{
xReturn = pdFAIL;
}
if( xBlockingCycles == xLastBlockingCycleCount )
{
xReturn = pdFAIL;
}
if( xErrorOccurred == pdTRUE )
{
xReturn = pdFAIL;
}
xLastBlockingCycleCount = xBlockingCycles;
xLastControllingCycleCount = xControllingCycles;
return xReturn;
}
#endif /* INCLUDE_xTaskAbortDelay == 1 */

View file

@ -1,336 +0,0 @@
/*
FreeRTOS V8.2.3 - 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!
*/
/*
* This is a version of BlockQ.c that uses the alternative (Alt) API.
*
* Creates six tasks that operate on three queues as follows:
*
* The first two tasks send and receive an incrementing number to/from a queue.
* One task acts as a producer and the other as the consumer. The consumer is a
* higher priority than the producer and is set to block on queue reads. The queue
* only has space for one item - as soon as the producer posts a message on the
* queue the consumer will unblock, pre-empt the producer, and remove the item.
*
* The second two tasks work the other way around. Again the queue used only has
* enough space for one item. This time the consumer has a lower priority than the
* producer. The producer will try to post on the queue blocking when the queue is
* full. When the consumer wakes it will remove the item from the queue, causing
* the producer to unblock, pre-empt the consumer, and immediately re-fill the
* queue.
*
* The last two tasks use the same queue producer and consumer functions. This time the queue has
* enough space for lots of items and the tasks operate at the same priority. The
* producer will execute, placing items into the queue. The consumer will start
* executing when either the queue becomes full (causing the producer to block) or
* a context switch occurs (tasks of the same priority will time slice).
*
*/
#include <stdlib.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Demo program include files. */
#include "AltBlckQ.h"
#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE
#define blckqNUM_TASK_SETS ( 3 )
/* Structure used to pass parameters to the blocking queue tasks. */
typedef struct BLOCKING_QUEUE_PARAMETERS
{
QueueHandle_t xQueue; /*< The queue to be used by the task. */
TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */
volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */
} xBlockingQueueParameters;
/* Task function that creates an incrementing number and posts it on a queue. */
static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters );
/* Task function that removes the incrementing number from a queue and checks that
it is the expected number. */
static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters );
/* Variables which are incremented each time an item is removed from a queue, and
found to be the expected value.
These are used to check that the tasks are still running. */
static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
/* Variable which are incremented each time an item is posted on a queue. These
are used to check that the tasks are still running. */
static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
/*-----------------------------------------------------------*/
void vStartAltBlockingQueueTasks( UBaseType_t uxPriority )
{
xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;
xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
const UBaseType_t uxQueueSize1 = 1, uxQueueSize5 = 5;
const TickType_t xBlockTime = ( TickType_t ) 1000 / portTICK_PERIOD_MS;
const TickType_t xDontBlock = ( TickType_t ) 0;
/* Create the first two tasks as described at the top of the file. */
/* First create the structure used to pass parameters to the consumer tasks. */
pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
/* Create the queue used by the first two tasks to pass the incrementing number.
Pass a pointer to the queue in the parameter structure. */
pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) );
/* The consumer is created first so gets a block time as described above. */
pxQueueParameters1->xBlockTime = xBlockTime;
/* Pass in the variable that this task is going to increment so we can check it
is still running. */
pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] );
/* Create the structure used to pass parameters to the producer task. */
pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
/* Pass the queue to this task also, using the parameter structure. */
pxQueueParameters2->xQueue = pxQueueParameters1->xQueue;
/* The producer is not going to block - as soon as it posts the consumer will
wake and remove the item so the producer should always have room to post. */
pxQueueParameters2->xBlockTime = xDontBlock;
/* Pass in the variable that this task is going to increment so we can check
it is still running. */
pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] );
/* Note the producer has a lower priority than the consumer when the tasks are
spawned. */
xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL );
xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL );
/* Create the second two tasks as described at the top of the file. This uses
the same mechanism but reverses the task priorities. */
pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) );
pxQueueParameters3->xBlockTime = xDontBlock;
pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] );
pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
pxQueueParameters4->xQueue = pxQueueParameters3->xQueue;
pxQueueParameters4->xBlockTime = xBlockTime;
pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] );
xTaskCreate( vBlockingQueueConsumer, "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL );
xTaskCreate( vBlockingQueueProducer, "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL );
/* Create the last two tasks as described above. The mechanism is again just
the same. This time both parameter structures are given a block time. */
pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( UBaseType_t ) sizeof( uint16_t ) );
pxQueueParameters5->xBlockTime = xBlockTime;
pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] );
pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
pxQueueParameters6->xQueue = pxQueueParameters5->xQueue;
pxQueueParameters6->xBlockTime = xBlockTime;
pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] );
xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL );
xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL );
}
/*-----------------------------------------------------------*/
static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )
{
uint16_t usValue = 0;
xBlockingQueueParameters *pxQueueParameters;
short sErrorEverOccurred = pdFALSE;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Alt blocking queue producer task started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
for( ;; )
{
if( xQueueAltSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )
{
sErrorEverOccurred = pdTRUE;
}
else
{
/* We have successfully posted a message, so increment the variable
used to check we are still running. */
if( sErrorEverOccurred == pdFALSE )
{
( *pxQueueParameters->psCheckVariable )++;
}
/* Increment the variable we are going to post next time round. The
consumer will expect the numbers to follow in numerical order. */
++usValue;
}
}
}
/*-----------------------------------------------------------*/
static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters )
{
uint16_t usData, usExpectedValue = 0;
xBlockingQueueParameters *pxQueueParameters;
short sErrorEverOccurred = pdFALSE;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
for( ;; )
{
if( xQueueAltReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS )
{
if( usData != usExpectedValue )
{
/* Catch-up. */
usExpectedValue = usData;
sErrorEverOccurred = pdTRUE;
}
else
{
/* We have successfully received a message, so increment the
variable used to check we are still running. */
if( sErrorEverOccurred == pdFALSE )
{
( *pxQueueParameters->psCheckVariable )++;
}
/* Increment the value we expect to remove from the queue next time
round. */
++usExpectedValue;
}
}
}
}
/*-----------------------------------------------------------*/
/* This is called to check that all the created tasks are still running. */
BaseType_t xAreAltBlockingQueuesStillRunning( void )
{
static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
BaseType_t xReturn = pdPASS, xTasks;
/* Not too worried about mutual exclusion on these variables as they are 16
bits and we are only reading them. We also only care to see if they have
changed or not.
Loop through each check variable to and return pdFALSE if any are found not
to have changed since the last call. */
for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ )
{
if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] )
{
xReturn = pdFALSE;
}
sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ];
if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] )
{
xReturn = pdFALSE;
}
sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ];
}
return xReturn;
}

View file

@ -1,553 +0,0 @@
/*
FreeRTOS V8.2.3 - 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!
*/
/*
* This is a version of BlockTim.c that uses the light weight API.
*
* This file contains some test scenarios that ensure tasks do not exit queue
* send or receive functions prematurely. A description of the tests is
* included within the code.
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Demo includes. */
#include "AltBlock.h"
/* Task priorities. */
#define bktPRIMARY_PRIORITY ( 3 )
#define bktSECONDARY_PRIORITY ( 2 )
/* Task behaviour. */
#define bktQUEUE_LENGTH ( 5 )
#define bktSHORT_WAIT ( ( ( TickType_t ) 20 ) / portTICK_PERIOD_MS )
#define bktPRIMARY_BLOCK_TIME ( 10 )
#define bktALLOWABLE_MARGIN ( 12 )
#define bktTIME_TO_BLOCK ( 175 )
#define bktDONT_BLOCK ( ( TickType_t ) 0 )
#define bktRUN_INDICATOR ( ( UBaseType_t ) 0x55 )
/* The queue on which the tasks block. */
static QueueHandle_t xTestQueue;
/* Handle to the secondary task is required by the primary task for calls
to vTaskSuspend/Resume(). */
static TaskHandle_t xSecondary;
/* Used to ensure that tasks are still executing without error. */
static BaseType_t xPrimaryCycles = 0, xSecondaryCycles = 0;
static BaseType_t xErrorOccurred = pdFALSE;
/* Provides a simple mechanism for the primary task to know when the
secondary task has executed. */
static volatile UBaseType_t xRunIndicator;
/* The two test tasks. Their behaviour is commented within the files. */
static void vPrimaryBlockTimeTestTask( void *pvParameters );
static void vSecondaryBlockTimeTestTask( void *pvParameters );
/*-----------------------------------------------------------*/
void vCreateAltBlockTimeTasks( void )
{
/* Create the queue on which the two tasks block. */
xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) );
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
in use. The queue registry is provided as a means for kernel aware
debuggers to locate queues and has no purpose if a kernel aware debugger
is not being used. The call to vQueueAddToRegistry() will be removed
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
defined to be less than 1. */
vQueueAddToRegistry( xTestQueue, "AltBlockQueue" );
/* Create the two test tasks. */
xTaskCreate( vPrimaryBlockTimeTestTask, "FBTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );
xTaskCreate( vSecondaryBlockTimeTestTask, "FBTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );
}
/*-----------------------------------------------------------*/
static void vPrimaryBlockTimeTestTask( void *pvParameters )
{
BaseType_t xItem, xData;
TickType_t xTimeWhenBlocking;
TickType_t xTimeToBlock, xBlockedTime;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Alt primary block time test started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
( void ) pvParameters;
for( ;; )
{
/*********************************************************************
Test 1
Simple block time wakeup test on queue receives. */
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
{
/* The queue is empty. Attempt to read from the queue using a block
time. When we wake, ensure the delta in time is as expected. */
xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;
/* A critical section is used to minimise the jitter in the time
measurements. */
portENTER_CRITICAL();
{
xTimeWhenBlocking = xTaskGetTickCount();
/* We should unblock after xTimeToBlock having not received
anything on the queue. */
if( xQueueAltReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )
{
xErrorOccurred = pdTRUE;
}
/* How long were we blocked for? */
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
}
portEXIT_CRITICAL();
if( xBlockedTime < xTimeToBlock )
{
/* Should not have blocked for less than we requested. */
xErrorOccurred = pdTRUE;
}
if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
{
/* Should not have blocked for longer than we requested,
although we would not necessarily run as soon as we were
unblocked so a margin is allowed. */
xErrorOccurred = pdTRUE;
}
}
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/*********************************************************************
Test 2
Simple block time wakeup test on queue sends.
First fill the queue. It should be empty so all sends should pass. */
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
{
if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}
}
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
{
/* The queue is full. Attempt to write to the queue using a block
time. When we wake, ensure the delta in time is as expected. */
xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;
portENTER_CRITICAL();
{
xTimeWhenBlocking = xTaskGetTickCount();
/* We should unblock after xTimeToBlock having not received
anything on the queue. */
if( xQueueAltSendToBack( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )
{
xErrorOccurred = pdTRUE;
}
/* How long were we blocked for? */
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
}
portEXIT_CRITICAL();
if( xBlockedTime < xTimeToBlock )
{
/* Should not have blocked for less than we requested. */
xErrorOccurred = pdTRUE;
}
if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
{
/* Should not have blocked for longer than we requested,
although we would not necessarily run as soon as we were
unblocked so a margin is allowed. */
xErrorOccurred = pdTRUE;
}
}
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/*********************************************************************
Test 3
Wake the other task, it will block attempting to post to the queue.
When we read from the queue the other task will wake, but before it
can run we will post to the queue again. When the other task runs it
will find the queue still full, even though it was woken. It should
recognise that its block time has not expired and return to block for
the remains of its block time.
Wake the other task so it blocks attempting to post to the already
full queue. */
xRunIndicator = 0;
vTaskResume( xSecondary );
/* We need to wait a little to ensure the other task executes. */
while( xRunIndicator != bktRUN_INDICATOR )
{
/* The other task has not yet executed. */
vTaskDelay( bktSHORT_WAIT );
}
/* Make sure the other task is blocked on the queue. */
vTaskDelay( bktSHORT_WAIT );
xRunIndicator = 0;
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
{
/* Now when we make space on the queue the other task should wake
but not execute as this task has higher priority. */
if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}
/* Now fill the queue again before the other task gets a chance to
execute. If the other task had executed we would find the queue
full ourselves, and the other task have set xRunIndicator. */
if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}
if( xRunIndicator == bktRUN_INDICATOR )
{
/* The other task should not have executed. */
xErrorOccurred = pdTRUE;
}
/* Raise the priority of the other task so it executes and blocks
on the queue again. */
vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );
/* The other task should now have re-blocked without exiting the
queue function. */
if( xRunIndicator == bktRUN_INDICATOR )
{
/* The other task should not have executed outside of the
queue function. */
xErrorOccurred = pdTRUE;
}
/* Set the priority back down. */
vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
}
/* Let the other task timeout. When it unblockes it will check that it
unblocked at the correct time, then suspend itself. */
while( xRunIndicator != bktRUN_INDICATOR )
{
vTaskDelay( bktSHORT_WAIT );
}
vTaskDelay( bktSHORT_WAIT );
xRunIndicator = 0;
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/*********************************************************************
Test 4
As per test 3 - but with the send and receive the other way around.
The other task blocks attempting to read from the queue.
Empty the queue. We should find that it is full. */
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
{
if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}
}
/* Wake the other task so it blocks attempting to read from the
already empty queue. */
vTaskResume( xSecondary );
/* We need to wait a little to ensure the other task executes. */
while( xRunIndicator != bktRUN_INDICATOR )
{
vTaskDelay( bktSHORT_WAIT );
}
vTaskDelay( bktSHORT_WAIT );
xRunIndicator = 0;
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
{
/* Now when we place an item on the queue the other task should
wake but not execute as this task has higher priority. */
if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}
/* Now empty the queue again before the other task gets a chance to
execute. If the other task had executed we would find the queue
empty ourselves, and the other task would be suspended. */
if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}
if( xRunIndicator == bktRUN_INDICATOR )
{
/* The other task should not have executed. */
xErrorOccurred = pdTRUE;
}
/* Raise the priority of the other task so it executes and blocks
on the queue again. */
vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );
/* The other task should now have re-blocked without exiting the
queue function. */
if( xRunIndicator == bktRUN_INDICATOR )
{
/* The other task should not have executed outside of the
queue function. */
xErrorOccurred = pdTRUE;
}
vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
}
/* Let the other task timeout. When it unblockes it will check that it
unblocked at the correct time, then suspend itself. */
while( xRunIndicator != bktRUN_INDICATOR )
{
vTaskDelay( bktSHORT_WAIT );
}
vTaskDelay( bktSHORT_WAIT );
xPrimaryCycles++;
}
}
/*-----------------------------------------------------------*/
static void vSecondaryBlockTimeTestTask( void *pvParameters )
{
TickType_t xTimeWhenBlocking, xBlockedTime;
BaseType_t xData;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Alt secondary block time test started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
( void ) pvParameters;
for( ;; )
{
/*********************************************************************
Test 1 and 2
This task does does not participate in these tests. */
vTaskSuspend( NULL );
/*********************************************************************
Test 3
The first thing we do is attempt to read from the queue. It should be
full so we block. Note the time before we block so we can check the
wake time is as per that expected. */
portENTER_CRITICAL();
{
xTimeWhenBlocking = xTaskGetTickCount();
/* We should unblock after bktTIME_TO_BLOCK having not received
anything on the queue. */
xData = 0;
xRunIndicator = bktRUN_INDICATOR;
if( xQueueAltSendToBack( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL )
{
xErrorOccurred = pdTRUE;
}
/* How long were we inside the send function? */
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
}
portEXIT_CRITICAL();
/* We should not have blocked for less time than bktTIME_TO_BLOCK. */
if( xBlockedTime < bktTIME_TO_BLOCK )
{
xErrorOccurred = pdTRUE;
}
/* We should of not blocked for much longer than bktALLOWABLE_MARGIN
either. A margin is permitted as we would not necessarily run as
soon as we unblocked. */
if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )
{
xErrorOccurred = pdTRUE;
}
/* Suspend ready for test 3. */
xRunIndicator = bktRUN_INDICATOR;
vTaskSuspend( NULL );
/*********************************************************************
Test 4
As per test three, but with the send and receive reversed. */
portENTER_CRITICAL();
{
xTimeWhenBlocking = xTaskGetTickCount();
/* We should unblock after bktTIME_TO_BLOCK having not received
anything on the queue. */
xRunIndicator = bktRUN_INDICATOR;
if( xQueueAltReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )
{
xErrorOccurred = pdTRUE;
}
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
}
portEXIT_CRITICAL();
/* We should not have blocked for less time than bktTIME_TO_BLOCK. */
if( xBlockedTime < bktTIME_TO_BLOCK )
{
xErrorOccurred = pdTRUE;
}
/* We should of not blocked for much longer than bktALLOWABLE_MARGIN
either. A margin is permitted as we would not necessarily run as soon
as we unblocked. */
if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )
{
xErrorOccurred = pdTRUE;
}
xRunIndicator = bktRUN_INDICATOR;
xSecondaryCycles++;
}
}
/*-----------------------------------------------------------*/
BaseType_t xAreAltBlockTimeTestTasksStillRunning( void )
{
static BaseType_t xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;
BaseType_t xReturn = pdPASS;
/* Have both tasks performed at least one cycle since this function was
last called? */
if( xPrimaryCycles == xLastPrimaryCycleCount )
{
xReturn = pdFAIL;
}
if( xSecondaryCycles == xLastSecondaryCycleCount )
{
xReturn = pdFAIL;
}
if( xErrorOccurred == pdTRUE )
{
xReturn = pdFAIL;
}
xLastSecondaryCycleCount = xSecondaryCycles;
xLastPrimaryCycleCount = xPrimaryCycles;
return xReturn;
}

View file

@ -1,279 +0,0 @@
/*
FreeRTOS V8.2.3 - 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!
*/
/*
* This is a version of PollQ.c that uses the alternative (Alt) API.
*
* Creates two tasks that communicate over a single queue. One task acts as a
* producer, the other a consumer.
*
* The producer loops for three iteration, posting an incrementing number onto the
* queue each cycle. It then delays for a fixed period before doing exactly the
* same again.
*
* The consumer loops emptying the queue. Each item removed from the queue is
* checked to ensure it contains the expected value. When the queue is empty it
* blocks for a fixed period, then does the same again.
*
* All queue access is performed without blocking. The consumer completely empties
* the queue each time it runs so the producer should never find the queue full.
*
* An error is flagged if the consumer obtains an unexpected value or the producer
* find the queue is full.
*/
/*
Changes from V2.0.0
+ Delay periods are now specified using variables and constants of
TickType_t rather than uint32_t.
*/
#include <stdlib.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Demo program include files. */
#include "AltPollQ.h"
#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE
#define pollqQUEUE_SIZE ( 10 )
#define pollqPRODUCER_DELAY ( ( TickType_t ) 200 / portTICK_PERIOD_MS )
#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( TickType_t ) ( 20 / portTICK_PERIOD_MS ) )
#define pollqNO_DELAY ( ( TickType_t ) 0 )
#define pollqVALUES_TO_PRODUCE ( ( BaseType_t ) 3 )
#define pollqINITIAL_VALUE ( ( BaseType_t ) 0 )
/* The task that posts the incrementing number onto the queue. */
static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters );
/* The task that empties the queue. */
static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters );
/* Variables that are used to check that the tasks are still running with no
errors. */
static volatile BaseType_t xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE;
/*-----------------------------------------------------------*/
void vStartAltPolledQueueTasks( UBaseType_t uxPriority )
{
static QueueHandle_t xPolledQueue;
/* Create the queue used by the producer and consumer. */
xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( UBaseType_t ) sizeof( uint16_t ) );
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
in use. The queue registry is provided as a means for kernel aware
debuggers to locate queues and has no purpose if a kernel aware debugger
is not being used. The call to vQueueAddToRegistry() will be removed
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
defined to be less than 1. */
vQueueAddToRegistry( xPolledQueue, "AltPollQueue" );
/* Spawn the producer and consumer. */
xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
}
/*-----------------------------------------------------------*/
static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )
{
uint16_t usValue = ( uint16_t ) 0;
BaseType_t xError = pdFALSE, xLoop;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Alt polling queue producer task started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
for( ;; )
{
for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ )
{
/* Send an incrementing number on the queue without blocking. */
if( xQueueAltSendToBack( *( ( QueueHandle_t * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS )
{
/* We should never find the queue full so if we get here there
has been an error. */
xError = pdTRUE;
}
else
{
if( xError == pdFALSE )
{
/* If an error has ever been recorded we stop incrementing the
check variable. */
portENTER_CRITICAL();
xPollingProducerCount++;
portEXIT_CRITICAL();
}
/* Update the value we are going to post next time around. */
usValue++;
}
}
/* Wait before we start posting again to ensure the consumer runs and
empties the queue. */
vTaskDelay( pollqPRODUCER_DELAY );
}
} /*lint !e818 Function prototype must conform to API. */
/*-----------------------------------------------------------*/
static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters )
{
uint16_t usData, usExpectedValue = ( uint16_t ) 0;
BaseType_t xError = pdFALSE;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
for( ;; )
{
/* Loop until the queue is empty. */
while( uxQueueMessagesWaiting( *( ( QueueHandle_t * ) pvParameters ) ) )
{
if( xQueueAltReceive( *( ( QueueHandle_t * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS )
{
if( usData != usExpectedValue )
{
/* This is not what we expected to receive so an error has
occurred. */
xError = pdTRUE;
/* Catch-up to the value we received so our next expected
value should again be correct. */
usExpectedValue = usData;
}
else
{
if( xError == pdFALSE )
{
/* Only increment the check variable if no errors have
occurred. */
portENTER_CRITICAL();
xPollingConsumerCount++;
portEXIT_CRITICAL();
}
}
/* Next time round we would expect the number to be one higher. */
usExpectedValue++;
}
}
/* Now the queue is empty we block, allowing the producer to place more
items in the queue. */
vTaskDelay( pollqCONSUMER_DELAY );
}
} /*lint !e818 Function prototype must conform to API. */
/*-----------------------------------------------------------*/
/* This is called to check that all the created tasks are still running with no errors. */
BaseType_t xAreAltPollingQueuesStillRunning( void )
{
BaseType_t xReturn;
/* Check both the consumer and producer poll count to check they have both
been changed since out last trip round. We do not need a critical section
around the check variables as this is called from a higher priority than
the other tasks that access the same variables. */
if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) ||
( xPollingProducerCount == pollqINITIAL_VALUE )
)
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
/* Set the check variables back down so we know if they have been
incremented the next time around. */
xPollingConsumerCount = pollqINITIAL_VALUE;
xPollingProducerCount = pollqINITIAL_VALUE;
return xReturn;
}

View file

@ -1,591 +0,0 @@
/*
FreeRTOS V8.2.3 - 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!
*/
/*
* This file implements the same demo and test as GenQTest.c, but uses the
* light weight API in place of the fully featured API.
*
* See the comments at the top of GenQTest.c for a description.
*/
#include <stdlib.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Demo program include files. */
#include "AltQTest.h"
#define genqQUEUE_LENGTH ( 5 )
#define genqNO_BLOCK ( 0 )
#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY )
#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 )
/*-----------------------------------------------------------*/
/*
* Tests the behaviour of the xQueueAltSendToFront() and xQueueAltSendToBack()
* macros by using both to fill a queue, then reading from the queue to
* check the resultant queue order is as expected. Queue data is also
* peeked.
*/
static void prvSendFrontAndBackTest( void *pvParameters );
/*
* The following three tasks are used to demonstrate the mutex behaviour.
* Each task is given a different priority to demonstrate the priority
* inheritance mechanism.
*
* The low priority task obtains a mutex. After this a high priority task
* attempts to obtain the same mutex, causing its priority to be inherited
* by the low priority task. The task with the inherited high priority then
* resumes a medium priority task to ensure it is not blocked by the medium
* priority task while it holds the inherited high priority. Once the mutex
* is returned the task with the inherited priority returns to its original
* low priority, and is therefore immediately preempted by first the high
* priority task and then the medium prioroity task before it can continue.
*/
static void prvLowPriorityMutexTask( void *pvParameters );
static void prvMediumPriorityMutexTask( void *pvParameters );
static void prvHighPriorityMutexTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
detected in any of the tasks. */
static BaseType_t xErrorDetected = pdFALSE;
/* Counters that are incremented on each cycle of a test. This is used to
detect a stalled task - a test that is no longer running. */
static volatile uint32_t ulLoopCounter = 0;
static volatile uint32_t ulLoopCounter2 = 0;
/* The variable that is guarded by the mutex in the mutex demo tasks. */
static volatile uint32_t ulGuardedVariable = 0;
/* Handles used in the mutext test to suspend and resume the high and medium
priority mutex test tasks. */
static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask;
/*-----------------------------------------------------------*/
void vStartAltGenericQueueTasks( UBaseType_t uxPriority )
{
QueueHandle_t xQueue;
SemaphoreHandle_t xMutex;
/* Create the queue that we are going to use for the
prvSendFrontAndBackTest demo. */
xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) );
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
in use. The queue registry is provided as a means for kernel aware
debuggers to locate queues and has no purpose if a kernel aware debugger
is not being used. The call to vQueueAddToRegistry() will be removed
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
defined to be less than 1. */
vQueueAddToRegistry( xQueue, "Alt_Gen_Test_Queue" );
/* Create the demo task and pass it the queue just created. We are
passing the queue handle by value so it does not matter that it is
declared on the stack here. */
xTaskCreate( prvSendFrontAndBackTest, "FGenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );
/* Create the mutex used by the prvMutexTest task. */
xMutex = xSemaphoreCreateMutex();
/* vQueueAddToRegistry() adds the mutex to the registry, if one is
in use. The registry is provided as a means for kernel aware
debuggers to locate mutex and has no purpose if a kernel aware debugger
is not being used. The call to vQueueAddToRegistry() will be removed
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
defined to be less than 1. */
vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Alt_Q_Mutex" );
/* Create the mutex demo tasks and pass it the mutex just created. We are
passing the mutex handle by value so it does not matter that it is declared
on the stack here. */
xTaskCreate( prvLowPriorityMutexTask, "FMuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
xTaskCreate( prvMediumPriorityMutexTask, "FMuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
xTaskCreate( prvHighPriorityMutexTask, "FMuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
}
/*-----------------------------------------------------------*/
static void prvSendFrontAndBackTest( void *pvParameters )
{
uint32_t ulData, ulData2;
QueueHandle_t xQueue;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Alt queue SendToFront/SendToBack/Peek test started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
xQueue = ( QueueHandle_t ) pvParameters;
for( ;; )
{
/* The queue is empty, so sending an item to the back of the queue
should have the same efect as sending it to the front of the queue.
First send to the front and check everything is as expected. */
xQueueAltSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
if( uxQueueMessagesWaiting( xQueue ) != 1 )
{
xErrorDetected = pdTRUE;
}
if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
/* The data we sent to the queue should equal the data we just received
from the queue. */
if( ulLoopCounter != ulData )
{
xErrorDetected = pdTRUE;
}
/* Then do the same, sending the data to the back, checking everything
is as expected. */
if( uxQueueMessagesWaiting( xQueue ) != 0 )
{
xErrorDetected = pdTRUE;
}
xQueueAltSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
if( uxQueueMessagesWaiting( xQueue ) != 1 )
{
xErrorDetected = pdTRUE;
}
if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
if( uxQueueMessagesWaiting( xQueue ) != 0 )
{
xErrorDetected = pdTRUE;
}
/* The data we sent to the queue should equal the data we just received
from the queue. */
if( ulLoopCounter != ulData )
{
xErrorDetected = pdTRUE;
}
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/* Place 2, 3, 4 into the queue, adding items to the back of the queue. */
for( ulData = 2; ulData < 5; ulData++ )
{
xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );
}
/* Now the order in the queue should be 2, 3, 4, with 2 being the first
thing to be read out. Now add 1 then 0 to the front of the queue. */
if( uxQueueMessagesWaiting( xQueue ) != 3 )
{
xErrorDetected = pdTRUE;
}
ulData = 1;
xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
ulData = 0;
xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
/* Now the queue should be full, and when we read the data out we
should receive 0, 1, 2, 3, 4. */
if( uxQueueMessagesWaiting( xQueue ) != 5 )
{
xErrorDetected = pdTRUE;
}
if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
{
xErrorDetected = pdTRUE;
}
if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
{
xErrorDetected = pdTRUE;
}
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/* Check the data we read out is in the expected order. */
for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )
{
/* Try peeking the data first. */
if( xQueueAltPeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
if( ulData != ulData2 )
{
xErrorDetected = pdTRUE;
}
/* Now try receiving the data for real. The value should be the
same. Clobber the value first so we know we really received it. */
ulData2 = ~ulData2;
if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
if( ulData != ulData2 )
{
xErrorDetected = pdTRUE;
}
}
/* The queue should now be empty again. */
if( uxQueueMessagesWaiting( xQueue ) != 0 )
{
xErrorDetected = pdTRUE;
}
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/* Our queue is empty once more, add 10, 11 to the back. */
ulData = 10;
if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
ulData = 11;
if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
if( uxQueueMessagesWaiting( xQueue ) != 2 )
{
xErrorDetected = pdTRUE;
}
/* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the
front. */
for( ulData = 9; ulData >= 7; ulData-- )
{
if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
}
/* Now check that the queue is full, and that receiving data provides
the expected sequence of 7, 8, 9, 10, 11. */
if( uxQueueMessagesWaiting( xQueue ) != 5 )
{
xErrorDetected = pdTRUE;
}
if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
{
xErrorDetected = pdTRUE;
}
if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
{
xErrorDetected = pdTRUE;
}
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/* Check the data we read out is in the expected order. */
for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )
{
if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
if( ulData != ulData2 )
{
xErrorDetected = pdTRUE;
}
}
if( uxQueueMessagesWaiting( xQueue ) != 0 )
{
xErrorDetected = pdTRUE;
}
ulLoopCounter++;
}
}
/*-----------------------------------------------------------*/
static void prvLowPriorityMutexTask( void *pvParameters )
{
SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Fast mutex with priority inheritance test started.\r\n";
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
( void ) pvParameters;
for( ;; )
{
/* Take the mutex. It should be available now. */
if( xSemaphoreAltTake( xMutex, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
/* Set our guarded variable to a known start value. */
ulGuardedVariable = 0;
/* Our priority should be as per that assigned when the task was
created. */
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* Now unsuspend the high priority task. This will attempt to take the
mutex, and block when it finds it cannot obtain it. */
vTaskResume( xHighPriorityMutexTask );
/* We should now have inherited the prioritoy of the high priority task,
as by now it will have attempted to get the mutex. */
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* We can attempt to set our priority to the test priority - between the
idle priority and the medium/high test priorities, but our actual
prioroity should remain at the high priority. */
vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* Now unsuspend the medium priority task. This should not run as our
inherited priority is above that of the medium priority task. */
vTaskResume( xMediumPriorityMutexTask );
/* If the did run then it will have incremented our guarded variable. */
if( ulGuardedVariable != 0 )
{
xErrorDetected = pdTRUE;
}
/* When we give back the semaphore our priority should be disinherited
back to the priority to which we attempted to set ourselves. This means
that when the high priority task next blocks, the medium priority task
should execute and increment the guarded variable. When we next run
both the high and medium priority tasks will have been suspended again. */
if( xSemaphoreAltGive( xMutex ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
/* Check that the guarded variable did indeed increment... */
if( ulGuardedVariable != 1 )
{
xErrorDetected = pdTRUE;
}
/* ... and that our priority has been disinherited to
genqMUTEX_TEST_PRIORITY. */
if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* Set our priority back to our original priority ready for the next
loop around this test. */
vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );
/* Just to show we are still running. */
ulLoopCounter2++;
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
}
}
/*-----------------------------------------------------------*/
static void prvMediumPriorityMutexTask( void *pvParameters )
{
( void ) pvParameters;
for( ;; )
{
/* The medium priority task starts by suspending itself. The low
priority task will unsuspend this task when required. */
vTaskSuspend( NULL );
/* When this task unsuspends all it does is increment the guarded
variable, this is so the low priority task knows that it has
executed. */
ulGuardedVariable++;
}
}
/*-----------------------------------------------------------*/
static void prvHighPriorityMutexTask( void *pvParameters )
{
SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
( void ) pvParameters;
for( ;; )
{
/* The high priority task starts by suspending itself. The low
priority task will unsuspend this task when required. */
vTaskSuspend( NULL );
/* When this task unsuspends all it does is attempt to obtain
the mutex. It should find the mutex is not available so a
block time is specified. */
if( xSemaphoreAltTake( xMutex, portMAX_DELAY ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
/* When we eventually obtain the mutex we just give it back then
return to suspend ready for the next test. */
if( xSemaphoreAltGive( xMutex ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
}
}
/*-----------------------------------------------------------*/
/* This is called to check that all the created tasks are still running. */
BaseType_t xAreAltGenericQueueTasksStillRunning( void )
{
static uint32_t ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;
/* If the demo task is still running then we expect the loopcounters to
have incremented since this function was last called. */
if( ulLastLoopCounter == ulLoopCounter )
{
xErrorDetected = pdTRUE;
}
if( ulLastLoopCounter2 == ulLoopCounter2 )
{
xErrorDetected = pdTRUE;
}
ulLastLoopCounter = ulLoopCounter;
ulLastLoopCounter2 = ulLoopCounter2;
/* Errors detected in the task itself will have latched xErrorDetected
to true. */
return !xErrorDetected;
}

View file

@ -102,7 +102,7 @@
/*-----------------------------------------------------------*/
/*
* The two test tasks. Their behaviour is commented within the files.
* The two test tasks. Their behaviour is commented within the functions.
*/
static void vPrimaryBlockTimeTestTask( void *pvParameters );
static void vSecondaryBlockTimeTestTask( void *pvParameters );
@ -420,7 +420,7 @@ BaseType_t xData;
/*********************************************************************
Test 0, 1 and 2
This task does does not participate in these tests. */
This task does not participate in these tests. */
vTaskSuspend( NULL );
/*********************************************************************

View file

@ -0,0 +1,2 @@
This directory contains the implementation of the "common demo tasks". These
are test tasks and demo tasks that are used by nearly all the demo applications.

View file

@ -67,11 +67,11 @@
1 tab == 4 spaces!
*/
#ifndef ALT_POLLED_Q_H
#define ALT_POLLED_Q_H
#ifndef ABORT_DELAY_H
#define ABORT_DELAY_H
void vStartAltPolledQueueTasks( UBaseType_t uxPriority );
BaseType_t xAreAltPollingQueuesStillRunning( void );
void vCreateAbortDelayTasks( void );
BaseType_t xAreAbortDelayTestTasksStillRunning( void );
#endif

View file

@ -1,78 +0,0 @@
/*
FreeRTOS V8.2.3 - 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!
*/
#ifndef ALT_BLOCK_Q_H
#define ALT_BLOCK_Q_H
void vStartAltBlockingQueueTasks( UBaseType_t uxPriority );
BaseType_t xAreAltBlockingQueuesStillRunning( void );
#endif

View file

@ -1,78 +0,0 @@
/*
FreeRTOS V8.2.3 - 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!
*/
#ifndef FAST_BLOCK_TIME_TEST_H
#define FAST_BLOCK_TIME_TEST_H
void vCreateAltBlockTimeTasks( void );
BaseType_t xAreAltBlockTimeTestTasksStillRunning( void );
#endif

View file

@ -1,79 +0,0 @@
/*
FreeRTOS V8.2.3 - 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!
*/
#ifndef FAST_GEN_Q_TEST_H
#define FAST_GEN_Q_TEST_H
void vStartAltGenericQueueTasks( UBaseType_t uxPriority );
BaseType_t xAreAltGenericQueueTasksStillRunning( void );
#endif /* GEN_Q_TEST_H */