mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 17:48:33 -04:00
First version under SVN is V4.0.1
This commit is contained in:
parent
243393860c
commit
b6df57c7e3
918 changed files with 269038 additions and 0 deletions
111
Source/include/FreeRTOS.h
Normal file
111
Source/include/FreeRTOS.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#define INC_FREERTOS_H
|
||||
|
||||
|
||||
/*
|
||||
* Include the generic headers required for the FreeRTOS port being used.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
|
||||
/* Basic FreeRTOS definitions. */
|
||||
#include "projdefs.h"
|
||||
|
||||
/* Application specific configuration options. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
/* Definitions specific to the port being used. */
|
||||
#include "portable.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Check all the required application specific macros have been defined.
|
||||
* These macros are application specific and (as downloaded) are defined
|
||||
* within FreeRTOSConfig.h.
|
||||
*/
|
||||
|
||||
#ifndef configUSE_PREEMPTION
|
||||
#error Missing definition: configUSE_PREEMPTION 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_IDLE_HOOK
|
||||
#error Missing definition: configUSE_IDLE_HOOK 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_TICK_HOOK
|
||||
#error Missing definition: configUSE_TICK_HOOK 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_CO_ROUTINES
|
||||
#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskPrioritySet
|
||||
#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_uxTaskPriorityGet
|
||||
#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelete
|
||||
#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskCleanUpResources
|
||||
#error Missing definition: INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskSuspend
|
||||
#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelayUntil
|
||||
#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelay
|
||||
#error Missing definition: INCLUDE_vTaskDelay 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_16_BIT_TICKS
|
||||
#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
|
||||
|
||||
#endif
|
713
Source/include/croutine.h
Normal file
713
Source/include/croutine.h
Normal file
|
@ -0,0 +1,713 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
#ifndef CO_ROUTINE_H
|
||||
#define CO_ROUTINE_H
|
||||
|
||||
#include "list.h"
|
||||
|
||||
/* Used to hide the implementation of the co-routine control block. The
|
||||
control block structure however has to be included in the header due to
|
||||
the macro implementation of the co-routine functionality. */
|
||||
typedef void * xCoRoutineHandle;
|
||||
|
||||
/* Defines the prototype to which co-routine functions must conform. */
|
||||
typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
|
||||
|
||||
typedef struct corCoRoutineControlBlock
|
||||
{
|
||||
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||
xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
||||
xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */
|
||||
unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
||||
unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
||||
unsigned portSHORT uxState; /*< Used internally by the co-routine implementation. */
|
||||
} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
portBASE_TYPE xCoRoutineCreate(
|
||||
crCOROUTINE_CODE pxCoRoutineCode,
|
||||
unsigned portBASE_TYPE uxPriority,
|
||||
unsigned portBASE_TYPE uxIndex
|
||||
);</pre>
|
||||
*
|
||||
* Create a new co-routine and add it to the list of co-routines that are
|
||||
* ready to run.
|
||||
*
|
||||
* @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
|
||||
* functions require special syntax - see the co-routine section of the WEB
|
||||
* documentation for more information.
|
||||
*
|
||||
* @param uxPriority The priority with respect to other co-routines at which
|
||||
* the co-routine will run.
|
||||
*
|
||||
* @param uxIndex Used to distinguish between different co-routines that
|
||||
* execute the same function. See the example below and the co-routine section
|
||||
* of the WEB documentation for further information.
|
||||
*
|
||||
* @return pdPASS if the co-routine was successfully created and added to a ready
|
||||
* list, otherwise an error code defined with ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
// This may not be necessary for const variables.
|
||||
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||
static const portTickType xTimeToDelay[ 2 ] = { 200, 400 };
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// This co-routine just delays for a fixed period, then toggles
|
||||
// an LED. Two co-routines are created using this function, so
|
||||
// the uxIndex parameter is used to tell the co-routine which
|
||||
// LED to flash and how long to delay. This assumes xQueue has
|
||||
// already been created.
|
||||
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}
|
||||
|
||||
// Function that creates two co-routines.
|
||||
void vOtherFunction( void )
|
||||
{
|
||||
unsigned char ucParameterToPass;
|
||||
xTaskHandle xHandle;
|
||||
|
||||
// Create two co-routines at priority 0. The first is given index 0
|
||||
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||
// is given index 1 so toggles LED 6 every 400 ticks.
|
||||
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||
{
|
||||
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
|
||||
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
void vCoRoutineSchedule( void );</pre>
|
||||
*
|
||||
* Run a co-routine.
|
||||
*
|
||||
* vCoRoutineSchedule() executes the highest priority co-routine that is able
|
||||
* to run. The co-routine will execute until it either blocks, yields or is
|
||||
* preempted by a task. Co-routines execute cooperatively so one
|
||||
* co-routine cannot be preempted by another, but can be preempted by a task.
|
||||
*
|
||||
* If an application comprises of both tasks and co-routines then
|
||||
* vCoRoutineSchedule should be called from the idle task (in an idle task
|
||||
* hook).
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// This idle task hook will schedule a co-routine each time it is called.
|
||||
// The rest of the idle task will execute between co-routine calls.
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
vCoRoutineSchedule();
|
||||
}
|
||||
|
||||
// Alternatively, if you do not require any other part of the idle task to
|
||||
// execute, the idle task hook can call vCoRoutineScheduler() within an
|
||||
// infinite loop.
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
vCoRoutineSchedule();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
void vCoRoutineSchedule( void );
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crSTART( xCoRoutineHandle xHandle );</pre>
|
||||
*
|
||||
* This macro MUST always be called at the start of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static portLONG ulAVariable;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Co-routine functionality goes here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crEND();</pre>
|
||||
*
|
||||
* This macro MUST always be called at the end of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static portLONG ulAVariable;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Co-routine functionality goes here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crEND() }
|
||||
|
||||
/*
|
||||
* These macros are intended for internal use by the co-routine implementation
|
||||
* only. The macros should not be used directly by application writers.
|
||||
*/
|
||||
#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
||||
#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
|
||||
*
|
||||
* Delay a co-routine for a fixed period of time.
|
||||
*
|
||||
* crDELAY can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* @param xHandle The handle of the co-routine to delay. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should delay
|
||||
* for. The actual amount of time this equates to is defined by
|
||||
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
|
||||
* can be used to convert ticks to milliseconds.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
// This may not be necessary for const variables.
|
||||
// We are to delay for 200ms.
|
||||
static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Delay for 200ms.
|
||||
crDELAY( xHandle, xDelayTime );
|
||||
|
||||
// Do something here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crDELAY crDELAY
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crDELAY( xHandle, xTicksToDelay ) \
|
||||
if( xTicksToDelay > 0 ) \
|
||||
{ \
|
||||
vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \
|
||||
} \
|
||||
crSET_STATE0( xHandle );
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
crQUEUE_SEND(
|
||||
xCoRoutineHandle xHandle,
|
||||
xQueueHandle pxQueue,
|
||||
void *pvItemToQueue,
|
||||
portTickType xTicksToWait,
|
||||
portBASE_TYPE *pxResult
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||
*
|
||||
* crQUEUE_SEND can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param pxQueue The handle of the queue on which the data will be posted.
|
||||
* The handle is obtained as the return value when the queue is created using
|
||||
* the xQueueCreate() API function.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the data being posted onto the queue.
|
||||
* The number of bytes of each queued item is specified when the queue is
|
||||
* created. This number of bytes is copied from pvItemToQueue into the queue
|
||||
* itself.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||
* to wait for space to become available on the queue, should space not be
|
||||
* available immediately. The actual amount of time this equates to is defined
|
||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
|
||||
* below).
|
||||
*
|
||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||
* data was successfully posted onto the queue, otherwise it will be set to an
|
||||
* error defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine function that blocks for a fixed period then posts a number onto
|
||||
// a queue.
|
||||
static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static portBASE_TYPE xNumberToPost = 0;
|
||||
static portBASE_TYPE xResult;
|
||||
|
||||
// Co-routines must begin with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// This assumes the queue has already been created.
|
||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||
|
||||
if( xResult != pdPASS )
|
||||
{
|
||||
// The message was not posted!
|
||||
}
|
||||
|
||||
// Increment the number to be posted onto the queue.
|
||||
xNumberToPost++;
|
||||
|
||||
// Delay for 100 ticks.
|
||||
crDELAY( xHandle, 100 );
|
||||
}
|
||||
|
||||
// Co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
|
||||
{ \
|
||||
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \
|
||||
if( *pxResult == errQUEUE_BLOCKED ) \
|
||||
{ \
|
||||
crSET_STATE0( xHandle ); \
|
||||
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \
|
||||
} \
|
||||
if( *pxResult == errQUEUE_YIELD ) \
|
||||
{ \
|
||||
crSET_STATE1( xHandle ); \
|
||||
*pxResult = pdPASS; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_RECEIVE(
|
||||
xCoRoutineHandle xHandle,
|
||||
xQueueHandle pxQueue,
|
||||
void *pvBuffer,
|
||||
portTickType xTicksToWait,
|
||||
portBASE_TYPE *pxResult
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||
*
|
||||
* crQUEUE_RECEIVE can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param pxQueue The handle of the queue from which the data will be received.
|
||||
* The handle is obtained as the return value when the queue is created using
|
||||
* the xQueueCreate() API function.
|
||||
*
|
||||
* @param pvBuffer The buffer into which the received item is to be copied.
|
||||
* The number of bytes of each queued item is specified when the queue is
|
||||
* created. This number of bytes is copied into pvBuffer.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||
* to wait for data to become available from the queue, should data not be
|
||||
* available immediately. The actual amount of time this equates to is defined
|
||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
|
||||
* crQUEUE_SEND example).
|
||||
*
|
||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||
* data was successfully retrieved from the queue, otherwise it will be set to
|
||||
* an error code as defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine receives the number of an LED to flash from a queue. It
|
||||
// blocks on the queue until the number is received.
|
||||
static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static portBASE_TYPE xResult;
|
||||
static unsigned portBASE_TYPE uxLEDToFlash;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Wait for data to become available on the queue.
|
||||
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// We received the LED to flash - flash it!
|
||||
vParTestToggleLED( uxLEDToFlash );
|
||||
}
|
||||
}
|
||||
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
|
||||
{ \
|
||||
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \
|
||||
if( *pxResult == errQUEUE_BLOCKED ) \
|
||||
{ \
|
||||
crSET_STATE0( xHandle ); \
|
||||
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \
|
||||
} \
|
||||
if( *pxResult == errQUEUE_YIELD ) \
|
||||
{ \
|
||||
crSET_STATE1( xHandle ); \
|
||||
*pxResult = pdPASS; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_SEND_FROM_ISR(
|
||||
xQueueHandle pxQueue,
|
||||
void *pvItemToQueue,
|
||||
portBASE_TYPE xCoRoutinePreviouslyWoken
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
* functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||
* ISR.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
|
||||
* that is being used from within a co-routine.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||
* queue. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||
* into the queue storage area.
|
||||
*
|
||||
* @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
|
||||
* the same queue multiple times from a single interrupt. The first call
|
||||
* should always pass in pdFALSE. Subsequent calls should pass in
|
||||
* the value returned from the previous call.
|
||||
*
|
||||
* @return pdTRUE if a co-routine was woken by posting onto the queue. This is
|
||||
* used by the ISR to determine if a context switch may be required following
|
||||
* the ISR.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine that blocks on a queue waiting for characters to be received.
|
||||
static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
portCHAR cRxedChar;
|
||||
portBASE_TYPE xResult;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Wait for data to become available on the queue. This assumes the
|
||||
// queue xCommsRxQueue has already been created!
|
||||
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
|
||||
// Was a character received?
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// Process the character here.
|
||||
}
|
||||
}
|
||||
|
||||
// All co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}
|
||||
|
||||
// An ISR that uses a queue to send characters received on a serial port to
|
||||
// a co-routine.
|
||||
void vUART_ISR( void )
|
||||
{
|
||||
portCHAR cRxedChar;
|
||||
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
||||
|
||||
// We loop around reading characters until there are none left in the UART.
|
||||
while( UART_RX_REG_NOT_EMPTY() )
|
||||
{
|
||||
// Obtain the character from the UART.
|
||||
cRxedChar = UART_RX_REG;
|
||||
|
||||
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||
// the first time around the loop. If the post causes a co-routine
|
||||
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||
// In this manner we can ensure that if more than one co-routine is
|
||||
// blocked on the queue only one is woken by this ISR no matter how
|
||||
// many characters are posted to the queue.
|
||||
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||
}
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
|
||||
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_SEND_FROM_ISR(
|
||||
xQueueHandle pxQueue,
|
||||
void *pvBuffer,
|
||||
portBASE_TYPE * pxCoRoutineWoken
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
* functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||
* ISR.
|
||||
*
|
||||
* crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
|
||||
* from a queue that is being used from within a co-routine (a co-routine
|
||||
* posted to the queue).
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvBuffer A pointer to a buffer into which the received item will be
|
||||
* placed. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from the queue into
|
||||
* pvBuffer.
|
||||
*
|
||||
* @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
|
||||
* available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
|
||||
* co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
|
||||
* *pxCoRoutineWoken will remain unchanged.
|
||||
*
|
||||
* @return pdTRUE an item was successfully received from the queue, otherwise
|
||||
* pdFALSE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine that posts a character to a queue then blocks for a fixed
|
||||
// period. The character is incremented each time.
|
||||
static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||
{
|
||||
// cChar holds its value while this co-routine is blocked and must therefore
|
||||
// be declared static.
|
||||
static portCHAR cCharToTx = 'a';
|
||||
portBASE_TYPE xResult;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Send the next character to the queue.
|
||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// The character was successfully posted to the queue.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could not post the character to the queue.
|
||||
}
|
||||
|
||||
// Enable the UART Tx interrupt to cause an interrupt in this
|
||||
// hypothetical UART. The interrupt will obtain the character
|
||||
// from the queue and send it.
|
||||
ENABLE_RX_INTERRUPT();
|
||||
|
||||
// Increment to the next character then block for a fixed period.
|
||||
// cCharToTx will maintain its value across the delay as it is
|
||||
// declared static.
|
||||
cCharToTx++;
|
||||
if( cCharToTx > 'x' )
|
||||
{
|
||||
cCharToTx = 'a';
|
||||
}
|
||||
crDELAY( 100 );
|
||||
}
|
||||
|
||||
// All co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}
|
||||
|
||||
// An ISR that uses a queue to receive characters to send on a UART.
|
||||
void vUART_ISR( void )
|
||||
{
|
||||
portCHAR cCharToTx;
|
||||
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
||||
|
||||
while( UART_TX_REG_EMPTY() )
|
||||
{
|
||||
// Are there any characters in the queue waiting to be sent?
|
||||
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||
// is woken by the post - ensuring that only a single co-routine is
|
||||
// woken no matter how many times we go around this loop.
|
||||
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||
{
|
||||
SEND_CHARACTER( cCharToTx );
|
||||
}
|
||||
}
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
|
||||
|
||||
/*
|
||||
* This function is intended for internal use by the co-routine macros only.
|
||||
* The macro nature of the co-routine implementation requires that the
|
||||
* prototype appears here. The function should not be used by application
|
||||
* writers.
|
||||
*
|
||||
* Removes the current co-routine from its ready list and places it in the
|
||||
* appropriate delayed list.
|
||||
*/
|
||||
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
|
||||
|
||||
/*
|
||||
* This function is intended for internal use by the queue implementation only.
|
||||
* The function should not be used by application writers.
|
||||
*
|
||||
* Removes the highest priority co-routine from the event list and places it in
|
||||
* the pending ready list.
|
||||
*/
|
||||
portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
|
||||
|
||||
|
||||
#endif /* CO_ROUTINE_H */
|
270
Source/include/list.h
Normal file
270
Source/include/list.h
Normal file
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the list implementation used by the scheduler. While it is tailored
|
||||
* heavily for the schedulers needs, it is also available for use by
|
||||
* application code.
|
||||
*
|
||||
* xLists can only store pointers to xListItems. Each xListItem contains a
|
||||
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||
* descending item value order.
|
||||
*
|
||||
* Lists are created already containing one list item. The value of this
|
||||
* item is the maximum possible that can be stored, it is therefore always at
|
||||
* the end of the list and acts as a marker. The list member pxHead always
|
||||
* points to this marker - even though it is at the tail of the list. This
|
||||
* is because the tail contains a wrap back pointer to the true head of
|
||||
* the list.
|
||||
*
|
||||
* In addition to it's value, each list item contains a pointer to the next
|
||||
* item in the list (pxNext), a pointer to the list it is in (pxContainer)
|
||||
* and a pointer to back to the object that contains it. These later two
|
||||
* pointers are included for efficiency of list manipulation. There is
|
||||
* effectively a two way link between the object containing the list item and
|
||||
* the list item itself.
|
||||
*
|
||||
*
|
||||
* \page ListIntroduction List Implementation
|
||||
* \ingroup FreeRTOSIntro
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
/*
|
||||
* Definition of the only type of object that a list can contain.
|
||||
*/
|
||||
struct xLIST_ITEM
|
||||
{
|
||||
portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||
volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
|
||||
volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
|
||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||
void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||
};
|
||||
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
|
||||
|
||||
struct xMINI_LIST_ITEM
|
||||
{
|
||||
portTickType xItemValue;
|
||||
volatile struct xLIST_ITEM *pxNext;
|
||||
volatile struct xLIST_ITEM *pxPrevious;
|
||||
};
|
||||
typedef struct xMINI_LIST_ITEM xMiniListItem;
|
||||
|
||||
/*
|
||||
* Definition of the type of queue used by the scheduler.
|
||||
*/
|
||||
typedef struct xLIST
|
||||
{
|
||||
volatile unsigned portBASE_TYPE uxNumberOfItems;
|
||||
volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
|
||||
volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||
} xList;
|
||||
|
||||
/*
|
||||
* Access macro to set the owner of a list item. The owner of a list item
|
||||
* is the object (usually a TCB) that contains the list item.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner
|
||||
|
||||
/*
|
||||
* Access macro to set the value of the list item. In most cases the value is
|
||||
* used to sort the list in descending order.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue
|
||||
|
||||
/*
|
||||
* Access macro the retrieve the value of the list item. The value can
|
||||
* represent anything - for example a the priority of a task, or the time at
|
||||
* which a task should be unblocked.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||
|
||||
/*
|
||||
* Access macro to determine if a list contains any items. The macro will
|
||||
* only have the value true if the list is empty.
|
||||
*
|
||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
|
||||
|
||||
/*
|
||||
* Access macro to return the number of items in the list.
|
||||
*/
|
||||
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the next entry in a list.
|
||||
*
|
||||
* The list member pxIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
|
||||
* and returns that entries pxOwner parameter. Using multiple calls to this
|
||||
* function it is therefore possible to move through every item contained in
|
||||
* a list.
|
||||
*
|
||||
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||
* the list item. In the scheduler this is normally a task control block.
|
||||
* The pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @param pxList The list from which the next item owner is to be returned.
|
||||
*
|
||||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||
/* Increment the index to the next item and return the item, ensuring */ \
|
||||
/* we don't return the marker used at the end of the list. */ \
|
||||
( pxList )->pxIndex = ( pxList )->pxIndex->pxNext; \
|
||||
if( ( pxList )->pxIndex == ( xListItem * ) &( ( pxList )->xListEnd ) ) \
|
||||
{ \
|
||||
( pxList )->pxIndex = ( pxList )->pxIndex->pxNext; \
|
||||
} \
|
||||
pxTCB = ( pxList )->pxIndex->pvOwner
|
||||
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the first entry in a list. Lists
|
||||
* are normally sorted in ascending item value order.
|
||||
*
|
||||
* This function returns the pxOwner member of the first item in the list.
|
||||
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||
* the list item. In the scheduler this is normally a task control block.
|
||||
* The pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @param pxList The list from which the owner of the head item is to be
|
||||
* returned.
|
||||
*
|
||||
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )
|
||||
|
||||
/*
|
||||
* Check to see if a list item is within a list. The list item maintains a
|
||||
* "container" pointer that points to the list it is in. All this macro does
|
||||
* is check to see if the container and the list match.
|
||||
*
|
||||
* @param pxList The list we want to know if the list item is within.
|
||||
* @param pxListItem The list item we want to know if is in the list.
|
||||
* @return pdTRUE is the list item is in the list, otherwise pdFALSE.
|
||||
* pointer against
|
||||
*/
|
||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )
|
||||
|
||||
/*
|
||||
* Must be called before a list is used! This initialises all the members
|
||||
* of the list structure and inserts the xListEnd item into the list as a
|
||||
* marker to the back of the list.
|
||||
*
|
||||
* @param pxList Pointer to the list being initialised.
|
||||
*
|
||||
* \page vListInitialise vListInitialise
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialise( xList *pxList );
|
||||
|
||||
/*
|
||||
* Must be called before a list item is used. This sets the list container to
|
||||
* null so the item does not think that it is already contained in a list.
|
||||
*
|
||||
* @param pxItem Pointer to the list item being initialised.
|
||||
*
|
||||
* \page vListInitialiseItem vListInitialiseItem
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialiseItem( xListItem *pxItem );
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted into the list in
|
||||
* a position determined by its item value (descending item value order).
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The item to that is to be placed in the list.
|
||||
*
|
||||
* \page vListInsert vListInsert
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsert( xList *pxList, xListItem *pxNewListItem );
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted in a position
|
||||
* such that it will be the last item within the list returned by multiple
|
||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||
*
|
||||
* The list member pvIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
|
||||
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||
* in the list position pointed to by pvIndex. This means that every other
|
||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||
* the pvIndex parameter again points to the item being inserted.
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The list item to be inserted into the list.
|
||||
*
|
||||
* \page vListInsertEnd vListInsertEnd
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
|
||||
|
||||
/*
|
||||
* Remove an item from a list. The list item has a pointer to the list that
|
||||
* it is in, so only the list item need be passed into the function.
|
||||
*
|
||||
* @param vListRemove The item to be removed. The item will remove itself from
|
||||
* the list pointed to by it's pxContainer parameter.
|
||||
*
|
||||
* \page vListRemove vListRemove
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListRemove( xListItem *pxItemToRemove );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
172
Source/include/portable.h
Normal file
172
Source/include/portable.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Portable layer API. Each function must be defined for each port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#ifndef PORTABLE_H
|
||||
#define PORTABLE_H
|
||||
|
||||
/* Include the macro file relevant to the port being used. */
|
||||
|
||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||
#include "..\..\source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||
#include "..\..\source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MEGA_AVR
|
||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC18F_PORT
|
||||
#include "..\..\source\portable\MPLAB\PIC18F\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _FEDPICC
|
||||
#include "libFreeRTOS/Include/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDCC_CYGNAL
|
||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7
|
||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MSP430
|
||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_MSP430
|
||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef KEIL_ARM7
|
||||
#include "..\..\Source\portable\Keil\ARM7\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_GCC
|
||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPC2000_IAR
|
||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR71X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_H8S
|
||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_AT91FR40008
|
||||
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef RVDS_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef HCS12_CODE_WARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MICROBLAZE_GCC
|
||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef BCC_FLASH_LITE_186_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
/*
|
||||
* Setup the stack of a new task so it is ready to be placed under the
|
||||
* scheduler control. The registers have to be placed on the stack in
|
||||
* the order that the port expects to find them.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );
|
||||
|
||||
/*
|
||||
* Map to the memory management routines required for the port.
|
||||
*/
|
||||
void *pvPortMalloc( size_t xSize );
|
||||
void vPortFree( void *pv );
|
||||
void vPortInitialiseBlocks( void );
|
||||
|
||||
/*
|
||||
* Setup the hardware ready for the scheduler to take control. This generally
|
||||
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||
*/
|
||||
portBASE_TYPE xPortStartScheduler( void );
|
||||
|
||||
/*
|
||||
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||
* the hardware is left in its original condition after the scheduler stops
|
||||
* executing.
|
||||
*/
|
||||
void vPortEndScheduler( void );
|
||||
|
||||
|
||||
#endif /* PORTABLE_H */
|
||||
|
54
Source/include/projdefs.h
Normal file
54
Source/include/projdefs.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef PROJDEFS_H
|
||||
#define PROJDEFS_H
|
||||
|
||||
/* Defines to prototype to which task functions must conform. */
|
||||
typedef void (*pdTASK_CODE)( void * );
|
||||
|
||||
#define pdTRUE ( 1 )
|
||||
#define pdFALSE ( 0 )
|
||||
|
||||
#define pdPASS ( 1 )
|
||||
#define pdFAIL ( 0 )
|
||||
|
||||
/* Error definitions. */
|
||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||
#define errNO_TASK_TO_RUN ( -2 )
|
||||
#define errQUEUE_FULL ( -3 )
|
||||
#define errQUEUE_BLOCKED ( -4 )
|
||||
#define errQUEUE_YIELD ( -5 )
|
||||
|
||||
#endif
|
||||
|
||||
|
471
Source/include/queue.h
Normal file
471
Source/include/queue.h
Normal file
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
|
||||
typedef void * xQueueHandle;
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>
|
||||
xQueueHandle xQueueCreate(
|
||||
unsigned portBASE_TYPE uxQueueLength,
|
||||
unsigned portBASE_TYPE uxItemSize
|
||||
);
|
||||
* </pre>
|
||||
*
|
||||
* Creates a new queue instance. This allocates the storage required by the
|
||||
* new queue and returns a handle for the queue.
|
||||
*
|
||||
* @param uxQueueLength The maximum number of items that the queue can contain.
|
||||
*
|
||||
* @param uxItemSize The number of bytes each item in the queue will require.
|
||||
* Items are queued by copy, not by reference, so this is the number of bytes
|
||||
* that will be copied for each posted item. Each item on the queue must be
|
||||
* the same size.
|
||||
*
|
||||
* @return If the queue is successfully create then a handle to the newly
|
||||
* created queue is returned. If the queue cannot be created then 0 is
|
||||
* returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
struct AMessage
|
||||
{
|
||||
portCHAR ucMessageID;
|
||||
portCHAR ucData[ 20 ];
|
||||
};
|
||||
|
||||
void vATask( void *pvParameters )
|
||||
{
|
||||
xQueueHandle xQueue1, xQueue2;
|
||||
|
||||
// Create a queue capable of containing 10 unsigned long values.
|
||||
xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );
|
||||
if( xQueue1 == 0 )
|
||||
{
|
||||
// Queue was not created and must not be used.
|
||||
}
|
||||
|
||||
// Create a queue capable of containing 10 pointers to AMessage structures.
|
||||
// These should be passed by pointer as they contain a lot of data.
|
||||
xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
|
||||
if( xQueue2 == 0 )
|
||||
{
|
||||
// Queue was not created and must not be used.
|
||||
}
|
||||
|
||||
// ... Rest of task code.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueCreate xQueueCreate
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>
|
||||
portBASE_TYPE xQueueSend(
|
||||
xQueueHandle xQueue,
|
||||
const void * pvItemToQueue,
|
||||
portTickType xTicksToWait
|
||||
);
|
||||
* </pre>
|
||||
*
|
||||
* Post an item on a queue. The item is queued by copy, not by reference.
|
||||
* This function must not be called from an interrupt service routine.
|
||||
* See xQueueSendFromISR () for an alternative which may be used in an ISR.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||
* queue. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||
* into the queue storage area.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should block
|
||||
* waiting for space to become available on the queue, should it already
|
||||
* be full. The call will return immediately if this is set to 0. The
|
||||
* time is defined in tick periods so the constant portTICK_RATE_MS
|
||||
* should be used to convert to real time if this is required.
|
||||
*
|
||||
* @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
struct AMessage
|
||||
{
|
||||
portCHAR ucMessageID;
|
||||
portCHAR ucData[ 20 ];
|
||||
} xMessage;
|
||||
|
||||
unsigned portLONG ulVar = 10UL;
|
||||
|
||||
void vATask( void *pvParameters )
|
||||
{
|
||||
xQueueHandle xQueue1, xQueue2;
|
||||
struct AMessage *pxMessage;
|
||||
|
||||
// Create a queue capable of containing 10 unsigned long values.
|
||||
xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );
|
||||
|
||||
// Create a queue capable of containing 10 pointers to AMessage structures.
|
||||
// These should be passed by pointer as they contain a lot of data.
|
||||
xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
|
||||
|
||||
// ...
|
||||
|
||||
if( xQueue1 != 0 )
|
||||
{
|
||||
// Send an unsigned long. Wait for 10 ticks for space to become
|
||||
// available if necessary.
|
||||
if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
|
||||
{
|
||||
// Failed to post the message, even after 10 ticks.
|
||||
}
|
||||
}
|
||||
|
||||
if( xQueue2 != 0 )
|
||||
{
|
||||
// Send a pointer to a struct AMessage object. Don't block if the
|
||||
// queue is already full.
|
||||
pxMessage = & xMessage;
|
||||
xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
|
||||
}
|
||||
|
||||
// ... Rest of task code.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueSend xQueueSend
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait );
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>
|
||||
portBASE_TYPE xQueueReceive(
|
||||
xQueueHandle xQueue,
|
||||
void *pvBuffer,
|
||||
portTickType xTicksToWait
|
||||
);</pre>
|
||||
*
|
||||
* Receive an item from a queue. The item is received by copy so a buffer of
|
||||
* adequate size must be provided. The number of bytes copied into the buffer
|
||||
* was defined when the queue was created.
|
||||
*
|
||||
* This function must not be used in an interrupt service routine. See
|
||||
* xQueueReceiveFromISR for an alternative that can.
|
||||
*
|
||||
* @param pxQueue The handle to the queue from which the item is to be
|
||||
* received.
|
||||
*
|
||||
* @param pvBuffer Pointer to the buffer into which the received item will
|
||||
* be copied.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should block
|
||||
* waiting for an item to receive should the queue be empty at the time
|
||||
* of the call. The time is defined in tick periods so the constant
|
||||
* portTICK_RATE_MS should be used to convert to real time if this is required.
|
||||
*
|
||||
* @return pdTRUE if an item was successfully received from the queue,
|
||||
* otherwise pdFALSE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
struct AMessage
|
||||
{
|
||||
portCHAR ucMessageID;
|
||||
portCHAR ucData[ 20 ];
|
||||
} xMessage;
|
||||
|
||||
xQueueHandle xQueue;
|
||||
|
||||
// Task to create a queue and post a value.
|
||||
void vATask( void *pvParameters )
|
||||
{
|
||||
struct AMessage *pxMessage;
|
||||
|
||||
// Create a queue capable of containing 10 pointers to AMessage structures.
|
||||
// These should be passed by pointer as they contain a lot of data.
|
||||
xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
|
||||
if( xQueue == 0 )
|
||||
{
|
||||
// Failed to create the queue.
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
// Send a pointer to a struct AMessage object. Don't block if the
|
||||
// queue is already full.
|
||||
pxMessage = & xMessage;
|
||||
xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
|
||||
|
||||
// ... Rest of task code.
|
||||
}
|
||||
|
||||
// Task to receive from the queue.
|
||||
void vADifferentTask( void *pvParameters )
|
||||
{
|
||||
struct AMessage *pxRxedMessage;
|
||||
|
||||
if( xQueue != 0 )
|
||||
{
|
||||
// Receive a message on the created queue. Block for 10 ticks if a
|
||||
// message is not immediately available.
|
||||
if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
|
||||
{
|
||||
// pcRxedMessage now points to the struct AMessage variable posted
|
||||
// by vATask.
|
||||
}
|
||||
}
|
||||
|
||||
// ... Rest of task code.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueReceive xQueueReceive
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
signed portBASE_TYPE xQueueReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait );
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );</pre>
|
||||
*
|
||||
* Return the number of messages stored in a queue.
|
||||
*
|
||||
* @param xQueue A handle to the queue being queried.
|
||||
*
|
||||
* @return The number of messages available in the queue.
|
||||
*
|
||||
* \page uxQueueMessagesWaiting uxQueueMessagesWaiting
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>void vQueueDelete( xQueueHandle xQueue );</pre>
|
||||
*
|
||||
* Delete a queue - freeing all the memory allocated for storing of items
|
||||
* placed on the queue.
|
||||
*
|
||||
* @param xQueue A handle to the queue to be deleted.
|
||||
*
|
||||
* \page vQueueDelete vQueueDelete
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
void vQueueDelete( xQueueHandle xQueue );
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>
|
||||
portBASE_TYPE xQueueSendFromISR(
|
||||
xQueueHandle pxQueue,
|
||||
const void *pvItemToQueue,
|
||||
portBASE_TYPE xTaskPreviouslyWoken
|
||||
);
|
||||
</pre>
|
||||
*
|
||||
* Post an item on a queue. It is safe to use this function from within an
|
||||
* interrupt service routine.
|
||||
*
|
||||
* Items are queued by copy not reference so it is preferable to only
|
||||
* queue small items, especially when called from an ISR. In most cases
|
||||
* it would be preferable to store a pointer to the item being queued.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||
* queue. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||
* into the queue storage area.
|
||||
*
|
||||
* @param cTaskPreviouslyWoken This is included so an ISR can post onto
|
||||
* the same queue multiple times from a single interrupt. The first call
|
||||
* should always pass in pdFALSE. Subsequent calls should pass in
|
||||
* the value returned from the previous call. See the file serial .c in the
|
||||
* PC port for a good example of this mechanism.
|
||||
*
|
||||
* @return pdTRUE if a task was woken by posting onto the queue. This is
|
||||
* used by the ISR to determine if a context switch may be required following
|
||||
* the ISR.
|
||||
*
|
||||
* Example usage for buffered IO (where the ISR can obtain more than one value
|
||||
* per call):
|
||||
<pre>
|
||||
void vBufferISR( void )
|
||||
{
|
||||
portCHAR cIn;
|
||||
portBASE_TYPE xTaskWokenByPost;
|
||||
|
||||
// We have not woken a task at the start of the ISR.
|
||||
cTaskWokenByPost = pdFALSE;
|
||||
|
||||
// Loop until the buffer is empty.
|
||||
do
|
||||
{
|
||||
// Obtain a byte from the buffer.
|
||||
cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
|
||||
|
||||
// Post the byte. The first time round the loop cTaskWokenByPost
|
||||
// will be pdFALSE. If the queue send causes a task to wake we do
|
||||
// not want the task to run until we have finished the ISR, so
|
||||
// xQueueSendFromISR does not cause a context switch. Also we
|
||||
// don't want subsequent posts to wake any other tasks, so we store
|
||||
// the return value back into cTaskWokenByPost so xQueueSendFromISR
|
||||
// knows not to wake any task the next iteration of the loop.
|
||||
xTaskWokenByPost = xQueueSendFromISR( xRxQueue, &cIn, cTaskWokenByPost );
|
||||
|
||||
} while( portINPUT_BYTE( BUFFER_COUNT ) );
|
||||
|
||||
// Now the buffer is empty we can switch context if necessary.
|
||||
if( cTaskWokenByPost )
|
||||
{
|
||||
taskYIELD ();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
*
|
||||
* \defgroup xQueueSendFromISR xQueueSendFromISR
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken );
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>
|
||||
portBASE_TYPE xQueueReceiveFromISR(
|
||||
xQueueHandle pxQueue,
|
||||
void *pvBuffer,
|
||||
portBASE_TYPE *pxTaskWoken
|
||||
);
|
||||
* </pre>
|
||||
*
|
||||
* Receive an item from a queue. It is safe to use this function from within an
|
||||
* interrupt service routine.
|
||||
*
|
||||
* @param pxQueue The handle to the queue from which the item is to be
|
||||
* received.
|
||||
*
|
||||
* @param pvBuffer Pointer to the buffer into which the received item will
|
||||
* be copied.
|
||||
*
|
||||
* @param pxTaskWoken A task may be blocked waiting for space to become
|
||||
* available on the queue. If xQueueReceiveFromISR causes such a task to
|
||||
* unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will
|
||||
* remain unchanged.
|
||||
*
|
||||
* @return pdTRUE if an item was successfully received from the queue,
|
||||
* otherwise pdFALSE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
|
||||
xQueueHandle xQueue;
|
||||
|
||||
// Function to create a queue and post some values.
|
||||
void vAFunction( void *pvParameters )
|
||||
{
|
||||
portCHAR cValueToPost;
|
||||
const portTickType xBlockTime = ( portTickType )0xff;
|
||||
|
||||
// Create a queue capable of containing 10 characters.
|
||||
xQueue = xQueueCreate( 10, sizeof( portCHAR ) );
|
||||
if( xQueue == 0 )
|
||||
{
|
||||
// Failed to create the queue.
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
// Post some characters that will be used within an ISR. If the queue
|
||||
// is full then this task will block for xBlockTime ticks.
|
||||
cValueToPost = 'a';
|
||||
xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
|
||||
cValueToPost = 'b';
|
||||
xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
|
||||
|
||||
// ... keep posting characters ... this task may block when the queue
|
||||
// becomes full.
|
||||
|
||||
cValueToPost = 'c';
|
||||
xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
|
||||
}
|
||||
|
||||
// ISR that outputs all the characters received on the queue.
|
||||
void vISR_Routine( void )
|
||||
{
|
||||
portBASE_TYPE xTaskWokenByReceive = pdFALSE;
|
||||
portCHAR cRxedChar;
|
||||
|
||||
while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
|
||||
{
|
||||
// A character was received. Output the character now.
|
||||
vOutputCharacter( cRxedChar );
|
||||
|
||||
// If removing the character from the queue woke the task that was
|
||||
// posting onto the queue cTaskWokenByReceive will have been set to
|
||||
// pdTRUE. No matter how many times this loop iterates only one
|
||||
// task will be woken.
|
||||
}
|
||||
|
||||
if( cTaskWokenByPost != ( portCHAR ) pdFALSE;
|
||||
{
|
||||
taskYIELD ();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueReceiveFromISR xQueueReceiveFromISR
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );
|
||||
|
||||
|
||||
/*
|
||||
* The functions defined above are for passing data to and from tasks. The
|
||||
* functions below are the equivalents for passing data to and from
|
||||
* co-rtoutines.
|
||||
*
|
||||
* These functions are called from the co-routine macro implementation and
|
||||
* should not be called directly from application code. Instead use the macro
|
||||
* wrappers defined within croutine.h.
|
||||
*/
|
||||
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
|
||||
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );
|
||||
signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );
|
||||
signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
|
||||
|
||||
#endif
|
||||
|
289
Source/include/semphr.h
Normal file
289
Source/include/semphr.h
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
#ifndef SEMAPHORE_H
|
||||
#define SEMAPHORE_H
|
||||
|
||||
typedef xQueueHandle xSemaphoreHandle;
|
||||
|
||||
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned portCHAR ) 1 )
|
||||
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portCHAR ) 0 )
|
||||
#define semGIVE_BLOCK_TIME ( ( portTickType ) 0 )
|
||||
|
||||
|
||||
/**
|
||||
* semphr. h
|
||||
* <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
|
||||
*
|
||||
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
|
||||
* The queue length is 1 as this is a binary semaphore. The data size is 0
|
||||
* as we don't want to actually store any data - we just want to know if the
|
||||
* queue is empty or full.
|
||||
*
|
||||
* @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
xSemaphoreHandle xSemaphore;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
||||
// This is a macro so pass the variable in directly.
|
||||
vSemaphoreCreateBinary( xSemaphore );
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// The semaphore was created successfully.
|
||||
// The semaphore can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define vSemaphoreCreateBinary( xSemaphore ) { \
|
||||
xSemaphore = xQueueCreate( ( unsigned portCHAR ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
|
||||
if( xSemaphore != NULL ) \
|
||||
{ \
|
||||
xSemaphoreGive( xSemaphore ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* semphr. h
|
||||
* xSemaphoreTake(
|
||||
* xSemaphoreHandle xSemaphore,
|
||||
* portTickType xBlockTime
|
||||
* )</pre>
|
||||
*
|
||||
* <i>Macro</i> to obtain a semaphore. The semaphore must of been created using
|
||||
* vSemaphoreCreateBinary ().
|
||||
*
|
||||
* @param xSemaphore A handle to the semaphore being obtained. This is the
|
||||
* handle returned by vSemaphoreCreateBinary ();
|
||||
*
|
||||
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
||||
* available. The macro portTICK_RATE_MS can be used to convert this to a
|
||||
* real time. A block time of zero can be used to poll the semaphore.
|
||||
*
|
||||
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
|
||||
* expired without the semaphore becoming available.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
xSemaphoreHandle xSemaphore = NULL;
|
||||
|
||||
// A task that creates a semaphore.
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Create the semaphore to guard a shared resource.
|
||||
vSemaphoreCreateBinary( xSemaphore );
|
||||
}
|
||||
|
||||
// A task that uses the semaphore.
|
||||
void vAnotherTask( void * pvParameters )
|
||||
{
|
||||
// ... Do other things.
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// See if we can obtain the semaphore. If the semaphore is not available
|
||||
// wait 10 ticks to see if it becomes free.
|
||||
if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
|
||||
{
|
||||
// We were able to obtain the semaphore and can now access the
|
||||
// shared resource.
|
||||
|
||||
// ...
|
||||
|
||||
// We have finished accessing the shared resource. Release the
|
||||
// semaphore.
|
||||
xSemaphoreGive( xSemaphore );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We could not obtain the semaphore and can therefore not access
|
||||
// the shared resource safely.
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xSemaphoreTake xSemaphoreTake
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime )
|
||||
|
||||
/**
|
||||
* semphr. h
|
||||
* <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
|
||||
*
|
||||
* <i>Macro</i> to release a semaphore. The semaphore must of been created using
|
||||
* vSemaphoreCreateBinary (), and obtained using sSemaphoreTake ().
|
||||
*
|
||||
* This must not be used from an ISR. See xSemaphoreGiveFromISR () for
|
||||
* an alternative which can be used from an ISR.
|
||||
*
|
||||
* @param xSemaphore A handle to the semaphore being released. This is the
|
||||
* handle returned by vSemaphoreCreateBinary ();
|
||||
*
|
||||
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
|
||||
* Semaphores are implemented using queues. An error can occur if there is
|
||||
* no space on the queue to post a message - indicating that the
|
||||
* semaphore was not first obtained correctly.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
xSemaphoreHandle xSemaphore = NULL;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Create the semaphore to guard a shared resource.
|
||||
vSemaphoreCreateBinary( xSemaphore );
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||
{
|
||||
// We would expect this call to fail because we cannot give
|
||||
// a semaphore without first "taking" it!
|
||||
}
|
||||
|
||||
// Obtain the semaphore - don't block if the semaphore is not
|
||||
// immediately available.
|
||||
if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
|
||||
{
|
||||
// We now have the semaphore and can access the shared resource.
|
||||
|
||||
// ...
|
||||
|
||||
// We have finished accessing the shared resource so can free the
|
||||
// semaphore.
|
||||
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||
{
|
||||
// We would not expect this call to fail because we must have
|
||||
// obtained the semaphore to get here.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xSemaphoreGive xSemaphoreGive
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define xSemaphoreGive( xSemaphore ) xQueueSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME )
|
||||
|
||||
/**
|
||||
* semphr. h
|
||||
* <pre>
|
||||
xSemaphoreGiveFromISR(
|
||||
xSemaphoreHandle xSemaphore,
|
||||
portSHORT sTaskPreviouslyWoken
|
||||
)</pre>
|
||||
*
|
||||
* <i>Macro</i> to release a semaphore. The semaphore must of been created using
|
||||
* vSemaphoreCreateBinary (), and obtained using xSemaphoreTake ().
|
||||
*
|
||||
* This macro can be used from an ISR.
|
||||
*
|
||||
* @param xSemaphore A handle to the semaphore being released. This is the
|
||||
* handle returned by vSemaphoreCreateBinary ();
|
||||
*
|
||||
* @param sTaskPreviouslyWoken This is included so an ISR can make multiple calls
|
||||
* to xSemaphoreGiveFromISR () from a single interrupt. The first call
|
||||
* should always pass in pdFALSE. Subsequent calls should pass in
|
||||
* the value returned from the previous call. See the file serial .c in the
|
||||
* PC port for a good example of using xSemaphoreGiveFromISR ().
|
||||
*
|
||||
* @return pdTRUE if a task was woken by releasing the semaphore. This is
|
||||
* used by the ISR to determine if a context switch may be required following
|
||||
* the ISR.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define LONG_TIME 0xffff
|
||||
#define TICKS_TO_WAIT 10
|
||||
xSemaphoreHandle xSemaphore = NULL;
|
||||
|
||||
// Repetitive task.
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// We want this task to run every 10 ticks or a timer. The semaphore
|
||||
// was created before this task was started
|
||||
|
||||
// Block waiting for the semaphore to become available.
|
||||
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
|
||||
{
|
||||
// It is time to execute.
|
||||
|
||||
// ...
|
||||
|
||||
// We have finished our task. Return to the top of the loop where
|
||||
// we will block on the semaphore until it is time to execute
|
||||
// again.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Timer ISR
|
||||
void vTimerISR( void * pvParameters )
|
||||
{
|
||||
static unsigned portCHAR ucLocalTickCount = 0;
|
||||
|
||||
// A timer tick has occurred.
|
||||
|
||||
// ... Do other time functions.
|
||||
|
||||
// Is it time for vATask () to run?
|
||||
ucLocalTickCount++;
|
||||
if( ucLocalTickCount >= TICKS_TO_WAIT )
|
||||
{
|
||||
// Unblock the task by releasing the semaphore.
|
||||
xSemaphoreGive( xSemaphore );
|
||||
|
||||
// Reset the count so we release the semaphore again in 10 ticks time.
|
||||
ucLocalTickCount = 0;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken ) xQueueSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken )
|
||||
|
||||
|
||||
#endif
|
||||
|
906
Source/include/task.h
Normal file
906
Source/include/task.h
Normal file
|
@ -0,0 +1,906 @@
|
|||
/*
|
||||
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FreeRTOS; 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, 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.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef TASK_H
|
||||
#define TASK_H
|
||||
|
||||
#include "portable.h"
|
||||
#include "list.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* MACROS AND DEFINITIONS
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define tskKERNEL_VERSION_NUMBER "V3.2.4"
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Type by which tasks are referenced. For example, a call to xTaskCreate
|
||||
* returns (via a pointer parameter) an xTaskHandle variable that can then
|
||||
* be used as a parameter to vTaskDelete to delete the task.
|
||||
*
|
||||
* \page xTaskHandle xTaskHandle
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
typedef void * xTaskHandle;
|
||||
|
||||
/*
|
||||
* Defines the priority used by the idle task. This must not be modified.
|
||||
*
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 )
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Macro for forcing a context switch.
|
||||
*
|
||||
* \page taskYIELD taskYIELD
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
#define taskYIELD() portYIELD()
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Macro to mark the start of a critical code region. Preemptive context
|
||||
* switches cannot occur when in a critical region.
|
||||
*
|
||||
* NOTE: This may alter the stack (depending on the portable implementation)
|
||||
* so must be used with care!
|
||||
*
|
||||
* \page taskENTER_CRITICAL taskENTER_CRITICAL
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
#define taskENTER_CRITICAL() portENTER_CRITICAL()
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Macro to mark the end of a critical code region. Preemptive context
|
||||
* switches cannot occur when in a critical region.
|
||||
*
|
||||
* NOTE: This may alter the stack (depending on the portable implementation)
|
||||
* so must be used with care!
|
||||
*
|
||||
* \page taskEXIT_CRITICAL taskEXIT_CRITICAL
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Macro to disable all maskable interrupts.
|
||||
*
|
||||
* \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Macro to enable microcontroller interrupts.
|
||||
*
|
||||
* \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* TASK CREATION API
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*<pre>
|
||||
portBASE_TYPE xTaskCreate(
|
||||
pdTASK_CODE pvTaskCode,
|
||||
const portCHAR * const pcName,
|
||||
unsigned portSHORT usStackDepth,
|
||||
void *pvParameters,
|
||||
unsigned portBASE_TYPE uxPriority,
|
||||
xTaskHandle *pvCreatedTask
|
||||
);</pre>
|
||||
*
|
||||
* Create a new task and add it to the list of tasks that are ready to run.
|
||||
*
|
||||
* @param pvTaskCode Pointer to the task entry function. Tasks
|
||||
* must be implemented to never return (i.e. continuous loop).
|
||||
*
|
||||
* @param pcName A descriptive name for the task. This is mainly used to
|
||||
* facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default
|
||||
* is 16.
|
||||
*
|
||||
* @param usStackDepth The size of the task stack specified as the number of
|
||||
* variables the stack can hold - not the number of bytes. For example, if
|
||||
* the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes
|
||||
* will be allocated for stack storage.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
*
|
||||
* @param uxPriority The priority at which the task should run.
|
||||
*
|
||||
* @param pvCreatedTask Used to pass back a handle by which the created task
|
||||
* can be referenced.
|
||||
*
|
||||
* @return pdPASS if the task was successfully created and added to a ready
|
||||
* list, otherwise an error code defined in the file errors. h
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Task to be created.
|
||||
void vTaskCode( void * pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Task code goes here.
|
||||
}
|
||||
}
|
||||
|
||||
// Function that creates a task.
|
||||
void vOtherFunction( void )
|
||||
{
|
||||
unsigned char ucParameterToPass;
|
||||
xTaskHandle xHandle;
|
||||
|
||||
// Create the task, storing the handle.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
|
||||
|
||||
// Use the handle to delete the task.
|
||||
vTaskDelete( xHandle );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xTaskCreate xTaskCreate
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskDelete( xTaskHandle pxTask );</pre>
|
||||
*
|
||||
* INCLUDE_vTaskDelete must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* Remove a task from the RTOS real time kernels management. The task being
|
||||
* deleted will be removed from all ready, blocked, suspended and event lists.
|
||||
*
|
||||
* NOTE: The idle task is responsible for freeing the kernel allocated
|
||||
* memory from tasks that have been deleted. It is therefore important that
|
||||
* the idle task is not starved of microcontroller processing time if your
|
||||
* application makes any calls to vTaskDelete (). Memory allocated by the
|
||||
* task code is not automatically freed, and should be freed before the task
|
||||
* is deleted.
|
||||
*
|
||||
* See the demo application file death.c for sample code that utilises
|
||||
* vTaskDelete ().
|
||||
*
|
||||
* @param pxTask The handle of the task to be deleted. Passing NULL will
|
||||
* cause the calling task to be deleted.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vOtherFunction( void )
|
||||
{
|
||||
xTaskHandle xHandle;
|
||||
|
||||
// Create the task, storing the handle.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
|
||||
|
||||
// Use the handle to delete the task.
|
||||
vTaskDelete( xHandle );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskDelete vTaskDelete
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
void vTaskDelete( xTaskHandle pxTask );
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* TASK CONTROL API
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskDelay( portTickType xTicksToDelay );</pre>
|
||||
*
|
||||
* Delay a task for a given number of ticks. The actual time that the
|
||||
* task remains blocked depends on the tick rate. The constant
|
||||
* portTICK_RATE_MS can be used to calculate real time from the tick
|
||||
* rate - with the resolution of one tick period.
|
||||
*
|
||||
* INCLUDE_vTaskDelay must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* @param xTicksToDelay The amount of time, in tick periods, that
|
||||
* the calling task should block.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Wait 10 ticks before performing an action.
|
||||
// NOTE:
|
||||
// This is for demonstration only and would be better achieved
|
||||
// using vTaskDelayUntil ().
|
||||
void vTaskFunction( void * pvParameters )
|
||||
{
|
||||
portTickType xDelay, xNextTime;
|
||||
|
||||
// Calc the time at which we want to perform the action
|
||||
// next.
|
||||
xNextTime = xTaskGetTickCount () + ( portTickType ) 10;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
xDelay = xNextTime - xTaskGetTickCount ();
|
||||
xNextTime += ( portTickType ) 10;
|
||||
|
||||
// Guard against overflow
|
||||
if( xDelay <= ( portTickType ) 10 )
|
||||
{
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
|
||||
// Perform action here.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskDelay vTaskDelay
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
void vTaskDelay( portTickType xTicksToDelay );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );</pre>
|
||||
*
|
||||
* INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* Delay a task until a specified time. This function can be used by cyclical
|
||||
* tasks to ensure a constant execution frequency.
|
||||
*
|
||||
* This function differs from vTaskDelay () in one important aspect: vTaskDelay () will
|
||||
* cause a task to block for the specified number of ticks from the time vTaskDelay () is
|
||||
* called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed
|
||||
* execution frequency as the time between a task starting to execute and that task
|
||||
* calling vTaskDelay () may not be fixed [the task may take a different path though the
|
||||
* code between calls, or may get interrupted or preempted a different number of times
|
||||
* each time it executes].
|
||||
*
|
||||
* Whereas vTaskDelay () specifies a wake time relative to the time at which the function
|
||||
* is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to
|
||||
* unblock.
|
||||
*
|
||||
* The constant portTICK_RATE_MS can be used to calculate real time from the tick
|
||||
* rate - with the resolution of one tick period.
|
||||
*
|
||||
* @param pxPreviousWakeTime Pointer to a variable that holds the time at which the
|
||||
* task was last unblocked. The variable must be initialised with the current time
|
||||
* prior to its first use (see the example below). Following this the variable is
|
||||
* automatically updated within vTaskDelayUntil ().
|
||||
*
|
||||
* @param xTimeIncrement The cycle time period. The task will be unblocked at
|
||||
* time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the
|
||||
* same xTimeIncrement parameter value will cause the task to execute with
|
||||
* a fixed interface period.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Perform an action every 10 ticks.
|
||||
void vTaskFunction( void * pvParameters )
|
||||
{
|
||||
portTickType xLastWakeTime;
|
||||
const portTickType xFrequency = 10;
|
||||
|
||||
// Initialise the xLastWakeTime variable with the current time.
|
||||
xLastWakeTime = xTaskGetTickCount ();
|
||||
for( ;; )
|
||||
{
|
||||
// Wait for the next cycle.
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );
|
||||
|
||||
// Perform action here.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskDelayUntil vTaskDelayUntil
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );</pre>
|
||||
*
|
||||
* INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* Obtain the priority of any task.
|
||||
*
|
||||
* @param pxTask Handle of the task to be queried. Passing a NULL
|
||||
* handle results in the priority of the calling task being returned.
|
||||
*
|
||||
* @return The priority of pxTask.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vAFunction( void )
|
||||
{
|
||||
xTaskHandle xHandle;
|
||||
|
||||
// Create a task, storing the handle.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
|
||||
|
||||
// ...
|
||||
|
||||
// Use the handle to obtain the priority of the created task.
|
||||
// It was created with tskIDLE_PRIORITY, but may have changed
|
||||
// it itself.
|
||||
if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
|
||||
{
|
||||
// The task has changed it's priority.
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
// Is our priority higher than the created task?
|
||||
if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
|
||||
{
|
||||
// Our priority (obtained using NULL handle) is higher.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup uxTaskPriorityGet uxTaskPriorityGet
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );</pre>
|
||||
*
|
||||
* INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* Set the priority of any task.
|
||||
*
|
||||
* A context switch will occur before the function returns if the priority
|
||||
* being set is higher than the currently executing task.
|
||||
*
|
||||
* @param pxTask Handle to the task for which the priority is being set.
|
||||
* Passing a NULL handle results in the priority of the calling task being set.
|
||||
*
|
||||
* @param uxNewPriority The priority to which the task will be set.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vAFunction( void )
|
||||
{
|
||||
xTaskHandle xHandle;
|
||||
|
||||
// Create a task, storing the handle.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
|
||||
|
||||
// ...
|
||||
|
||||
// Use the handle to raise the priority of the created task.
|
||||
vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
|
||||
|
||||
// ...
|
||||
|
||||
// Use a NULL handle to raise our priority to the same value.
|
||||
vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskPrioritySet vTaskPrioritySet
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskSuspend( xTaskHandle pxTaskToSuspend );</pre>
|
||||
*
|
||||
* INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* Suspend any task. When suspended a task will never get any microcontroller
|
||||
* processing time, no matter what its priority.
|
||||
*
|
||||
* Calls to vTaskSuspend are not accumulative -
|
||||
* i.e. calling vTaskSuspend () twice on the same task still only requires one
|
||||
* call to vTaskResume () to ready the suspended task.
|
||||
*
|
||||
* @param pxTaskToSuspend Handle to the task being suspended. Passing a NULL
|
||||
* handle will cause the calling task to be suspended.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vAFunction( void )
|
||||
{
|
||||
xTaskHandle xHandle;
|
||||
|
||||
// Create a task, storing the handle.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
|
||||
|
||||
// ...
|
||||
|
||||
// Use the handle to suspend the created task.
|
||||
vTaskSuspend( xHandle );
|
||||
|
||||
// ...
|
||||
|
||||
// The created task will not run during this period, unless
|
||||
// another task calls vTaskResume( xHandle ).
|
||||
|
||||
//...
|
||||
|
||||
|
||||
// Suspend ourselves.
|
||||
vTaskSuspend( NULL );
|
||||
|
||||
// We cannot get here unless another task calls vTaskResume
|
||||
// with our handle as the parameter.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskSuspend vTaskSuspend
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
void vTaskSuspend( xTaskHandle pxTaskToSuspend );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskResume( xTaskHandle pxTaskToResume );</pre>
|
||||
*
|
||||
* INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* Resumes a suspended task.
|
||||
*
|
||||
* A task that has been suspended by one of more calls to vTaskSuspend ()
|
||||
* will be made available for running again by a single call to
|
||||
* vTaskResume ().
|
||||
*
|
||||
* @param pxTaskToResume Handle to the task being readied.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vAFunction( void )
|
||||
{
|
||||
xTaskHandle xHandle;
|
||||
|
||||
// Create a task, storing the handle.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
|
||||
|
||||
// ...
|
||||
|
||||
// Use the handle to suspend the created task.
|
||||
vTaskSuspend( xHandle );
|
||||
|
||||
// ...
|
||||
|
||||
// The created task will not run during this period, unless
|
||||
// another task calls vTaskResume( xHandle ).
|
||||
|
||||
//...
|
||||
|
||||
|
||||
// Resume the suspended task ourselves.
|
||||
vTaskResume( xHandle );
|
||||
|
||||
// The created task will once again get microcontroller processing
|
||||
// time in accordance with it priority within the system.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskResume vTaskResume
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
void vTaskResume( xTaskHandle pxTaskToResume );
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* SCHEDULER CONTROL
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskStartScheduler( void );</pre>
|
||||
*
|
||||
* Starts the real time kernel tick processing. After calling the kernel
|
||||
* has control over which tasks are executed and when. This function
|
||||
* does not return until an executing task calls vTaskEndScheduler ().
|
||||
*
|
||||
* At least one task should be created via a call to xTaskCreate ()
|
||||
* before calling vTaskStartScheduler (). The idle task is created
|
||||
* automatically when the first application task is created.
|
||||
*
|
||||
* See the demo application file main.c for an example of creating
|
||||
* tasks and starting the kernel.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vAFunction( void )
|
||||
{
|
||||
// Create at least one task before starting the kernel.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
|
||||
// Start the real time kernel with preemption.
|
||||
vTaskStartScheduler ();
|
||||
|
||||
// Will not get here unless a task calls vTaskEndScheduler ()
|
||||
}
|
||||
</pre>
|
||||
*
|
||||
* \defgroup vTaskStartScheduler vTaskStartScheduler
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
void vTaskStartScheduler( void );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskEndScheduler( void );</pre>
|
||||
*
|
||||
* Stops the real time kernel tick. All created tasks will be automatically
|
||||
* deleted and multitasking (either preemptive or cooperative) will
|
||||
* stop. Execution then resumes from the point where vTaskStartScheduler ()
|
||||
* was called, as if vTaskStartScheduler () had just returned.
|
||||
*
|
||||
* See the demo application file main. c in the demo/PC directory for an
|
||||
* example that uses vTaskEndScheduler ().
|
||||
*
|
||||
* vTaskEndScheduler () requires an exit function to be defined within the
|
||||
* portable layer (see vPortEndScheduler () in port. c for the PC port). This
|
||||
* performs hardware specific operations such as stopping the kernel tick.
|
||||
*
|
||||
* vTaskEndScheduler () will cause all of the resources allocated by the
|
||||
* kernel to be freed - but will not free resources allocated by application
|
||||
* tasks.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vTaskCode( void * pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Task code goes here.
|
||||
|
||||
// At some point we want to end the real time kernel processing
|
||||
// so call ...
|
||||
vTaskEndScheduler ();
|
||||
}
|
||||
}
|
||||
|
||||
void vAFunction( void )
|
||||
{
|
||||
// Create at least one task before starting the kernel.
|
||||
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
|
||||
// Start the real time kernel with preemption.
|
||||
vTaskStartScheduler ();
|
||||
|
||||
// Will only get here when the vTaskCode () task has called
|
||||
// vTaskEndScheduler (). When we get here we are back to single task
|
||||
// execution.
|
||||
}
|
||||
</pre>
|
||||
*
|
||||
* \defgroup vTaskEndScheduler vTaskEndScheduler
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
void vTaskEndScheduler( void );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskSuspendAll( void );</pre>
|
||||
*
|
||||
* Suspends all real time kernel activity while keeping interrupts (including the
|
||||
* kernel tick) enabled.
|
||||
*
|
||||
* After calling vTaskSuspendAll () the calling task will continue to execute
|
||||
* without risk of being swapped out until a call to xTaskResumeAll () has been
|
||||
* made.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vTask1( void * pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Task code goes here.
|
||||
|
||||
// ...
|
||||
|
||||
// At some point the task wants to perform a long operation during
|
||||
// which it does not want to get swapped out. It cannot use
|
||||
// taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
|
||||
// operation may cause interrupts to be missed - including the
|
||||
// ticks.
|
||||
|
||||
// Prevent the real time kernel swapping out the task.
|
||||
vTaskSuspendAll ();
|
||||
|
||||
// Perform the operation here. There is no need to use critical
|
||||
// sections as we have all the microcontroller processing time.
|
||||
// During this time interrupts will still operate and the kernel
|
||||
// tick count will be maintained.
|
||||
|
||||
// ...
|
||||
|
||||
// The operation is complete. Restart the kernel.
|
||||
xTaskResumeAll ();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskSuspendAll vTaskSuspendAll
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
void vTaskSuspendAll( void );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>portCHAR xTaskResumeAll( void );</pre>
|
||||
*
|
||||
* Resumes real time kernel activity following a call to vTaskSuspendAll ().
|
||||
* After a call to vTaskSuspendAll () the kernel will take control of which
|
||||
* task is executing at any time.
|
||||
*
|
||||
* @return If resuming the scheduler caused a context switch then pdTRUE is
|
||||
* returned, otherwise pdFALSE is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vTask1( void * pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Task code goes here.
|
||||
|
||||
// ...
|
||||
|
||||
// At some point the task wants to perform a long operation during
|
||||
// which it does not want to get swapped out. It cannot use
|
||||
// taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
|
||||
// operation may cause interrupts to be missed - including the
|
||||
// ticks.
|
||||
|
||||
// Prevent the real time kernel swapping out the task.
|
||||
vTaskSuspendAll ();
|
||||
|
||||
// Perform the operation here. There is no need to use critical
|
||||
// sections as we have all the microcontroller processing time.
|
||||
// During this time interrupts will still operate and the real
|
||||
// time kernel tick count will be maintained.
|
||||
|
||||
// ...
|
||||
|
||||
// The operation is complete. Restart the kernel. We want to force
|
||||
// a context switch - but there is no point if resuming the scheduler
|
||||
// caused a context switch already.
|
||||
if( !xTaskResumeAll () )
|
||||
{
|
||||
taskYIELD ();
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xTaskResumeAll xTaskResumeAll
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
signed portBASE_TYPE xTaskResumeAll( void );
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* TASK UTILITIES
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>volatile portTickType xTaskGetTickCount( void );</PRE>
|
||||
*
|
||||
* @return The count of ticks since vTaskStartScheduler was called.
|
||||
*
|
||||
* \page xTaskGetTickCount xTaskGetTickCount
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
portTickType xTaskGetTickCount( void );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>unsigned portSHORT uxTaskGetNumberOfTasks( void );</PRE>
|
||||
*
|
||||
* @return The number of tasks that the real time kernel is currently managing.
|
||||
* This includes all ready, blocked and suspended tasks. A task that
|
||||
* has been deleted but not yet freed by the idle task will also be
|
||||
* included in the count.
|
||||
*
|
||||
* \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>void vTaskList( portCHAR *pcWriteBuffer );</PRE>
|
||||
*
|
||||
* configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and INCLUDE_vTaskSuspend
|
||||
* must all be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* NOTE: This function will disable interrupts for its duration. It is
|
||||
* not intended for normal application runtime use but as a debug aid.
|
||||
*
|
||||
* Lists all the current tasks, along with their current state and stack
|
||||
* usage high water mark.
|
||||
*
|
||||
* Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
|
||||
* suspended ('S').
|
||||
*
|
||||
* @param pcWriteBuffer A buffer into which the above mentioned details
|
||||
* will be written, in ascii form. This buffer is assumed to be large
|
||||
* enough to contain the generated report. Approximately 40 bytes per
|
||||
* task should be sufficient.
|
||||
*
|
||||
* \page vTaskList vTaskList
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
void vTaskList( signed portCHAR *pcWriteBuffer );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>void vTaskStartTrace( portCHAR * pcBuffer, unsigned portBASE_TYPE uxBufferSize );</PRE>
|
||||
*
|
||||
* Starts a real time kernel activity trace. The trace logs the identity of
|
||||
* which task is running when.
|
||||
*
|
||||
* The trace file is stored in binary format. A separate DOS utility called
|
||||
* convtrce.exe is used to convert this into a tab delimited text file which
|
||||
* can be viewed and plotted in a spread sheet.
|
||||
*
|
||||
* @param pcBuffer The buffer into which the trace will be written.
|
||||
*
|
||||
* @param ulBufferSize The size of pcBuffer in bytes. The trace will continue
|
||||
* until either the buffer in full, or ulTaskEndTrace () is called.
|
||||
*
|
||||
* \page vTaskStartTrace vTaskStartTrace
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
void vTaskStartTrace( signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>unsigned portLONG ulTaskEndTrace( void );</PRE>
|
||||
*
|
||||
* Stops a kernel activity trace. See vTaskStartTrace ().
|
||||
*
|
||||
* @return The number of bytes that have been written into the trace buffer.
|
||||
*
|
||||
* \page usTaskEndTrace usTaskEndTrace
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
unsigned portLONG ulTaskEndTrace( void );
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
|
||||
* INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
|
||||
* AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
*
|
||||
* Called from the real time kernel tick (either preemptive or cooperative),
|
||||
* this increments the tick count and checks if any tasks that are blocked
|
||||
* for a finite period required removing from a blocked list and placing on
|
||||
* a ready list.
|
||||
*/
|
||||
inline void vTaskIncrementTick( void );
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
|
||||
* INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
*
|
||||
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
|
||||
*
|
||||
* Removes the calling task from the ready list and places it both
|
||||
* on the list of tasks waiting for a particular event, and the
|
||||
* list of delayed tasks. The task will be removed from both lists
|
||||
* and replaced on the ready list should either the event occur (and
|
||||
* there be no higher priority tasks waiting on the same event) or
|
||||
* the delay period expires.
|
||||
*
|
||||
* @param pxEventList The list containing tasks that are blocked waiting
|
||||
* for the event to occur.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time that the task should wait
|
||||
* for the event to occur. This is specified in kernel ticks,the constant
|
||||
* portTICK_RATE_MS can be used to convert kernel ticks into a real time
|
||||
* period.
|
||||
*/
|
||||
void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait );
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
|
||||
* INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
*
|
||||
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
|
||||
*
|
||||
* Removes a task from both the specified event list and the list of blocked
|
||||
* tasks, and places it on a ready queue.
|
||||
*
|
||||
* xTaskRemoveFromEventList () will be called if either an event occurs to
|
||||
* unblock a task, or the block timeout period expires.
|
||||
*
|
||||
* @return pdTRUE if the task being removed has a higher priority than the task
|
||||
* making the call, otherwise pdFALSE.
|
||||
*/
|
||||
signed portBASE_TYPE xTaskRemoveFromEventList( const xList *pxEventList );
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
|
||||
* INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
*
|
||||
* INCLUDE_vTaskCleanUpResources and INCLUDE_vTaskSuspend must be defined as 1
|
||||
* for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
*
|
||||
* Empties the ready and delayed queues of task control blocks, freeing the
|
||||
* memory allocated for the task control block and task stacks as it goes.
|
||||
*/
|
||||
void vTaskCleanUpResources( void );
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
|
||||
* INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
|
||||
* AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
*
|
||||
* Sets the pointer to the current TCB to the TCB of the highest priority task
|
||||
* that is ready to run.
|
||||
*/
|
||||
inline void vTaskSwitchContext( void );
|
||||
|
||||
/*
|
||||
* Return the handle of the calling task.
|
||||
*/
|
||||
xTaskHandle xTaskGetCurrentTaskHandle( void );
|
||||
|
||||
|
||||
#endif /* TASK_H */
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue