1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

Merge branch 'bugfix-flight'

This commit is contained in:
James Cotton 2011-06-05 09:48:43 -05:00
commit 8bec19f4a5
31 changed files with 3095 additions and 955 deletions

View File

@ -38,7 +38,7 @@ C: Cathy Moss
D: October 2010
M: First OpenPilot night flight
C: Dale Schintock
C: Dale Schinstock
D: October 2010
V: http://www.youtube.com/watch?v=yk8ckeRMV8U
@ -53,7 +53,7 @@ D: November 2010
V: http://vimeo.com/17488702
M: First solid OpenPilot Position Hold
C: Dale Schintock
C: Dale Schinstock
D: December 2010
V: http://www.youtube.com/watch?v=BBCGVP0Vpgw

View File

@ -128,17 +128,20 @@ static void actuatorTask(void* parameters)
portTickType lastSysTime;
portTickType thisSysTime;
float dT = 0.0f;
ActuatorCommandData command;
ActuatorSettingsData settings;
SystemSettingsData sysSettings;
ActuatorCommandData command;
MixerSettingsData mixerSettings;
ActuatorDesiredData desired;
MixerStatusData mixerStatus;
FlightStatusData flightStatus;
ActuatorSettingsGet(&settings);
PIOS_Servo_SetHz(&settings.ChannelUpdateFreq[0], ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
uint8_t MotorsSpinWhileArmed;
int16_t ChannelMax[ACTUATORCOMMAND_CHANNEL_NUMELEM];
int16_t ChannelMin[ACTUATORCOMMAND_CHANNEL_NUMELEM];
int16_t ChannelNeutral[ACTUATORCOMMAND_CHANNEL_NUMELEM];
uint16_t ChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM];
ActuatorSettingsChannelUpdateFreqGet(ChannelUpdateFreq);
PIOS_Servo_SetHz(&ChannelUpdateFreq[0], ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
float * status = (float *)&mixerStatus; //access status objects as an array of floats
@ -164,14 +167,16 @@ static void actuatorTask(void* parameters)
dT = (thisSysTime - lastSysTime) / portTICK_RATE_MS / 1000.0f;
lastSysTime = thisSysTime;
FlightStatusGet(&flightStatus);
SystemSettingsGet(&sysSettings);
MixerStatusGet(&mixerStatus);
MixerSettingsGet (&mixerSettings);
ActuatorDesiredGet(&desired);
ActuatorCommandGet(&command);
ActuatorSettingsGet(&settings);
ActuatorSettingsMotorsSpinWhileArmedGet(&MotorsSpinWhileArmed);
ActuatorSettingsChannelMaxGet(ChannelMax);
ActuatorSettingsChannelMinGet(ChannelMin);
ActuatorSettingsChannelNeutralGet(ChannelNeutral);
int nMixers = 0;
Mixer_t * mixers = (Mixer_t *)&mixerSettings.Mixer1Type;
@ -192,7 +197,7 @@ static void actuatorTask(void* parameters)
bool armed = flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED;
bool positiveThrottle = desired.Throttle >= 0.00;
bool spinWhileArmed = settings.MotorsSpinWhileArmed == ACTUATORSETTINGS_MOTORSSPINWHILEARMED_TRUE;
bool spinWhileArmed = MotorsSpinWhileArmed == ACTUATORSETTINGS_MOTORSSPINWHILEARMED_TRUE;
float curve1 = MixerCurve(desired.Throttle,mixerSettings.ThrottleCurve1);
float curve2 = MixerCurve(desired.Throttle,mixerSettings.ThrottleCurve2);
@ -223,11 +228,11 @@ static void actuatorTask(void* parameters)
(status[ct] < 0) )
status[ct] = 0;
}
command.Channel[ct] = scaleChannel(status[ct],
settings.ChannelMax[ct],
settings.ChannelMin[ct],
settings.ChannelNeutral[ct]);
ChannelMax[ct],
ChannelMin[ct],
ChannelNeutral[ct]);
}
MixerStatusSet(&mixerStatus);
@ -391,11 +396,13 @@ static int16_t scaleChannel(float value, int16_t max, int16_t min, int16_t neutr
*/
static void setFailsafe()
{
ActuatorCommandData command;
ActuatorSettingsData settings;
ActuatorCommandGet(&command);
ActuatorSettingsGet(&settings);
/* grab only the modules parts that we are going to use */
int16_t ChannelMin[ACTUATORCOMMAND_CHANNEL_NUMELEM];
ActuatorSettingsChannelMinGet(ChannelMin);
int16_t ChannelNeutral[ACTUATORCOMMAND_CHANNEL_NUMELEM];
ActuatorSettingsChannelNeutralGet(ChannelNeutral);
int16_t Channel[ACTUATORCOMMAND_CHANNEL_NUMELEM];
ActuatorCommandChannelGet(Channel);
MixerSettingsData mixerSettings;
MixerSettingsGet (&mixerSettings);
@ -407,15 +414,15 @@ static void setFailsafe()
if(mixers[n].type == MIXERSETTINGS_MIXER1TYPE_MOTOR)
{
command.Channel[n] = settings.ChannelMin[n];
Channel[n] = ChannelMin[n];
}
else if(mixers[n].type == MIXERSETTINGS_MIXER1TYPE_SERVO)
{
command.Channel[n] = settings.ChannelNeutral[n];
Channel[n] = ChannelNeutral[n];
}
else
{
command.Channel[n] = 0;
Channel[n] = 0;
}
}
@ -425,11 +432,11 @@ static void setFailsafe()
// Update servo outputs
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
{
set_channel(n, command.Channel[n]);
set_channel(n, Channel[n]);
}
// Update output object
ActuatorCommandSet(&command);
// Update output object's parts that we changed
ActuatorCommandChannelGet(Channel);
}
@ -438,10 +445,10 @@ static void setFailsafe()
*/
static void actuator_update_rate(UAVObjEvent * ev)
{
ActuatorSettingsData settings;
uint16_t ChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM];
if ( ev->obj == ActuatorSettingsHandle() ) {
ActuatorSettingsGet(&settings);
PIOS_Servo_SetHz(&settings.ChannelUpdateFreq[0], ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
ActuatorSettingsChannelUpdateFreqGet(ChannelUpdateFreq);
PIOS_Servo_SetHz(&ChannelUpdateFreq[0], ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
}
}

View File

@ -288,7 +288,7 @@ class UAVObject:
uint32_t type;
uint32_t numElements;
uint8_t const *tmpStr;
int8_t tmpInt8;
int8_t tmpInt8 = 0;
int16_t tmpInt16;
int32_t tmpInt32;
float tmpFloat;

View File

@ -236,7 +236,7 @@ void updateVtolDesiredVelocity()
{
static portTickType lastSysTime;
portTickType thisSysTime = xTaskGetTickCount();;
float dT;
float dT = 0;
GuidanceSettingsData guidanceSettings;
PositionActualData positionActual;
@ -304,7 +304,7 @@ static void updateVtolDesiredAttitude()
{
static portTickType lastSysTime;
portTickType thisSysTime = xTaskGetTickCount();;
float dT;
float dT = 0;
VelocityDesiredData velocityDesired;
VelocityActualData velocityActual;

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -222,7 +228,7 @@ static void prvCheckPendingReadyList( void )
/* Are there any co-routines waiting to get moved to the ready list? These
are co-routines that have been readied by an ISR. The ISR cannot access
the ready lists itself. */
while( !listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) )
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
{
corCRCB *pxUnblockedCRCB;
@ -263,8 +269,10 @@ corCRCB *pxCRCB;
}
/* See if this tick has made a timeout expire. */
while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL )
{
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
{
pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
{
/* Timeout not yet expired. */
@ -352,7 +360,8 @@ corCRCB *pxUnblockedCRCB;
signed portBASE_TYPE xReturn;
/* This function is called from within an interrupt. It can only access
event lists and the pending ready list. */
event lists and the pending ready list. This function assumes that a
check has already been made to ensure pxEventList is not empty. */
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );

View File

@ -1,38 +1,44 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
@ -148,6 +154,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#define configUSE_MUTEXES 0
#endif
#ifndef configUSE_TIMERS
#define configUSE_TIMERS 0
#endif
#ifndef configUSE_COUNTING_SEMAPHORES
#define configUSE_COUNTING_SEMAPHORES 0
#endif
@ -169,27 +179,40 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#endif
#if configMAX_TASK_NAME_LEN < 1
#undef configMAX_TASK_NAME_LEN
#define configMAX_TASK_NAME_LEN 1
#error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h
#endif
#ifndef INCLUDE_xTaskResumeFromISR
#define INCLUDE_xTaskResumeFromISR 1
#endif
#ifndef configASSERT
#define configASSERT( x )
#endif
/* The timers module relies on xTaskGetSchedulerState(). */
#if configUSE_TIMERS == 1
#ifndef configTIMER_TASK_PRIORITY
#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.
#endif /* configTIMER_TASK_PRIORITY */
#ifndef configTIMER_QUEUE_LENGTH
#error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.
#endif /* configTIMER_QUEUE_LENGTH */
#ifndef configTIMER_TASK_STACK_DEPTH
#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.
#endif /* configTIMER_TASK_STACK_DEPTH */
#endif /* configUSE_TIMERS */
#ifndef INCLUDE_xTaskGetSchedulerState
#define INCLUDE_xTaskGetSchedulerState 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
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 0
#endif
@ -203,11 +226,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#ifndef configQUEUE_REGISTRY_SIZE
#define configQUEUE_REGISTRY_SIZE 0
#define configQUEUE_REGISTRY_SIZE 0U
#endif
#if configQUEUE_REGISTRY_SIZE < 1
#define configQUEUE_REGISTRY_SIZE 0
#if ( configQUEUE_REGISTRY_SIZE < 1U )
#define vQueueAddToRegistry( xQueue, pcName )
#define vQueueUnregisterQueue( xQueue )
#endif
@ -380,6 +402,26 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#define traceTASK_INCREMENT_TICK( xTickCount )
#endif
#ifndef traceTIMER_CREATE
#define traceTIMER_CREATE( pxNewTimer )
#endif
#ifndef traceTIMER_CREATE_FAILED
#define traceTIMER_CREATE_FAILED()
#endif
#ifndef traceTIMER_COMMAND_SEND
#define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn )
#endif
#ifndef traceTIMER_EXPIRED
#define traceTIMER_EXPIRED( pxTimer )
#endif
#ifndef traceTIMER_COMMAND_RECEIVED
#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )
#endif
#ifndef configGENERATE_RUN_TIME_STATS
#define configGENERATE_RUN_TIME_STATS 0
#endif
@ -415,7 +457,7 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#endif
#ifndef pvPortMallocAligned
#define pvPortMallocAligned( x, puxStackBuffer ) ( ( puxStackBuffer == NULL ) ? ( pvPortMalloc( x ) ) : ( puxStackBuffer ) )
#define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )
#endif
#ifndef vPortFreeAligned

View File

@ -1,38 +1,44 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
@ -93,8 +99,6 @@
/* Only the current stack state is to be checked. */
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
\
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
{ \
@ -110,7 +114,6 @@
/* Only the current stack state is to be checked. */
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
\
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
@ -124,21 +127,20 @@
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\
\
/* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
{ \
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\
\
/* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
@ -146,24 +148,23 @@
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\
\
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\
/* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
{ \
char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\
\
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\
/* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -51,16 +57,13 @@
licensing and training services.
*/
#ifndef CO_ROUTINE_H
#define CO_ROUTINE_H
#ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include croutine.h"
#endif
#ifndef CO_ROUTINE_H
#define CO_ROUTINE_H
#include "list.h"
#ifdef __cplusplus
@ -230,7 +233,7 @@ void vCoRoutineSchedule( void );
* \defgroup crSTART crSTART
* \ingroup Tasks
*/
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:
/**
* croutine. h
@ -267,8 +270,8 @@ void vCoRoutineSchedule( void );
* 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):
#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
@ -317,11 +320,11 @@ void vCoRoutineSchedule( void );
* \ingroup Tasks
*/
#define crDELAY( xHandle, xTicksToDelay ) \
if( xTicksToDelay > 0 ) \
if( ( xTicksToDelay ) > 0 ) \
{ \
vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
} \
crSET_STATE0( xHandle );
crSET_STATE0( ( xHandle ) );
/**
* <pre>
@ -408,15 +411,15 @@ void vCoRoutineSchedule( void );
*/
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
{ \
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \
if( *pxResult == errQUEUE_BLOCKED ) \
*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \
if( *( pxResult ) == errQUEUE_BLOCKED ) \
{ \
crSET_STATE0( xHandle ); \
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \
crSET_STATE0( ( xHandle ) ); \
*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \
} \
if( *pxResult == errQUEUE_YIELD ) \
{ \
crSET_STATE1( xHandle ); \
crSET_STATE1( ( xHandle ) ); \
*pxResult = pdPASS; \
} \
}
@ -500,16 +503,16 @@ void vCoRoutineSchedule( void );
*/
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
{ \
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \
if( *pxResult == errQUEUE_BLOCKED ) \
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \
if( *( pxResult ) == errQUEUE_BLOCKED ) \
{ \
crSET_STATE0( xHandle ); \
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \
crSET_STATE0( ( xHandle ) ); \
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \
} \
if( *pxResult == errQUEUE_YIELD ) \
if( *( pxResult ) == errQUEUE_YIELD ) \
{ \
crSET_STATE1( xHandle ); \
*pxResult = pdPASS; \
crSET_STATE1( ( xHandle ) ); \
*( pxResult ) = pdPASS; \
} \
}
@ -607,7 +610,7 @@ void vCoRoutineSchedule( void );
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
* \ingroup Tasks
*/
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
/**
@ -720,7 +723,7 @@ void vCoRoutineSchedule( void );
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
* \ingroup Tasks
*/
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
#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.

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -79,12 +85,6 @@
* \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
@ -130,7 +130,7 @@ typedef struct xLIST
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
* \ingroup LinkedList
*/
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner
#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
@ -139,7 +139,7 @@ typedef struct xLIST
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
* \ingroup LinkedList
*/
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = ( xValue )
/*
* Access macro the retrieve the value of the list item. The value can
@ -151,6 +151,15 @@ typedef struct xLIST
*/
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
/*
* Access macro the retrieve the value of the list item at the head of a given
* list.
*
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
* \ingroup LinkedList
*/
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue )
/*
* Access macro to determine if a list contains any items. The macro will
* only have the value true if the list is empty.
@ -186,7 +195,7 @@ typedef struct xLIST
*/
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
{ \
xList * const pxConstList = 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; \
@ -194,7 +203,7 @@ xList * const pxConstList = pxList; \
{ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
} \
pxTCB = ( pxConstList )->pxIndex->pvOwner; \
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
}
@ -214,7 +223,7 @@ xList * const pxConstList = pxList; \
* \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 ) )
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
/*
* Check to see if a list item is within a list. The list item maintains a
@ -226,7 +235,7 @@ xList * const pxConstList = pxList; \
* @return pdTRUE is the list item is in the list, otherwise pdFALSE.
* pointer against
*/
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) )
/*
* Must be called before a list is used! This initialises all the members

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -51,16 +57,14 @@
licensing and training services.
*/
#ifndef INC_FREERTOS_H
#error "#include FreeRTOS.h" must appear in source files before "#include queue.h"
#endif
#ifndef QUEUE_H
#define QUEUE_H
#ifndef INC_FREERTOS_H
#error "#include FreeRTOS.h" must appear in source files before "#include queue.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -68,7 +72,11 @@ extern "C" {
#include "mpu_wrappers.h"
/**
* Type by which queues are referenced. For example, a call to xQueueCreate
* returns (via a pointer parameter) an xQueueHandle variable that can then
* be used as a parameter to xQueueSend(), xQueueReceive(), etc.
*/
typedef void * xQueueHandle;
@ -140,7 +148,7 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
* <pre>
portBASE_TYPE xQueueSendToToFront(
xQueueHandle xQueue,
const void * pvItemToQueue,
const void * pvItemToQueue,
portTickType xTicksToWait
);
* </pre>
@ -215,7 +223,7 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
* \defgroup xQueueSend xQueueSend
* \ingroup QueueManagement
*/
#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
/**
* queue. h
@ -297,7 +305,7 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
* \defgroup xQueueSend xQueueSend
* \ingroup QueueManagement
*/
#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
/**
* queue. h
@ -381,7 +389,7 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
* \defgroup xQueueSend xQueueSend
* \ingroup QueueManagement
*/
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
/**
@ -469,7 +477,7 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
* \defgroup xQueueSend xQueueSend
* \ingroup QueueManagement
*/
signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
/**
* queue. h
@ -563,7 +571,7 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const
* \defgroup xQueueReceive xQueueReceive
* \ingroup QueueManagement
*/
#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )
/**
* queue. h
@ -656,7 +664,7 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const
* \defgroup xQueueReceive xQueueReceive
* \ingroup QueueManagement
*/
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )
/**
@ -784,7 +792,7 @@ unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
* \page vQueueDelete vQueueDelete
* \ingroup QueueManagement
*/
void vQueueDelete( xQueueHandle xQueue );
void vQueueDelete( xQueueHandle pxQueue );
/**
* queue. h
@ -854,7 +862,7 @@ void vQueueDelete( xQueueHandle xQueue );
* \defgroup xQueueSendFromISR xQueueSendFromISR
* \ingroup QueueManagement
*/
#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_FRONT )
#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )
/**
@ -925,7 +933,7 @@ void vQueueDelete( xQueueHandle xQueue );
* \defgroup xQueueSendFromISR xQueueSendFromISR
* \ingroup QueueManagement
*/
#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
/**
* queue. h
@ -999,7 +1007,7 @@ void vQueueDelete( xQueueHandle xQueue );
* \defgroup xQueueSendFromISR xQueueSendFromISR
* \ingroup QueueManagement
*/
#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
/**
* queue. h
@ -1193,10 +1201,10 @@ unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue
*/
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )
#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )
/*
* The functions defined above are for passing data to and from tasks. The
@ -1223,8 +1231,8 @@ xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue,
* For internal use only. Use xSemaphoreTakeMutexRecursive() or
* xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
*/
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime );
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime );
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex );
/*
* The registry is provided as a means for kernel aware debuggers to
@ -1246,11 +1254,12 @@ portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );
* @param pcName The name to be associated with the handle. This is the
* name that the kernel aware debugger will display.
*/
#if configQUEUE_REGISTRY_SIZE > 0
#if configQUEUE_REGISTRY_SIZE > 0U
void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName );
#endif
/* Not a public API function, hence the 'Restricted' in the name. */
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );
#ifdef __cplusplus

