/*
 * FreeRTOS Kernel V10.3.0
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */

/* Standard includes. */
#include "stdio.h"
#include "string.h"

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "stream_buffer.h"

/* Demo app includes. */
#include "StreamBufferDemo.h"

/* The number of bytes of storage in the stream buffers used in this test. */
#define sbSTREAM_BUFFER_LENGTH_BYTES	( ( size_t ) 30 )

/* Stream buffer length one. */
#define sbSTREAM_BUFFER_LENGTH_ONE		( ( size_t ) 1 )

/* Start and end ASCII characters used in data sent to the buffers. */
#define sbASCII_SPACE					32
#define sbASCII_TILDA					126

/* Defines the number of tasks to create in this test and demo. */
#define sbNUMBER_OF_ECHO_CLIENTS	( 2 )
#define sbNUMBER_OF_SENDER_TASKS	( 2 )

/* Priority of the test tasks.  The send and receive go from low to high
priority tasks, and from high to low priority tasks. */
#define sbLOWER_PRIORITY			( tskIDLE_PRIORITY )
#define sbHIGHER_PRIORITY			( tskIDLE_PRIORITY + 1 )

/* Block times used when sending and receiving from the stream buffers. */
#define sbRX_TX_BLOCK_TIME			pdMS_TO_TICKS( 125UL )

/* A block time of 0 means "don't block". */
#define sbDONT_BLOCK				( 0 )

/* The trigger level sets the number of bytes that must be present in the
stream buffer before a task that is blocked on the stream buffer is moved out of
the Blocked state so it can read the bytes. */
#define sbTRIGGER_LEVEL_1			( 1 )

/* The size of the stack allocated to the tasks that run as part of this demo/
test.  The stack size is over generous in most cases. */
#define sbSTACK_SIZE				( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )

/*-----------------------------------------------------------*/

/*
 * Performs various tests that do not require multiple tasks to interact.
 */
static void prvSingleTaskTests( StreamBufferHandle_t xStreamBuffer );

/*
 * Tests sending and receiving various lengths of data via a stream buffer.
 * The echo client sends the data to the echo server, which then sends the
 * data back to the echo client, which checks it receives exactly what it
 * sent.
 */
static void prvEchoClient( void *pvParameters );
static void prvEchoServer( void *pvParameters );

/*
 * Tasks that send and receive to a stream buffer at a low priority and without
 * blocking, so the send and receive functions interleave in time as the tasks
 * are switched in and out.
 */
static void prvNonBlockingReceiverTask( void *pvParameters );
static void prvNonBlockingSenderTask( void *pvParameters );

/* Performs an assert() like check in a way that won't get removed when
performing a code coverage analysis. */
static void prvCheckExpectedState( BaseType_t xState );

/*
 * A task that creates a stream buffer with a specific trigger level, then
 * receives a string from an interrupt (the RTOS tick hook) byte by byte to
 * check it is only unblocked when the specified trigger level is reached.
 */
static void prvInterruptTriggerLevelTest( void *pvParameters );

#if( configSUPPORT_STATIC_ALLOCATION == 1  )
	/* This file tests both statically and dynamically allocated stream buffers.
	Allocate the structures and buffers to be used by the statically allocated
	objects, which get used in the echo tests. */
	static void prvReceiverTask( void *pvParameters );
	static void prvSenderTask( void *pvParameters );

	static StaticStreamBuffer_t xStaticStreamBuffers[ sbNUMBER_OF_ECHO_CLIENTS ];
	static uint8_t ucBufferStorage[ sbNUMBER_OF_SENDER_TASKS ][ sbSTREAM_BUFFER_LENGTH_BYTES + 1 ];
	static uint32_t ulSenderLoopCounters[ sbNUMBER_OF_SENDER_TASKS ] = { 0 };
#endif /* configSUPPORT_STATIC_ALLOCATION */

/*-----------------------------------------------------------*/

/* The buffers used by the echo client and server tasks. */
typedef struct ECHO_STREAM_BUFFERS
{
	/* Handles to the data structures that describe the stream buffers. */
	StreamBufferHandle_t xEchoClientBuffer;
	StreamBufferHandle_t xEchoServerBuffer;
} EchoStreamBuffers_t;
static volatile uint32_t ulEchoLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 };

/* The non-blocking tasks monitor their operation, and if no errors have been
found, increment ulNonBlockingRxCounter.  xAreStreamBufferTasksStillRunning()
then checks ulNonBlockingRxCounter and only returns pdPASS if
ulNonBlockingRxCounter is still incrementing. */
static volatile uint32_t ulNonBlockingRxCounter = 0;

/* The task that receives characters from the tick interrupt in order to test
different trigger levels monitors its own behaviour.  If it has not detected any
error then it increments ulInterruptTriggerCounter to indicate to the check task
that it is still operating correctly. */
static volatile uint32_t ulInterruptTriggerCounter = 0UL;

/* The stream buffer used from the tick interrupt.  This sends one byte at a time
to a test task to test the trigger level operation.  The variable is set to NULL
in between test runs. */
static volatile StreamBufferHandle_t xInterruptStreamBuffer = NULL;

/* The data sent from the tick interrupt to the task that tests the trigger
level functionality. */
static const char *pcDataSentFromInterrupt = "12345678";

