mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:59:01 +01:00 
			
		
		
		
	Add first version of alternative API.
This commit is contained in:
		
							parent
							
								
									b6d2b739f3
								
							
						
					
					
						commit
						8603259d40
					
				
							
								
								
									
										303
									
								
								Demo/Common/Minimal/AltBlckQ.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								Demo/Common/Minimal/AltBlckQ.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,303 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
{
 | 
			
		||||
	xQueueHandle xQueue;					/*< The queue to be used by the task. */
 | 
			
		||||
	portTickType xBlockTime;				/*< The block time to use on queue reads/writes. */
 | 
			
		||||
	volatile portSHORT *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 portSHORT sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 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 portSHORT sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 };
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vStartAltBlockingQueueTasks( unsigned portBASE_TYPE uxPriority )
 | 
			
		||||
{
 | 
			
		||||
xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;
 | 
			
		||||
xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
 | 
			
		||||
xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
 | 
			
		||||
const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5;
 | 
			
		||||
const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS;
 | 
			
		||||
const portTickType xDontBlock = ( portTickType ) 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, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) );
 | 
			
		||||
 | 
			
		||||
	/* 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, ( signed portCHAR * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL );
 | 
			
		||||
	xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "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, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) );
 | 
			
		||||
	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, ( signed portCHAR * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL );
 | 
			
		||||
	xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "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, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) );
 | 
			
		||||
	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, ( signed portCHAR * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL );
 | 
			
		||||
	xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )
 | 
			
		||||
{
 | 
			
		||||
unsigned portSHORT usValue = 0;
 | 
			
		||||
xBlockingQueueParameters *pxQueueParameters;
 | 
			
		||||
portSHORT sErrorEverOccurred = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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 )
 | 
			
		||||
{
 | 
			
		||||
unsigned portSHORT usData, usExpectedValue = 0;
 | 
			
		||||
xBlockingQueueParameters *pxQueueParameters;
 | 
			
		||||
portSHORT sErrorEverOccurred = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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. */
 | 
			
		||||
portBASE_TYPE xAreAltBlockingQueuesStillRunning( void )
 | 
			
		||||
{
 | 
			
		||||
static portSHORT sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 };
 | 
			
		||||
static portSHORT sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 };
 | 
			
		||||
portBASE_TYPE 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										498
									
								
								Demo/Common/Minimal/AltBlock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								Demo/Common/Minimal/AltBlock.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,498 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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				( ( ( portTickType ) 20 ) / portTICK_RATE_MS )
 | 
			
		||||
#define bktPRIMARY_BLOCK_TIME		( 10 )
 | 
			
		||||
#define bktALLOWABLE_MARGIN			( 12 )
 | 
			
		||||
#define bktTIME_TO_BLOCK			( 175 )
 | 
			
		||||
#define bktDONT_BLOCK				( ( portTickType ) 0 )
 | 
			
		||||
#define bktRUN_INDICATOR			( ( unsigned portBASE_TYPE ) 0x55 )
 | 
			
		||||
 | 
			
		||||
/* The queue on which the tasks block. */
 | 
			
		||||
static xQueueHandle xTestQueue;
 | 
			
		||||
 | 
			
		||||
/* Handle to the secondary task is required by the primary task for calls
 | 
			
		||||
to vTaskSuspend/Resume(). */
 | 
			
		||||
static xTaskHandle xSecondary;
 | 
			
		||||
 | 
			
		||||
/* Used to ensure that tasks are still executing without error. */
 | 
			
		||||
static portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0;
 | 
			
		||||
static portBASE_TYPE xErrorOccurred = pdFALSE;
 | 
			
		||||
 | 
			
		||||
/* Provides a simple mechanism for the primary task to know when the
 | 
			
		||||
secondary task has executed. */
 | 
			
		||||