View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -51,20 +57,20 @@
licensing and training services.
*/
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#ifndef INC_FREERTOS_H
#error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
#endif
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include "queue.h"
typedef xQueueHandle xSemaphoreHandle;
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1 )
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0 )
#define semGIVE_BLOCK_TIME ( ( portTickType ) 0 )
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U )
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U )
#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U )
/**
@ -105,12 +111,12 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores
*/
#define vSemaphoreCreateBinary( xSemaphore ) { \
xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( xSemaphore != NULL ) \
{ \
xSemaphoreGive( xSemaphore ); \
} \
#define vSemaphoreCreateBinary( xSemaphore ) { \
( xSemaphore ) = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( ( xSemaphore ) != NULL ) \
{ \
xSemaphoreGive( ( xSemaphore ) ); \
} \
}
/**
@ -178,7 +184,7 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup xSemaphoreTake xSemaphoreTake
* \ingroup Semaphores
*/
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
/**
* semphr. h
@ -271,7 +277,7 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
* \ingroup Semaphores
*/
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime )
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
/*
@ -286,7 +292,7 @@ typedef xQueueHandle xSemaphoreHandle;
* 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 )
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
/**
* semphr. h
@ -349,7 +355,7 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup xSemaphoreGive xSemaphoreGive
* \ingroup Semaphores
*/
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
@ -433,7 +439,7 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
* \ingroup Semaphores
*/
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex )
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
/*
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
@ -447,7 +453,7 @@ typedef xQueueHandle xSemaphoreHandle;
* 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 )
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
@ -538,7 +544,7 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
* \ingroup Semaphores
*/
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
/**
* semphr. h
@ -703,7 +709,7 @@ typedef xQueueHandle xSemaphoreHandle;
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
* \ingroup Semaphores
*/
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
#endif /* SEMAPHORE_H */

View File

@ -1,38 +1,44 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
@ -52,15 +58,13 @@
*/
#ifndef TASK_H
#define TASK_H
#ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include task.h"
#endif
#ifndef TASK_H
#define TASK_H
#include "portable.h"
#include "list.h"
@ -72,7 +76,7 @@ extern "C" {
* MACROS AND DEFINITIONS
*----------------------------------------------------------*/
#define tskKERNEL_VERSION_NUMBER "V6.1.1"
#define tskKERNEL_VERSION_NUMBER "V7.0.1"
/**
* task. h
@ -124,7 +128,7 @@ typedef struct xTASK_PARAMTERS
*
* \ingroup TaskUtils
*/
#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 )
#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0U )
/**
* task. h
@ -427,8 +431,7 @@ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxR
* \defgroup vTaskDelete vTaskDelete
* \ingroup Tasks
*/
void vTaskDelete( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;
void vTaskDelete( xTaskHandle pxTaskToDelete ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------
* TASK CONTROL API
@ -1103,7 +1106,7 @@ unsigned long ulTaskEndTrace( void ) PRIVILEGED_FUNCTION;
*
* Returns the high water mark of the stack associated with xTask. That is,
* the minimum free stack space there has been (in words, so on a 32 bit machine
* a value of 1 means 4 bytes) since the task started. The smaller the returned
* a value of 1 means 4 bytes) since the task started. The smaller the returned
* number the closer the task has come to overflowing its stack.
*
* @param xTask Handle of the task associated with the stack to be checked.
@ -1126,7 +1129,7 @@ unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEG
* @return The run time of selected task
*/
unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask );
/* When using trace macros it is sometimes necessary to include tasks.h before
FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined,
so the following two prototypes will cause a compilation error. This can be
@ -1207,6 +1210,21 @@ void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION;
*/
void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
/*
* 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.
*
* This function performs nearly the same function as vTaskPlaceOnEventList().
* The difference being that this function does not permit tasks to block
* indefinitely, whereas vTaskPlaceOnEventList() does.
*
* @return pdTRUE if the task being removed has a higher priority than the task
* making the call, otherwise pdFALSE.
*/
void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
/*
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
* INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
@ -1291,7 +1309,7 @@ void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUN
* Generic version of the task creation function which is in turn called by the
* xTaskCreate() and xTaskCreateRestricted() macros.
*/
signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION;
signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION;
#ifdef __cplusplus
}

View File