/* Data that is longer than the buffer that is sent to the buffers as a stream
of bytes.  Parts of which are written to the stream buffer to test writing
different lengths at different offsets, to many bytes, part streams, streams
that wrap, etc..  Two messages are defined to ensure left over data is not
accidentally read out of the buffer. */
static const char *pc55ByteString = "One two three four five six seven eight nine ten eleven";
static const char *pc54ByteString = "01234567891abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ";

/* Used to log the status of the tests contained within this file for reporting
to a monitoring task ('check' task). */
static BaseType_t xErrorStatus = pdPASS;

/*-----------------------------------------------------------*/

void vStartStreamBufferTasks( void )
{
StreamBufferHandle_t xStreamBuffer;

	/* The echo servers sets up the stream buffers before creating the echo
	client tasks.  One set of tasks has the server as the higher priority, and
	the other has the client as the higher priority. */
	xTaskCreate( prvEchoServer, "1StrEchoServer", sbSTACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL );
	xTaskCreate( prvEchoServer, "2StrEchoServer", sbSTACK_SIZE, NULL, sbLOWER_PRIORITY, NULL );

	/* The non blocking tasks run continuously and will interleave with each
	other, so must be created at the lowest priority.  The stream buffer they
	use is created and passed in using the task's parameter. */
	xStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 );
	xTaskCreate( prvNonBlockingReceiverTask, "StrNonBlkRx", configMINIMAL_STACK_SIZE, ( void * ) xStreamBuffer, tskIDLE_PRIORITY, NULL );
	xTaskCreate( prvNonBlockingSenderTask, "StrNonBlkTx", configMINIMAL_STACK_SIZE, ( void * ) xStreamBuffer, tskIDLE_PRIORITY, NULL );

	/* The task that receives bytes from an interrupt to test that it unblocks
	at a specific trigger level must run at a high priority to minimise the risk
	of it receiving more characters before it can execute again after being
	unblocked. */
	xTaskCreate( prvInterruptTriggerLevelTest, "StrTrig", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );

	#if( configSUPPORT_STATIC_ALLOCATION == 1  )
	{
		/* The sender tasks set up the stream buffers before creating the
		receiver tasks.  Priorities must be 0 and 1 as the priority is used to
		index into the xStaticStreamBuffers and ucBufferStorage arrays. */
		xTaskCreate( prvSenderTask, "Str1Sender", sbSTACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL );
		xTaskCreate( prvSenderTask, "Str2Sender", sbSTACK_SIZE, NULL, sbLOWER_PRIORITY, NULL );
	}
	#endif /* configSUPPORT_STATIC_ALLOCATION */
}
/*-----------------------------------------------------------*/

static void prvCheckExpectedState( BaseType_t xState )
{
	configASSERT( xState );
	if( xState == pdFAIL )
	{
		xErrorStatus = pdFAIL;
	}
}
/*-----------------------------------------------------------*/

