PPC405 working but not yet released.

This commit is contained in:
Richard Barry 2008-03-07 11:16:23 +00:00
parent 2de068cd70
commit df711a4a65
2617 changed files with 719397 additions and 0 deletions

View file

@ -0,0 +1,315 @@
/*
FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
+++ http://www.FreeRTOS.org +++
Documentation, latest information, license and contact details.
+++ http://www.SafeRTOS.com +++
A version that is certified for use in safety critical systems.
+++ http://www.OpenRTOS.com +++
Commercial support, development, porting, licensing and training services.
***************************************************************************
*/
#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
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#endif
#ifndef configUSE_RECURSIVE_MUTEXES
#define configUSE_RECURSIVE_MUTEXES 0
#endif
#ifndef configUSE_MUTEXES
#define configUSE_MUTEXES 0
#endif
#ifndef configUSE_COUNTING_SEMAPHORES
#define configUSE_COUNTING_SEMAPHORES 0
#endif
#ifndef configUSE_ALTERNATIVE_API
#define configUSE_ALTERNATIVE_API 0
#endif
#ifndef portCRITICAL_NESTING_IN_TCB
#define portCRITICAL_NESTING_IN_TCB 0
#endif
#if ( configUSE_MUTEXES == 1 )
/* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism
within the mutex implementation so must be available if mutexes are used. */
#undef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#else
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 0
#endif
#endif
/* Remove any unused trace macros. */
#ifndef traceSTART
/* Used to perform any necessary initialisation - for example, open a file
into which trace is to be written. */
#define traceSTART()
#endif
#ifndef traceEND
/* Use to close a trace, for example close a file into which trace has been
written. */
#define traceEND()
#endif
#ifndef traceTASK_SWITCHED_IN
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the selected task. */
#define traceTASK_SWITCHED_IN()
#endif
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
/* Task is about to block because it cannot read from a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the read was attempted. pxCurrentTCB points to the TCB of the
task that attempted the read. */
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
#endif
#ifndef traceBLOCKING_ON_QUEUE_SEND
/* Task is about to block because it cannot write to a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the write was attempted. pxCurrentTCB points to the TCB of the
task that attempted the write. */
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
#endif
#ifndef configCHECK_FOR_STACK_OVERFLOW
#define configCHECK_FOR_STACK_OVERFLOW 0
#endif
/* The following event macros are embedded in the kernel API calls. */
#ifndef traceQUEUE_CREATE
#define traceQUEUE_CREATE( pxNewQueue )
#endif
#ifndef traceQUEUE_CREATE_FAILED
#define traceQUEUE_CREATE_FAILED()
#endif
#ifndef traceCREATE_MUTEX
#define traceCREATE_MUTEX( pxNewQueue )
#endif
#ifndef traceCREATE_MUTEX_FAILED
#define traceCREATE_MUTEX_FAILED()
#endif
#ifndef traceGIVE_MUTEX_RECURSIVE
#define traceGIVE_MUTEX_RECURSIVE( pxMutex )
#endif
#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
#endif
#ifndef traceTAKE_MUTEX_RECURSIVE
#define traceTAKE_MUTEX_RECURSIVE( pxMutex )
#endif
#ifndef traceCREATE_COUNTING_SEMAPHORE
#define traceCREATE_COUNTING_SEMAPHORE()
#endif
#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
#endif
#ifndef traceQUEUE_SEND
#define traceQUEUE_SEND( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FAILED
#define traceQUEUE_SEND_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE
#define traceQUEUE_RECEIVE( pxQueue )
#endif
#ifndef traceQUEUE_PEEK
#define traceQUEUE_PEEK( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FAILED
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FROM_ISR
#define traceQUEUE_SEND_FROM_ISR( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FROM_ISR
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_DELETE
#define traceQUEUE_DELETE( pxQueue )
#endif
#ifndef traceTASK_CREATE
#define traceTASK_CREATE( pxNewTCB )
#endif
#ifndef traceTASK_CREATE_FAILED
#define traceTASK_CREATE_FAILED( pxNewTCB )
#endif
#ifndef traceTASK_DELETE
#define traceTASK_DELETE( pxTaskToDelete )
#endif
#ifndef traceTASK_DELAY_UNTIL
#define traceTASK_DELAY_UNTIL()
#endif
#ifndef traceTASK_DELAY
#define traceTASK_DELAY()
#endif
#ifndef traceTASK_PRIORITY_SET
#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
#endif
#ifndef traceTASK_SUSPEND
#define traceTASK_SUSPEND( pxTaskToSuspend )
#endif
#ifndef traceTASK_RESUME
#define traceTASK_RESUME( pxTaskToResume )
#endif
#ifndef traceTASK_RESUME_FROM_ISR
#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
#endif
#ifndef traceTASK_INCREMENT_TICK
#define traceTASK_INCREMENT_TICK( xTickCount )
#endif
#endif /* INC_FREERTOS_H */