@ -0,0 +1,936 @@
/*
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
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 TIMERS_H
#define TIMERS_H
#ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include timers.h"
#endif
#include "portable.h"
#include "list.h"
#ifdef __cplusplus
extern "C" {
#endif
/* IDs for commands that can be sent/received on the timer queue. These are to
be used solely through the macros that make up the public software timer API,
as defined below. */
#define tmrCOMMAND_START 0
#define tmrCOMMAND_STOP 1
#define tmrCOMMAND_CHANGE_PERIOD 2
#define tmrCOMMAND_DELETE 3
/*-----------------------------------------------------------
* MACROS AND DEFINITIONS
*----------------------------------------------------------*/
/**
* Type by which software timers are referenced. For example, a call to
* xTimerCreate() returns an xTimerHandle variable that can then be used to
* reference the subject timer in calls to other software timer API functions
* (for example, xTimerStart(), xTimerReset(), etc.).
*/
typedef void * xTimerHandle;
/* Define the prototype to which timer callback functions must conform. */
typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );
/**
* xTimerHandle xTimerCreate( const signed char *pcTimerName,
* portTickType xTimerPeriod,
* unsigned portBASE_TYPE uxAutoReload,
* void * pvTimerID,
* tmrTIMER_CALLBACK pxCallbackFunction );
*
* Creates a new software timer instance. This allocates the storage required
* by the new timer, initialises the new timers internal state, and returns a
* handle by which the new timer can be referenced.
*
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
* xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the
* active state.
*
* @param pcTimerName A text name that is assigned to the timer. This is done
* purely to assist debugging. The kernel itself only ever references a timer by
* its handle, and never by its name.
*
* @param xTimerPeriod The timer period. The time is defined in tick periods so
* the constant portTICK_RATE_MS can be used to convert a time that has been
* specified in milliseconds. For example, if the timer must expire after 100
* ticks, then xTimerPeriod should be set to 100. Alternatively, if the timer
* must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS )
* provided configTICK_RATE_HZ is less than or equal to 1000.
*
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
* expire repeatedly with a frequency set by the xTimerPeriod parameter. If
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
* enter the dormant state after it expires.
*
* @param pvTimerID An identifier that is assigned to the timer being created.
* Typically this would be used in the timer callback function to identify which
* timer expired when the same callback function is assigned to more than one
* timer.
*
* @param pxCallbackFunction The function to call when the timer expires.
* Callback functions must have the prototype defined by tmrTIMER_CALLBACK,
* which is "void vCallbackFunction( xTIMER *xTimer );".
*
* @return If the timer is successfully create then a handle to the newly
* created timer is returned. If the timer cannot be created (because either
* there is insufficient FreeRTOS heap remaining to allocate the timer
* structures, or the timer period was set to 0) then 0 is returned.
*
* Example usage:
*
*
* #define NUM_TIMERS 5
*
* // An array to hold handles to the created timers.
* xTimerHandle xTimers[ NUM_TIMERS ];
*
* // An array to hold a count of the number of times each timer expires.
* long lExpireCounters[ NUM_TIMERS ] = { 0 };
*
* // Define a callback function that will be used by multiple timer instances.
* // The callback function does nothing but count the number of times the
* // associated timer expires, and stop the timer once the timer has expired
* // 10 times.
* void vTimerCallback( xTIMER *pxTimer )
* {
* long lArrayIndex;
* const long xMaxExpiryCountBeforeStopping = 10;
*
* // Optionally do something if the pxTimer parameter is NULL.
* configASSERT( pxTimer );
*
* // Which timer expired?
* lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );
*
* // Increment the number of times that pxTimer has expired.
* lExpireCounters[ lArrayIndex ] += 1;
*
* // If the timer has expired 10 times then stop it from running.
* if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping )
* {
* // Do not use a block time if calling a timer API function from a
* // timer callback function, as doing so could cause a deadlock!
* xTimerStop( pxTimer, 0 );
* }
* }
*
* void main( void )
* {
* long x;
*
* // Create then start some timers. Starting the timers before the scheduler
* // has been started means the timers will start running immediately that
* // the scheduler starts.
* for( x = 0; x < NUM_TIMERS; x++ )
* {
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
* ( 100 * x ), // The timer period in ticks.
* pdTRUE, // The timers will auto-reload themselves when they expire.
* ( void * ) x, // Assign each timer a unique id equal to its array index.
* vTimerCallback // Each timer calls the same callback when it expires.
* );
*
* if( xTimers[ x ] == NULL )
* {
* // The timer was not created.
* }
* else
* {
* // Start the timer. No block time is specified, and even if one was
* // it would be ignored because the scheduler has not yet been
* // started.
* if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )
* {
* // The timer could not be set into the Active state.
* }
* }
* }
*
* // ...
* // Create tasks here.
* // ...
*
* // Starting the scheduler will start the timers running as they have already
* // been set into the active state.
* xTaskStartScheduler();
*
* // Should not reach here.
* for( ;; );
* }
*/
xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION;
/**
* void *pvTimerGetTimerID( xTimerHandle xTimer );
*
* Returns the ID assigned to the timer.
*
* IDs are assigned to timers using the pvTimerID parameter of the call to
* xTimerCreated() that was used to create the timer.
*
* If the same callback function is assigned to multiple timers then the timer
* ID can be used within the callback function to identify which timer actually
* expired.
*
* @param xTimer The timer being queried.
*
* @return The ID assigned to the timer being queried.
*
* Example usage:
*
* See the xTimerCreate() API function example usage scenario.
*/
void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
/**
* portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer );
*
* Queries a timer to see if it is active or dormant.
*
* A timer will be dormant if:
* 1) It has been created but not started, or
* 2) It is an expired on-shot timer that has not been restarted.
*
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
* xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the
* active state.
*
* @param xTimer The timer being queried.
*
* @return pdFALSE will be returned if the timer is dormant. A value other than
* pdFALSE will be returned if the timer is active.
*
* Example usage:
*
* // This function assumes xTimer has already been created.
* void vAFunction( xTimerHandle xTimer )
* {
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
* {
* // xTimer is active, do something.
* }
* else
* {
* // xTimer is not active, do something else.
* }
* }
*/
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
/**
* portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* though a queue called the timer command queue. The timer command queue is
* private to the kernel itself and is not directly accessible to application
* code. The length of the timer command queue is set by the
* configTIMER_QUEUE_LENGTH configuration constant.
*
* xTimerStart() starts a timer that was previously created using the
* xTimerCreate() API function. If the timer had already been started and was
* already in the active state, then xTimerStart() has equivalent functionality
* to the xTimerReset() API function.
*
* Starting a timer ensures the timer is in the active state. If the timer
* is not stopped, deleted, or reset in the mean time, the callback function
* associated with the timer will get called 'n' ticks after xTimerStart() was
* called, where 'n' is the timers defined period.
*
* It is valid to call xTimerStart() before the scheduler has been started, but
* when this is done the timer will not actually start until the scheduler is
* started, and the timers expiry time will be relative to when the scheduler is
* started, not relative to when xTimerStart() was called.
*
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart()
* to be available.
*
* @param xTimer The handle of the timer being started/restarted.
*
* @param xBlockTime Specifies the time, in ticks, that the calling task should
* be held in the Blocked state to wait for the start command to be successfully
* sent to the timer command queue, should the queue already be full when
* xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called
* before the scheduler is started.
*
* @return pdFAIL will be returned if the start command could not be sent to
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
* be returned if the command was successfully sent to the timer command queue.
* When the command is actually processed will depend on the priority of the
* timer service/daemon task relative to other tasks in the system, although the
* timers expiry time is relative to when xTimerStart() is actually called. The
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
* configuration constant.
*
* Example usage:
*
* See the xTimerCreate() API function example usage scenario.
*
*/
#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
/**
* portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* though a queue called the timer command queue. The timer command queue is
* private to the kernel itself and is not directly accessible to application
* code. The length of the timer command queue is set by the
* configTIMER_QUEUE_LENGTH configuration constant.
*
* xTimerStop() stops a timer that was previously started using either of the
* The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(),
* xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions.
*
* Stopping a timer ensures the timer is not in the active state.
*
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop()
* to be available.
*
* @param xTimer The handle of the timer being stopped.
*
* @param xBlockTime Specifies the time, in ticks, that the calling task should
* be held in the Blocked state to wait for the stop command to be successfully
* sent to the timer command queue, should the queue already be full when
* xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called
* before the scheduler is started.
*
* @return pdFAIL will be returned if the stop command could not be sent to
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
* be returned if the command was successfully sent to the timer command queue.
* When the command is actually processed will depend on the priority of the
* timer service/daemon task relative to other tasks in the system. The timer
* service/daemon task priority is set by the configTIMER_TASK_PRIORITY
* configuration constant.
*
* Example usage:
*
* See the xTimerCreate() API function example usage scenario.
*
*/
#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )
/**
* portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer,
* portTickType xNewPeriod,
* portTickType xBlockTime );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* though a queue called the timer command queue. The timer command queue is
* private to the kernel itself and is not directly accessible to application
* code. The length of the timer command queue is set by the
* configTIMER_QUEUE_LENGTH configuration constant.
*
* xTimerChangePeriod() changes the period of a timer that was previously
* created using the xTimerCreate() API function.
*
* xTimerChangePeriod() can be called to change the period of an active or
* dormant state timer.
*
* The configUSE_TIMERS configuration constant must be set to 1 for
* xTimerChangePeriod() to be available.
*
* @param xTimer The handle of the timer that is having its period changed.
*
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
* that has been specified in milliseconds. For example, if the timer must
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
* if the timer must expire after 500ms, then xNewPeriod can be set to
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
* or equal to 1000.
*
* @param xBlockTime Specifies the time, in ticks, that the calling task should
* be held in the Blocked state to wait for the change period command to be
* successfully sent to the timer command queue, should the queue already be
* full when xTimerChangePeriod() was called. xBlockTime is ignored if
* xTimerChangePeriod() is called before the scheduler is started.
*
* @return pdFAIL will be returned if the change period command could not be
* sent to the timer command queue even after xBlockTime ticks had passed.
* pdPASS will be returned if the command was successfully sent to the timer
* command queue. When the command is actually processed will depend on the
* priority of the timer service/daemon task relative to other tasks in the
* system. The timer service/daemon task priority is set by the
* configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
*
* // This function assumes xTimer has already been created. If the timer
* // referenced by xTimer is already active when it is called, then the timer
* // is deleted. If the timer referenced by xTimer is not active when it is
* // called, then the period of the timer is set to 500ms and the timer is
* // started.
* void vAFunction( xTimerHandle xTimer )
* {
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
* {
* // xTimer is already active - delete it.
* xTimerDelete( xTimer );
* }
* else
* {
* // xTimer is not active, change its period to 500ms. This will also
* // cause the timer to start. Block for a maximum of 100 ticks if the
* // change period command cannot immediately be sent to the timer
* // command queue.
* if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS )
* {
* // The command was successfully sent.
* }
* else
* {
* // The command could not be sent, even after waiting for 100 ticks
* // to pass. Take appropriate action here.
* }
* }
* }
*/
#define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )
/**
* portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* though a queue called the timer command queue. The timer command queue is
* private to the kernel itself and is not directly accessible to application
* code. The length of the timer command queue is set by the
* configTIMER_QUEUE_LENGTH configuration constant.
*
* xTimerDelete() deletes a timer that was previously created using the
* xTimerCreate() API function.
*
* The configUSE_TIMERS configuration constant must be set to 1 for
* xTimerDelete() to be available.
*
* @param xTimer The handle of the timer being deleted.
*
* @param xBlockTime Specifies the time, in ticks, that the calling task should
* be held in the Blocked state to wait for the delete command to be
* successfully sent to the timer command queue, should the queue already be
* full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete()
* is called before the scheduler is started.
*
* @return pdFAIL will be returned if the delete command could not be sent to
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
* be returned if the command was successfully sent to the timer command queue.
* When the command is actually processed will depend on the priority of the
* timer service/daemon task relative to other tasks in the system. The timer
* service/daemon task priority is set by the configTIMER_TASK_PRIORITY
* configuration constant.
*
* Example usage:
*
* See the xTimerChangePeriod() API function example usage scenario.
*/
#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) )
/**
* portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime );
*
* Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task
* though a queue called the timer command queue. The timer command queue is
* private to the kernel itself and is not directly accessible to application
* code. The length of the timer command queue is set by the
* configTIMER_QUEUE_LENGTH configuration constant.
*
* xTimerReset() re-starts a timer that was previously created using the
* xTimerCreate() API function. If the timer had already been started and was
* already in the active state, then xTimerReset() will cause the timer to
* re-evaluate its expiry time so that it is relative to when xTimerReset() was
* called. If the timer was in the dormant state then xTimerReset() has
* equivalent functionality to the xTimerStart() API function.
*
* Resetting a timer ensures the timer is in the active state. If the timer
* is not stopped, deleted, or reset in the mean time, the callback function
* associated with the timer will get called 'n' ticks after xTimerReset() was
* called, where 'n' is the timers defined period.
*
* It is valid to call xTimerReset() before the scheduler has been started, but
* when this is done the timer will not actually start until the scheduler is
* started, and the timers expiry time will be relative to when the scheduler is
* started, not relative to when xTimerReset() was called.
*
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset()
* to be available.
*
* @param xTimer The handle of the timer being reset/started/restarted.
*
* @param xBlockTime Specifies the time, in ticks, that the calling task should
* be held in the Blocked state to wait for the reset command to be successfully
* sent to the timer command queue, should the queue already be full when
* xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called
* before the scheduler is started.
*
* @return pdFAIL will be returned if the reset command could not be sent to
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
* be returned if the command was successfully sent to the timer command queue.
* When the command is actually processed will depend on the priority of the
* timer service/daemon task relative to other tasks in the system, although the
* timers expiry time is relative to when xTimerStart() is actually called. The
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
* configuration constant.
*
* Example usage:
*
* // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass
* // without a key being pressed, then the LCD back-light is switched off. In
* // this case, the timer is a one-shot timer.
*
* xTimerHandle xBacklightTimer = NULL;
*
* // The callback function assigned to the one-shot timer. In this case the
* // parameter is not used.
* void vBacklightTimerCallback( xTIMER *pxTimer )
* {
* // The timer expired, therefore 5 seconds must have passed since a key
* // was pressed. Switch off the LCD back-light.
* vSetBacklightState( BACKLIGHT_OFF );
* }
*
* // The key press event handler.
* void vKeyPressEventHandler( char cKey )
* {
* // Ensure the LCD back-light is on, then reset the timer that is
* // responsible for turning the back-light off after 5 seconds of
* // key inactivity. Wait 10 ticks for the command to be successfully sent
* // if it cannot be sent immediately.
* vSetBacklightState( BACKLIGHT_ON );
* if( xTimerReset( xBacklightTimer, 100 ) != pdPASS )
* {
* // The reset command was not executed successfully. Take appropriate
* // action here.
* }
*
* // Perform the rest of the key processing here.
* }
*
* void main( void )
* {
* long x;
*
* // Create then start the one-shot timer that is responsible for turning
* // the back-light off if no keys are pressed within a 5 second period.
* xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.
* ( 5000 / portTICK_RATE_MS), // The timer period in ticks.
* pdFALSE, // The timer is a one-shot timer.
* 0, // The id is not used by the callback so can take any value.
* vBacklightTimerCallback // The callback function that switches the LCD back-light off.
* );
*
* if( xBacklightTimer == NULL )
* {
* // The timer was not created.
* }
* else
* {
* // Start the timer. No block time is specified, and even if one was
* // it would be ignored because the scheduler has not yet been
* // started.
* if( xTimerStart( xBacklightTimer, 0 ) != pdPASS )
* {
* // The timer could not be set into the Active state.
* }
* }
*
* // ...
* // Create tasks here.
* // ...
*
* // Starting the scheduler will start the timer running as it has already
* // been set into the active state.
* xTaskStartScheduler();
*
* // Should not reach here.
* for( ;; );
* }
*/
#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
/**
* portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer,
* portBASE_TYPE *pxHigherPriorityTaskWoken );
*
* A version of xTimerStart() that can be called from an interrupt service
* routine.
*
* @param xTimer The handle of the timer being started/restarted.
*
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
* of its time in the Blocked state, waiting for messages to arrive on the timer
* command queue. Calling xTimerStartFromISR() writes a message to the timer
* command queue, so has the potential to transition the timer service/daemon
* task out of the Blocked state. If calling xTimerStartFromISR() causes the
* timer service/daemon task to leave the Blocked state, and the timer service/
* daemon task has a priority equal to or greater than the currently executing
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
* get set to pdTRUE internally within the xTimerStartFromISR() function. If
* xTimerStartFromISR() sets this value to pdTRUE then a context switch should
* be performed before the interrupt exits.
*
* @return pdFAIL will be returned if the start command could not be sent to
* the timer command queue. pdPASS will be returned if the command was
* successfully sent to the timer command queue. When the command is actually
* processed will depend on the priority of the timer service/daemon task
* relative to other tasks in the system, although the timers expiry time is
* relative to when xTimerStartFromISR() is actually called. The timer service/daemon
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
*
* // This scenario assumes xBacklightTimer has already been created. When a
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
* // without a key being pressed, then the LCD back-light is switched off. In
* // this case, the timer is a one-shot timer, and unlike the example given for
* // the xTimerReset() function, the key press event handler is an interrupt
* // service routine.
*
* // The callback function assigned to the one-shot timer. In this case the
* // parameter is not used.
* void vBacklightTimerCallback( xTIMER *pxTimer )
* {
* // The timer expired, therefore 5 seconds must have passed since a key
* // was pressed. Switch off the LCD back-light.
* vSetBacklightState( BACKLIGHT_OFF );
* }
*
* // The key press interrupt service routine.
* void vKeyPressEventInterruptHandler( void )
* {
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
*
* // Ensure the LCD back-light is on, then restart the timer that is
* // responsible for turning the back-light off after 5 seconds of
* // key inactivity. This is an interrupt service routine so can only
* // call FreeRTOS API functions that end in "FromISR".
* vSetBacklightState( BACKLIGHT_ON );
*
* // xTimerStartFromISR() or xTimerResetFromISR() could be called here
* // as both cause the timer to re-calculate its expiry time.
* // xHigherPriorityTaskWoken was initialised to pdFALSE when it was
* // declared (in this function).
* if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
* {
* // The start command was not executed successfully. Take appropriate
* // action here.
* }
*
* // Perform the rest of the key processing here.
*
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
* // should be performed. The syntax required to perform a context switch
* // from inside an ISR varies from port to port, and from compiler to
* // compiler. Inspect the demos for the port you are using to find the
* // actual syntax required.
* if( xHigherPriorityTaskWoken != pdFALSE )
* {
* // Call the interrupt safe yield function here (actual function
* // depends on the FreeRTOS port being used.
* }
* }
*/
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
/**
* portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer,
* portBASE_TYPE *pxHigherPriorityTaskWoken );
*
* A version of xTimerStop() that can be called from an interrupt service
* routine.
*
* @param xTimer The handle of the timer being stopped.
*
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
* of its time in the Blocked state, waiting for messages to arrive on the timer
* command queue. Calling xTimerStopFromISR() writes a message to the timer
* command queue, so has the potential to transition the timer service/daemon
* task out of the Blocked state. If calling xTimerStopFromISR() causes the
* timer service/daemon task to leave the Blocked state, and the timer service/
* daemon task has a priority equal to or greater than the currently executing
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
* get set to pdTRUE internally within the xTimerStopFromISR() function. If
* xTimerStopFromISR() sets this value to pdTRUE then a context switch should
* be performed before the interrupt exits.
*
* @return pdFAIL will be returned if the stop command could not be sent to
* the timer command queue. pdPASS will be returned if the command was
* successfully sent to the timer command queue. When the command is actually
* processed will depend on the priority of the timer service/daemon task
* relative to other tasks in the system. The timer service/daemon task
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
*
* // This scenario assumes xTimer has already been created and started. When
* // an interrupt occurs, the timer should be simply stopped.
*
* // The interrupt service routine that stops the timer.
* void vAnExampleInterruptServiceRoutine( void )
* {
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
*
* // The interrupt has occurred - simply stop the timer.
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
* // (within this function). As this is an interrupt service routine, only
* // FreeRTOS API functions that end in "FromISR" can be used.
* if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
* {
* // The stop command was not executed successfully. Take appropriate
* // action here.
* }
*
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
* // should be performed. The syntax required to perform a context switch
* // from inside an ISR varies from port to port, and from compiler to
* // compiler. Inspect the demos for the port you are using to find the
* // actual syntax required.
* if( xHigherPriorityTaskWoken != pdFALSE )
* {
* // Call the interrupt safe yield function here (actual function
* // depends on the FreeRTOS port being used.
* }
* }
*/
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U )
/**
* portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer,
* portTickType xNewPeriod,
* portBASE_TYPE *pxHigherPriorityTaskWoken );
*
* A version of xTimerChangePeriod() that can be called from an interrupt
* service routine.
*
* @param xTimer The handle of the timer that is having its period changed.
*
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
* that has been specified in milliseconds. For example, if the timer must
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
* if the timer must expire after 500ms, then xNewPeriod can be set to
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
* or equal to 1000.
*
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
* of its time in the Blocked state, waiting for messages to arrive on the timer
* command queue. Calling xTimerChangePeriodFromISR() writes a message to the
* timer command queue, so has the potential to transition the timer service/
* daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR()
* causes the timer service/daemon task to leave the Blocked state, and the
* timer service/daemon task has a priority equal to or greater than the
* currently executing task (the task that was interrupted), then
* *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the
* xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets
* this value to pdTRUE then a context switch should be performed before the
* interrupt exits.
*
* @return pdFAIL will be returned if the command to change the timers period
* could not be sent to the timer command queue. pdPASS will be returned if the
* command was successfully sent to the timer command queue. When the command
* is actually processed will depend on the priority of the timer service/daemon
* task relative to other tasks in the system. The timer service/daemon task
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
*
* // This scenario assumes xTimer has already been created and started. When
* // an interrupt occurs, the period of xTimer should be changed to 500ms.
*
* // The interrupt service routine that changes the period of xTimer.
* void vAnExampleInterruptServiceRoutine( void )
* {
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
*
* // The interrupt has occurred - change the period of xTimer to 500ms.
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
* // (within this function). As this is an interrupt service routine, only
* // FreeRTOS API functions that end in "FromISR" can be used.
* if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
* {
* // The command to change the timers period was not executed
* // successfully. Take appropriate action here.
* }
*
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
* // should be performed. The syntax required to perform a context switch
* // from inside an ISR varies from port to port, and from compiler to
* // compiler. Inspect the demos for the port you are using to find the
* // actual syntax required.
* if( xHigherPriorityTaskWoken != pdFALSE )
* {
* // Call the interrupt safe yield function here (actual function
* // depends on the FreeRTOS port being used.
* }
* }
*/
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
/**
* portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer,
* portBASE_TYPE *pxHigherPriorityTaskWoken );
*
* A version of xTimerReset() that can be called from an interrupt service
* routine.
*
* @param xTimer The handle of the timer that is to be started, reset, or
* restarted.
*
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
* of its time in the Blocked state, waiting for messages to arrive on the timer
* command queue. Calling xTimerResetFromISR() writes a message to the timer
* command queue, so has the potential to transition the timer service/daemon
* task out of the Blocked state. If calling xTimerResetFromISR() causes the
* timer service/daemon task to leave the Blocked state, and the timer service/
* daemon task has a priority equal to or greater than the currently executing
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
* get set to pdTRUE internally within the xTimerResetFromISR() function. If
* xTimerResetFromISR() sets this value to pdTRUE then a context switch should
* be performed before the interrupt exits.
*
* @return pdFAIL will be returned if the reset command could not be sent to
* the timer command queue. pdPASS will be returned if the command was
* successfully sent to the timer command queue. When the command is actually
* processed will depend on the priority of the timer service/daemon task
* relative to other tasks in the system, although the timers expiry time is
* relative to when xTimerResetFromISR() is actually called. The timer service/daemon
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
*
* Example usage:
*
* // This scenario assumes xBacklightTimer has already been created. When a
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
* // without a key being pressed, then the LCD back-light is switched off. In
* // this case, the timer is a one-shot timer, and unlike the example given for
* // the xTimerReset() function, the key press event handler is an interrupt
* // service routine.
*
* // The callback function assigned to the one-shot timer. In this case the
* // parameter is not used.
* void vBacklightTimerCallback( xTIMER *pxTimer )
* {
* // The timer expired, therefore 5 seconds must have passed since a key
* // was pressed. Switch off the LCD back-light.
* vSetBacklightState( BACKLIGHT_OFF );
* }
*
* // The key press interrupt service routine.
* void vKeyPressEventInterruptHandler( void )
* {
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
*
* // Ensure the LCD back-light is on, then reset the timer that is
* // responsible for turning the back-light off after 5 seconds of
* // key inactivity. This is an interrupt service routine so can only
* // call FreeRTOS API functions that end in "FromISR".
* vSetBacklightState( BACKLIGHT_ON );
*
* // xTimerStartFromISR() or xTimerResetFromISR() could be called here
* // as both cause the timer to re-calculate its expiry time.
* // xHigherPriorityTaskWoken was initialised to pdFALSE when it was
* // declared (in this function).
* if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
* {
* // The reset command was not executed successfully. Take appropriate
* // action here.
* }
*
* // Perform the rest of the key processing here.
*
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
* // should be performed. The syntax required to perform a context switch
* // from inside an ISR varies from port to port, and from compiler to
* // compiler. Inspect the demos for the port you are using to find the
* // actual syntax required.
* if( xHigherPriorityTaskWoken != pdFALSE )
* {
* // Call the interrupt safe yield function here (actual function
* // depends on the FreeRTOS port being used.
* }
* }
*/
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
/*
* Functions beyond this part are not part of the public API and are intended
* for use by the kernel only.
*/
portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
#ifdef __cplusplus
}
#endif
#endif /* TIMERS_H */