static void prvSingleTaskTests( StreamBufferHandle_t xStreamBuffer )
{
size_t xReturned, xItem, xExpectedSpace;
const size_t xMax6ByteMessages = sbSTREAM_BUFFER_LENGTH_BYTES / 6;
const size_t x6ByteLength = 6, x17ByteLength = 17, xFullBufferSize = sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2;
uint8_t *pucFullBuffer, *pucData, *pucReadData;
TickType_t xTimeBeforeCall, xTimeAfterCall;
const TickType_t xBlockTime = pdMS_TO_TICKS( 15 ), xAllowableMargin = pdMS_TO_TICKS( 3 ), xMinimalBlockTime = 2;
UBaseType_t uxOriginalPriority;

	/* Remove warning in case configASSERT() is not defined. */
	( void ) xAllowableMargin;

	/* To minimise stack and heap usage a full size buffer is allocated from the
	heap, then buffers which hold smaller amounts of data are overlayed with the
	larger buffer - just make sure not to use both at once! */
	pucFullBuffer = pvPortMalloc( xFullBufferSize );
	configASSERT( pucFullBuffer );

	pucData = pucFullBuffer;
	pucReadData = pucData + x17ByteLength;

	/* Nothing has been added or removed yet, so expect the free space to be
	exactly as created. */
	xExpectedSpace = xStreamBufferSpacesAvailable( xStreamBuffer );
	prvCheckExpectedState( xExpectedSpace == sbSTREAM_BUFFER_LENGTH_BYTES );
	prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE );


	/* The buffer is 30 bytes long.  6 5 byte messages should fit before the
	buffer is completely full. */
	for( xItem = 0; xItem < xMax6ByteMessages; xItem++ )
	{
		prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE );

		/* Generate recognisable data to write to the buffer.  This is just
		ascii characters that shows which loop iteration the data was written
		in. The 'FromISR' version is used to give it some exercise as a block
		time is not used, so the call must be inside a critical section so it
		runs with ports that don't support interrupt nesting (and therefore
		don't have interrupt safe critical sections). */
		memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength );
		taskENTER_CRITICAL();
		{
			xReturned = xStreamBufferSendFromISR( xStreamBuffer, ( void * ) pucData, x6ByteLength, NULL );
		}
		taskEXIT_CRITICAL();
		prvCheckExpectedState( xReturned == x6ByteLength );

		/* The space in the buffer will have reduced by the amount of user data
		written into the buffer. */
		xExpectedSpace -= x6ByteLength;
		xReturned = xStreamBufferSpacesAvailable( xStreamBuffer );
		prvCheckExpectedState( xReturned == xExpectedSpace );
		xReturned = xStreamBufferBytesAvailable( xStreamBuffer );
		/* +1 as it is zero indexed. */
		prvCheckExpectedState( xReturned == ( ( xItem + 1 ) * x6ByteLength ) );
	}

	/* Now the buffer should be full, and attempting to add anything will should
	fail. */
	prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE );
	xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), sbDONT_BLOCK );
	prvCheckExpectedState( xReturned == 0 );

	/* Adding with a timeout should also fail after the appropriate time.  The
	priority is temporarily boosted in this part of the test to keep the
	allowable margin to a minimum. */
	uxOriginalPriority = uxTaskPriorityGet( NULL );
	vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );
	xTimeBeforeCall = xTaskGetTickCount();
	xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), xBlockTime );
	xTimeAfterCall = xTaskGetTickCount();
	vTaskPrioritySet( NULL, uxOriginalPriority );
	prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime );
	prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) );
	prvCheckExpectedState( xReturned == 0 );

	/* The buffer is now full of data in the form "000000", "111111", etc.  Make
	sure the data is read out as expected. */
	for( xItem = 0; xItem < xMax6ByteMessages; xItem++ )
	{
		/* Generate the data that is expected to be read out for this loop
		iteration. */
		memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength );

		/* Read the next 6 bytes out.  The 'FromISR' version is used to give it
		some exercise as a block time is not used, so a it must be called from
		a critical section so this will work on ports that don't support
		interrupt nesting (so don't have interrupt safe critical sections). */
		taskENTER_CRITICAL();
		{
			xReturned = xStreamBufferReceiveFromISR( xStreamBuffer, ( void * ) pucReadData, x6ByteLength, NULL );
		}
		taskEXIT_CRITICAL();
		prvCheckExpectedState( xReturned == x6ByteLength );

		/* Does the data read out match that expected? */
		prvCheckExpectedState( memcmp( ( void * ) pucData, ( void * ) pucReadData, x6ByteLength ) == 0 );

		/* The space in the buffer will have increased by the amount of user
		data removed from the buffer. */
		xExpectedSpace += x6ByteLength;
		xReturned = xStreamBufferSpacesAvailable( xStreamBuffer );
		prvCheckExpectedState( xReturned == xExpectedSpace );
		xReturned = xStreamBufferBytesAvailable( xStreamBuffer );
		prvCheckExpectedState( xReturned == ( sbSTREAM_BUFFER_LENGTH_BYTES - xExpectedSpace ) );
	}

	/* The buffer should be empty again. */
	prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE );
	xExpectedSpace = xStreamBufferSpacesAvailable( xStreamBuffer );
	prvCheckExpectedState( xExpectedSpace == sbSTREAM_BUFFER_LENGTH_BYTES );

	/* Reading with a timeout should also fail after the appropriate time.  The
	priority is temporarily boosted in this part of the test to keep the
	allowable margin to a minimum. */
	vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );
	xTimeBeforeCall = xTaskGetTickCount();
	xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucReadData, x6ByteLength, xBlockTime );
	xTimeAfterCall = xTaskGetTickCount();
	vTaskPrioritySet( NULL, uxOriginalPriority );
	prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime );
	prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) );
	prvCheckExpectedState( xReturned == 0 );


	/* In the next loop 17 bytes are written to then read out on each
	iteration.  As 30 is not divisible by 17 the data will wrap around. */
	xExpectedSpace = sbSTREAM_BUFFER_LENGTH_BYTES - x17ByteLength;

	for( xItem = 0; xItem < 100; xItem++ )
	{
		/* Generate recognisable data to write to the queue.  This is just
		ascii characters that shows which loop iteration the data was written
		in. */
		memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x17ByteLength );
		xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, x17ByteLength, sbDONT_BLOCK );
		prvCheckExpectedState( xReturned == x17ByteLength );

		/* The space in the buffer will have reduced by the amount of user data
		written into the buffer. */
		xReturned = xStreamBufferSpacesAvailable( xStreamBuffer );
		prvCheckExpectedState( xReturned == xExpectedSpace );
		xReturned = xStreamBufferBytesAvailable( xStreamBuffer );
		prvCheckExpectedState( xReturned == x17ByteLength );
		prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE );
		prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE );

		/* Read the 17 bytes out again. */
		xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucReadData, x17ByteLength, sbDONT_BLOCK );
		prvCheckExpectedState( xReturned == x17ByteLength );

		/* Does the data read out match that expected? */
		prvCheckExpectedState( memcmp( ( void * ) pucData, ( void * ) pucReadData, x17ByteLength ) == 0 );

		/* Full buffer space available again. */
		xReturned = xStreamBufferSpacesAvailable( xStreamBuffer );
		prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES );
		xReturned = xStreamBufferBytesAvailable( xStreamBuffer );
		prvCheckExpectedState( xReturned == 0 );
		prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE );
		prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE );
	}

	/* Fill the buffer with one message, check it is full, then read it back
	again and check the correct data is received. */
	xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES, sbDONT_BLOCK );
	xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES, sbDONT_BLOCK );
	prvCheckExpectedState( memcmp( pc55ByteString, pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 );

	/* Fill the buffer one bytes at a time. */
	for( xItem = 0; xItem < sbSTREAM_BUFFER_LENGTH_BYTES; xItem++ )
	{
		/* Block time is only for test coverage, the task should never actually
		block here. */
		xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc54ByteString[ xItem ] ), sizeof( char ), sbRX_TX_BLOCK_TIME );
	}

	/* The buffer should now be full. */
	prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE );

	/* Read the message out in one go, even though it was written in individual
	bytes.  Try reading much more data than is actually available to ensure only
	the available bytes are returned (otherwise this read will write outside of
	the memory allocated anyway!). */
	xReturned = xStreamBufferReceive( xStreamBuffer, pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, sbRX_TX_BLOCK_TIME );
	prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES );
	prvCheckExpectedState( memcmp( ( const void * ) pc54ByteString, ( const void * ) pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 );

	/* Now do the opposite, write in one go and read out in single bytes. */
	xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES, sbRX_TX_BLOCK_TIME );
	prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES );
	prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE );
	prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE );
	prvCheckExpectedState( xStreamBufferBytesAvailable( xStreamBuffer ) == sbSTREAM_BUFFER_LENGTH_BYTES );
	prvCheckExpectedState( xStreamBufferSpacesAvailable( xStreamBuffer ) == 0 );

	/* Read from the buffer one byte at a time. */
	for( xItem = 0; xItem < sbSTREAM_BUFFER_LENGTH_BYTES; xItem++ )
	{
		/* Block time is only for test coverage, the task should never actually
		block here. */
		xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, sizeof( char ), sbRX_TX_BLOCK_TIME );
		prvCheckExpectedState( pc55ByteString[ xItem ] == pucFullBuffer[ 0 ] );
	}
	prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE );
	prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE );

	/* Try writing more bytes than there is space. */
	vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );
	xTimeBeforeCall = xTaskGetTickCount();
	xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, xMinimalBlockTime );
	xTimeAfterCall = xTaskGetTickCount();
	vTaskPrioritySet( NULL, uxOriginalPriority );
	prvCheckExpectedState( ( xTimeAfterCall - xTimeBeforeCall ) >= xMinimalBlockTime );
	prvCheckExpectedState( ( xTimeAfterCall - xTimeBeforeCall ) < ( xMinimalBlockTime + xAllowableMargin ) );
	prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES );
	prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE );
	prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE );

	/* No space now though. */
	xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, xMinimalBlockTime );
	prvCheckExpectedState( xReturned == 0 );

	/* Ensure data was written as expected even when there was an attempt to
	write more than was available.  This also tries to read more bytes than are
	available. */
	xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, xFullBufferSize, xMinimalBlockTime );
	prvCheckExpectedState( memcmp( ( const void * ) pucFullBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 );
	prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE );
	prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE );

	/* Clean up with data in the buffer to ensure the tests that follow don't
	see the data (the data should be discarded). */
	( void ) xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES / ( size_t ) 2, sbDONT_BLOCK );
	vPortFree( pucFullBuffer );
	xStreamBufferReset( xStreamBuffer );
}
/*-----------------------------------------------------------*/

