blob: d35455ec78ee3f039c2b0f6f684fb4986c939c8c [file] [log] [blame]
/*
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available from the following
link: http://www.freertos.org/a00114.html
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/*
* Basic task to demonstrate the xQueueOverwrite() function. See the comments
* in the function itself.
*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Demo program include files. */
#include "QueueOverwrite.h"
/* A block time of 0 just means "don't block". */
#define qoDONT_BLOCK 0
/* Number of times to overwrite the value in the queue. */
#define qoLOOPS 5
/* The task that uses the queue. */
static void prvQueueOverwriteTask( void *pvParameters );
/* Variable that is incremented on each loop of prvQueueOverwriteTask() provided
prvQueueOverwriteTask() has not found any errors. */
static unsigned long ulLoopCounter = 0;
/* Set to pdFALSE if an error is discovered by the
vQueueOverwritePeriodicISRDemo() function. */
static portBASE_TYPE xISRTestStatus = pdPASS;
/* The queue that is accessed from the ISR. The queue accessed by the task is
created inside the task itself. */
static QueueHandle_t xISRQueue = NULL;
/*-----------------------------------------------------------*/
void vStartQueueOverwriteTask( unsigned portBASE_TYPE uxPriority )
{
const unsigned portBASE_TYPE uxQueueLength = 1;
/* Create the queue used by the ISR. xQueueOverwriteFromISR() should only
be used on queues that have a length of 1. */
xISRQueue = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( unsigned long ) );
/* Create the test task. The queue used by the test task is created inside
the task itself. */
xTaskCreate( prvQueueOverwriteTask, "QOver", configMINIMAL_STACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );
}
/*-----------------------------------------------------------*/
static void prvQueueOverwriteTask( void *pvParameters )
{
QueueHandle_t xTaskQueue;
const unsigned portBASE_TYPE uxQueueLength = 1;
unsigned long ulValue, ulStatus = pdPASS, x;
/* The parameter is not used. */
( void ) pvParameters;
/* Create the queue. xQueueOverwrite() should only be used on queues that
have a length of 1. */
xTaskQueue = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( unsigned long ) );
configASSERT( xTaskQueue );
for( ;; )
{
/* The queue is empty. Writing to the queue then reading from the queue
should return the item written. */
ulValue = 10;
xQueueOverwrite( xTaskQueue, &ulValue );
ulValue = 0;
xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );
if( ulValue != 10 )
{
ulStatus = pdFAIL;
}
/* Now try writing to the queue several times. Each time the value
in the queue should get overwritten. */
for( x = 0; x < qoLOOPS; x++ )
{
/* Write to the queue. */
xQueueOverwrite( xTaskQueue, &x );
/* Check the value in the queue is that written, even though the
queue was not necessarily empty. */
xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK );
if( ulValue != x )
{
ulStatus = pdFAIL;
}
/* There should always be one item in the queue. */
if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength )
{
ulStatus = pdFAIL;
}
}
/* Empty the queue again. */
xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );
if( uxQueueMessagesWaiting( xTaskQueue ) != 0 )
{
ulStatus = pdFAIL;
}
if( ulStatus != pdFAIL )
{
/* Increment a counter to show this task is still running without
error. */
ulLoopCounter++;
}
#if( configUSE_PREEMPTION == 0 )
taskYIELD();
#endif
}
}
/*-----------------------------------------------------------*/
portBASE_TYPE xIsQueueOverwriteTaskStillRunning( void )
{
portBASE_TYPE xReturn;
if( xISRTestStatus != pdPASS )
{
xReturn = pdFAIL;
}
else if( ulLoopCounter > 0 )
{
xReturn = pdPASS;
}
else
{
/* The task has either stalled of discovered an error. */
xReturn = pdFAIL;
}
ulLoopCounter = 0;
return xReturn;
}
/*-----------------------------------------------------------*/
void vQueueOverwritePeriodicISRDemo( void )
{
static unsigned long ulCallCount = 0;
const unsigned long ulTx1 = 10UL, ulTx2 = 20UL, ulNumberOfSwitchCases = 3UL;
unsigned long ulRx;
/* This function should be called from an interrupt, such as the tick hook
function vApplicationTickHook(). */
configASSERT( xISRQueue );
switch( ulCallCount )
{
case 0:
/* The queue is empty. Write ulTx1 to the queue. In this demo the
last parameter is not used because there are no tasks blocked on
this queue. */
xQueueOverwriteFromISR( xISRQueue, &ulTx1, NULL );
/* Peek the queue to check it holds the expected value. */
xQueuePeekFromISR( xISRQueue, &ulRx );
if( ulRx != ulTx1 )
{
xISRTestStatus = pdFAIL;
}
break;
case 1:
/* The queue already holds ulTx1. Overwrite the value in the queue
with ulTx2. */
xQueueOverwriteFromISR( xISRQueue, &ulTx2, NULL );
break;
case 2:
/* Read from the queue to empty the queue again. The value read
should be ulTx2. */
xQueueReceiveFromISR( xISRQueue, &ulRx, NULL );
if( ulRx != ulTx2 )
{
xISRTestStatus = pdFAIL;
}
break;
}
/* Run the next case in the switch statement above next time this function
is called. */
ulCallCount++;
if( ulCallCount >= ulNumberOfSwitchCases )
{
/* Go back to the start. */
ulCallCount = 0;
}
}