78
flight/PiOS/STM32F10x/Libraries/FreeRTOS/Source/list.c Executable file → Normal file
View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -76,7 +82,7 @@ void vListInitialise( xList *pxList )
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );
pxList->uxNumberOfItems = 0;
pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;
}
/*-----------------------------------------------------------*/
@ -121,9 +127,9 @@ portTickType xValueOfInsertion;
/* If the list already contains a list item with the same item value then
the new list item should be placed after it. This ensures that TCB's which
are stored in ready lists (all of which have the same ulListItem value)
get an equal share of the CPU. However, if the xItemValue is the same as
get an equal share of the CPU. However, if the xItemValue is the same as
the back marker the iteration loop below will not end. This means we need
to guard against this by checking the value first and modifying the
to guard against this by checking the value first and modifying the
algorithm slightly if necessary. */
if( xValueOfInsertion == portMAX_DELAY )
{
@ -133,18 +139,18 @@ portTickType xValueOfInsertion;
{
/* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are:
1) Stack overflow -
1) Stack overflow -
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
2) Incorrect interrupt priority assignment, especially on Cortex M3
parts where numerically high priority values denote low actual
interrupt priories, which can seem counter intuitive. See
2) Incorrect interrupt priority assignment, especially on Cortex-M3
parts where numerically high priority values denote low actual
interrupt priories, which can seem counter intuitive. See
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when
the scheduler is suspended.
4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?).
See http://www.freertos.org/FAQHelp.html for more tips.
See http://www.freertos.org/FAQHelp.html for more tips.
**********************************************************************/
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )

View File

@ -1,41 +1,41 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

View File

@ -1,41 +1,41 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -140,7 +140,7 @@ extern void vPortExitCritical( void );
void PIOS_RTC_Init();
uint32_t PIOS_RTC_Counter();
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
#define portENTER_CRITICAL() vPortEnterCritical()

View File

@ -1,41 +1,41 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

View File

@ -1,41 +1,41 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

View File

@ -1,41 +1,41 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

202
flight/PiOS/STM32F10x/Libraries/FreeRTOS/Source/queue.c Executable file → Normal file
View File

@ -1,41 +1,47 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
@ -144,6 +150,7 @@ signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const
signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
/*
* Co-routine queue functions differ from task queue functions. Co-routines are
@ -222,21 +229,19 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
* Macro to mark a queue as locked. Locking a queue prevents an ISR from
* accessing the queue event lists.
*/
#define prvLockQueue( pxQueue ) \
{ \
taskENTER_CRITICAL(); \
{ \
if( pxQueue->xRxLock == queueUNLOCKED ) \
{ \
pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \
} \
if( pxQueue->xTxLock == queueUNLOCKED ) \
{ \
pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \
} \
} \
taskEXIT_CRITICAL(); \
}
#define prvLockQueue( pxQueue ) \
taskENTER_CRITICAL(); \
{ \
if( ( pxQueue )->xRxLock == queueUNLOCKED ) \
{ \
( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \
} \
if( ( pxQueue )->xTxLock == queueUNLOCKED ) \
{ \
( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \
} \
} \
taskEXIT_CRITICAL()
/*-----------------------------------------------------------*/
@ -248,6 +253,7 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
{
xQUEUE *pxNewQueue;
size_t xQueueSizeInBytes;
xQueueHandle xReturn = NULL;
/* Allocate the new queue structure. */
if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
@ -265,9 +271,9 @@ size_t xQueueSizeInBytes;
/* Initialise the queue members as described above where the
queue type is defined. */
pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
pxNewQueue->uxMessagesWaiting = 0;
pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );
pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - ( unsigned portBASE_TYPE ) 1U ) * uxItemSize );
pxNewQueue->uxLength = uxQueueLength;
pxNewQueue->uxItemSize = uxItemSize;
pxNewQueue->xRxLock = queueUNLOCKED;
@ -278,7 +284,7 @@ size_t xQueueSizeInBytes;
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
traceQUEUE_CREATE( pxNewQueue );
return pxNewQueue;
xReturn = pxNewQueue;
}
else
{
@ -288,9 +294,9 @@ size_t xQueueSizeInBytes;
}
}
/* Will only reach here if we could not allocate enough memory or no memory
was required. */
return NULL;
configASSERT( xReturn );
return xReturn;
}
/*-----------------------------------------------------------*/
@ -316,9 +322,9 @@ size_t xQueueSizeInBytes;
/* Each mutex has a length of 1 (like a binary semaphore) and
an item size of 0 as nothing is actually copied into or out
of the mutex. */
pxNewQueue->uxMessagesWaiting = 0;
pxNewQueue->uxLength = 1;
pxNewQueue->uxItemSize = 0;
pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U;
pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U;
pxNewQueue->xRxLock = queueUNLOCKED;
pxNewQueue->xTxLock = queueUNLOCKED;
@ -327,7 +333,7 @@ size_t xQueueSizeInBytes;
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
/* Start with the semaphore in the expected state. */
xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK );
xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK );
traceCREATE_MUTEX( pxNewQueue );
}
@ -336,6 +342,7 @@ size_t xQueueSizeInBytes;
traceCREATE_MUTEX_FAILED();
}
configASSERT( pxNewQueue );
return pxNewQueue;
}
@ -348,6 +355,8 @@ size_t xQueueSizeInBytes;
{
portBASE_TYPE xReturn;
configASSERT( pxMutex );
/* If this is the task that holds the mutex then pxMutexHolder will not
change outside of this task. If this task does not hold the mutex then
pxMutexHolder can never coincidentally equal the tasks handle, and as
@ -395,6 +404,8 @@ size_t xQueueSizeInBytes;
{
portBASE_TYPE xReturn;
configASSERT( pxMutex );
/* Comments regarding mutual exclusion as per those within
xQueueGiveMutexRecursive(). */
@ -446,6 +457,7 @@ size_t xQueueSizeInBytes;
traceCREATE_COUNTING_SEMAPHORE_FAILED();
}
configASSERT( pxHandle );
return pxHandle;
}
@ -457,6 +469,9 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut;
configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest
of execution time efficiency. */
@ -575,6 +590,9 @@ xTimeOutType xTimeOut;
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut;
configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
for( ;; )
{
taskENTER_CRITICAL();
@ -650,6 +668,9 @@ xTimeOutType xTimeOut;
xTimeOutType xTimeOut;
signed char *pcOriginalReadPosition;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
for( ;; )
{
taskENTER_CRITICAL();
@ -697,7 +718,7 @@ xTimeOutType xTimeOut;
/* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
@ -773,6 +794,10 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void
signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus;
configASSERT( pxQueue );
configASSERT( pxHigherPriorityTaskWoken );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* Similar to xQueueGenericSend, except we don't block if there is no room
in the queue. Also we don't directly wake a task that was blocked on a
queue read, instead we return a flag to say whether a context switch is
@ -790,7 +815,7 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
be done when the queue is unlocked later. */
if( pxQueue->xTxLock == queueUNLOCKED )
{
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
@ -827,6 +852,9 @@ signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut;
signed char *pcOriginalReadPosition;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest
of execution time efficiency. */
@ -880,7 +908,7 @@ signed char *pcOriginalReadPosition;
/* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
@ -973,6 +1001,10 @@ signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pv
signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus;
configASSERT( pxQueue );
configASSERT( pxTaskWoken );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* We cannot block from an ISR, so check there is data available. */
@ -988,7 +1020,7 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
that an ISR has removed data while the queue was locked. */
if( pxQueue->xRxLock == queueUNLOCKED )
{
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
@ -1023,6 +1055,8 @@ unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )
{
unsigned portBASE_TYPE uxReturn;
configASSERT( pxQueue );
taskENTER_CRITICAL();
uxReturn = pxQueue->uxMessagesWaiting;
taskEXIT_CRITICAL();
@ -1035,6 +1069,8 @@ unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue
{
unsigned portBASE_TYPE uxReturn;
configASSERT( pxQueue );
uxReturn = pxQueue->uxMessagesWaiting;
return uxReturn;
@ -1043,6 +1079,8 @@ unsigned portBASE_TYPE uxReturn;
void vQueueDelete( xQueueHandle pxQueue )
{
configASSERT( pxQueue );
traceQUEUE_DELETE( pxQueue );
vQueueUnregisterQueue( pxQueue );
vPortFree( pxQueue->pcHead );
@ -1117,7 +1155,7 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
{
/* Data was posted while the queue was locked. Are any tasks
blocked waiting for data to become available? */
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
@ -1145,7 +1183,7 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
{
while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
{
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
@ -1182,6 +1220,7 @@ signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )
{
signed portBASE_TYPE xReturn;
configASSERT( pxQueue );
xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
return xReturn;
@ -1204,6 +1243,7 @@ signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )
{
signed portBASE_TYPE xReturn;
configASSERT( pxQueue );
xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
return xReturn;
@ -1252,7 +1292,7 @@ signed portBASE_TYPE xReturn;
xReturn = pdPASS;
/* Were any co-routines waiting for data to become available? */
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
/* In this instance the co-routine could be placed directly
into the ready list as we are within a critical section.
@ -1327,7 +1367,7 @@ signed portBASE_TYPE xReturn;
xReturn = pdPASS;
/* Were any co-routines waiting for space to become available? */
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
/* In this instance the co-routine could be placed directly
into the ready list as we are within a critical section.
@ -1366,7 +1406,7 @@ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvIt
co-routine has not already been woken. */
if( !xCoRoutinePreviouslyWoken )
{
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
@ -1401,7 +1441,7 @@ signed portBASE_TYPE xReturn;
if( !( *pxCoRoutineWoken ) )
{
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
@ -1430,7 +1470,7 @@ signed portBASE_TYPE xReturn;
/* See if there is an empty space in the registry. A NULL name denotes
a free slot. */
for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
for( ux = ( unsigned portBASE_TYPE ) 0U; ux < configQUEUE_REGISTRY_SIZE; ux++ )
{
if( xQueueRegistry[ ux ].pcQueueName == NULL )
{
@ -1443,7 +1483,7 @@ signed portBASE_TYPE xReturn;
}
#endif
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#if configQUEUE_REGISTRY_SIZE > 0
@ -1453,7 +1493,7 @@ signed portBASE_TYPE xReturn;
/* See if the handle of the queue being unregistered in actually in the
registry. */
for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
for( ux = ( unsigned portBASE_TYPE ) 0U; ux < configQUEUE_REGISTRY_SIZE; ux++ )
{
if( xQueueRegistry[ ux ].xHandle == xQueue )
{
@ -1466,4 +1506,34 @@ signed portBASE_TYPE xReturn;
}
#endif
/*-----------------------------------------------------------*/
#if configUSE_TIMERS == 1
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait )
{
/* This function should not be called by application code hence the
'Restricted' in its name. It is not part of the public API. It is
designed for use by kernel code, and has special calling requirements.
It can result in vListInsert() being called on a list that can only
possibly ever have one item in it, so the list will be fast, but even
so it should be called with the scheduler locked and not from a critical
section. */
/* Only do anything if there are no messages in the queue. This function
will not actually cause the task to block, just place it on a blocked
list. It will not block until the scheduler is unlocked - at which
time a yield will be performed. If an item is added to the queue while
the queue is locked, and the calling task blocks on the queue, then the
calling task will be immediately unblocked when the queue is unlocked. */
prvLockQueue( pxQueue );
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U )
{
/* There is nothing in the queue, block for the specified period. */
vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
}
prvUnlockQueue( pxQueue );
}
#endif

586
flight/PiOS/STM32F10x/Libraries/FreeRTOS/Source/tasks.c Executable file → Normal file
View File

@ -1,38 +1,44 @@
/*
FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS books - available as PDF or paperback *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
@ -63,6 +69,7 @@ task.h is included from an application file. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "StackMacros.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
@ -161,6 +168,7 @@ PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsi
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;
PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;
#if ( configGENERATE_RUN_TIME_STATS == 1 )
@ -176,7 +184,7 @@ PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned po
* The value used to fill the stack of a task when the task is created. This
* is used purely for checking the high water mark for tasks.
*/
#define tskSTACK_FILL_BYTE ( 0xa5 )
#define tskSTACK_FILL_BYTE ( 0xa5U )
/*
* Macros used by vListTask to indicate which state a task is in.
@ -196,7 +204,7 @@ PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned po
PRIVILEGED_DATA static signed char *pcTraceBufferStart;
PRIVILEGED_DATA static signed char *pcTraceBufferEnd;
PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE;
static unsigned portBASE_TYPE uxPreviousTask = 255;
static unsigned portBASE_TYPE uxPreviousTask = 255U;
PRIVILEGED_DATA static char pcStatusString[ 50 ];
#endif
@ -220,10 +228,10 @@ PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned po
if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \
{ \
uxPreviousTask = pxCurrentTCB->uxTCBNumber; \
*( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \
pcTraceBuffer += sizeof( unsigned long ); \
*( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \
pcTraceBuffer += sizeof( unsigned long ); \
*( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \
pcTraceBuffer += sizeof( unsigned long ); \
*( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \
pcTraceBuffer += sizeof( unsigned long ); \
} \
else \
{ \
@ -247,14 +255,12 @@ PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned po
* executing task, then it will only be rescheduled after the currently
* executing task has been rescheduled.
*/
#define prvAddTaskToReadyQueue( pxTCB ) \
{ \
if( pxTCB->uxPriority > uxTopReadyPriority ) \
{ \
uxTopReadyPriority = pxTCB->uxPriority; \
} \
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \
}
#define prvAddTaskToReadyQueue( pxTCB ) \
if( ( pxTCB )->uxPriority > uxTopReadyPriority ) \
{ \
uxTopReadyPriority = ( pxTCB )->uxPriority; \
} \
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
/*-----------------------------------------------------------*/
/*
@ -265,24 +271,56 @@ PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned po
* once one tasks has been found whose timer has not expired we need not look
* any further down the list.
*/
#define prvCheckDelayedTasks() \
{ \
register tskTCB *pxTCB; \
\
while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \
{ \
if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \
{ \
break; \
} \
vListRemove( &( pxTCB->xGenericListItem ) ); \
/* Is the task waiting on an event also? */ \
if( pxTCB->xEventListItem.pvContainer ) \
{ \
vListRemove( &( pxTCB->xEventListItem ) ); \
} \
prvAddTaskToReadyQueue( pxTCB ); \
} \
#define prvCheckDelayedTasks() \
{ \
portTickType xItemValue; \
\
/* Is the tick count greater than or equal to the wake time of the first \
task referenced from the delayed tasks list? */ \
if( xTickCount >= xNextTaskUnblockTime ) \
{ \
for( ;; ) \
{ \
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \
{ \
/* The delayed list is empty. Set xNextTaskUnblockTime to the \
maximum possible value so it is extremely unlikely that the \
if( xTickCount >= xNextTaskUnblockTime ) test will pass next \
time through. */ \
xNextTaskUnblockTime = portMAX_DELAY; \
break; \
} \
else \
{ \
/* The delayed list is not empty, get the value of the item at \
the head of the delayed list. This is the time at which the \
task at the head of the delayed list should be removed from \
the Blocked state. */ \
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \
\
if( xTickCount < xItemValue ) \
{ \
/* It is not time to unblock this item yet, but the item \
value is the time at which the task at the head of the \
blocked list should be removed from the Blocked state - \
so record the item value in xNextTaskUnblockTime. */ \
xNextTaskUnblockTime = xItemValue; \
break; \
} \
\
/* It is time to remove the item from the Blocked state. */ \
vListRemove( &( pxTCB->xGenericListItem ) ); \
\
/* Is the task waiting on an event also? */ \
if( pxTCB->xEventListItem.pvContainer ) \
{ \
vListRemove( &( pxTCB->xEventListItem ) ); \
} \
prvAddTaskToReadyQueue( pxTCB ); \
} \
} \
} \
}
/*-----------------------------------------------------------*/
@ -292,9 +330,12 @@ register tskTCB *pxTCB; \
* task should be used in place of the parameter. This macro simply checks to
* see if the parameter is NULL and returns a pointer to the appropriate TCB.
*/
#define prvGetTCBFromHandle( pxHandle ) ( ( pxHandle == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) pxHandle )
#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) )
/* Callback function prototypes. --------------------------*/
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );
extern void vApplicationTickHook( void );
/* File private functions. --------------------------------*/
/*
@ -342,6 +383,12 @@ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
*/
static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
/*
* The currently executing task is entering the Blocked state. Add the task to
* either the current or the overflow delayed task list.
*/
static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGED_FUNCTION;
/*
* Allocates memory from the heap for a TCB and associated stack. Checks the
* allocation was successful.
@ -388,6 +435,9 @@ signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed ch
signed portBASE_TYPE xReturn;
tskTCB * pxNewTCB;
configASSERT( pxTaskCode );
configASSERT( ( uxPriority < configMAX_PRIORITIES ) );
/* Allocate the memory required by the TCB and stack for the new task,
checking that the allocation was successful. */
pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
@ -416,12 +466,18 @@ tskTCB * pxNewTCB;
required by the port. */
#if( portSTACK_GROWTH < 0 )
{
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 );
pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) );
/* Check the alignment of the calculated top of stack is correct. */
configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
}
#else
{
pxTopOfStack = pxNewTCB->pxStack;
/* Check the alignment of the stack buffer is correct. */
configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
/* If we want to use stack checking on architectures that use
a positive stack growth direction then we also need to store the
@ -447,6 +503,9 @@ tskTCB * pxNewTCB;
}
#endif
/* Check the alignment of the initialised stack. */
configASSERT( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
if( ( void * ) pxCreatedTask != NULL )
{
/* Pass the TCB out - in an anonymous way. The calling function/
@ -457,7 +516,7 @@ tskTCB * pxNewTCB;
/* We are going to manipulate the task queues to add this task to a
ready list, so must make sure no interrupts occur. */
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
uxCurrentNumberOfTasks++;
if( pxCurrentTCB == NULL )
@ -508,7 +567,7 @@ tskTCB * pxNewTCB;
xReturn = pdPASS;
traceTASK_CREATE( pxNewTCB );
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
}
else
{
@ -539,7 +598,7 @@ tskTCB * pxNewTCB;
{
tskTCB *pxTCB;
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
/* Ensure a yield is performed if the current task is being
deleted. */
@ -576,7 +635,7 @@ tskTCB * pxNewTCB;
traceTASK_DELETE( pxTCB );
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
/* Force a reschedule if we have just deleted the current task. */
if( xSchedulerRunning != pdFALSE )
@ -606,6 +665,9 @@ tskTCB * pxNewTCB;
portTickType xTimeToWake;
portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;
configASSERT( pxPreviousWakeTime );
configASSERT( ( xTimeIncrement > 0 ) );
vTaskSuspendAll();
{
/* Generate the tick time at which the task wants to wake. */
@ -637,7 +699,7 @@ tskTCB * pxNewTCB;
/* Update the wake time ready for the next call. */
*pxPreviousWakeTime = xTimeToWake;
if( xShouldDelay )
if( xShouldDelay != pdFALSE )
{
traceTASK_DELAY_UNTIL();
@ -645,22 +707,7 @@ tskTCB * pxNewTCB;
ourselves to the blocked list as the same list item is used for
both lists. */
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
/* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xTickCount )
{
/* Wake time has overflowed. Place this item in the
overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the
current block list. */
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
prvAddCurrentTaskToDelayedList( xTimeToWake );
}
}
xAlreadyYielded = xTaskResumeAll();
@ -706,22 +753,7 @@ tskTCB * pxNewTCB;
ourselves to the blocked list as the same list item is used for
both lists. */
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
/* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xTickCount )
{
/* Wake time has overflowed. Place this item in the
overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the
current block list. */
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
prvAddCurrentTaskToDelayedList( xTimeToWake );
}
xAlreadyYielded = xTaskResumeAll();
}
@ -744,14 +776,14 @@ tskTCB * pxNewTCB;
tskTCB *pxTCB;
unsigned portBASE_TYPE uxReturn;
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
/* If null is passed in here then we are changing the
priority of the calling function. */
pxTCB = prvGetTCBFromHandle( pxTask );
uxReturn = pxTCB->uxPriority;
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
return uxReturn;
}
@ -764,15 +796,18 @@ tskTCB * pxNewTCB;
void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )
{
tskTCB *pxTCB;
unsigned portBASE_TYPE uxCurrentPriority, xYieldRequired = pdFALSE;
unsigned portBASE_TYPE uxCurrentPriority;
portBASE_TYPE xYieldRequired = pdFALSE;
configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
/* Ensure the new priority is valid. */
if( uxNewPriority >= configMAX_PRIORITIES )
{
uxNewPriority = configMAX_PRIORITIES - 1;
uxNewPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;
}
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
if( pxTask == pxCurrentTCB )
{
@ -858,7 +893,7 @@ tskTCB * pxNewTCB;
}
}
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
}
#endif
@ -870,7 +905,7 @@ tskTCB * pxNewTCB;
{
tskTCB *pxTCB;
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
/* Ensure a yield is performed if the current task is being
suspended. */
@ -895,7 +930,7 @@ tskTCB * pxNewTCB;
vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
if( ( void * ) pxTaskToSuspend == NULL )
{
@ -909,9 +944,9 @@ tskTCB * pxNewTCB;
/* The scheduler is not running, but the task that was pointed
to by pxCurrentTCB has just been suspended and pxCurrentTCB
must be adjusted to point to a different task. */
if( uxCurrentNumberOfTasks == 1 )
if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
{
/* No other tasks are defined, so set pxCurrentTCB back to
/* No other tasks are ready, so set pxCurrentTCB back to
NULL so when the next task is created pxCurrentTCB will
be set to point to it no matter what its relative priority
is. */
@ -935,6 +970,9 @@ tskTCB * pxNewTCB;
portBASE_TYPE xReturn = pdFALSE;
const tskTCB * const pxTCB = ( tskTCB * ) xTask;
/* It does not make sense to check if the calling task is suspended. */
configASSERT( xTask );
/* Is the task we are attempting to resume actually in the
suspended list? */
if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
@ -965,6 +1003,9 @@ tskTCB * pxNewTCB;
{
tskTCB *pxTCB;
/* It does not make sense to resume the calling task. */
configASSERT( pxTaskToResume );
/* Remove the task from whichever list it is currently in, and place
it in the ready list. */
pxTCB = ( tskTCB * ) pxTaskToResume;
@ -973,7 +1014,7 @@ tskTCB * pxNewTCB;
currently executing task. */
if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
{
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
{
@ -993,7 +1034,7 @@ tskTCB * pxNewTCB;
}
}
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
}
}
@ -1008,6 +1049,8 @@ tskTCB * pxNewTCB;
portBASE_TYPE xYieldRequired = pdFALSE;
tskTCB *pxTCB;
configASSERT( pxTaskToResume );
pxTCB = ( tskTCB * ) pxTaskToResume;
if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
@ -1049,6 +1092,15 @@ portBASE_TYPE xReturn;
/* Add the idle task at the lowest priority. */
xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL );
#if ( configUSE_TIMERS == 1 )
{
if( xReturn == pdPASS )
{
xReturn = xTimerCreateTimerTask();
}
}
#endif
if( xReturn == pdPASS )
{
/* Interrupts are turned off here, to ensure a tick does not occur
@ -1081,6 +1133,9 @@ portBASE_TYPE xReturn;
/* Should only reach here if a task calls xTaskEndScheduler(). */
}
}
/* This line will only be reached if the kernel could not be started. */
configASSERT( xReturn );
}
/*-----------------------------------------------------------*/
@ -1108,12 +1163,16 @@ signed portBASE_TYPE xTaskResumeAll( void )
register tskTCB *pxTCB;
signed portBASE_TYPE xAlreadyYielded = pdFALSE;
/* If uxSchedulerSuspended is zero then this function does not match a
previous call to vTaskSuspendAll(). */
configASSERT( uxSchedulerSuspended );
/* It is possible that an ISR caused a task to be removed from an event
list while the scheduler was suspended. If this was the case then the
removed task will have been added to the xPendingReadyList. Once the
scheduler has been resumed it is safe to move all the pending ready
tasks from this list into their appropriate ready list. */
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
--uxSchedulerSuspended;
@ -1125,8 +1184,9 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
/* Move any readied tasks from the pending list into the
appropriate ready list. */
while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL )
while( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE )
{
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) );
vListRemove( &( pxTCB->xEventListItem ) );
vListRemove( &( pxTCB->xGenericListItem ) );
prvAddTaskToReadyQueue( pxTCB );
@ -1169,7 +1229,7 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
}
}
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
return xAlreadyYielded;
}
@ -1190,11 +1250,11 @@ portTickType xTaskGetTickCount( void )
portTickType xTicks;
/* Critical section required if running on a 16 bit processor. */
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
xTicks = xTickCount;
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
return xTicks;
}
@ -1202,7 +1262,14 @@ portTickType xTicks;
portTickType xTaskGetTickCountFromISR( void )
{
return xTickCount;
portTickType xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus;
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
xReturn = xTickCount;
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
return xReturn;
}
/*-----------------------------------------------------------*/
@ -1228,34 +1295,34 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
/* Run through all the lists that could potentially contain a TCB and
report the task name, state and stack high water mark. */
pcWriteBuffer[ 0 ] = ( signed char ) 0x00;
*pcWriteBuffer = ( signed char ) 0x00;
strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );
uxQueue = uxTopUsedPriority + 1;
uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;
do
{
uxQueue--;
if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE )
{
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );
}
}while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE )
{
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR );
}
if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )
{
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );
}
#if( INCLUDE_vTaskDelete == 1 )
{
if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE )
{
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR );
}
@ -1264,7 +1331,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
#if ( INCLUDE_vTaskSuspend == 1 )
{
if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )
{
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR );
}
@ -1303,34 +1370,34 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
generating a table of run timer percentages in the provided
buffer. */
pcWriteBuffer[ 0 ] = ( signed char ) 0x00;
*pcWriteBuffer = ( signed char ) 0x00;
strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );
uxQueue = uxTopUsedPriority + 1;
uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;
do
{
uxQueue--;
if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime );
}
}while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime );
}
if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime );
}
#if ( INCLUDE_vTaskDelete == 1 )
{
if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, ulTotalRunTime );
}
@ -1339,7 +1406,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
#if ( INCLUDE_vTaskSuspend == 1 )
{
if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, ulTotalRunTime );
}
@ -1356,14 +1423,17 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize )
{
portENTER_CRITICAL();
configASSERT( pcBuffer );
configASSERT( ulBufferSize );
taskENTER_CRITICAL();
{
pcTraceBuffer = ( signed char * )pcBuffer;
pcTraceBufferStart = pcBuffer;
pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE );
xTracing = pdTRUE;
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
}
#endif
@ -1375,9 +1445,9 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
{
unsigned long ulBufferLength;
portENTER_CRITICAL();
taskENTER_CRITICAL();
xTracing = pdFALSE;
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart );
@ -1396,6 +1466,8 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
void vTaskIncrementTick( void )
{
tskTCB * pxTCB;
/* Called by the portable layer each time a tick interrupt occurs.
Increments the tick then checks to see if the new tick value will cause any
tasks to be unblocked. */
@ -1409,10 +1481,31 @@ void vTaskIncrementTick( void )
/* Tick count has overflowed so we need to swap the delay lists.
If there are any items in pxDelayedTaskList here then there is
an error! */
configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) );
pxTemp = pxDelayedTaskList;
pxDelayedTaskList = pxOverflowDelayedTaskList;
pxOverflowDelayedTaskList = pxTemp;
xNumOfOverflows++;
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
{
/* The new current delayed list is empty. Set
xNextTaskUnblockTime to the maximum possible value so it is
extremely unlikely that the
if( xTickCount >= xNextTaskUnblockTime ) test will pass until
there is an item in the delayed list. */
xNextTaskUnblockTime = portMAX_DELAY;
}
else
{
/* The new current delayed list is not empty, get the value of
the item at the head of the delayed list. This is the time at
which the task at the head of the delayed list should be removed
from the Blocked state. */
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
}
}
/* See if this tick has made a timeout expire. */
@ -1426,8 +1519,6 @@ void vTaskIncrementTick( void )
scheduler is locked. */
#if ( configUSE_TICK_HOOK == 1 )
{
extern void vApplicationTickHook( void );
vApplicationTickHook();
}
#endif
@ -1435,11 +1526,9 @@ void vTaskIncrementTick( void )
#if ( configUSE_TICK_HOOK == 1 )
{
extern void vApplicationTickHook( void );
/* Guard against the tick hook being called when the missed tick
count is being unwound (when the scheduler is being unlocked. */
if( uxMissedTicks == 0 )
if( uxMissedTicks == ( unsigned portBASE_TYPE ) 0U )
{
vApplicationTickHook();
}
@ -1464,7 +1553,7 @@ void vTaskIncrementTick( void )
{
usQueue--;
while( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ usQueue ] ) ) )
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ usQueue ] ) ) == pdFALSE )
{
listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &( pxReadyTasksLists[ usQueue ] ) );
vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
@ -1474,7 +1563,7 @@ void vTaskIncrementTick( void )
}while( usQueue > ( unsigned short ) tskIDLE_PRIORITY );
/* Remove any TCB's from the delayed queue. */
while( !listLIST_IS_EMPTY( &xDelayedTaskList1 ) )
while( listLIST_IS_EMPTY( &xDelayedTaskList1 ) == pdFALSE )
{
listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList1 );
vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
@ -1483,7 +1572,7 @@ void vTaskIncrementTick( void )
}
/* Remove any TCB's from the overflow delayed queue. */
while( !listLIST_IS_EMPTY( &xDelayedTaskList2 ) )
while( listLIST_IS_EMPTY( &xDelayedTaskList2 ) == pdFALSE )
{
listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 );
vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
@ -1491,7 +1580,7 @@ void vTaskIncrementTick( void )
prvDeleteTCB( ( tskTCB * ) pxTCB );
}
while( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
while( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )
{
listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xSuspendedTaskList );
vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
@ -1505,7 +1594,7 @@ void vTaskIncrementTick( void )
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue )
void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction )
{
tskTCB *xTCB;
@ -1521,9 +1610,9 @@ void vTaskIncrementTick( void )
/* Save the hook function in the TCB. A critical section is required as
the value can be accessed from an interrupt. */
portENTER_CRITICAL();
xTCB->pxTaskTag = pxTagValue;
portEXIT_CRITICAL();
taskENTER_CRITICAL();
xTCB->pxTaskTag = pxHookFunction;
taskEXIT_CRITICAL();
}
#endif
@ -1548,9 +1637,9 @@ void vTaskIncrementTick( void )
/* Save the hook function in the TCB. A critical section is required as
the value can be accessed from an interrupt. */
portENTER_CRITICAL();
taskENTER_CRITICAL();
xReturn = xTCB->pxTaskTag;
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
return xReturn;
}
@ -1597,46 +1686,48 @@ void vTaskSwitchContext( void )
/* The scheduler is currently suspended - do not allow a context
switch. */
xMissedYield = pdTRUE;
return;
}
traceTASK_SWITCHED_OUT();
#if ( configGENERATE_RUN_TIME_STATS == 1 )
else
{
unsigned long ulTempCounter;
#ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
portALT_GET_RUN_TIME_COUNTER_VALUE( ulTempCounter );
#else
ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();
#endif
/* Add the amount of time the task has been running to the accumulated
time so far. The time the task started running was stored in
ulTaskSwitchedInTime. Note that there is no overflow protection here
so count values are only valid until the timer overflows. Generally
this will be about 1 hour assuming a 1uS timer increment. */
pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime );
ulTaskSwitchedInTime = ulTempCounter;
traceTASK_SWITCHED_OUT();
#if ( configGENERATE_RUN_TIME_STATS == 1 )
{
unsigned long ulTempCounter;
#ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
portALT_GET_RUN_TIME_COUNTER_VALUE( ulTempCounter );
#else
ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();
#endif
/* Add the amount of time the task has been running to the accumulated
time so far. The time the task started running was stored in
ulTaskSwitchedInTime. Note that there is no overflow protection here
so count values are only valid until the timer overflows. Generally
this will be about 1 hour assuming a 1uS timer increment. */
pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime );
ulTaskSwitchedInTime = ulTempCounter;
}
#endif
taskFIRST_CHECK_FOR_STACK_OVERFLOW();
taskSECOND_CHECK_FOR_STACK_OVERFLOW();
/* Find the highest priority queue that contains ready tasks. */
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
{
configASSERT( uxTopReadyPriority );
--uxTopReadyPriority;
}
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the
same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );
traceTASK_SWITCHED_IN();
vWriteTraceToBuffer();
}
#endif
taskFIRST_CHECK_FOR_STACK_OVERFLOW();
taskSECOND_CHECK_FOR_STACK_OVERFLOW();
/* Find the highest priority queue that contains ready tasks. */
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
{
--uxTopReadyPriority;
}
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the
same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );
traceTASK_SWITCHED_IN();
vWriteTraceToBuffer();
}
/*-----------------------------------------------------------*/
@ -1644,6 +1735,8 @@ void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicks
{
portTickType xTimeToWake;
configASSERT( pxEventList );
/* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
SCHEDULER SUSPENDED. */
@ -1672,19 +1765,7 @@ portTickType xTimeToWake;
/* Calculate the time at which the task should be woken if the event does
not occur. This may overflow but this doesn't matter. */
xTimeToWake = xTickCount + xTicksToWait;
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xTickCount )
{
/* Wake time has overflowed. Place this item in the overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the current block list. */
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
prvAddCurrentTaskToDelayedList( xTimeToWake );
}
}
#else
@ -1692,24 +1773,46 @@ portTickType xTimeToWake;
/* Calculate the time at which the task should be woken if the event does
not occur. This may overflow but this doesn't matter. */
xTimeToWake = xTickCount + xTicksToWait;
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xTickCount )
{
/* Wake time has overflowed. Place this item in the overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the current block list. */
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
prvAddCurrentTaskToDelayedList( xTimeToWake );
}
#endif
}
/*-----------------------------------------------------------*/
#if configUSE_TIMERS == 1
void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait )
{
portTickType xTimeToWake;
configASSERT( pxEventList );
/* This function should not be called by application code hence the
'Restricted' in its name. It is not part of the public API. It is
designed for use by kernel code, and has special calling requirements -
it should be called from a critical section. */
/* Place the event list item of the TCB in the appropriate event list.
In this case it is assume that this is the only task that is going to
be waiting on this event list, so the faster vListInsertEnd() function
can be used in place of vListInsert. */
vListInsertEnd( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );
/* We must remove this task from the ready list before adding it to the
blocked list as the same list item is used for both lists. This
function is called form a critical section. */
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
/* Calculate the time at which the task should be woken if the event does
not occur. This may overflow but this doesn't matter. */
xTimeToWake = xTickCount + xTicksToWait;
prvAddCurrentTaskToDelayedList( xTimeToWake );
}
#endif /* configUSE_TIMERS */
/*-----------------------------------------------------------*/
signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )
{
tskTCB *pxUnblockedTCB;
@ -1724,8 +1827,12 @@ portBASE_TYPE xReturn;
If an event is for a queue that is locked then this function will never
get called - the lock count on the queue will get modified instead. This
means we can always expect exclusive access to the event list here. */
means we can always expect exclusive access to the event list here.
This function assumes that a check has already been made to ensure that
pxEventList is not empty. */
pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
configASSERT( pxUnblockedTCB );
vListRemove( &( pxUnblockedTCB->xEventListItem ) );
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
@ -1759,6 +1866,7 @@ portBASE_TYPE xReturn;
void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )
{
configASSERT( pxTimeOut );
pxTimeOut->xOverflowCount = xNumOfOverflows;
pxTimeOut->xTimeOnEntering = xTickCount;
}
@ -1768,7 +1876,10 @@ portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType
{
portBASE_TYPE xReturn;
portENTER_CRITICAL();
configASSERT( pxTimeOut );
configASSERT( pxTicksToWait );
taskENTER_CRITICAL();
{
#if ( INCLUDE_vTaskSuspend == 1 )
/* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
@ -1801,7 +1912,7 @@ portBASE_TYPE xReturn;
xReturn = pdTRUE;
}
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
return xReturn;
}
@ -1897,13 +2008,13 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );
}
#endif
pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = '\0';
pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = ( signed char ) '\0';
/* This is used as an array index so must ensure it's not too large. First
remove the privilege bit if one is present. */
if( uxPriority >= configMAX_PRIORITIES )
{
uxPriority = configMAX_PRIORITIES - 1;
uxPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;
}
pxTCB->uxPriority = uxPriority;
@ -1978,7 +2089,7 @@ static void prvInitialiseTaskLists( void )
{
unsigned portBASE_TYPE uxPriority;
for( uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++ )
for( uxPriority = ( unsigned portBASE_TYPE ) 0U; uxPriority < configMAX_PRIORITIES; uxPriority++ )
{
vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) );
}
@ -2020,18 +2131,18 @@ static void prvCheckTasksWaitingTermination( void )
xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
xTaskResumeAll();
if( !xListIsEmpty )
if( xListIsEmpty == pdFALSE )
{
tskTCB *pxTCB;
portENTER_CRITICAL();
taskENTER_CRITICAL();
{
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) );
vListRemove( &( pxTCB->xGenericListItem ) );
--uxCurrentNumberOfTasks;
--uxTasksDeleted;
}
portEXIT_CRITICAL();
taskEXIT_CRITICAL();
prvDeleteTCB( pxTCB );
}
@ -2041,6 +2152,32 @@ static void prvCheckTasksWaitingTermination( void )
}
/*-----------------------------------------------------------*/
static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake )
{
/* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xTickCount )
{
/* Wake time has overflowed. Place this item in the overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the current block list. */
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
/* If the task entering the blocked state was placed at the head of the
list of blocked tasks then xNextTaskUnblockTime needs to be updated
too. */
if( xTimeToWake < xNextTaskUnblockTime )
{
xNextTaskUnblockTime = xTimeToWake;
}
}
}
/*-----------------------------------------------------------*/
static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer )
{
tskTCB *pxNewTCB;
@ -2130,7 +2267,7 @@ tskTCB *pxNewTCB;
else
{
/* What percentage of the total run time has the task used?
This will always be rounded down to the nearest integer.
This will always be rounded down to the nearest integer.
ulTotalRunTime has already been divided by 100. */
ulStatsAsPercentage = pxNextTCB->ulRunTimeCounter / ulTotalRunTime;
@ -2184,7 +2321,6 @@ unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask )
}
#endif
/*-----------------------------------------------------------*/
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
@ -2250,7 +2386,7 @@ unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask )
/*-----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 )
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
xTaskHandle xTaskGetCurrentTaskHandle( void )
{
@ -2268,7 +2404,7 @@ unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask )
/*-----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetSchedulerState == 1 )
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
portBASE_TYPE xTaskGetSchedulerState( void )
{
@ -2302,6 +2438,8 @@ unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask )
{
tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;
configASSERT( pxMutexHolder );
if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
{
/* Adjust the mutex holder state to account for its new priority. */

View File

@ -0,0 +1,649 @@
/*
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:
Atollic AB - Atollic provides professional embedded systems development
tools for C/C++ development, code analysis and test automation.
See http://www.atollic.com
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
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.
*/
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* This entire source file will be skipped if the application is not configured
to include software timer functionality. This #if is closed at the very bottom
of this file. If you want to include software timer functionality then ensure
configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
#if ( configUSE_TIMERS == 1 )
/* Misc definitions. */
#define tmrNO_DELAY ( portTickType ) 0U
/* The definition of the timers themselves. */
typedef struct tmrTimerControl
{
const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */
xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */
} xTIMER;
/* The definition of messages that can be sent and received on the timer
queue. */
typedef struct tmrTimerQueueMessage
{
portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */
portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */
xTIMER * pxTimer; /*<< The timer to which the command will be applied. */
} xTIMER_MESSAGE;
/* The list in which active timers are stored. Timers are referenced in expire
time order, with the nearest expiry time at the front of the list. Only the
timer service task is allowed to access xActiveTimerList. */
PRIVILEGED_DATA static xList xActiveTimerList1;
PRIVILEGED_DATA static xList xActiveTimerList2;
PRIVILEGED_DATA static xList *pxCurrentTimerList;
PRIVILEGED_DATA static xList *pxOverflowTimerList;
/* A queue that is used to send commands to the timer service task. */
PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;
/*-----------------------------------------------------------*/
/*
* Initialise the infrastructure used by the timer service task if it has not
* been initialised already.
*/
static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
/*
* The timer service task (daemon). Timer functionality is controlled by this
* task. Other tasks communicate with the timer service task using the
* xTimerQueue queue.
*/
static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
/*
* Called by the timer service task to interpret and process a command it
* received on the timer queue.
*/
static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
/*
* Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
* depending on if the expire time causes a timer counter overflow.
*/
static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION;
/*
* An active timer has reached its expire time. Reload the timer if it is an
* auto reload timer, then call its callback.
*/
static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION;
/*
* The tick count has overflowed. Switch the timer lists after ensuring the
* current timer list does not still reference some timers.
*/
static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION;
/*
* Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE
* if a tick count overflow occurred since prvSampleTimeNow() was last called.
*/
static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;
/*
* If the timer list contains any active timers then return the expire time of
* the timer that will expire first and set *pxListWasEmpty to false. If the
* timer list does not contain any timers then return 0 and set *pxListWasEmpty
* to pdTRUE.
*/
static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION;
/*
* If a timer has expired, process it. Otherwise, block the timer service task
* until either a timer does expire or a command is received.
*/
static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/
portBASE_TYPE xTimerCreateTimerTask( void )
{
portBASE_TYPE xReturn = pdFAIL;
/* This function is called when the scheduler is started if
configUSE_TIMERS is set to 1. Check that the infrastructure used by the
timer service task has been created/initialised. If timers have already
been created then the initialisation will already have been performed. */
prvCheckForValidListAndQueue();
if( xTimerQueue != NULL )
{
xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, NULL);
}
configASSERT( xReturn );
return xReturn;
}
/*-----------------------------------------------------------*/
xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction )
{
xTIMER *pxNewTimer;
/* Allocate the timer structure. */
if( xTimerPeriodInTicks == ( portTickType ) 0U )
{
pxNewTimer = NULL;
configASSERT( ( xTimerPeriodInTicks > 0 ) );
}
else
{
pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );
if( pxNewTimer != NULL )
{
/* Ensure the infrastructure used by the timer service task has been
created/initialised. */
prvCheckForValidListAndQueue();
/* Initialise the timer structure members using the function parameters. */
pxNewTimer->pcTimerName = pcTimerName;
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
pxNewTimer->uxAutoReload = uxAutoReload;
pxNewTimer->pvTimerID = pvTimerID;
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
traceTIMER_CREATE( pxNewTimer );
}
else
{
traceTIMER_CREATE_FAILED();
}
}
return ( xTimerHandle ) pxNewTimer;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime )
{
portBASE_TYPE xReturn = pdFAIL;
xTIMER_MESSAGE xMessage;
/* Send a message to the timer service task to perform a particular action
on a particular timer definition. */
if( xTimerQueue != NULL )
{
/* Send a command to the timer service task to start the xTimer timer. */
xMessage.xMessageID = xCommandID;
xMessage.xMessageValue = xOptionalValue;
xMessage.pxTimer = ( xTIMER * ) xTimer;
if( pxHigherPriorityTaskWoken == NULL )
{
if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )
{
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );
}
else
{
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
}
}
else
{
xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
}
traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
}
return xReturn;
}
/*-----------------------------------------------------------*/
static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )
{
xTIMER *pxTimer;
portBASE_TYPE xResult;
/* Remove the timer from the list of active timers. A check has already
been performed to ensure the list is not empty. */
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
vListRemove( &( pxTimer->xTimerListItem ) );
traceTIMER_EXPIRED( pxTimer );
/* If the timer is an auto reload timer then calculate the next
expiry time and re-insert the timer in the list of active timers. */
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
{
/* This is the only time a timer is inserted into a list using
a time relative to anything other than the current time. It
will therefore be inserted into the correct list relative to
the time this task thinks it is now, even if a command to
switch lists due to a tick count overflow is already waiting in
the timer queue. */
if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )
{
/* The timer expired before it was added to the active timer
list. Reload it now. */
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
/* Call the timer callback. */
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
}
/*-----------------------------------------------------------*/
static void prvTimerTask( void *pvParameters )
{
portTickType xNextExpireTime;
portBASE_TYPE xListWasEmpty;
/* Just to avoid compiler warnings. */
( void ) pvParameters;
for( ;; )
{
/* Query the timers list to see if it contains any timers, and if so,
obtain the time at which the next timer will expire. */
xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
/* If a timer has expired, process it. Otherwise, block this task
until either a timer does expire, or a command is received. */
prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
/* Empty the command queue. */
prvProcessReceivedCommands();
}
}
/*-----------------------------------------------------------*/
static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty )
{
portTickType xTimeNow;
portBASE_TYPE xTimerListsWereSwitched;
vTaskSuspendAll();
{
/* Obtain the time now to make an assessment as to whether the timer
has expired or not. If obtaining the time causes the lists to switch
then don't process this timer as any timers that remained in the list
when the lists were switched will have been processed within the
prvSampelTimeNow() function. */
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
if( xTimerListsWereSwitched == pdFALSE )
{
/* The tick count has not overflowed, has the timer expired? */
if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
{
xTaskResumeAll();
prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
}
else
{
/* The tick count has not overflowed, and the next expire
time has not been reached yet. This task should therefore
block to wait for the next expire time or a command to be
received - whichever comes first. The following line cannot
be reached unless xNextExpireTime > xTimeNow, except in the
case when the current timer list is empty. */
vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );
if( xTaskResumeAll() == pdFALSE )
{
/* Yield to wait for either a command to arrive, or the block time
to expire. If a command arrived between the critical section being
exited and this yield then the yield will not cause the task
to block. */
portYIELD_WITHIN_API();
}
}
}
else
{
xTaskResumeAll();
}
}
}
/*-----------------------------------------------------------*/
static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty )
{
portTickType xNextExpireTime;
/* Timers are listed in expiry time order, with the head of the list
referencing the task that will expire first. Obtain the time at which
the timer with the nearest expiry time will expire. If there are no
active timers then just set the next expire time to 0. That will cause
this task to unblock when the tick count overflows, at which point the
timer lists will be switched and the next expiry time can be
re-assessed. */
*pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );
if( *pxListWasEmpty == pdFALSE )
{
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
}
else
{
/* Ensure the task unblocks when the tick count rolls over. */
xNextExpireTime = ( portTickType ) 0U;
}
return xNextExpireTime;
}
/*-----------------------------------------------------------*/
static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched )
{
portTickType xTimeNow;
static portTickType xLastTime = ( portTickType ) 0U;
xTimeNow = xTaskGetTickCount();
if( xTimeNow < xLastTime )
{
prvSwitchTimerLists( xLastTime );
*pxTimerListsWereSwitched = pdTRUE;
}
else
{
*pxTimerListsWereSwitched = pdFALSE;
}
xLastTime = xTimeNow;
return xTimeNow;
}
/*-----------------------------------------------------------*/
static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime )
{
portBASE_TYPE xProcessTimerNow = pdFALSE;
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
if( xNextExpiryTime <= xTimeNow )
{
/* Has the expiry time elapsed between the command to start/reset a
timer was issued, and the time the command was processed? */
if( ( ( portTickType ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks )
{
/* The time between a command being issued and the command being
processed actually exceeds the timers period. */
xProcessTimerNow = pdTRUE;
}
else
{
vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );
}
}
else
{
if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )
{
/* If, since the command was issued, the tick count has overflowed
but the expiry time has not, then the timer must have already passed
its expiry time and should be processed immediately. */
xProcessTimerNow = pdTRUE;
}
else
{
vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
}
}
return xProcessTimerNow;
}
/*-----------------------------------------------------------*/
static void prvProcessReceivedCommands( void )
{
xTIMER_MESSAGE xMessage;
xTIMER *pxTimer;
portBASE_TYPE xTimerListsWereSwitched, xResult;
portTickType xTimeNow;
/* In this case the xTimerListsWereSwitched parameter is not used, but it
must be present in the function call. */
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL )
{
pxTimer = xMessage.pxTimer;
/* Is the timer already in a list of active timers? When the command
is trmCOMMAND_PROCESS_TIMER_OVERFLOW, the timer will be NULL as the
command is to the task rather than to an individual timer. */
if( pxTimer != NULL )
{
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
{
/* The timer is in a list, remove it. */
vListRemove( &( pxTimer->xTimerListItem ) );
}
}
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue );
switch( xMessage.xMessageID )
{
case tmrCOMMAND_START :
/* Start or restart a timer. */
if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE )
{
/* The timer expired before it was added to the active timer
list. Process it now. */
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
{
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
break;
case tmrCOMMAND_STOP :
/* The timer has already been removed from the active list.
There is nothing to do here. */
break;
case tmrCOMMAND_CHANGE_PERIOD :
pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
break;
case tmrCOMMAND_DELETE :
/* The timer has already been removed from the active list,
just free up the memory. */
vPortFree( pxTimer );
break;
default :
/* Don't expect to get here. */
break;
}
}
}
/*-----------------------------------------------------------*/
static void prvSwitchTimerLists( portTickType xLastTime )
{
portTickType xNextExpireTime, xReloadTime;
xList *pxTemp;
xTIMER *pxTimer;
portBASE_TYPE xResult;
/* Remove compiler warnings if configASSERT() is not defined. */
( void ) xLastTime;
/* The tick count has overflowed. The timer lists must be switched.
If there are any timers still referenced from the current timer list
then they must have expired and should be processed before the lists
are switched. */
while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )
{
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
/* Remove the timer from the list. */
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
vListRemove( &( pxTimer->xTimerListItem ) );
/* Execute its callback, then send a command to restart the timer if
it is an auto-reload timer. It cannot be restarted here as the lists
have not yet been switched. */
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
{
/* Calculate the reload value, and if the reload value results in
the timer going into the same timer list then it has already expired
and the timer should be re-inserted into the current list so it is
processed again within this loop. Otherwise a command should be sent
to restart the timer to ensure it is only inserted into a list after
the lists have been swapped. */
xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );
if( xReloadTime > xNextExpireTime )
{
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
}
else
{
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
}
pxTemp = pxCurrentTimerList;
pxCurrentTimerList = pxOverflowTimerList;
pxOverflowTimerList = pxTemp;
}
/*-----------------------------------------------------------*/
static void prvCheckForValidListAndQueue( void )
{
/* Check that the list from which active timers are referenced, and the
queue used to communicate with the timer service, have been
initialised. */
taskENTER_CRITICAL();
{
if( xTimerQueue == NULL )
{
vListInitialise( &xActiveTimerList1 );
vListInitialise( &xActiveTimerList2 );
pxCurrentTimerList = &xActiveTimerList1;
pxOverflowTimerList = &xActiveTimerList2;
xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) );
}
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer )
{
portBASE_TYPE xTimerIsInActiveList;
xTIMER *pxTimer = ( xTIMER * ) xTimer;
/* Is the timer in the list of active timers? */
taskENTER_CRITICAL();
{
/* Checking to see if it is in the NULL list in effect checks to see if
it is referenced from either the current or the overflow timer lists in
one go, but the logic has to be reversed, hence the '!'. */
xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );
}
taskEXIT_CRITICAL();
return xTimerIsInActiveList;
}
/*-----------------------------------------------------------*/
void *pvTimerGetTimerID( xTimerHandle xTimer )
{
xTIMER *pxTimer = ( xTIMER * ) xTimer;
return pxTimer->pvTimerID;
}
/*-----------------------------------------------------------*/
/* This entire source file will be skipped if the application is not configured
to include software timer functionality. If you want to include software timer
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
#endif /* configUSE_TIMERS == 1 */