static void prvNonBlockingSenderTask( void *pvParameters )
{
StreamBufferHandle_t xStreamBuffer;
size_t xNextChar = 0, xBytesToSend, xBytesActuallySent;
const size_t xStringLength = strlen( pc54ByteString );

	/* In this case the stream buffer has already been created and is passed
	into the task using the task's parameter. */
	xStreamBuffer = ( StreamBufferHandle_t ) pvParameters;

	/* Keep sending the string to the stream buffer as many bytes as possible in
	each go.  Doesn't block so calls can interleave with the non-blocking
	receives performed by prvNonBlockingReceiverTask(). */
	for( ;; )
	{
		/* The whole string cannot be sent at once, so xNextChar is an index to
		the position within the string that has been sent so far.  How many
		bytes are there left to send before the end of the string? */
		xBytesToSend = xStringLength - xNextChar;

		/* Attempt to send right up to the end of the string. */
		xBytesActuallySent = xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc54ByteString[ xNextChar ] ), xBytesToSend, sbDONT_BLOCK );
		prvCheckExpectedState( xBytesActuallySent <= xBytesToSend );

		/* Move the index up the string to the next character to be sent,
		wrapping if the end of the string has been reached. */
		xNextChar += xBytesActuallySent;
		prvCheckExpectedState( xNextChar <= xStringLength );

		if( xNextChar == xStringLength )
		{
			xNextChar = 0;
		}
	}
}
/*-----------------------------------------------------------*/