View file

@ -0,0 +1,730 @@
/*
FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
+++ http://www.FreeRTOS.org +++
Documentation, latest information, license and contact details.
+++ http://www.SafeRTOS.com +++
A version that is certified for use in safety critical systems.
+++ http://www.OpenRTOS.com +++
Commercial support, development, porting, licensing and training services.
***************************************************************************
*/
#ifndef CO_ROUTINE_H
#define CO_ROUTINE_H
#include "list.h"
#ifdef __cplusplus
extern "C" {
#endif
/* 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
*/
signed 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.
*/
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
#ifdef __cplusplus
}
#endif
#endif /* CO_ROUTINE_H */

View file

@ -0,0 +1,294 @@
/*
FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
+++ http://www.FreeRTOS.org +++
Documentation, latest information, license and contact details.
+++ http://www.SafeRTOS.com +++
A version that is certified for use in safety critical systems.
+++ http://www.OpenRTOS.com +++
Commercial support, development, porting, licensing and training services.
***************************************************************************
*/
/*
* 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
*/
/*
Changes from V4.3.1
+ Included local const within listGET_OWNER_OF_NEXT_ENTRY() to assist
compiler with optimisation. Thanks B.R.
*/
#ifndef LIST_H
#define LIST_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* 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 ) \
{ \
xList * const pxConstList = 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. */ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \
{ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
} \
pxTCB = ( pxConstList )->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 );
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,272 @@
/*
FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http:www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
+++ http://www.FreeRTOS.org +++
Documentation, latest information, license and contact details.
+++ http://www.SafeRTOS.com +++
A version that is certified for use in safety critical systems.
+++ http://www.OpenRTOS.com +++
Commercial support, development, porting, licensing and training services.
***************************************************************************
*/
/*-----------------------------------------------------------
* 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_PIC24_PORT
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
#endif
#ifdef MPLAB_DSPIC_PORT
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
#endif
#ifdef MPLAB_PIC18F_PORT
#include "..\..\source\portable\MPLAB\PIC18F\portmacro.h"
#endif
#ifdef MPLAB_PIC32MX_PORT
#include "..\..\Source\portable\MPLAB\PIC32MX\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_ARM7_ECLIPSE
#include "portmacro.h"
#endif
#ifdef ROWLEY_LPC23xx
#include "../../Source/portable/GCC/ARM7_LPC23xx/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 STR75X_IAR
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
#endif
#ifdef STR75X_GCC
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
#endif
#ifdef STR91X_IAR
#include "..\..\Source\portable\IAR\STR91x\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 GCC_ARMCM3
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
#endif
#ifdef IAR_ARM_CM3
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
#endif
#ifdef IAR_ARMCM3_LM
#include "../../Source/portable/IAR/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 TERN_EE
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
#endif
#ifdef GCC_HCS12
#include "../../Source/portable/GCC/HCS12/portmacro.h"
#endif
#ifdef GCC_MCF5235
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
#endif
#ifdef GCC_PPC405
#include "../../Source/portable/GCC/PPC405_Xilinx/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
#ifdef __GNUC__
#ifdef __AVR32_AVR32A__
#include "portmacro.h"
#endif
#endif
#ifdef __ICCAVR32__
#ifdef __CORE__
#if __CORE__ == __AVR32A__
#include "portmacro.h"
#endif
#endif
#endif
#ifdef __91467D
#include "portmacro.h"
#endif
#ifdef __96340
#include "portmacro.h"
#endif
#ifdef __cplusplus
extern "C" {
#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 );
#ifdef __cplusplus
}
#endif
#endif /* PORTABLE_H */

View file