View File

@ -34,7 +34,6 @@
/* Private Function Prototypes */
uint16_t servo_positions[8];
/**
* Initialise Servos
*/
@ -174,19 +173,15 @@ void PIOS_Servo_Set(uint8_t Servo, uint16_t Position)
switch(pios_servo_cfg.channels[Servo].channel) {
case TIM_Channel_1:
servo_positions[Servo] = Position;
TIM_SetCompare1(pios_servo_cfg.channels[Servo].timer, Position);
break;
case TIM_Channel_2:
servo_positions[Servo] = Position;
TIM_SetCompare2(pios_servo_cfg.channels[Servo].timer, Position);
break;
case TIM_Channel_3:
servo_positions[Servo] = Position;
TIM_SetCompare3(pios_servo_cfg.channels[Servo].timer, Position);
break;
case TIM_Channel_4:
servo_positions[Servo] = Position;
TIM_SetCompare4(pios_servo_cfg.channels[Servo].timer, Position);
break;
}

View File

@ -153,9 +153,13 @@ int32_t UAVObjSaveMetaobjects();
int32_t UAVObjLoadMetaobjects();
int32_t UAVObjDeleteMetaobjects();
int32_t UAVObjSetData(UAVObjHandle obj, const void* dataIn);
int32_t UAVObjSetDataField(UAVObjHandle obj, const void* dataIn, uint32_t offset, uint32_t size);
int32_t UAVObjGetData(UAVObjHandle obj, void* dataOut);
int32_t UAVObjGetDataField(UAVObjHandle obj, void* dataOut, uint32_t offset, uint32_t size);
int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId, const void* dataIn);
int32_t UAVObjSetInstanceDataField(UAVObjHandle obj, uint16_t instId, const void* dataIn, uint32_t offset, uint32_t size);
int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId, void* dataOut);
int32_t UAVObjGetInstanceDataField(UAVObjHandle obj, uint16_t instId, void* dataOut, uint32_t offset, uint32_t size);
int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata* dataIn);
int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata* dataOut);
int8_t UAVObjReadOnly(UAVObjHandle obj);