static void prvNonBlockingReceiverTask( void *pvParameters )
{
StreamBufferHandle_t xStreamBuffer;
size_t xNextChar = 0, xReceiveLength, xBytesToTest, xStartIndex;
const size_t xStringLength = strlen( pc54ByteString );
char cRxString[ 12 ]; /* Holds received characters. */
BaseType_t xNonBlockingReceiveError = pdFALSE;

	/* In this case the stream buffer has already been created and is passed
	into the task using the task's parameter. */
	xStreamBuffer = ( StreamBufferHandle_t ) pvParameters;

	/* Expects to receive the pc54ByteString over and over again.  Sends and
	receives are not blocking so will interleave. */
	for( ;; )
	{
		/* Attempt to receive as many bytes as possible, up to the limit of the
		Rx buffer size. */
		xReceiveLength = xStreamBufferReceive( xStreamBuffer, ( void * ) cRxString, sizeof( cRxString ), sbDONT_BLOCK );

		if( xReceiveLength > 0 )
		{
			/* xNextChar is the index into pc54ByteString that has been received
			already.  If xReceiveLength bytes are added to that, will it go off
			the end of the string?  If so, then first test up to the end of the
			string, then go back to the start of pc54ByteString to test the
			remains of the received data. */
			xBytesToTest = xReceiveLength;
			if( ( xNextChar + xBytesToTest ) > xStringLength )
			{
				/* Cap to test the received data to the end of the string. */
				xBytesToTest = xStringLength - xNextChar;

				if( memcmp( ( const void * ) &( pc54ByteString[ xNextChar ] ), ( const void * ) cRxString, xBytesToTest ) != 0 )
				{
					xNonBlockingReceiveError = pdTRUE;
				}

				/* Then move back to the start of the string to test the
				remaining received bytes. */
				xNextChar = 0;
				xStartIndex = xBytesToTest;
				xBytesToTest = xReceiveLength - xBytesToTest;
			}
			else
			{
				/* The string didn't wrap in the buffer, so start comparing from
				the start of the received data. */
				xStartIndex = 0;
			}

			/* Test the received bytes are as expected, then move the index
			along the string to the next expected char to receive. */
			if( memcmp( ( const void * ) &( pc54ByteString[ xNextChar ] ), ( const void * ) &( cRxString[ xStartIndex ] ), xBytesToTest ) != 0 )
			{
				xNonBlockingReceiveError = pdTRUE;
			}

			if( xNonBlockingReceiveError == pdFALSE )
			{
				/* No errors detected so increment the counter that lets the
				check task know this test is still functioning correctly. */
				ulNonBlockingRxCounter++;
			}

			xNextChar += xBytesToTest;
			if( xNextChar >= xStringLength )
			{
				xNextChar = 0;
			}
		}
	}
}
/*-----------------------------------------------------------*/

#if( configSUPPORT_STATIC_ALLOCATION == 1  )

	static void prvSenderTask( void *pvParameters )
	{
	StreamBufferHandle_t xStreamBuffer, xTempStreamBuffer;
	static uint8_t ucTempBuffer[ 10 ]; /* Just used to exercise stream buffer creating and deletion. */
	const TickType_t xTicksToWait = sbRX_TX_BLOCK_TIME, xShortDelay = pdMS_TO_TICKS( 50 );
	StaticStreamBuffer_t xStaticStreamBuffer;
	size_t xNextChar = 0, xBytesToSend, xBytesActuallySent;
	const size_t xStringLength = strlen( pc55ByteString );

	/* The task's priority is used as an index into the loop counters used to
	indicate this task is still running. */
	UBaseType_t uxIndex = uxTaskPriorityGet( NULL );

		/* Make sure a change in priority does not inadvertently result in an
		invalid array index. */
		prvCheckExpectedState( uxIndex < sbNUMBER_OF_ECHO_CLIENTS );

		/* Avoid compiler warnings about unused parameters. */
		( void ) pvParameters;

		xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ) / sbNUMBER_OF_SENDER_TASKS, /* The number of bytes in each buffer in the array. */
												   sbTRIGGER_LEVEL_1, /* The number of bytes to be in the buffer before a task blocked to wait for data is unblocked. */
												   &( ucBufferStorage[ uxIndex ][ 0 ] ), /* The address of the buffer to use within the array. */
												   &( xStaticStreamBuffers[ uxIndex ] ) ); /* The static stream buffer structure to use within the array. */

		/* Now the stream buffer has been created the receiver task can be
		created.  If this sender task has the higher priority then the receiver
		task is created at the lower priority - if this sender task has the
		lower priority then the receiver task is created at the higher
		priority. */
		if( uxTaskPriorityGet( NULL ) == sbLOWER_PRIORITY )
		{
			/* Here prvSingleTaskTests() performs various tests on a stream buffer
			that was created statically. */
			prvSingleTaskTests( xStreamBuffer );
			xTaskCreate( prvReceiverTask, "StrReceiver", sbSTACK_SIZE,  ( void * ) xStreamBuffer, sbHIGHER_PRIORITY, NULL );
		}
		else
		{
			xTaskCreate( prvReceiverTask, "StrReceiver", sbSTACK_SIZE,  ( void * ) xStreamBuffer, sbLOWER_PRIORITY, NULL );
		}

		for( ;; )
		{
			/* The whole string cannot be sent at once, so xNextChar is an index
			to the position within the string that has been sent so far.  How
			many bytes are there left to send before the end of the string? */
			xBytesToSend = xStringLength - xNextChar;

			/* Attempt to send right up to the end of the string. */
			xBytesActuallySent = xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc55ByteString[ xNextChar ] ), xBytesToSend, xTicksToWait );
			prvCheckExpectedState( xBytesActuallySent <= xBytesToSend );

			/* Move the index up the string to the next character to be sent,
			wrapping if the end of the string has been reached. */
			xNextChar += xBytesActuallySent;
			prvCheckExpectedState( xNextChar <= xStringLength );

			if( xNextChar == xStringLength )
			{
				xNextChar = 0;
			}

			/* Increment a loop counter so a check task can tell this task is
			still running as expected. */
			ulSenderLoopCounters[ uxIndex ]++;

			if( uxTaskPriorityGet( NULL ) == sbHIGHER_PRIORITY )
			{
				/* Allow other tasks to run. */
				vTaskDelay( xShortDelay );
			}

			/* This stream buffer is just created and deleted to ensure no
			issues when attempting to delete a stream buffer that was
			created using statically allocated memory.  To save stack space
			the buffer is set to point to the pc55ByteString, which is a const
			string, but no data is written into the buffer so any valid address
			will do. */
			xTempStreamBuffer = xStreamBufferCreateStatic( sizeof( ucTempBuffer ), sbTRIGGER_LEVEL_1, ucTempBuffer, &xStaticStreamBuffer );
			xStreamBufferReset( xTempStreamBuffer );
			vStreamBufferDelete( xTempStreamBuffer );
		}
	}