@ -0,0 +1,66 @@
/*
FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
+++ http://www.FreeRTOS.org +++
Documentation, latest information, license and contact details.
+++ http://www.SafeRTOS.com +++
A version that is certified for use in safety critical systems.
+++ http://www.OpenRTOS.com +++
Commercial support, development, porting, licensing and training services.
***************************************************************************
*/
#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 )
#define errQUEUE_EMPTY ( 0 )
#define errQUEUE_FULL ( 0 )
/* Error definitions. */
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
#define errNO_TASK_TO_RUN ( -2 )
#define errQUEUE_BLOCKED ( -4 )
#define errQUEUE_YIELD ( -5 )
#endif /* PROJDEFS_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,698 @@
/*
FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
+++ http://www.FreeRTOS.org +++
Documentation, latest information, license and contact details.
+++ http://www.SafeRTOS.com +++
A version that is certified for use in safety critical systems.
+++ http://www.OpenRTOS.com +++
Commercial support, development, porting, licensing and training services.
***************************************************************************
*/
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include "queue.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.
*
* This type of semaphore can be used for pure synchronisation between tasks or
* between an interrupt and a task. The semaphore need not be given back once
* obtained, so one task/interrupt can continuously 'give' the semaphore while
* another continuously 'takes' the semaphore. For this reason this type of
* semaphore does not use a priority inheritance mechanism. For an alternative
* that does use priority inheritance see xSemaphoreCreateMutex().
*
* @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 portBASE_TYPE ) 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 have previously been
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting().
*
* @param xSemaphore A handle to the semaphore being taken - obtained when
* the semaphore was created.
*
* @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. A block
* time of portMAX_DELAY can be used to block indefinitely (provided
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
*
* @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 ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
/**
* semphr. h
* xSemaphoreTakeRecursive(
* xSemaphoreHandle xMutex,
* portTickType xBlockTime
* )
*
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
* The mutex must have previously been created using a call to
* xSemaphoreCreateRecursiveMutex();
*
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
* macro to be available.
*
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being obtained. This is the
* handle returned by xSemaphoreCreateRecursiveMutex();
*
* @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. If
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
* return immediately no matter what the value of xBlockTime.
*
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
* expired without the semaphore becoming available.
*
* Example usage:
<pre>
xSemaphoreHandle xMutex = NULL;
// A task that creates a mutex.
void vATask( void * pvParameters )
{
// Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex();
}
// A task that uses the mutex.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xMutex != NULL )
{
// See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the mutex and can now access the
// shared resource.
// ...
// For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside
// a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
// The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, but instead buried in a more complex
// call structure. This is just for illustrative purposes.
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
// Now the mutex can be taken by other tasks.
}
else
{
// We could not obtain the mutex and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
* \ingroup Semaphores
*/
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime )
/*
* xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
*
* The source code that implements the alternative (Alt) API is much
* simpler because it executes everything from within a critical section.
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
* preferred fully featured API too. The fully featured API has more
* complex code that takes longer to execute, but makes much less use of
* critical sections. Therefore the alternative API sacrifices interrupt
* responsiveness to gain execution speed, whereas the fully featured API
* sacrifices execution speed to ensure better interrupt responsiveness.
*/
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
/**
* semphr. h
* <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
*
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
* an alternative which can be used from an ISR.
*
* This macro must also not be used on semaphores created using
* xSemaphoreCreateRecursiveMutex().
*
* @param xSemaphore A handle to the semaphore being released. This is the
* handle returned when the semaphore was created.
*
* @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 ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
*
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
* The mutex must have previously been created using a call to
* xSemaphoreCreateRecursiveMutex();
*
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
* macro to be available.
*
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being released, or 'given'. This is the
* handle returned by xSemaphoreCreateMutex();
*
* @return pdTRUE if the semaphore was given.
*
* Example usage:
<pre>
xSemaphoreHandle xMutex = NULL;
// A task that creates a mutex.
void vATask( void * pvParameters )
{
// Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex();
}
// A task that uses the mutex.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xMutex != NULL )
{
// See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the mutex and can now access the
// shared resource.
// ...
// For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside
// a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
// The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, it would be more likely that the calls
// to xSemaphoreGiveRecursive() would be called as a call stack
// unwound. This is just for demonstrative purposes.
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
// Now the mutex can be taken by other tasks.
}
else
{
// We could not obtain the mutex and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
* \ingroup Semaphores
*/
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex )
/*
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
*
* The source code that implements the alternative (Alt) API is much
* simpler because it executes everything from within a critical section.
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
* preferred fully featured API too. The fully featured API has more
* complex code that takes longer to execute, but makes much less use of
* critical sections. Therefore the alternative API sacrifices interrupt
* responsiveness to gain execution speed, whereas the fully featured API
* sacrifices execution speed to ensure better interrupt responsiveness.
*/
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>
xSemaphoreGiveFromISR(
xSemaphoreHandle xSemaphore,
portSHORT sTaskPreviouslyWoken
)</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
*
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
* must not be used with this macro.
*
* This macro can be used from an ISR.
*
* @param xSemaphore A handle to the semaphore being released. This is the
* handle returned when the semaphore was created.
*
* @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 of 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. Note when using the semaphore for synchronisation with an
// ISR in this manner there is no need to 'give' the semaphore back.
}
}
}
// Timer ISR
void vTimerISR( void * pvParameters )
{
static unsigned portCHAR ucLocalTickCount = 0;
static portBASE_TYPE xTaskWoken;
// A timer tick has occurred.
// ... Do other time functions.
// Is it time for vATask () to run?
xTaskWoken = pdFALSE;
ucLocalTickCount++;
if( ucLocalTickCount >= TICKS_TO_WAIT )
{
// Unblock the task by releasing the semaphore.
xTaskWoken = xSemaphoreGiveFromISR( xSemaphore, xTaskWoken );
// Reset the count so we release the semaphore again in 10 ticks time.
ucLocalTickCount = 0;
}
if( xTaskWoken != pdFALSE )
{
// We can force a context switch here. Context switching from an
// ISR uses port specific syntax. Check the demo task for your port
// to find the syntax required.
}
}
</pre>
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
* \ingroup Semaphores
*/
#define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
*
* <i>Macro</i> that implements a mutex semaphore by using the existing queue
* mechanism.
*
* Mutexes created using this macro can be accessed using the xSemaphoreTake()
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
* xSemaphoreGiveRecursive() macros should not be used.
*
* This type of semaphore uses a priority inheritance mechanism so a task
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
* semaphore it is no longer required.
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
* See xSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
* xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateMutex();
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
* \ingroup Semaphores
*/
#define xSemaphoreCreateMutex() xQueueCreateMutex()
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
*
* <i>Macro</i> that implements a recursive mutex by using the existing queue
* mechanism.
*
* Mutexes created using this macro can be accessed using the
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
* xSemaphoreTake() and xSemaphoreGive() macros should not be used.
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* This type of semaphore uses a priority inheritance mechanism so a task
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
* semaphore it is no longer required.
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
* See xSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
* xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateRecursiveMutex();
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
* \ingroup Semaphores
*/
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
*
* <i>Macro</i> that creates a counting semaphore by using the existing
* queue mechanism.
*
* Counting semaphores are typically used for two things:
*
* 1) Counting events.
*
* In this usage scenario an event handler will 'give' a semaphore each time
* an event occurs (incrementing the semaphore count value), and a handler
* task will 'take' a semaphore each time it processes an event
* (decrementing the semaphore count value). The count value is therefore
* the difference between the number of events that have occurred and the
* number that have been processed. In this case it is desirable for the
* initial count value to be zero.
*
* 2) Resource management.
*
* In this usage scenario the count value indicates the number of resources
* available. To obtain control of a resource a task must first obtain a
* semaphore - decrementing the semaphore count value. When the count value
* reaches zero there are no free resources. When a task finishes with the
* resource it 'gives' the semaphore back - incrementing the semaphore count
* value. In this case it is desirable for the initial count value to be
* equal to the maximum count value, indicating that all resources are free.
*
* @param uxMaxCount The maximum count value that can be reached. When the
* semaphore reaches this value it can no longer be 'given'.
*
* @param uxInitialCount The count value assigned to the semaphore when it is
* created.
*
* @return Handle to the created semaphore. Null if the semaphore could not be
* created.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
xSemaphoreHandle xSemaphore = NULL;
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
// The max value to which the semaphore can count should be 10, and the
// initial value assigned to the count should be 0.
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
* \ingroup Semaphores
*/
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
#endif /* SEMAPHORE_H */

File diff suppressed because it is too large Load diff