View File

@ -82,6 +82,9 @@ int32_t $(NAME)Initialize();
UAVObjHandle $(NAME)Handle();
void $(NAME)SetDefaults(UAVObjHandle obj, uint16_t instId);
// set/Get functions
$(SETGETFIELDSEXTERN)
#endif // $(NAMEUC)_H
/**

View File

@ -993,6 +993,17 @@ int32_t UAVObjSetData(UAVObjHandle obj, const void *dataIn)
return UAVObjSetInstanceData(obj, 0, dataIn);
}
/**
* Set the object data
* \param[in] obj The object handle
* \param[in] dataIn The object's data structure
* \return 0 if success or -1 if failure
*/
int32_t UAVObjSetDataField(UAVObjHandle obj, const void* dataIn, uint32_t offset, uint32_t size)
{
return UAVObjSetInstanceDataField(obj, 0, dataIn, offset, size);
}
/**
* Get the object data
* \param[in] obj The object handle
@ -1004,6 +1015,17 @@ int32_t UAVObjGetData(UAVObjHandle obj, void *dataOut)
return UAVObjGetInstanceData(obj, 0, dataOut);
}
/**
* Get the object data
* \param[in] obj The object handle
* \param[out] dataOut The object's data structure
* \return 0 if success or -1 if failure
*/
int32_t UAVObjGetDataField(UAVObjHandle obj, void* dataOut, uint32_t offset, uint32_t size)
{
return UAVObjGetInstanceDataField(obj, 0, dataOut, offset, size);
}
/**
* Set the data of a specific object instance
* \param[in] obj The object handle
@ -1052,6 +1074,63 @@ int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId,
return 0;
}
/**
* Set the data of a specific object instance
* \param[in] obj The object handle
* \param[in] instId The object instance ID
* \param[in] dataIn The object's data structure
* \return 0 if success or -1 if failure
*/
int32_t UAVObjSetInstanceDataField(UAVObjHandle obj, uint16_t instId, const void* dataIn, uint32_t offset, uint32_t size)
{
ObjectList* objEntry;
ObjectInstList* instEntry;
UAVObjMetadata* mdata;
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Cast to object info
objEntry = (ObjectList*)obj;
// Check access level
if ( !objEntry->isMetaobject )
{
mdata = (UAVObjMetadata*)(objEntry->linkedObj->instances.data);
if ( mdata->access == ACCESS_READONLY )
{
xSemaphoreGiveRecursive(mutex);
return -1;
}
}
// Get instance information
instEntry = getInstance(objEntry, instId);
if ( instEntry == NULL )
{
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
// return if we set too much of what we have
if ( (size + offset) > objEntry->numBytes) {
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Set data
memcpy(instEntry->data + offset, dataIn, size);
// Fire event
sendEvent(objEntry, instId, EV_UPDATED);
// Unlock
xSemaphoreGiveRecursive(mutex);
return 0;
}
/**
* Get the data of a specific object instance
* \param[in] obj The object handle
@ -1086,6 +1165,49 @@ int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId,
return 0;
}
/**
* Get the data of a specific object instance
* \param[in] obj The object handle
* \param[in] instId The object instance ID
* \param[out] dataOut The object's data structure
* \return 0 if success or -1 if failure
*/
int32_t UAVObjGetInstanceDataField(UAVObjHandle obj, uint16_t instId, void* dataOut, uint32_t offset, uint32_t size)
{
ObjectList* objEntry;
ObjectInstList* instEntry;
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Cast to object info
objEntry = (ObjectList*)obj;
// Get instance information
instEntry = getInstance(objEntry, instId);
if ( instEntry == NULL )
{
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
// return if we request too much of what we can give
if ( (size + offset) > objEntry->numBytes)
{
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Set data
memcpy(dataOut, instEntry->data + offset, size);
// Unlock
xSemaphoreGiveRecursive(mutex);
return 0;
}
/**
* Set the object metadata
* \param[in] obj The object handle

View File

@ -104,6 +104,11 @@ UAVObjHandle $(NAME)Handle()
return handle;
}
/**
* Get/Set object Functions
*/
$(SETGETFIELDS)
/**
* @}
*/

View File

@ -237,6 +237,96 @@ bool UAVObjectGeneratorFlight::process_object(ObjectInfo* info)
}
outCode.replace(QString("$(INITFIELDS)"), initfields);
// Replace the $(SETGETFIELDS) tag
QString setgetfields;
for (int n = 0; n < info->fields.length(); ++n)
{
//if (!info->fields[n]->defaultValues.isEmpty() )
{
// For non-array fields
if ( info->fields[n]->numElements == 1)
{
/* Set */
setgetfields.append( QString("void %2%3Set( %1 *New%3 )\r\n")
.arg( fieldTypeStrC[info->fields[n]->type] )
.arg( info->name )
.arg( info->fields[n]->name ) );
setgetfields.append( QString("{\r\n") );
setgetfields.append( QString("\tUAVObjSetDataField(%1Handle(), (void*)New%2, offsetof( %1Data, %2), sizeof(%3));\r\n")
.arg( info->name )
.arg( info->fields[n]->name )
.arg( fieldTypeStrC[info->fields[n]->type] ) );
setgetfields.append( QString("}\r\n") );
/* GET */
setgetfields.append( QString("void %2%3Get( %1 *New%3 )\r\n")
.arg( fieldTypeStrC[info->fields[n]->type] )
.arg( info->name )
.arg( info->fields[n]->name ));
setgetfields.append( QString("{\r\n") );
setgetfields.append( QString("\tUAVObjGetDataField(%1Handle(), (void*)New%2, offsetof( %1Data, %2), sizeof(%3));\r\n")
.arg( info->name )
.arg( info->fields[n]->name )
.arg( fieldTypeStrC[info->fields[n]->type] ) );
setgetfields.append( QString("}\r\n") );
}
else
{
/* SET */
setgetfields.append( QString("void %2%3Set( %1 *New%3 )\r\n")
.arg( fieldTypeStrC[info->fields[n]->type] )
.arg( info->name )
.arg( info->fields[n]->name ) );
setgetfields.append( QString("{\r\n") );
setgetfields.append( QString("\tUAVObjSetDataField(%1Handle(), (void*)New%2, offsetof( %1Data, %2), %3*sizeof(%4));\r\n")
.arg( info->name )
.arg( info->fields[n]->name )
.arg( info->fields[n]->numElements )
.arg( fieldTypeStrC[info->fields[n]->type] ) );
setgetfields.append( QString("}\r\n") );
/* GET */
setgetfields.append( QString("void %2%3Get( %1 *New%3 )\r\n")
.arg( fieldTypeStrC[info->fields[n]->type] )
.arg( info->name )
.arg( info->fields[n]->name ) );
setgetfields.append( QString("{\r\n") );
setgetfields.append( QString("\tUAVObjGetDataField(%1Handle(), (void*)New%2, offsetof( %1Data, %2), %3*sizeof(%4));\r\n")
.arg( info->name )
.arg( info->fields[n]->name )
.arg( info->fields[n]->numElements )
.arg( fieldTypeStrC[info->fields[n]->type] ) );
setgetfields.append( QString("}\r\n") );
}
}
}
outCode.replace(QString("$(SETGETFIELDS)"), setgetfields);
// Replace the $(SETGETFIELDSEXTERN) tag
QString setgetfieldsextern;
for (int n = 0; n < info->fields.length(); ++n)
{
//if (!info->fields[n]->defaultValues.isEmpty() )
{
/* SET */
setgetfieldsextern.append( QString("extern void %2%3Set( %1 *New%3 );\r\n")
.arg( fieldTypeStrC[info->fields[n]->type] )
.arg( info->name )
.arg( info->fields[n]->name ) );
/* GET */
setgetfieldsextern.append( QString("extern void %2%3Get( %1 *New%3 );\r\n")
.arg( fieldTypeStrC[info->fields[n]->type] )
.arg( info->name )
.arg( info->fields[n]->name ) );
}
}
outInclude.replace(QString("$(SETGETFIELDSEXTERN)"), setgetfieldsextern);
// Write the flight code
bool res = writeFileIfDiffrent( flightOutputPath.absolutePath() + "/" + info->namelc + ".c", outCode );
if (!res) {