#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/

#if( configSUPPORT_STATIC_ALLOCATION == 1  )

	static void prvReceiverTask( void *pvParameters )
	{
	StreamBufferHandle_t const pxStreamBuffer = ( StreamBufferHandle_t ) pvParameters;
	char cRxString[ 12 ]; /* Large enough to hold a 32-bit number in ASCII. */
	const TickType_t xTicksToWait = pdMS_TO_TICKS( 5UL );
	const size_t xStringLength = strlen( pc55ByteString );
	size_t xNextChar = 0, xReceivedLength, xBytesToReceive;

		for( ;; )
		{
			/* Attempt to receive the number of bytes to the end of the string,
			or the number of byte that can be placed into the rx buffer,
			whichever is smallest. */
			xBytesToReceive = configMIN( ( xStringLength - xNextChar ), sizeof( cRxString ) );

			do
			{
				xReceivedLength = xStreamBufferReceive( pxStreamBuffer, ( void * ) cRxString, xBytesToReceive, xTicksToWait );

			} while( xReceivedLength == 0 );

			/* Ensure the received string matches the expected string. */
			prvCheckExpectedState( memcmp( ( void * ) cRxString, ( const void * ) &( pc55ByteString[ xNextChar ] ), xReceivedLength ) == 0 );

			/* Move the index into the string up to the end of the bytes
			received so far - wrapping if the end of the string has been
			reached. */
			xNextChar += xReceivedLength;
			if( xNextChar >= xStringLength )
			{
				xNextChar = 0;
			}
		}
	}

#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/

static void prvEchoClient( void *pvParameters )
{
size_t xSendLength = 0, ux;
char *pcStringToSend, *pcStringReceived, cNextChar = sbASCII_SPACE;
const TickType_t xTicksToWait = pdMS_TO_TICKS( 50 );
StreamBufferHandle_t xTempStreamBuffer;

/* The task's priority is used as an index into the loop counters used to
indicate this task is still running. */
UBaseType_t uxIndex = uxTaskPriorityGet( NULL );

/* Pointers to the client and server stream buffers are passed into this task
using the task's parameter. */
EchoStreamBuffers_t *pxStreamBuffers = ( EchoStreamBuffers_t * ) pvParameters;

	/* Prevent compiler warnings. */
	( void ) pvParameters;

	/* Create the buffer into which strings to send to the server will be
	created, and the buffer into which strings echoed back from the server will
	be copied. */
	pcStringToSend = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES );
	pcStringReceived = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES );

	configASSERT( pcStringToSend );
	configASSERT( pcStringReceived );

	for( ;; )
	{
		/* Generate the length of the next string to send. */
		xSendLength++;

		/* The stream buffer is being used to hold variable length data, so
		each data item requires sizeof( size_t ) bytes to hold the data's
		length, hence the sizeof() in the if() condition below. */
		if( xSendLength > ( sbSTREAM_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) )
		{
			/* Back to a string length of 1. */
			xSendLength = sizeof( char );
		}

		memset( pcStringToSend, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );

		for( ux = 0; ux < xSendLength; ux++ )
		{
			pcStringToSend[ ux ] = cNextChar;

			cNextChar++;

			if( cNextChar > sbASCII_TILDA )
			{
				cNextChar = sbASCII_SPACE;
			}
		}

		/* Send the generated string to the buffer. */
		do
		{
			ux = xStreamBufferSend( pxStreamBuffers->xEchoClientBuffer, ( void * ) pcStringToSend, xSendLength, xTicksToWait );

		} while( ux == 0 );

		/* Wait for the string to be echoed back. */
		memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );
		xStreamBufferReceive( pxStreamBuffers->xEchoServerBuffer, ( void * ) pcStringReceived, xSendLength, portMAX_DELAY );

		prvCheckExpectedState( strcmp( pcStringToSend, pcStringReceived ) == 0 );

		/* Maintain a count of the number of times this code executes so a
		check task can determine if this task is still functioning as
		expected or not.  As there are two client tasks, and the priorities
		used are 0 and 1, the task's priority is used as an index into the
		loop count array. */
		ulEchoLoopCounters[ uxIndex ]++;

		/* This stream buffer is just created and deleted to ensure no memory
		leaks. */
		xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 );
		prvSingleTaskTests( xTempStreamBuffer );
		vStreamBufferDelete( xTempStreamBuffer );

		/* The following are tests for a stream buffer of size one. */
		/* Create a buffer of size one. */
		xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_ONE, sbTRIGGER_LEVEL_1 );
		/* Ensure that the buffer was created successfully. */
		configASSERT( xTempStreamBuffer );

		/* Send one byte to the buffer. */
		ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK );
		/* Ensure that the byte was sent successfully. */
		configASSERT( ux == 1 );
		/* Try sending another byte to the buffer. */
		ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK );
		/* Make sure that send failed as the buffer is full. */
		configASSERT( ux == 0 );

		/* Receive one byte from the buffer. */
		memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );
		ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK );
		/* Ensure that the receive was successful. */
		configASSERT( ux == 1 );
		/* Ensure that the correct data was received. */
		configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] );
		/* Try receiving another byte from the buffer. */
		ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK );
		/* Ensure that the receive failed as the buffer is empty. */
		configASSERT( ux == 0 );

		/* Try sending two bytes to the buffer. Since the size of the
		 * buffer is one, we must not be able to send more than one. */
		ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 2, sbDONT_BLOCK );
		/* Ensure that only one byte was sent. */
		configASSERT( ux == 1 );

		/* Try receiving two bytes from the buffer. Since the size of the
		 * buffer is one, we must not be able to get more than one. */
		memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );
		ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 2, sbDONT_BLOCK );
		/* Ensure that only one byte was received. */
		configASSERT( ux == 1 );
		/* Ensure that the correct data was received. */
		configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] );

		/* Delete the buffer. */
		vStreamBufferDelete( xTempStreamBuffer );
	}
}
/*-----------------------------------------------------------*/