static volatile unsigned portBASE_TYPE 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( portBASE_TYPE ) );
 | 
			
		||||
 | 
			
		||||
	/* Create the two test tasks. */
 | 
			
		||||
	xTaskCreate( vPrimaryBlockTimeTestTask, ( signed portCHAR * )"FBTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );
 | 
			
		||||
	xTaskCreate( vSecondaryBlockTimeTestTask, ( signed portCHAR * )"FBTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void vPrimaryBlockTimeTestTask( void *pvParameters )
 | 
			
		||||
{
 | 
			
		||||
portBASE_TYPE xItem, xData;
 | 
			
		||||
portTickType xTimeWhenBlocking;
 | 
			
		||||
portTickType xTimeToBlock, xBlockedTime;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*********************************************************************
 | 
			
		||||
        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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		/*********************************************************************
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		/*********************************************************************
 | 
			
		||||
        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 )
 | 
			
		||||
{
 | 
			
		||||
portTickType xTimeWhenBlocking, xBlockedTime;
 | 
			
		||||
portBASE_TYPE xData;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
portBASE_TYPE xAreAltBlockTimeTestTasksStillRunning( void )
 | 
			
		||||
{
 | 
			
		||||
static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;
 | 
			
		||||
portBASE_TYPE 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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										237
									
								
								Demo/Common/Minimal/AltPollQ.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								Demo/Common/Minimal/AltPollQ.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,237 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
	  portTickType rather than unsigned portLONG.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#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		( ( portTickType ) 200 / portTICK_RATE_MS )
 | 
			
		||||
#define pollqCONSUMER_DELAY		( pollqPRODUCER_DELAY - ( portTickType ) ( 20 / portTICK_RATE_MS ) )
 | 
			
		||||
#define pollqNO_DELAY			( ( portTickType ) 0 )
 | 
			
		||||
#define pollqVALUES_TO_PRODUCE	( ( signed portBASE_TYPE ) 3 )
 | 
			
		||||
#define pollqINITIAL_VALUE		( ( signed portBASE_TYPE ) 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 signed portBASE_TYPE xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vStartAltPolledQueueTasks( unsigned portBASE_TYPE uxPriority )
 | 
			
		||||
{
 | 
			
		||||
static xQueueHandle xPolledQueue;
 | 
			
		||||
 | 
			
		||||
	/* Create the queue used by the producer and consumer. */
 | 
			
		||||
	xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) );
 | 
			
		||||
 | 
			
		||||
	/* Spawn the producer and consumer. */
 | 
			
		||||
	xTaskCreate( vPolledQueueConsumer, ( signed portCHAR * ) "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );
 | 
			
		||||
	xTaskCreate( vPolledQueueProducer, ( signed portCHAR * ) "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )
 | 
			
		||||
{
 | 
			
		||||
unsigned portSHORT usValue = ( unsigned portSHORT ) 0;
 | 
			
		||||
signed portBASE_TYPE xError = pdFALSE, xLoop;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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( *( ( xQueueHandle * ) 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 )
 | 
			
		||||
{
 | 
			
		||||
unsigned portSHORT usData, usExpectedValue = ( unsigned portSHORT ) 0;
 | 
			
		||||
signed portBASE_TYPE xError = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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( *( ( xQueueHandle * ) pvParameters ) ) )
 | 
			
		||||
		{
 | 
			
		||||
			if( xQueueAltReceive( *( ( xQueueHandle * ) 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. */
 | 
			
		||||
portBASE_TYPE xAreAltPollingQueuesStillRunning( void )
 | 
			
		||||
{
 | 
			
		||||
portBASE_TYPE 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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										542
									
								
								Demo/Common/Minimal/AltQTest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										542
									
								
								Demo/Common/Minimal/AltQTest.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,542 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * 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 portBASE_TYPE 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 unsigned portLONG ulLoopCounter = 0;
 | 
			
		||||
static volatile unsigned portLONG ulLoopCounter2 = 0;
 | 
			
		||||
 | 
			
		||||
/* The variable that is guarded by the mutex in the mutex demo tasks. */
 | 
			
		||||
static volatile unsigned portLONG ulGuardedVariable = 0;
 | 
			
		||||
 | 
			
		||||
/* Handles used in the mutext test to suspend and resume the high and medium
 | 
			
		||||
priority mutex test tasks. */
 | 
			
		||||
static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vStartAltGenericQueueTasks( unsigned portBASE_TYPE uxPriority )
 | 
			
		||||
{
 | 
			
		||||
xQueueHandle xQueue;
 | 
			
		||||
xSemaphoreHandle xMutex;
 | 
			
		||||
 | 
			
		||||
	/* Create the queue that we are going to use for the
 | 
			
		||||
	prvSendFrontAndBackTest demo. */
 | 
			
		||||
	xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) );
 | 
			
		||||
 | 
			
		||||
	/* 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, ( signed portCHAR * ) "FGenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );
 | 
			
		||||
 | 
			
		||||
	/* Create the mutex used by the prvMutexTest task. */
 | 
			
		||||
	xMutex = xSemaphoreCreateMutex();
 | 
			
		||||
 | 
			
		||||
	/* 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, ( signed portCHAR * ) "FMuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
 | 
			
		||||
	xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * ) "FMuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
 | 
			
		||||
	xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * ) "FMuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvSendFrontAndBackTest( void *pvParameters )
 | 
			
		||||
{
 | 
			
		||||
unsigned portLONG ulData, ulData2;
 | 
			
		||||
xQueueHandle xQueue;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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 = ( xQueueHandle ) 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 )
 | 
			
		||||
{
 | 
			
		||||
xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;
 | 
			
		||||
 | 
			
		||||
	#ifdef USE_STDIO
 | 
			
		||||
	void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
 | 
			
		||||
	
 | 
			
		||||
		const portCHAR * 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 )
 | 
			
		||||
{
 | 
			
		||||
xSemaphoreHandle xMutex = ( xSemaphoreHandle ) 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. */
 | 
			
		||||
portBASE_TYPE xAreAltGenericQueueTasksStillRunning( void )
 | 
			
		||||
{
 | 
			
		||||
static unsigned portLONG 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										45
									
								
								Demo/Common/include/AltBlckQ.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Demo/Common/include/AltBlckQ.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section 
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license 
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant 
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef ALT_BLOCK_Q_H
 | 
			
		||||
#define ALT_BLOCK_Q_H
 | 
			
		||||
 | 
			
		||||
void vStartAltBlockingQueueTasks( unsigned portBASE_TYPE uxPriority );
 | 
			
		||||
portBASE_TYPE xAreAltBlockingQueuesStillRunning( void );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										45
									
								
								Demo/Common/include/AltBlock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Demo/Common/include/AltBlock.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section 
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license 
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant 
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef FAST_BLOCK_TIME_TEST_H
 | 
			
		||||
#define FAST_BLOCK_TIME_TEST_H
 | 
			
		||||
 | 
			
		||||
void vCreateAltBlockTimeTasks( void );
 | 
			
		||||
portBASE_TYPE xAreAltBlockTimeTestTasksStillRunning( void );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										45
									
								
								Demo/Common/include/AltPollQ.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Demo/Common/include/AltPollQ.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section 
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license 
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant 
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef ALT_POLLED_Q_H
 | 
			
		||||
#define ALT_POLLED_Q_H
 | 
			
		||||
 | 
			
		||||
void vStartAltPolledQueueTasks( unsigned portBASE_TYPE uxPriority );
 | 
			
		||||
portBASE_TYPE xAreAltPollingQueuesStillRunning( void );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										46
									
								
								Demo/Common/include/AltQTest.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Demo/Common/include/AltQTest.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
	FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.
 | 
			
		||||
 | 
			
		||||
	This file is part of the FreeRTOS.org distribution.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is free software; you can redistribute it and/or modify
 | 
			
		||||
	it under the terms of the GNU General Public License as published by
 | 
			
		||||
	the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
	(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
	FreeRTOS.org is distributed in the hope that it will be useful,
 | 
			
		||||
	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
	GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License
 | 
			
		||||
	along with FreeRTOS.org; if not, write to the Free Software
 | 
			
		||||
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
	A special exception to the GPL can be applied should you wish to distribute
 | 
			
		||||
	a combined work that includes FreeRTOS.org, without being obliged to provide
 | 
			
		||||
	the source code for any proprietary components.  See the licensing section
 | 
			
		||||
	of http://www.FreeRTOS.org for full details of how and when the exception
 | 
			
		||||
	can be applied.
 | 
			
		||||
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
	See http://www.FreeRTOS.org for documentation, latest information, license
 | 
			
		||||
	and contact details.  Please ensure to read the configuration and relevant
 | 
			
		||||
	port sections of the online documentation.
 | 
			
		||||
 | 
			
		||||
	Also see http://www.SafeRTOS.com a version that has been certified for use
 | 
			
		||||
	in safety critical systems, plus commercial licensing, development and
 | 
			
		||||
	support options.
 | 
			
		||||
	***************************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef FAST_GEN_Q_TEST_H
 | 
			
		||||
#define FAST_GEN_Q_TEST_H
 | 
			
		||||
 | 
			
		||||
void vStartAltGenericQueueTasks( unsigned portBASE_TYPE uxPriority );
 | 
			
		||||
portBASE_TYPE xAreAltGenericQueueTasksStillRunning( void );
 | 
			
		||||
 | 
			
		||||
#endif /* GEN_Q_TEST_H */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,7 @@
 | 
			
		||||
#define configUSE_CO_ROUTINES 			1
 | 
			
		||||
#define configUSE_MUTEXES				1
 | 
			
		||||
#define configUSE_COUNTING_SEMAPHORES	1
 | 
			
		||||
#define configUSE_ALTERNATIVE_API		1
 | 
			
		||||
 | 
			
		||||
#define configMAX_PRIORITIES		( ( unsigned portBASE_TYPE ) 10 )
 | 
			
		||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
 | 
			
		||||
 | 
			
		||||
@ -88,9 +88,13 @@
 | 
			
		||||
#include "mevents.h"
 | 
			
		||||
#include "crhook.h"
 | 
			
		||||
#include "blocktim.h"
 | 
			
		||||
#include "AltBlock.h"
 | 
			
		||||
#include "GenQTest.h"
 | 
			
		||||
#include "QPeek.h"
 | 
			
		||||
#include "countsem.h"
 | 
			
		||||
#include "AltQTest.h"
 | 
			
		||||
#include "AltPollQ.h"
 | 
			
		||||
#include "AltBlckQ.h"
 | 
			
		||||
 | 
			
		||||
/* Priority definitions for the tasks in the demo application. */
 | 
			
		||||
#define mainLED_TASK_PRIORITY		( tskIDLE_PRIORITY + 1 )
 | 
			
		||||
@ -155,7 +159,11 @@ portSHORT main( void )
 | 
			
		||||
	vStartMultiEventTasks();
 | 
			
		||||
	vStartQueuePeekTasks();
 | 
			
		||||
	vStartCountingSemaphoreTasks();
 | 
			
		||||
 | 
			
		||||
	vStartAltGenericQueueTasks( mainGENERIC_QUEUE_PRIORITY );
 | 
			
		||||
	vCreateAltBlockTimeTasks();
 | 
			
		||||
	vStartAltBlockingQueueTasks( mainQUEUE_BLOCK_PRIORITY );	
 | 
			
		||||
	vStartAltPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
 | 
			
		||||
		
 | 
			
		||||
	/* Create the "Print" task as described at the top of the file. */
 | 
			
		||||
	xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL );
 | 
			
		||||
 | 
			
		||||
@ -318,12 +326,24 @@ static portSHORT sErrorHasOccurred = pdFALSE;
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xAreAltBlockingQueuesStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Alt blocking queues count unchanged!\r\n" );
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xArePollingQueuesStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Polling queue count unchanged!\r\n" );
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xAreAltPollingQueuesStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Alt polling queue count unchanged!\r\n" );
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xIsCreateTaskStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Incorrect number of tasks running!\r\n" );
 | 
			
		||||
@ -366,12 +386,24 @@ static portSHORT sErrorHasOccurred = pdFALSE;
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xAreAltBlockTimeTestTasksStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Error in fast block time test tasks!\r\n" );
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xAreGenericQueueTasksStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Error in generic queue test task!\r\n" );
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xAreAltGenericQueueTasksStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Error in fast generic queue test task!\r\n" );
 | 
			
		||||
		sErrorHasOccurred = pdTRUE;		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( xAreQueuePeekTasksStillRunning() != pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		vDisplayMessage( "Error in queue peek test task!\r\n" );
 | 
			
		||||
 | 
			
		||||
@ -75,7 +75,7 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
19
 | 
			
		||||
WPickList
 | 
			
		||||
55
 | 
			
		||||
63
 | 
			
		||||
20
 | 
			
		||||
MItem
 | 
			
		||||
3
 | 
			
		||||
@ -707,7 +707,7 @@ WVList
 | 
			
		||||
168
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\MINIMAL\blocktim.c
 | 
			
		||||
..\COMMON\MINIMAL\AltBlckQ.c
 | 
			
		||||
169
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -725,7 +725,7 @@ WVList
 | 
			
		||||
172
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\MINIMAL\countsem.c
 | 
			
		||||
..\COMMON\MINIMAL\AltBlock.c
 | 
			
		||||
173
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -742,8 +742,8 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
176
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\COMMON\MINIMAL\crflash.c
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\MINIMAL\AltPollQ.c
 | 
			
		||||
177
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -760,8 +760,8 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
180
 | 
			
		||||
MItem
 | 
			
		||||
26
 | 
			
		||||
..\COMMON\MINIMAL\crhook.c
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\MINIMAL\AltQTest.c
 | 
			
		||||
181
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -779,7 +779,7 @@ WVList
 | 
			
		||||
184
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\MINIMAL\GenQTest.c
 | 
			
		||||
..\COMMON\MINIMAL\blocktim.c
 | 
			
		||||
185
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -796,8 +796,8 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
188
 | 
			
		||||
MItem
 | 
			
		||||
25
 | 
			
		||||
..\COMMON\MINIMAL\QPeek.c
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\MINIMAL\countsem.c
 | 
			
		||||
189
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -814,8 +814,8 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
192
 | 
			
		||||
MItem
 | 
			
		||||
15
 | 
			
		||||
fileio\fileio.c
 | 
			
		||||
27
 | 
			
		||||
..\COMMON\MINIMAL\crflash.c
 | 
			
		||||
193
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -832,8 +832,8 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
196
 | 
			
		||||
MItem
 | 
			
		||||
6
 | 
			
		||||
main.c
 | 
			
		||||
26
 | 
			
		||||
..\COMMON\MINIMAL\crhook.c
 | 
			
		||||
197
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -850,8 +850,8 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
200
 | 
			
		||||
MItem
 | 
			
		||||
17
 | 
			
		||||
partest\partest.c
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\MINIMAL\GenQTest.c
 | 
			
		||||
201
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -868,8 +868,8 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
204
 | 
			
		||||
MItem
 | 
			
		||||
15
 | 
			
		||||
serial\serial.c
 | 
			
		||||
25
 | 
			
		||||
..\COMMON\MINIMAL\QPeek.c
 | 
			
		||||
205
 | 
			
		||||
WString
 | 
			
		||||
4
 | 
			
		||||
@ -886,80 +886,80 @@ WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
MItem
 | 
			
		||||
3
 | 
			
		||||
*.h
 | 
			
		||||
15
 | 
			
		||||
fileio\fileio.c
 | 
			
		||||
209
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
4
 | 
			
		||||
COBJ
 | 
			
		||||
210
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
211
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
-1
 | 
			
		||||
20
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
0
 | 
			
		||||
212
 | 
			
		||||
MItem
 | 
			
		||||
31
 | 
			
		||||
..\..\SOURCE\INCLUDE\croutine.h
 | 
			
		||||
6
 | 
			
		||||
main.c
 | 
			
		||||
213
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
4
 | 
			
		||||
COBJ
 | 
			
		||||
214
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
215
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
20
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
216
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\..\source\include\list.h
 | 
			
		||||
17
 | 
			
		||||
partest\partest.c
 | 
			
		||||
217
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
4
 | 
			
		||||
COBJ
 | 
			
		||||
218
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
219
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
20
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
220
 | 
			
		||||
MItem
 | 
			
		||||
31
 | 
			
		||||
..\..\source\include\portable.h
 | 
			
		||||
15
 | 
			
		||||
serial\serial.c
 | 
			
		||||
221
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
4
 | 
			
		||||
COBJ
 | 
			
		||||
222
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
223
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
20
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
MItem
 | 
			
		||||
31
 | 
			
		||||
..\..\source\include\projdefs.h
 | 
			
		||||
3
 | 
			
		||||
*.h
 | 
			
		||||
225
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -970,14 +970,14 @@ WVList
 | 
			
		||||
227
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
1
 | 
			
		||||
-1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
0
 | 
			
		||||
228
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\..\source\include\queue.h
 | 
			
		||||
31
 | 
			
		||||
..\..\SOURCE\INCLUDE\croutine.h
 | 
			
		||||
229
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -988,14 +988,14 @@ WVList
 | 
			
		||||
231
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
232
 | 
			
		||||
MItem
 | 
			
		||||
29
 | 
			
		||||
..\..\source\include\semphr.h
 | 
			
		||||
27
 | 
			
		||||
..\..\source\include\list.h
 | 
			
		||||
233
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1006,14 +1006,14 @@ WVList
 | 
			
		||||
235
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
236
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\..\source\include\task.h
 | 
			
		||||
31
 | 
			
		||||
..\..\source\include\portable.h
 | 
			
		||||
237
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1024,14 +1024,14 @@ WVList
 | 
			
		||||
239
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
240
 | 
			
		||||
MItem
 | 
			
		||||
55
 | 
			
		||||
..\..\source\portable\owatcom\16bitdos\common\portasm.h
 | 
			
		||||
31
 | 
			
		||||
..\..\source\include\projdefs.h
 | 
			
		||||
241
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1042,14 +1042,14 @@ WVList
 | 
			
		||||
243
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
244
 | 
			
		||||
MItem
 | 
			
		||||
53
 | 
			
		||||
..\..\source\portable\owatcom\16bitdos\pc\portmacro.h
 | 
			
		||||
28
 | 
			
		||||
..\..\source\include\queue.h
 | 
			
		||||
245
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1060,14 +1060,14 @@ WVList
 | 
			
		||||
247
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
248
 | 
			
		||||
MItem
 | 
			
		||||
26
 | 
			
		||||
..\common\include\blockq.h
 | 
			
		||||
29
 | 
			
		||||
..\..\source\include\semphr.h
 | 
			
		||||
249
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1078,14 +1078,14 @@ WVList
 | 
			
		||||
251
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
252
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\blocktim.h
 | 
			
		||||
27
 | 
			
		||||
..\..\source\include\task.h
 | 
			
		||||
253
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1096,14 +1096,14 @@ WVList
 | 
			
		||||
255
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
256
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\common\include\comtest.h
 | 
			
		||||
55
 | 
			
		||||
..\..\source\portable\owatcom\16bitdos\common\portasm.h
 | 
			
		||||
257
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1114,14 +1114,14 @@ WVList
 | 
			
		||||
259
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
260
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\countsem.h
 | 
			
		||||
53
 | 
			
		||||
..\..\source\portable\owatcom\16bitdos\pc\portmacro.h
 | 
			
		||||
261
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1132,14 +1132,14 @@ WVList
 | 
			
		||||
263
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
264
 | 
			
		||||
MItem
 | 
			
		||||
26
 | 
			
		||||
..\COMMON\INCLUDE\crhook.h
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\AltBlckQ.h
 | 
			
		||||
265
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1150,14 +1150,14 @@ WVList
 | 
			
		||||
267
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
268
 | 
			
		||||
MItem
 | 
			
		||||
25
 | 
			
		||||
..\common\include\death.h
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\AltBlock.h
 | 
			
		||||
269
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1168,14 +1168,14 @@ WVList
 | 
			
		||||
271
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
272
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\COMMON\INCLUDE\dynamic.h
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\AltPollQ.h
 | 
			
		||||
273
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1186,14 +1186,14 @@ WVList
 | 
			
		||||
275
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
276
 | 
			
		||||
MItem
 | 
			
		||||
26
 | 
			
		||||
..\common\include\fileio.h
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\AltQTest.h
 | 
			
		||||
277
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1204,14 +1204,14 @@ WVList
 | 
			
		||||
279
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
280
 | 
			
		||||
MItem
 | 
			
		||||
25
 | 
			
		||||
..\common\include\flash.h
 | 
			
		||||
26
 | 
			
		||||
..\common\include\blockq.h
 | 
			
		||||
281
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1222,14 +1222,14 @@ WVList
 | 
			
		||||
283
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
284
 | 
			
		||||
MItem
 | 
			
		||||
24
 | 
			
		||||
..\common\include\flop.h
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\blocktim.h
 | 
			
		||||
285
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1240,14 +1240,14 @@ WVList
 | 
			
		||||
287
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
288
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\GenQTest.h
 | 
			
		||||
27
 | 
			
		||||
..\common\include\comtest.h
 | 
			
		||||
289
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1258,14 +1258,14 @@ WVList
 | 
			
		||||
291
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
292
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\common\include\partest.h
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\countsem.h
 | 
			
		||||
293
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1276,14 +1276,14 @@ WVList
 | 
			
		||||
295
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
296
 | 
			
		||||
MItem
 | 
			
		||||
25
 | 
			
		||||
..\common\include\pollq.h
 | 
			
		||||
26
 | 
			
		||||
..\COMMON\INCLUDE\crhook.h
 | 
			
		||||
297
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1294,14 +1294,14 @@ WVList
 | 
			
		||||
299
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
300
 | 
			
		||||
MItem
 | 
			
		||||
25
 | 
			
		||||
..\common\include\print.h
 | 
			
		||||
..\common\include\death.h
 | 
			
		||||
301
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1312,14 +1312,14 @@ WVList
 | 
			
		||||
303
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
304
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\common\include\semtest.h
 | 
			
		||||
..\COMMON\INCLUDE\dynamic.h
 | 
			
		||||
305
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1330,14 +1330,14 @@ WVList
 | 
			
		||||
307
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
308
 | 
			
		||||
MItem
 | 
			
		||||
26
 | 
			
		||||
..\common\include\serial.h
 | 
			
		||||
..\common\include\fileio.h
 | 
			
		||||
309
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1348,14 +1348,14 @@ WVList
 | 
			
		||||
311
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
312
 | 
			
		||||
MItem
 | 
			
		||||
16
 | 
			
		||||
FreeRTOSConfig.h
 | 
			
		||||
25
 | 
			
		||||
..\common\include\flash.h
 | 
			
		||||
313
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
@ -1366,7 +1366,151 @@ WVList
 | 
			
		||||
315
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
208
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
316
 | 
			
		||||
MItem
 | 
			
		||||
24
 | 
			
		||||
..\common\include\flop.h
 | 
			
		||||
317
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
318
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
319
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
320
 | 
			
		||||
MItem
 | 
			
		||||
28
 | 
			
		||||
..\COMMON\INCLUDE\GenQTest.h
 | 
			
		||||
321
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
322
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
323
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
324
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\common\include\partest.h
 | 
			
		||||
325
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
326
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
327
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
328
 | 
			
		||||
MItem
 | 
			
		||||
25
 | 
			
		||||
..\common\include\pollq.h
 | 
			
		||||
329
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
330
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
331
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
332
 | 
			
		||||
MItem
 | 
			
		||||
25
 | 
			
		||||
..\common\include\print.h
 | 
			
		||||
333
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
334
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
335
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
336
 | 
			
		||||
MItem
 | 
			
		||||
27
 | 
			
		||||
..\common\include\semtest.h
 | 
			
		||||
337
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
338
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
339
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
340
 | 
			
		||||
MItem
 | 
			
		||||
26
 | 
			
		||||
..\common\include\serial.h
 | 
			
		||||
341
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
342
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
343
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
344
 | 
			
		||||
MItem
 | 
			
		||||
16
 | 
			
		||||
FreeRTOSConfig.h
 | 
			
		||||
345
 | 
			
		||||
WString
 | 
			
		||||
3
 | 
			
		||||
NIL
 | 
			
		||||
346
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
347
 | 
			
		||||
WVList
 | 
			
		||||
0
 | 
			
		||||
224
 | 
			
		||||
1
 | 
			
		||||
1
 | 
			
		||||
0
 | 
			
		||||
 | 
			
		||||
@ -4,10 +4,10 @@ projectIdent
 | 
			
		||||
VpeMain
 | 
			
		||||
1
 | 
			
		||||
WRect
 | 
			
		||||
6
 | 
			
		||||
9
 | 
			
		||||
6229
 | 
			
		||||
7197
 | 
			
		||||
0
 | 
			
		||||
0
 | 
			
		||||
6209
 | 
			
		||||
7168
 | 
			
		||||
2
 | 
			
		||||
MProject
 | 
			
		||||
3
 | 
			
		||||
@ -31,7 +31,7 @@ WRect
 | 
			
		||||
0
 | 
			
		||||
0
 | 
			
		||||
7168
 | 
			
		||||
8270
 | 
			
		||||
8192
 | 
			
		||||
0
 | 
			
		||||
0
 | 
			
		||||
9
 | 
			
		||||
@ -39,5 +39,5 @@ WFileName
 | 
			
		||||
12
 | 
			
		||||
rtosdemo.tgt
 | 
			
		||||
0
 | 
			
		||||
25
 | 
			
		||||
0
 | 
			
		||||
7
 | 
			
		||||
 | 
			
		||||
@ -112,12 +112,16 @@
 | 
			
		||||
	#error Missing definition:  configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_MUTEXES
 | 
			
		||||
	#define configUSE_MUTEXES 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_COUNTING_SEMAPHORES
 | 
			
		||||
	#define configUSE_COUNTING_SEMAPHORES 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_MUTEXES
 | 
			
		||||
	#define configUSE_MUTEXES 0
 | 
			
		||||
#ifndef configUSE_ALTERNATIVE_API
 | 
			
		||||
	#define configUSE_ALTERNATIVE_API 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_MUTEXES == 1 )
 | 
			
		||||
 | 
			
		||||
@ -1159,6 +1159,30 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void
 | 
			
		||||
 */
 | 
			
		||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * xQueueAltGenericSend() is a light weight version of xQueueGenericSend().
 | 
			
		||||
 * Likewise xQueueAltGenericReceive() is a light weight version of
 | 
			
		||||
 * xQueueGenericReceive().
 | 
			
		||||
 *
 | 
			
		||||
 * The source code that implements the light weight (fast) API is much 
 | 
			
		||||
 * simpler	because it executes everything from within a critical section.  
 | 
			
		||||
 * This is	the approach taken by many other RTOSes, but FreeRTOS.org has the 
 | 
			
		||||
 * fully featured API as an alternative.  The fully featured API has more 
 | 
			
		||||
 * complex	code that takes longer to execute, but makes much less use of 
 | 
			
		||||
 * critical sections.  Therefore the light weight API sacrifices interrupt 
 | 
			
		||||
 * responsiveness to gain execution speed, whereas the fully featured API
 | 
			
		||||
 * sacrifices execution speed to ensure better interrupt responsiveness.
 | 
			
		||||
 */
 | 
			
		||||
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
 | 
			
		||||
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The light weight versions of the fully featured macros.
 | 
			
		||||
 */
 | 
			
		||||
#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
 | 
			
		||||
#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
 | 
			
		||||
#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
 | 
			
		||||
#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The functions defined above are for passing data to and from tasks.  The
 | 
			
		||||
 | 
			
		||||
@ -154,7 +154,8 @@ typedef xQueueHandle xSemaphoreHandle;
 | 
			
		||||
 * \defgroup xSemaphoreTake xSemaphoreTake
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreTake( xSemaphore, xBlockTime )	xQueueReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime )
 | 
			
		||||
#define xSemaphoreTake( xSemaphore, xBlockTime )		xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
 | 
			
		||||
#define xSemaphoreAltTake( xSemaphore, xBlockTime )		xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
@ -213,7 +214,8 @@ typedef xQueueHandle xSemaphoreHandle;
 | 
			
		||||
 * \defgroup xSemaphoreGive xSemaphoreGive
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreGive( xSemaphore )				xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
 | 
			
		||||
#define xSemaphoreGive( xSemaphore )		xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
 | 
			
		||||
#define xSemaphoreAltGive( xSemaphore )		xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,11 @@ is being used. */
 | 
			
		||||
/* Trap routine used by taskYIELD() to manually cause a context switch. */
 | 
			
		||||
static void __interrupt __far prvYieldProcessor( void );
 | 
			
		||||
 | 
			
		||||
/* The timer initialisation functions leave interrupts enabled,
 | 
			
		||||
which is not what we want.  This ISR is installed temporarily in case
 | 
			
		||||
the timer fires before we get a change to disable interrupts again. */
 | 
			
		||||
static void __interrupt __far prvDummyISR( void );
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/* See header file for description. */
 | 
			
		||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
 | 
			
		||||
@ -162,6 +167,15 @@ portBASE_TYPE xPortStartScheduler( void )
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void __interrupt __far prvDummyISR( void )
 | 
			
		||||
{
 | 
			
		||||
	/* The timer initialisation functions leave interrupts enabled,
 | 
			
		||||
	which is not what we want.  This ISR is installed temporarily in case
 | 
			
		||||
	the timer fires before we get a change to disable interrupts again. */
 | 
			
		||||
	outport( portEIO_REGISTER, portCLEAR_INTERRUPT );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
 | 
			
		||||
is being used. */
 | 
			
		||||
#if( configUSE_PREEMPTION == 1 )
 | 
			
		||||
@ -204,15 +218,23 @@ void vPortEndScheduler( void )
 | 
			
		||||
static void prvSetupTimerInterrupt( void )
 | 
			
		||||
{
 | 
			
		||||
const unsigned portSHORT usTimerACompare = portTIMER_COMPARE, usTimerAMode = portENABLE_TIMER_AND_INTERRUPT;
 | 
			
		||||
const unsigned portSHORT usT2_IRQ = 0x13;
 | 
			
		||||
 | 
			
		||||
	/* Configure the timer, the dummy handler is used here as the init
 | 
			
		||||
	function leaves interrupts enabled. */
 | 
			
		||||
	t2_init( usTimerAMode, usTimerACompare, prvDummyISR );
 | 
			
		||||
 | 
			
		||||
	/* Disable interrupts again before installing the real handlers. */
 | 
			
		||||
	portDISABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
	#if( configUSE_PREEMPTION == 1 )
 | 
			
		||||
		/* Tick service routine used by the scheduler when preemptive scheduling is
 | 
			
		||||
		being used. */
 | 
			
		||||
		t2_init( usTimerAMode, usTimerACompare, prvPreemptiveTick );
 | 
			
		||||
		setvect( usT2_IRQ, prvPreemptiveTick );
 | 
			
		||||
	#else
 | 
			
		||||
		/* Tick service routine used by the scheduler when cooperative scheduling is
 | 
			
		||||
		being used. */
 | 
			
		||||
		t2_init( usTimerAMode, usTimerACompare, prvNonPreemptiveTick );
 | 
			
		||||
		setvect( usT2_IRQ, prvNonPreemptiveTick );
 | 
			
		||||
	#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										200
									
								
								Source/queue.c
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								Source/queue.c
									
									
									
									
									
								
							@ -77,7 +77,7 @@ typedef struct QueueDefinition
 | 
			
		||||
	xList xTasksWaitingToSend;				/*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */
 | 
			
		||||
	xList xTasksWaitingToReceive;			/*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */
 | 
			
		||||
 | 
			
		||||
	unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
 | 
			
		||||
	volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
 | 
			
		||||
	unsigned portBASE_TYPE uxLength;		/*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
 | 
			
		||||
	unsigned portBASE_TYPE uxItemSize;		/*< The size of each items that the queue will hold. */
 | 
			
		||||
 | 
			
		||||
@ -107,6 +107,8 @@ signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * co
 | 
			
		||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
 | 
			
		||||
xQueueHandle xQueueCreateMutex( void );
 | 
			
		||||
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
 | 
			
		||||
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
 | 
			
		||||
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
 | 
			
		||||
 | 
			
		||||
#if configUSE_CO_ROUTINES == 1
 | 
			
		||||
	signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
 | 
			
		||||
@ -455,6 +457,202 @@ xTimeOutType xTimeOut;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if configUSE_ALTERNATIVE_API == 1
 | 
			
		||||
 | 
			
		||||
	signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
 | 
			
		||||
	{
 | 
			
		||||
	signed portBASE_TYPE xReturn;
 | 
			
		||||
	xTimeOutType xTimeOut;
 | 
			
		||||
 | 
			
		||||
		/* The source code that implements the light weight (fast) API is much 
 | 
			
		||||
		simpler	because it executes everything from within a critical section.  
 | 
			
		||||
		This is	the approach taken by many other RTOSes, but FreeRTOS.org has the 
 | 
			
		||||
		fully featured API as an alternative.  The fully featured API has more 
 | 
			
		||||
		complex	code that takes longer to execute, but makes much less use of 
 | 
			
		||||
		critical sections.  Therefore the light weight API sacrifices interrupt 
 | 
			
		||||
		responsiveness to gain execution speed, whereas the fully featured API
 | 
			
		||||
		sacrifices execution speed to ensure better interrupt responsiveness.  */
 | 
			
		||||
 | 
			
		||||
		taskENTER_CRITICAL();
 | 
			
		||||
		{
 | 
			
		||||
			/* Capture the current time status for future reference. */
 | 
			
		||||
			vTaskSetTimeOutState( &xTimeOut );
 | 
			
		||||
 | 
			
		||||
			/* If the queue is already full we may have to block. */
 | 
			
		||||
			do
 | 
			
		||||
			{
 | 
			
		||||
				if( pxQueue->uxMessagesWaiting == pxQueue->uxLength )
 | 
			
		||||
				{
 | 
			
		||||
					/* The queue is full - do we want to block or just leave without
 | 
			
		||||
					posting? */
 | 
			
		||||
					if( xTicksToWait > ( portTickType ) 0 )
 | 
			
		||||
					{
 | 
			
		||||
						/* We are going to place ourselves on the xTasksWaitingToSend 
 | 
			
		||||
						event list, and will get woken should the delay expire, or 
 | 
			
		||||
						space become available on the queue. */
 | 
			
		||||
						vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
 | 
			
		||||
			
 | 
			
		||||
						/* Force a context switch now as we are blocked.  We can do
 | 
			
		||||
						this from within a critical section as the task we are
 | 
			
		||||
						switching to has its own context.  When we return here (i.e.
 | 
			
		||||
						we unblock) we will leave the critical section as normal. */
 | 
			
		||||
						taskYIELD();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
					
 | 
			
		||||
				if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
 | 
			
		||||
				{
 | 
			
		||||
					/* There is room in the queue, copy the data into the queue. */			
 | 
			
		||||
					prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
 | 
			
		||||
					xReturn = pdPASS;
 | 
			
		||||
 | 
			
		||||
					if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
 | 
			
		||||
					{
 | 
			
		||||
						if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
 | 
			
		||||
						{
 | 
			
		||||
							/* The task waiting has a higher priority. */
 | 
			
		||||
							taskYIELD();
 | 
			
		||||
						}
 | 
			
		||||
					}			
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					xReturn = errQUEUE_FULL;
 | 
			
		||||
 | 
			
		||||
					if( xTicksToWait > 0 )
 | 
			
		||||
					{					
 | 
			
		||||
						if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
 | 
			
		||||
						{
 | 
			
		||||
							/* Another task must have accessed the queue between 
 | 
			
		||||
							this task unblocking and actually executing. */
 | 
			
		||||
							xReturn = queueERRONEOUS_UNBLOCK;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			while( xReturn == queueERRONEOUS_UNBLOCK );
 | 
			
		||||
		}
 | 
			
		||||
		taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_ALTERNATIVE_API */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if configUSE_ALTERNATIVE_API == 1
 | 
			
		||||
 | 
			
		||||
	signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
 | 
			
		||||
	{
 | 
			
		||||
	signed portBASE_TYPE xReturn = pdTRUE;
 | 
			
		||||
	xTimeOutType xTimeOut;
 | 
			
		||||
	signed portCHAR *pcOriginalReadPosition;
 | 
			
		||||
 | 
			
		||||
		/* The source code that implements the light weight (fast) API is much 
 | 
			
		||||
		simpler	because it executes everything from within a critical section.  
 | 
			
		||||
		This is	the approach taken by many other RTOSes, but FreeRTOS.org has the 
 | 
			
		||||
		fully featured API as an alternative.  The fully featured API has more 
 | 
			
		||||
		complex	code that takes longer to execute, but makes much less use of 
 | 
			
		||||
		critical sections.  Therefore the light weight API sacrifices interrupt 
 | 
			
		||||
		responsiveness to gain execution speed, whereas the fully featured API
 | 
			
		||||
		sacrifices execution speed to ensure better interrupt responsiveness.  */
 | 
			
		||||
 | 
			
		||||
		taskENTER_CRITICAL();
 | 
			
		||||
		{
 | 
			
		||||
			/* Capture the current time status for future reference. */
 | 
			
		||||
			vTaskSetTimeOutState( &xTimeOut );
 | 
			
		||||
 | 
			
		||||
			do
 | 
			
		||||
			{
 | 
			
		||||
				/* If there are no messages in the queue we may have to block. */
 | 
			
		||||
				if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
 | 
			
		||||
				{
 | 
			
		||||
					/* There are no messages in the queue, do we want to block or just
 | 
			
		||||
					leave with nothing? */			
 | 
			
		||||
					if( xTicksToWait > ( portTickType ) 0 )
 | 
			
		||||
					{
 | 
			
		||||
						#if ( configUSE_MUTEXES == 1 )
 | 
			
		||||
						{
 | 
			
		||||
							if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
 | 
			
		||||
							{
 | 
			
		||||
								vTaskPriorityInherit( ( void * const ) pxQueue->pxMutexHolder );
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						#endif
 | 
			
		||||
						
 | 
			
		||||
						vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
 | 
			
		||||
						taskYIELD();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			
 | 
			
		||||
				if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
 | 
			
		||||
				{
 | 
			
		||||
					/* Remember our read position in case we are just peeking. */
 | 
			
		||||
					pcOriginalReadPosition = pxQueue->pcReadFrom;
 | 
			
		||||
 | 
			
		||||
					prvCopyDataFromQueue( pxQueue, pvBuffer );
 | 
			
		||||
 | 
			
		||||
					if( xJustPeeking == pdFALSE )
 | 
			
		||||
					{
 | 
			
		||||
						/* We are actually removing data. */
 | 
			
		||||
						--( pxQueue->uxMessagesWaiting );
 | 
			
		||||
							
 | 
			
		||||
						#if ( configUSE_MUTEXES == 1 )
 | 
			
		||||
						{
 | 
			
		||||
							if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
 | 
			
		||||
							{
 | 
			
		||||
								/* Record the information required to implement
 | 
			
		||||
								priority inheritance should it become necessary. */
 | 
			
		||||
								pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						#endif
 | 
			
		||||
 | 
			
		||||
						if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
 | 
			
		||||
						{
 | 
			
		||||
							if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
 | 
			
		||||
							{
 | 
			
		||||
								/* The task waiting has a higher priority. */
 | 
			
		||||
								taskYIELD();
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						/* We are not removing the data, so reset our read
 | 
			
		||||
						pointer. */
 | 
			
		||||
						pxQueue->pcReadFrom = pcOriginalReadPosition;
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
					xReturn = pdPASS;					
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					xReturn = errQUEUE_EMPTY;
 | 
			
		||||
 | 
			
		||||
					if( xTicksToWait > 0 )
 | 
			
		||||
					{
 | 
			
		||||
						if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
 | 
			
		||||
						{
 | 
			
		||||
							xReturn = queueERRONEOUS_UNBLOCK;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			} while( xReturn == queueERRONEOUS_UNBLOCK );
 | 
			
		||||
		}
 | 
			
		||||
		taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_ALTERNATIVE_API */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition )
 | 
			
		||||
{
 | 
			
		||||
	/* Similar to xQueueGenericSend, except we don't block if there is no room
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user