static void prvEchoServer( void *pvParameters )
{
size_t xReceivedLength;
char *pcReceivedString;
EchoStreamBuffers_t xStreamBuffers;
TickType_t xTimeOnEntering;
const TickType_t xTicksToBlock = pdMS_TO_TICKS( 350UL );

	/* Prevent compiler warnings about unused parameters. */
	( void ) pvParameters;

	/* Create the stream buffer used to send data from the client to the server,
	and the stream buffer used to echo the data from the server back to the
	client. */
	xStreamBuffers.xEchoClientBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 );
	xStreamBuffers.xEchoServerBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 );
	configASSERT( xStreamBuffers.xEchoClientBuffer );
	configASSERT( xStreamBuffers.xEchoServerBuffer );

	/* Create the buffer into which received strings will be copied. */
	pcReceivedString = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES );
	configASSERT( pcReceivedString );

	/* Don't expect to receive anything yet! */
	xTimeOnEntering = xTaskGetTickCount();
	xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, xTicksToBlock );
	prvCheckExpectedState( ( ( TickType_t ) ( xTaskGetTickCount() - xTimeOnEntering ) ) >= xTicksToBlock );
	prvCheckExpectedState( xReceivedLength == 0 );

	/* Now the stream buffers have been created the echo client task can be
	created.  If this server task has the higher priority then the client task
	is created at the lower priority - if this server task has the lower
	priority then the client task is created at the higher priority. */
	if( uxTaskPriorityGet( NULL ) == sbLOWER_PRIORITY )
	{
		xTaskCreate( prvEchoClient, "EchoClient", sbSTACK_SIZE,  ( void * ) &xStreamBuffers, sbHIGHER_PRIORITY, NULL );
	}
	else
	{
		/* Here prvSingleTaskTests() performs various tests on a stream buffer
		that was created dynamically. */
		prvSingleTaskTests( xStreamBuffers.xEchoClientBuffer );
		xTaskCreate( prvEchoClient, "EchoClient", sbSTACK_SIZE, ( void * ) &xStreamBuffers, sbLOWER_PRIORITY, NULL );
	}

	for( ;; )
	{
		memset( pcReceivedString, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );

		/* Has any data been sent by the client? */
		xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, portMAX_DELAY );

		/* Should always receive data as max delay was used. */
		prvCheckExpectedState( xReceivedLength > 0 );

		/* Echo the received data back to the client. */
		xStreamBufferSend( xStreamBuffers.xEchoServerBuffer, ( void * ) pcReceivedString, xReceivedLength, portMAX_DELAY );
	}
}
/*-----------------------------------------------------------*/

void vPeriodicStreamBufferProcessing( void )
{
static size_t xNextChar = 0;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

	/* Called from the tick interrupt hook.  If the global stream buffer
	variable is not NULL then the prvInterruptTriggerTest() task expects a byte
	to be sent to the stream buffer on each tick interrupt. */
	if( xInterruptStreamBuffer != NULL )
	{
		/* One character from the pcDataSentFromInterrupt string is sent on each
		interrupt.  The task blocked on the stream buffer should not be
		unblocked until the defined trigger level is hit. */
		xStreamBufferSendFromISR( xInterruptStreamBuffer, ( const void * ) &( pcDataSentFromInterrupt[ xNextChar ] ), sizeof( char ), &xHigherPriorityTaskWoken );

		if( xNextChar < strlen( pcDataSentFromInterrupt ) )
		{
			xNextChar++;
		}
	}
	else
	{
		/* Start at the beginning of the string being sent again. */
		xNextChar = 0;
	}
}
/*-----------------------------------------------------------*/

static void prvInterruptTriggerLevelTest( void *pvParameters )
{
StreamBufferHandle_t xStreamBuffer;
size_t xTriggerLevel = 1, xBytesReceived;
const size_t xStreamBufferSizeBytes = ( size_t ) 8, xMaxTriggerLevel = ( size_t ) 6, xMinTriggerLevel = ( size_t ) 1;
const TickType_t xReadBlockTime = 4, xCycleBlockTime = pdMS_TO_TICKS( 100 );
uint8_t ucRxData[ 8 ];
BaseType_t xErrorDetected = pdFALSE;
#ifndef configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN
    const size_t xAllowableMargin = ( size_t ) 0;
#else
    const size_t xAllowableMargin = ( size_t ) configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN;
#endif

	/* Remove compiler warning about unused parameter. */
	( void ) pvParameters;

	for( ;; )
	{
		for( xTriggerLevel = xMinTriggerLevel; xTriggerLevel < xMaxTriggerLevel; xTriggerLevel++ )
		{
			/* Create the stream buffer that will be used from inside the tick
			interrupt. */
			memset( ucRxData, 0x00, sizeof( ucRxData ) );
			xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
			configASSERT( xStreamBuffer );

			/* Now the stream buffer has been created it can be assigned to the
			file scope variable, which will allow the tick interrupt to start
			using it. */
			taskENTER_CRITICAL();
			{
				xInterruptStreamBuffer = xStreamBuffer;
			}
			taskEXIT_CRITICAL();

			xBytesReceived = xStreamBufferReceive( xStreamBuffer, ( void * ) ucRxData, sizeof( ucRxData ), xReadBlockTime );

			/* Set the file scope variable back to NULL so the interrupt doesn't
			try to use it again. */
			taskENTER_CRITICAL();
			{
				xInterruptStreamBuffer = NULL;
			}
			taskEXIT_CRITICAL();

			/* Now check the number of bytes received equals the trigger level,
			except in the case that the read timed out before the trigger level
			was reached. */
			if( xTriggerLevel > xReadBlockTime )
			{
				/* Trigger level was greater than the block time so expect to
				time out having received xReadBlockTime bytes. */
				if( ( xReadBlockTime - xBytesReceived ) > xAllowableMargin )
				{
					xErrorDetected = pdTRUE;
				}
			}
			else if( xTriggerLevel < xReadBlockTime )
			{
				/* Trigger level was less than the block time so we expect to
				have received the trigger level number of bytes - could be more
				though depending on other activity between the task being
				unblocked and the task reading the number of bytes received. */
				if( ( xBytesReceived - xTriggerLevel ) > xAllowableMargin )
				{
					xErrorDetected = pdTRUE;
				}
			}
			else
			{
				/* The trigger level equaled the block time, so expect to
				receive no greater than the block time, but one or two less is
				ok due to variations in how far through the time slice the
				functions get executed. */
				if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin )
				{
					xErrorDetected = pdTRUE;
				}
			}

			if( xBytesReceived > sizeof( ucRxData ) )
			{
				xErrorDetected = pdTRUE;
			}
			else if( memcmp( ( void * ) ucRxData, ( const void * ) pcDataSentFromInterrupt, xBytesReceived ) != 0 )
			{
				/* Received data didn't match that expected. */
				xErrorDetected = pdTRUE;
			}

			if( xErrorDetected == pdFALSE )
			{
				/* Increment the cycle counter so the 'check' task knows this test
				is still running without error. */
				ulInterruptTriggerCounter++;
			}

			/* Tidy up ready for the next loop. */
			vStreamBufferDelete( xStreamBuffer );
			vTaskDelay( xCycleBlockTime );
		}
	}
}
/*-----------------------------------------------------------*/

BaseType_t xAreStreamBufferTasksStillRunning( void )
{
static uint32_t ulLastEchoLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 };
static uint32_t ulLastNonBlockingRxCounter = 0;
static uint32_t ulLastInterruptTriggerCounter = 0;
BaseType_t x;

	for( x = 0; x < sbNUMBER_OF_ECHO_CLIENTS; x++ )
	{
		if( ulLastEchoLoopCounters[ x ] == ulEchoLoopCounters[ x ] )
		{
			xErrorStatus = pdFAIL;
		}
		else
		{
			ulLastEchoLoopCounters[ x ] = ulEchoLoopCounters[ x ];
		}
	}

	if( ulNonBlockingRxCounter == ulLastNonBlockingRxCounter )
	{
		xErrorStatus = pdFAIL;
	}
	else
	{
		ulLastNonBlockingRxCounter = ulNonBlockingRxCounter;
	}

	if( ulLastInterruptTriggerCounter == ulInterruptTriggerCounter )
	{
		xErrorStatus = pdFAIL;
	}
	else
	{
		ulLastInterruptTriggerCounter = ulInterruptTriggerCounter;
	}

	#if( configSUPPORT_STATIC_ALLOCATION == 1 )
	{
		static uint32_t ulLastSenderLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 };

		for( x = 0; x < sbNUMBER_OF_SENDER_TASKS; x++ )
		{
			if( ulLastSenderLoopCounters[ x ] == ulSenderLoopCounters[ x ] )
			{
				xErrorStatus = pdFAIL;
			}
			else
			{
				ulLastSenderLoopCounters[ x ] = ulSenderLoopCounters[ x ];
			}
		}
	}
	#endif /* configSUPPORT_STATIC_ALLOCATION */

	return xErrorStatus;
}
/*-----------------------------------------------------------*/

