1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

OP-1079 - Update to FreeRTOS v7.5.2

This commit is contained in:
Mathieu Rondonneau 2013-09-04 20:26:23 -07:00
parent e973740b8b
commit 03b243fe31
33 changed files with 2856 additions and 1988 deletions

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -211,7 +201,7 @@ portTickType xTimeToWake;
/* We must remove ourselves from the ready list before adding /* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for ourselves to the blocked list as the same list item is used for
both lists. */ both lists. */
uxListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); ( void ) uxListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
/* The list item will be inserted in wake time order. */ /* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
@ -251,11 +241,11 @@ static void prvCheckPendingReadyList( void )
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
{ {
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
} }
} }
@ -306,7 +296,7 @@ corCRCB *pxCRCB;
/* Is the co-routine waiting on an event also? */ /* Is the co-routine waiting on an event also? */
if( pxCRCB->xEventListItem.pvContainer ) if( pxCRCB->xEventListItem.pvContainer )
{ {
uxListRemove( &( pxCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
} }
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -378,7 +368,7 @@ signed portBASE_TYPE xReturn;
event lists and the pending ready list. This function assumes that a event lists and the pending ready list. This function assumes that a
check has already been made to ensure pxEventList is not empty. */ check has already been made to ensure pxEventList is not empty. */
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
@ -229,10 +219,9 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#ifndef configASSERT #ifndef configASSERT
#define configASSERT( x ) #define configASSERT( x )
#endif #define configASSERT_DEFINED 0
#else
#ifndef portALIGNMENT_ASSERT_pxCurrentTCB #define configASSERT_DEFINED 1
#define portALIGNMENT_ASSERT_pxCurrentTCB configASSERT
#endif #endif
/* The timers module relies on xTaskGetSchedulerState(). */ /* The timers module relies on xTaskGetSchedulerState(). */
@ -309,6 +298,22 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#define traceTASK_SWITCHED_IN() #define traceTASK_SWITCHED_IN()
#endif #endif
#ifndef traceINCREASE_TICK_COUNT
/* Called before stepping the tick count after waking from tickless idle
sleep. */
#define traceINCREASE_TICK_COUNT( x )
#endif
#ifndef traceLOW_POWER_IDLE_BEGIN
/* Called immediately before entering tickless idle. */
#define traceLOW_POWER_IDLE_BEGIN()
#endif
#ifndef traceLOW_POWER_IDLE_END
/* Called when returning to the Idle task after a tickless idle. */
#define traceLOW_POWER_IDLE_END()
#endif
#ifndef traceTASK_SWITCHED_OUT #ifndef traceTASK_SWITCHED_OUT
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer /* Called before a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the task being switched out. */ to the task control block of the task being switched out. */
@ -414,6 +419,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#define traceQUEUE_PEEK( pxQueue ) #define traceQUEUE_PEEK( pxQueue )
#endif #endif
#ifndef traceQUEUE_PEEK_FROM_ISR
#define traceQUEUE_PEEK_FROM_ISR( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FAILED #ifndef traceQUEUE_RECEIVE_FAILED
#define traceQUEUE_RECEIVE_FAILED( pxQueue ) #define traceQUEUE_RECEIVE_FAILED( pxQueue )
#endif #endif
@ -434,6 +443,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
#endif #endif
#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED
#define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_DELETE #ifndef traceQUEUE_DELETE
#define traceQUEUE_DELETE( pxQueue ) #define traceQUEUE_DELETE( pxQueue )
#endif #endif
@ -568,6 +581,30 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#define configUSE_QUEUE_SETS 0 #define configUSE_QUEUE_SETS 0
#endif #endif
#ifndef portTASK_USES_FLOATING_POINT
#define portTASK_USES_FLOATING_POINT()
#endif
#ifndef configUSE_TIME_SLICING
#define configUSE_TIME_SLICING 1
#endif
#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
#endif
#ifndef configUSE_NEWLIB_REENTRANT
#define configUSE_NEWLIB_REENTRANT 0
#endif
#ifndef configUSE_STATS_FORMATTING_FUNCTIONS
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
#endif
#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
#endif
/* For backward compatability. */ /* For backward compatability. */
#define eTaskStateGet eTaskGetState #define eTaskStateGet eTaskGetState

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#ifndef STACK_MACROS_H #ifndef STACK_MACROS_H

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#ifndef CO_ROUTINE_H #ifndef CO_ROUTINE_H

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/* /*
@ -104,6 +94,38 @@
#ifndef LIST_H #ifndef LIST_H
#define LIST_H #define LIST_H
/*
* The list structure members are modified from within interrupts, and therefore
* by rights should be declared volatile. However, they are only modified in a
* functionally atomic way (within critical sections of with the scheduler
* suspended) and are either passed by reference into a function or indexed via
* a volatile variable. Therefore, in all use cases tested so far, the volatile
* qualifier can be omitted in order to provide a moderate performance
* improvement without adversely affecting functional behaviour. The assembly
* instructions generated by the IAR, ARM and GCC compilers when the respective
* compiler's options were set for maximum optimisation has been inspected and
* deemed to be as intended. That said, as compiler technology advances, and
* especially if aggressive cross module optimisation is used (a use case that
* has not been exercised to any great extend) then it is feasible that the
* volatile qualifier will be needed for correct optimisation. It is expected
* that a compiler removing essential code because, without the volatile
* qualifier on the list structure members and with aggressive cross module
* optimisation, the compiler deemed the code unnecessary will result in
* complete and obvious failure of the scheduler. If this is ever experienced
* then the volatile qualifier can be inserted in the relevant places within the
* list structures by simply defining configLIST_VOLATILE to volatile in
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
* If configLIST_VOLATILE is not defined then the preprocessor directives below
* will simply #define configLIST_VOLATILE away completely.
*
* To use volatile list structure members then add the following line to
* FreeRTOSConfig.h (without the quotes):
* "#define configLIST_VOLATILE volatile"
*/
#ifndef configLIST_VOLATILE
#define configLIST_VOLATILE
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -112,19 +134,19 @@ extern "C" {
*/ */
struct xLIST_ITEM struct xLIST_ITEM
{ {
portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ configLIST_VOLATILE portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next xListItem in the list. */
volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;/*< Pointer to the previous xListItem in the list. */
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
}; };
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */ typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
struct xMINI_LIST_ITEM struct xMINI_LIST_ITEM
{ {
portTickType xItemValue; configLIST_VOLATILE portTickType xItemValue;
volatile struct xLIST_ITEM *pxNext; struct xLIST_ITEM * configLIST_VOLATILE pxNext;
volatile struct xLIST_ITEM *pxPrevious; struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
}; };
typedef struct xMINI_LIST_ITEM xMiniListItem; typedef struct xMINI_LIST_ITEM xMiniListItem;
@ -133,9 +155,9 @@ typedef struct xMINI_LIST_ITEM xMiniListItem;
*/ */
typedef struct xLIST typedef struct xLIST
{ {
volatile unsigned portBASE_TYPE uxNumberOfItems; configLIST_VOLATILE unsigned portBASE_TYPE uxNumberOfItems;
volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */ xListItem * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
} xList; } xList;
/* /*
@ -145,7 +167,7 @@ typedef struct xLIST
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
* \ingroup LinkedList * \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 get the owner of a list item. The owner of a list item * Access macro to get the owner of a list item. The owner of a list item
@ -163,7 +185,7 @@ typedef struct xLIST
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = ( xValue ) #define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
/* /*
* Access macro to retrieve the value of the list item. The value can * Access macro to retrieve the value of the list item. The value can
@ -191,7 +213,7 @@ typedef struct xLIST
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 ) #define listLIST_IS_EMPTY( pxList ) ( ( portBASE_TYPE ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 ) )
/* /*
* Access macro to return the number of items in the list. * Access macro to return the number of items in the list.
@ -223,7 +245,7 @@ xList * const pxConstList = ( pxList ); \
/* Increment the index to the next item and return the item, ensuring */ \ /* 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. */ \ /* we don't return the marker used at the end of the list. */ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \ if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
{ \ { \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
} \ } \
@ -259,7 +281,7 @@ xList * const pxConstList = ( pxList ); \
* @return pdTRUE is the list item is in the list, otherwise pdFALSE. * @return pdTRUE is the list item is in the list, otherwise pdFALSE.
* pointer against * pointer against
*/ */
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( portBASE_TYPE ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
/* /*
* Return the list a list item is contained within (referenced from). * Return the list a list item is contained within (referenced from).
@ -286,7 +308,7 @@ xList * const pxConstList = ( pxList ); \
* \page vListInitialise vListInitialise * \page vListInitialise vListInitialise
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInitialise( xList *pxList ); void vListInitialise( xList * const pxList );
/* /*
* Must be called before a list item is used. This sets the list container to * Must be called before a list item is used. This sets the list container to
@ -297,7 +319,7 @@ void vListInitialise( xList *pxList );
* \page vListInitialiseItem vListInitialiseItem * \page vListInitialiseItem vListInitialiseItem
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInitialiseItem( xListItem *pxItem ); void vListInitialiseItem( xListItem * const pxItem );
/* /*
* Insert a list item into a list. The item will be inserted into the list in * Insert a list item into a list. The item will be inserted into the list in
@ -310,7 +332,7 @@ void vListInitialiseItem( xListItem *pxItem );
* \page vListInsert vListInsert * \page vListInsert vListInsert
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInsert( xList *pxList, xListItem *pxNewListItem ); void vListInsert( xList * const pxList, xListItem * const pxNewListItem );
/* /*
* Insert a list item into a list. The item will be inserted in a position * Insert a list item into a list. The item will be inserted in a position
@ -331,7 +353,7 @@ void vListInsert( xList *pxList, xListItem *pxNewListItem );
* \page vListInsertEnd vListInsertEnd * \page vListInsertEnd vListInsertEnd
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ); void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem );
/* /*
* Remove an item from a list. The list item has a pointer to the list that * Remove an item from a list. The list item has a pointer to the list that
@ -346,7 +368,7 @@ void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
* \page uxListRemove uxListRemove * \page uxListRemove uxListRemove
* \ingroup LinkedList * \ingroup LinkedList
*/ */
unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove ); unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove );
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#ifndef MPU_WRAPPERS_H #ifndef MPU_WRAPPERS_H
@ -108,6 +98,7 @@ only for ports that are using the MPU. */
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
#define xQueueGenericCreate MPU_xQueueGenericCreate #define xQueueGenericCreate MPU_xQueueGenericCreate
#define xQueueCreateMutex MPU_xQueueCreateMutex #define xQueueCreateMutex MPU_xQueueCreateMutex
@ -125,6 +116,7 @@ only for ports that are using the MPU. */
#define xQueueSelectFromSet MPU_xQueueSelectFromSet #define xQueueSelectFromSet MPU_xQueueSelectFromSet
#define xQueueAddToSet MPU_xQueueAddToSet #define xQueueAddToSet MPU_xQueueAddToSet
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#define xQueuePeekFromISR MPU_xQueuePeekFromISR
#define pvPortMalloc MPU_pvPortMalloc #define pvPortMalloc MPU_pvPortMalloc
#define vPortFree MPU_vPortFree #define vPortFree MPU_vPortFree
@ -144,7 +136,6 @@ only for ports that are using the MPU. */
/* Ensure API functions go in the privileged execution section. */ /* Ensure API functions go in the privileged execution section. */
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) #define PRIVILEGED_DATA __attribute__((section("privileged_data")))
//#define PRIVILEGED_DATA
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
@ -367,7 +357,7 @@ extern "C" {
#if( portUSING_MPU_WRAPPERS == 1 ) #if( portUSING_MPU_WRAPPERS == 1 )
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION; portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;
#else #else
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ); portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
#endif #endif
/* /*

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#ifndef PROJDEFS_H #ifndef PROJDEFS_H
@ -78,13 +68,13 @@
/* Defines the prototype to which task functions must conform. */ /* Defines the prototype to which task functions must conform. */
typedef void (*pdTASK_CODE)( void * ); typedef void (*pdTASK_CODE)( void * );
#define pdTRUE ( 1 ) #define pdFALSE ( ( portBASE_TYPE ) 0 )
#define pdFALSE ( 0 ) #define pdTRUE ( ( portBASE_TYPE ) 1 )
#define pdPASS ( 1 ) #define pdPASS ( pdTRUE )
#define pdFAIL ( 0 ) #define pdFAIL ( pdFALSE )
#define errQUEUE_EMPTY ( 0 ) #define errQUEUE_EMPTY ( ( portBASE_TYPE ) 0 )
#define errQUEUE_FULL ( 0 ) #define errQUEUE_FULL ( ( portBASE_TYPE ) 0 )
/* Error definitions. */ /* Error definitions. */
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
@ -85,8 +75,6 @@ extern "C" {
#endif #endif
#include "mpu_wrappers.h"
/** /**
* Type by which queues are referenced. For example, a call to xQueueCreate() * Type by which queues are referenced. For example, a call to xQueueCreate()
* returns an xQueueHandle variable that can then be used as a parameter to * returns an xQueueHandle variable that can then be used as a parameter to
@ -109,16 +97,17 @@ typedef void * xQueueSetHandle;
typedef void * xQueueSetMemberHandle; typedef void * xQueueSetMemberHandle;
/* For internal use only. */ /* For internal use only. */
#define queueSEND_TO_BACK ( 0 ) #define queueSEND_TO_BACK ( ( portBASE_TYPE ) 0 )
#define queueSEND_TO_FRONT ( 1 ) #define queueSEND_TO_FRONT ( ( portBASE_TYPE ) 1 )
#define queueOVERWRITE ( ( portBASE_TYPE ) 2 )
/* For internal use only. These definitions *must* match those in queue.c. */ /* For internal use only. These definitions *must* match those in queue.c. */
#define queueQUEUE_TYPE_BASE ( 0U ) #define queueQUEUE_TYPE_BASE ( ( unsigned char ) 0U )
#define queueQUEUE_TYPE_SET ( 0U ) #define queueQUEUE_TYPE_SET ( ( unsigned char ) 0U )
#define queueQUEUE_TYPE_MUTEX ( 1U ) #define queueQUEUE_TYPE_MUTEX ( ( unsigned char ) 1U )
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U ) #define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( unsigned char ) 2U )
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U ) #define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( unsigned char ) 3U )
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U ) #define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( unsigned char ) 4U )
/** /**
* queue. h * queue. h
@ -426,6 +415,89 @@ typedef void * xQueueSetMemberHandle;
*/ */
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) #define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
/**
* queue. h
* <pre>
portBASE_TYPE xQueueOverwrite(
xQueueHandle xQueue,
const void * pvItemToQueue
);
* </pre>
*
* Only for use with queues that have a length of one - so the queue is either
* empty or full.
*
* Post an item on a queue. If the queue is already full then overwrite the
* value held in the queue. The item is queued by copy, not by reference.
*
* This function must not be called from an interrupt service routine.
* See xQueueOverwriteFromISR () for an alternative which may be used in an ISR.
*
* @param xQueue The handle of the queue to which the data is being sent.
*
* @param pvItemToQueue A pointer to the item that is to be placed on the
* queue. The size of the items the queue will hold was defined when the
* queue was created, so this many bytes will be copied from pvItemToQueue
* into the queue storage area.
*
* @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and
* therefore has the same return values as xQueueSendToFront(). However, pdPASS
* is the only value that can be returned because xQueueOverwrite() will write
* to the queue even when the queue is already full.
*
* Example usage:
<pre>
void vFunction( void *pvParameters )
{
xQueueHandle xQueue;
unsigned long ulVarToSend, ulValReceived;
// Create a queue to hold one unsigned long value. It is strongly
// recommended *not* to use xQueueOverwrite() on queues that can
// contain more than one value, and doing so will trigger an assertion
// if configASSERT() is defined.
xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
// Write the value 10 to the queue using xQueueOverwrite().
ulVarToSend = 10;
xQueueOverwrite( xQueue, &ulVarToSend );
// Peeking the queue should now return 10, but leave the value 10 in
// the queue. A block time of zero is used as it is known that the
// queue holds a value.
ulValReceived = 0;
xQueuePeek( xQueue, &ulValReceived, 0 );
if( ulValReceived != 10 )
{
// Error unless the item was removed by a different task.
}
// The queue is still full. Use xQueueOverwrite() to overwrite the
// value held in the queue with 100.
ulVarToSend = 100;
xQueueOverwrite( xQueue, &ulVarToSend );
// This time read from the queue, leaving the queue empty once more.
// A block time of 0 is used again.
xQueueReceive( xQueue, &ulValReceived, 0 );
// The value read should be the last value written, even though the
// queue was already full when the value was written.
if( ulValReceived != 100 )
{
// Error!
}
// ...
}
</pre>
* \defgroup xQueueOverwrite xQueueOverwrite
* \ingroup QueueManagement
*/
#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE )
/** /**
* queue. h * queue. h
@ -512,7 +584,7 @@ typedef void * xQueueSetMemberHandle;
* \defgroup xQueueSend xQueueSend * \defgroup xQueueSend xQueueSend
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
@ -533,7 +605,9 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const
* Successfully received items remain on the queue so will be returned again * Successfully received items remain on the queue so will be returned again
* by the next call, or a call to xQueueReceive(). * by the next call, or a call to xQueueReceive().
* *
* This macro must not be used in an interrupt service routine. * This macro must not be used in an interrupt service routine. See
* xQueuePeekFromISR() for an alternative that can be called from an interrupt
* service routine.
* *
* @param xQueue The handle to the queue from which the item is to be * @param xQueue The handle to the queue from which the item is to be
* received. * received.
@ -608,6 +682,39 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const
*/ */
#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) #define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )
/**
* queue. h
* <pre>
portBASE_TYPE xQueuePeekFromISR(
xQueueHandle xQueue,
void *pvBuffer,
);</pre>
*
* A version of xQueuePeek() that can be called from an interrupt service
* routine (ISR).
*
* Receive an item from a queue without removing the item from the queue.
* The item is received by copy so a buffer of adequate size must be
* provided. The number of bytes copied into the buffer was defined when
* the queue was created.
*
* Successfully received items remain on the queue so will be returned again
* by the next call, or a call to xQueueReceive().
*
* @param xQueue The handle to the queue from which the item is to be
* received.
*
* @param pvBuffer Pointer to the buffer into which the received item will
* be copied.
*
* @return pdTRUE if an item was successfully received from the queue,
* otherwise pdFALSE.
*
* \defgroup xQueuePeekFromISR xQueuePeekFromISR
* \ingroup QueueManagement
*/
signed portBASE_TYPE xQueuePeekFromISR( xQueueHandle xQueue, const void * const pvBuffer ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
* <pre> * <pre>
@ -798,7 +905,7 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const
* \defgroup xQueueReceive xQueueReceive * \defgroup xQueueReceive xQueueReceive
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek ); signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
@ -810,10 +917,10 @@ signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvB
* *
* @return The number of messages available in the queue. * @return The number of messages available in the queue.
* *
* \page uxQueueMessagesWaiting uxQueueMessagesWaiting * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue ); unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
@ -824,10 +931,10 @@ unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
* *
* @param xQueue A handle to the queue to be deleted. * @param xQueue A handle to the queue to be deleted.
* *
* \page vQueueDelete vQueueDelete * \defgroup vQueueDelete vQueueDelete
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
void vQueueDelete( xQueueHandle xQueue ); void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
@ -970,6 +1077,93 @@ void vQueueDelete( xQueueHandle xQueue );
*/ */
#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) #define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
/**
* queue. h
* <pre>
portBASE_TYPE xQueueOverwriteFromISR(
xQueueHandle xQueue,
const void * pvItemToQueue,
portBASE_TYPE *pxHigherPriorityTaskWoken
);
* </pre>
*
* A version of xQueueOverwrite() that can be used in an interrupt service
* routine (ISR).
*
* Only for use with queues that can hold a single item - so the queue is either
* empty or full.
*
* Post an item on a queue. If the queue is already full then overwrite the
* value held in the queue. The item is queued by copy, not by reference.
*
* @param xQueue The handle to the queue on which the item is to be posted.
*
* @param pvItemToQueue A pointer to the item that is to be placed on the
* queue. The size of the items the queue will hold was defined when the
* queue was created, so this many bytes will be copied from pvItemToQueue
* into the queue storage area.
*
* @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set
* *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
* to unblock, and the unblocked task has a priority higher than the currently
* running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then
* a context switch should be requested before the interrupt is exited.
*
* @return xQueueOverwriteFromISR() is a macro that calls
* xQueueGenericSendFromISR(), and therefore has the same return values as
* xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be
* returned because xQueueOverwriteFromISR() will write to the queue even when
* the queue is already full.
*
* Example usage:
<pre>
xQueueHandle xQueue;
void vFunction( void *pvParameters )
{
// Create a queue to hold one unsigned long value. It is strongly
// recommended *not* to use xQueueOverwriteFromISR() on queues that can
// contain more than one value, and doing so will trigger an assertion
// if configASSERT() is defined.
xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
}
void vAnInterruptHandler( void )
{
// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
unsigned long ulVarToSend, ulValReceived;
// Write the value 10 to the queue using xQueueOverwriteFromISR().
ulVarToSend = 10;
xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
// The queue is full, but calling xQueueOverwriteFromISR() again will still
// pass because the value held in the queue will be overwritten with the
// new value.
ulVarToSend = 100;
xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
// Reading from the queue will now return 100.
// ...
if( xHigherPrioritytaskWoken == pdTRUE )
{
// Writing to the queue caused a task to unblock and the unblocked task
// has a priority higher than or equal to the priority of the currently
// executing task (the task this interrupt interrupted). Perform a context
// switch so this interrupt returns directly to the unblocked task.
portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
}
}
</pre>
* \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR
* \ingroup QueueManagement
*/
#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE )
/** /**
* queue. h * queue. h
* <pre> * <pre>
@ -1120,7 +1314,7 @@ void vQueueDelete( xQueueHandle xQueue );
* \defgroup xQueueSendFromISR xQueueSendFromISR * \defgroup xQueueSendFromISR xQueueSendFromISR
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ); signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
@ -1209,15 +1403,15 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void *
* \defgroup xQueueReceiveFromISR xQueueReceiveFromISR * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ); signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, const void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/* /*
* Utilities to query queues that are safe to use from an ISR. These utilities * Utilities to query queues that are safe to use from an ISR. These utilities
* should be used only from witin an ISR, or within a critical section. * should be used only from witin an ISR, or within a critical section.
*/ */
signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue ); signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle xQueue ); signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue ); unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
/* /*
@ -1260,16 +1454,16 @@ signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portT
* xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling
* these functions directly. * these functions directly.
*/ */
xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ); xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION;
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ); xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;
void* xQueueGetMutexHolder( xQueueHandle xSemaphore ); void* xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
/* /*
* For internal use only. Use xSemaphoreTakeMutexRecursive() or * For internal use only. Use xSemaphoreTakeMutexRecursive() or
* xSemaphoreGiveMutexRecursive() instead of calling these functions directly. * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
*/ */
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ); portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ); portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ) PRIVILEGED_FUNCTION;
/* /*
* Reset a queue back to its original empty state. pdPASS is returned if the * Reset a queue back to its original empty state. pdPASS is returned if the
@ -1299,15 +1493,29 @@ portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex );
* @param pcName The name to be associated with the handle. This is the * @param pcName The name to be associated with the handle. This is the
* name that the kernel aware debugger will display. * name that the kernel aware debugger will display.
*/ */
#if configQUEUE_REGISTRY_SIZE > 0U #if configQUEUE_REGISTRY_SIZE > 0
void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ); void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ) PRIVILEGED_FUNCTION;
#endif
/*
* The registry is provided as a means for kernel aware debuggers to
* locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add
* a queue, semaphore or mutex handle to the registry if you want the handle
* to be available to a kernel aware debugger, and vQueueUnregisterQueue() to
* remove the queue, semaphore or mutex from the register. If you are not using
* a kernel aware debugger then this function can be ignored.
*
* @param xQueue The handle of the queue being removed from the registry.
*/
#if configQUEUE_REGISTRY_SIZE > 0
void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
#endif #endif
/* /*
* Generic version of the queue creation function, which is in turn called by * Generic version of the queue creation function, which is in turn called by
* any queue, semaphore or mutex creation function or macro. * any queue, semaphore or mutex creation function or macro.
*/ */
xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ); xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;
/* /*
* Queue sets provide a mechanism to allow a task to block (pend) on a read * Queue sets provide a mechanism to allow a task to block (pend) on a read
@ -1357,7 +1565,7 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
* @return If the queue set is created successfully then a handle to the created * @return If the queue set is created successfully then a handle to the created
* queue set is returned. Otherwise NULL is returned. * queue set is returned. Otherwise NULL is returned.
*/ */
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ); xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
/* /*
* Adds a queue or semaphore to a queue set that was previously created by a * Adds a queue or semaphore to a queue set that was previously created by a
@ -1381,7 +1589,7 @@ xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength );
* queue set because it is already a member of a different queue set then pdFAIL * queue set because it is already a member of a different queue set then pdFAIL
* is returned. * is returned.
*/ */
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ); portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
/* /*
* Removes a queue or semaphore from a queue set. A queue or semaphore can only * Removes a queue or semaphore from a queue set. A queue or semaphore can only
@ -1400,7 +1608,7 @@ portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSet
* then pdPASS is returned. If the queue was not in the queue set, or the * then pdPASS is returned. If the queue was not in the queue set, or the
* queue (or semaphore) was not empty, then pdFAIL is returned. * queue (or semaphore) was not empty, then pdFAIL is returned.
*/ */
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ); portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
/* /*
* xQueueSelectFromSet() selects from the members of a queue set a queue or * xQueueSelectFromSet() selects from the members of a queue set a queue or
@ -1436,17 +1644,18 @@ portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQue
* in the queue set that is available, or NULL if no such queue or semaphore * in the queue set that is available, or NULL if no such queue or semaphore
* exists before before the specified block time expires. * exists before before the specified block time expires.
*/ */
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ); xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
/* /*
* A version of xQueueSelectFromSet() that can be used from an ISR. * A version of xQueueSelectFromSet() that can be used from an ISR.
*/ */
xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet ); xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
/* Not public API functions. */ /* Not public API functions. */
void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait ); void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue ); portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
void vQueueSetQueueNumber( xQueueHandle xQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION; void vQueueSetQueueNumber( xQueueHandle xQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION;
unsigned char ucQueueGetQueueNumber( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
unsigned char ucQueueGetQueueType( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; unsigned char ucQueueGetQueueType( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#ifndef SEMAPHORE_H #ifndef SEMAPHORE_H
@ -131,7 +121,7 @@ typedef xQueueHandle xSemaphoreHandle;
( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
if( ( xSemaphore ) != NULL ) \ if( ( xSemaphore ) != NULL ) \
{ \ { \
xSemaphoreGive( ( xSemaphore ) ); \ ( void ) xSemaphoreGive( ( xSemaphore ) ); \
} \ } \
} }
@ -770,7 +760,7 @@ typedef xQueueHandle xSemaphoreHandle;
* *
* @param xSemaphore A handle to the semaphore to be deleted. * @param xSemaphore A handle to the semaphore to be deleted.
* *
* \page vSemaphoreDelete vSemaphoreDelete * \defgroup vSemaphoreDelete vSemaphoreDelete
* \ingroup Semaphores * \ingroup Semaphores
*/ */
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) ( xSemaphore ) ) #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) ( xSemaphore ) )

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,32 +44,32 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#ifndef TASK_H #ifndef INC_TASK_H
#define TASK_H #define INC_TASK_H
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include task.h" #error "include FreeRTOS.h must appear in source files before include task.h"
#endif #endif
#include "portable.h"
#include "list.h" #include "list.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -91,7 +80,7 @@ extern "C" {
* MACROS AND DEFINITIONS * MACROS AND DEFINITIONS
*----------------------------------------------------------*/ *----------------------------------------------------------*/
#define tskKERNEL_VERSION_NUMBER "V7.4.0" #define tskKERNEL_VERSION_NUMBER "V7.5.2"
/** /**
* task. h * task. h
@ -100,11 +89,21 @@ extern "C" {
* returns (via a pointer parameter) an xTaskHandle variable that can then * returns (via a pointer parameter) an xTaskHandle variable that can then
* be used as a parameter to vTaskDelete to delete the task. * be used as a parameter to vTaskDelete to delete the task.
* *
* \page xTaskHandle xTaskHandle * \defgroup xTaskHandle xTaskHandle
* \ingroup Tasks * \ingroup Tasks
*/ */
typedef void * xTaskHandle; typedef void * xTaskHandle;
/* Task states returned by eTaskGetState. */
typedef enum
{
eRunning = 0, /* A task is querying the state of itself, so must be running. */
eReady, /* The task being queried is in a read or pending ready list. */
eBlocked, /* The task being queried is in the Blocked state. */
eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */
eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */
} eTaskState;
/* /*
* Used internally only. * Used internally only.
*/ */
@ -138,15 +137,19 @@ typedef struct xTASK_PARAMTERS
xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ]; xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ];
} xTaskParameters; } xTaskParameters;
/* Task states returned by eTaskGetState. */ /* Used with the uxTaskGetSystemState() function to return the state of each task
typedef enum in the system. */
typedef struct xTASK_STATUS
{ {
eRunning = 0, /* A task is querying the state of itself, so must be running. */ xTaskHandle xHandle; /* The handle of the task to which the rest of the information in the structure relates. */
eReady, /* The task being queried is in a read or pending ready list. */ const signed char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */
eBlocked, /* The task being queried is in the Blocked state. */ unsigned portBASE_TYPE xTaskNumber; /* A number unique to the task. */
eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */
eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */ unsigned portBASE_TYPE uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */
} eTaskState; unsigned portBASE_TYPE uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
unsigned long ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
unsigned short usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
} xTaskStatusType;
/* Possible return values for eTaskConfirmSleepModeStatus(). */ /* Possible return values for eTaskConfirmSleepModeStatus(). */
typedef enum typedef enum
@ -169,7 +172,7 @@ typedef enum
* *
* Macro for forcing a context switch. * Macro for forcing a context switch.
* *
* \page taskYIELD taskYIELD * \defgroup taskYIELD taskYIELD
* \ingroup SchedulerControl * \ingroup SchedulerControl
*/ */
#define taskYIELD() portYIELD() #define taskYIELD() portYIELD()
@ -183,7 +186,7 @@ typedef enum
* NOTE: This may alter the stack (depending on the portable implementation) * NOTE: This may alter the stack (depending on the portable implementation)
* so must be used with care! * so must be used with care!
* *
* \page taskENTER_CRITICAL taskENTER_CRITICAL * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL
* \ingroup SchedulerControl * \ingroup SchedulerControl
*/ */
#define taskENTER_CRITICAL() portENTER_CRITICAL() #define taskENTER_CRITICAL() portENTER_CRITICAL()
@ -197,7 +200,7 @@ typedef enum
* NOTE: This may alter the stack (depending on the portable implementation) * NOTE: This may alter the stack (depending on the portable implementation)
* so must be used with care! * so must be used with care!
* *
* \page taskEXIT_CRITICAL taskEXIT_CRITICAL * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL
* \ingroup SchedulerControl * \ingroup SchedulerControl
*/ */
#define taskEXIT_CRITICAL() portEXIT_CRITICAL() #define taskEXIT_CRITICAL() portEXIT_CRITICAL()
@ -207,7 +210,7 @@ typedef enum
* *
* Macro to disable all maskable interrupts. * Macro to disable all maskable interrupts.
* *
* \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
* \ingroup SchedulerControl * \ingroup SchedulerControl
*/ */
#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()
@ -217,15 +220,15 @@ typedef enum
* *
* Macro to enable microcontroller interrupts. * Macro to enable microcontroller interrupts.
* *
* \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS
* \ingroup SchedulerControl * \ingroup SchedulerControl
*/ */
#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
/* Definitions returned by xTaskGetSchedulerState(). */ /* Definitions returned by xTaskGetSchedulerState(). */
#define taskSCHEDULER_NOT_STARTED 0 #define taskSCHEDULER_NOT_STARTED ( ( portBASE_TYPE ) 0 )
#define taskSCHEDULER_RUNNING 1 #define taskSCHEDULER_RUNNING ( ( portBASE_TYPE ) 1 )
#define taskSCHEDULER_SUSPENDED 2 #define taskSCHEDULER_SUSPENDED ( ( portBASE_TYPE ) 2 )
/*----------------------------------------------------------- /*-----------------------------------------------------------
* TASK CREATION API * TASK CREATION API
@ -1003,7 +1006,7 @@ signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION;
/** /**
* task. h * task. h
* <pre>signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );</pre> * <pre>signed portBASE_TYPE xTaskIsTaskSuspended( const xTaskHandle xTask );</pre>
* *
* Utility task that simply returns pdTRUE if the task referenced by xTask is * Utility task that simply returns pdTRUE if the task referenced by xTask is
* currently in the Suspended state, or pdFALSE if the task referenced by xTask * currently in the Suspended state, or pdFALSE if the task referenced by xTask
@ -1022,7 +1025,7 @@ signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTI
* *
* @return The count of ticks since vTaskStartScheduler was called. * @return The count of ticks since vTaskStartScheduler was called.
* *
* \page xTaskGetTickCount xTaskGetTickCount * \defgroup xTaskGetTickCount xTaskGetTickCount
* \ingroup TaskUtils * \ingroup TaskUtils
*/ */
portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;
@ -1038,7 +1041,7 @@ portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;
* microcontroller being used or interrupt nesting is either not supported or * microcontroller being used or interrupt nesting is either not supported or
* not being used. * not being used.
* *
* \page xTaskGetTickCount xTaskGetTickCount * \defgroup xTaskGetTickCount xTaskGetTickCount
* \ingroup TaskUtils * \ingroup TaskUtils
*/ */
portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;
@ -1052,7 +1055,7 @@ portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;
* has been deleted but not yet freed by the idle task will also be * has been deleted but not yet freed by the idle task will also be
* included in the count. * included in the count.
* *
* \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks
* \ingroup TaskUtils * \ingroup TaskUtils
*/ */
unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;
@ -1066,69 +1069,11 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;
* handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be
* set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available. * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available.
* *
* \page pcTaskGetTaskName pcTaskGetTaskName * \defgroup pcTaskGetTaskName pcTaskGetTaskName
* \ingroup TaskUtils * \ingroup TaskUtils
*/ */
signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery ); signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );
/**
* task. h
* <PRE>void vTaskList( char *pcWriteBuffer );</PRE>
*
* configUSE_TRACE_FACILITY must be defined as 1 for this function to be
* available. See the configuration section for more information.
*
* NOTE: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Lists all the current tasks, along with their current state and stack
* usage high water mark.
*
* Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
* suspended ('S').
*
* @param pcWriteBuffer A buffer into which the above mentioned details
* will be written, in ascii form. This buffer is assumed to be large
* enough to contain the generated report. Approximately 40 bytes per
* task should be sufficient.
*
* \page vTaskList vTaskList
* \ingroup TaskUtils
*/
void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
/**
* task. h
* <PRE>void vTaskGetRunTimeStats( char *pcWriteBuffer );</PRE>
*
* configGENERATE_RUN_TIME_STATS must be defined as 1 for this function
* to be available. The application must also then provide definitions
* for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and
* portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter
* and return the timers current count value respectively. The counter
* should be at least 10 times the frequency of the tick count.
*
* NOTE: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
* accumulated execution time being stored for each task. The resolution
* of the accumulated time value depends on the frequency of the timer
* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
* Calling vTaskGetRunTimeStats() writes the total execution time of each
* task into a buffer, both as an absolute count value and as a percentage
* of the total system execution time.
*
* @param pcWriteBuffer A buffer into which the execution times will be
* written, in ascii form. This buffer is assumed to be large enough to
* contain the generated report. Approximately 40 bytes per task should
* be sufficient.
*
* \page vTaskGetRunTimeStats vTaskGetRunTimeStats
* \ingroup TaskUtils
*/
void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
/** /**
* task.h * task.h
* <PRE>unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask );</PRE> * <PRE>unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask );</PRE>
@ -1211,6 +1156,206 @@ portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter
*/ */
xTaskHandle xTaskGetIdleTaskHandle( void ); xTaskHandle xTaskGetIdleTaskHandle( void );
/**
* configUSE_TRACE_FACILITY must bet defined as 1 in FreeRTOSConfig.h for
* uxTaskGetSystemState() to be available.
*
* uxTaskGetSystemState() populates an xTaskStatusType structure for each task in
* the system. xTaskStatusType structures contain, among other things, members
* for the task handle, task name, task priority, task state, and total amount
* of run time consumed by the task. See the xTaskStatusType structure
* definition in this file for the full member list.
*
* NOTE: This function is intended for debugging use only as its use results in
* the scheduler remaining suspended for an extended period.
*
* @param pxTaskStatusArray A pointer to an array of xTaskStatusType structures.
* The array must contain at least one xTaskStatusType structure for each task
* that is under the control of the RTOS. The number of tasks under the control
* of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function.
*
* @param uxArraySize The size of the array pointed to by the pxTaskStatusArray
* parameter. The size is specified as the number of indexes in the array, or
* the number of xTaskStatusType structures contained in the array, not by the
* number of bytes in the array.
*
* @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in
* FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the
* total run time (as defined by the run time stats clock, see
* http://www.freertos.org/rtos-run-time-stats.html) since the target booted.
* pulTotalRunTime can be set to NULL to omit the total run time information.
*
* @return The number of xTaskStatusType structures that were populated by
* uxTaskGetSystemState(). This should equal the number returned by the
* uxTaskGetNumberOfTasks() API function, but will be zero if the value passed
* in the uxArraySize parameter was too small.
*
* Example usage:
<pre>
// This example demonstrates how a human readable table of run time stats
// information is generated from raw data provided by uxTaskGetSystemState().
// The human readable table is written to pcWriteBuffer
void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
{
xTaskStatusType *pxTaskStatusArray;
volatile unsigned portBASE_TYPE uxArraySize, x;
unsigned long ulTotalRunTime, ulStatsAsPercentage;
// Make sure the write buffer does not contain a string.
*pcWriteBuffer = 0x00;
// Take a snapshot of the number of tasks in case it changes while this
// function is executing.
uxArraySize = uxCurrentNumberOfTasks();
// Allocate a xTaskStatusType structure for each task. An array could be
// allocated statically at compile time.
pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) );
if( pxTaskStatusArray != NULL )
{
// Generate raw status information about each task.
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
// For percentage calculations.
ulTotalRunTime /= 100UL;
// Avoid divide by zero errors.
if( ulTotalRunTime > 0 )
{
// For each populated position in the pxTaskStatusArray array,
// format the raw data as human readable ASCII data
for( x = 0; x < uxArraySize; x++ )
{
// What percentage of the total run time has the task used?
// This will always be rounded down to the nearest integer.
// ulTotalRunTimeDiv100 has already been divided by 100.
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
if( ulStatsAsPercentage > 0UL )
{
sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
}
else
{
// If the percentage is zero here then the task has
// consumed less than 1% of the total run time.
sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
}
pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
}
}
// The array is no longer needed, free the memory it consumes.
vPortFree( pxTaskStatusArray );
}
}
</pre>
*/
unsigned portBASE_TYPE uxTaskGetSystemState( xTaskStatusType *pxTaskStatusArray, unsigned portBASE_TYPE uxArraySize, unsigned long *pulTotalRunTime );
/**
* task. h
* <PRE>void vTaskList( char *pcWriteBuffer );</PRE>
*
* configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must
* both be defined as 1 for this function to be available. See the
* configuration section of the FreeRTOS.org website for more information.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Lists all the current tasks, along with their current state and stack
* usage high water mark.
*
* Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
* suspended ('S').
*
* PLEASE NOTE:
*
* This function is provided for convenience only, and is used by many of the
* demo applications. Do not consider it to be part of the scheduler.
*
* vTaskList() calls uxTaskGetSystemState(), then formats part of the
* uxTaskGetSystemState() output into a human readable table that displays task
* names, states and stack usage.
*
* vTaskList() has a dependency on the sprintf() C library function that might
* bloat the code size, use a lot of stack, and provide different results on
* different platforms. An alternative, tiny, third party, and limited
* functionality implementation of sprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState()
* directly to get access to raw stats data, rather than indirectly through a
* call to vTaskList().
*
* @param pcWriteBuffer A buffer into which the above mentioned details
* will be written, in ascii form. This buffer is assumed to be large
* enough to contain the generated report. Approximately 40 bytes per
* task should be sufficient.
*
* \defgroup vTaskList vTaskList
* \ingroup TaskUtils
*/
void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
/**
* task. h
* <PRE>void vTaskGetRunTimeStats( char *pcWriteBuffer );</PRE>
*
* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS
* must both be defined as 1 for this function to be available. The application
* must also then provide definitions for
* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE
* to configure a peripheral timer/counter and return the timers current count
* value respectively. The counter should be at least 10 times the frequency of
* the tick count.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
* accumulated execution time being stored for each task. The resolution
* of the accumulated time value depends on the frequency of the timer
* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
* Calling vTaskGetRunTimeStats() writes the total execution time of each
* task into a buffer, both as an absolute count value and as a percentage
* of the total system execution time.
*
* NOTE 2:
*
* This function is provided for convenience only, and is used by many of the
* demo applications. Do not consider it to be part of the scheduler.
*
* vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the
* uxTaskGetSystemState() output into a human readable table that displays the
* amount of time each task has spent in the Running state in both absolute and
* percentage terms.
*
* vTaskGetRunTimeStats() has a dependency on the sprintf() C library function
* that might bloat the code size, use a lot of stack, and provide different
* results on different platforms. An alternative, tiny, third party, and
* limited functionality implementation of sprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState() directly
* to get access to raw stats data, rather than indirectly through a call to
* vTaskGetRunTimeStats().
*
* @param pcWriteBuffer A buffer into which the execution times will be
* written, in ascii form. This buffer is assumed to be large enough to
* contain the generated report. Approximately 40 bytes per task should
* be sufficient.
*
* \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats
* \ingroup TaskUtils
*/
void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
/*----------------------------------------------------------- /*-----------------------------------------------------------
* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
*----------------------------------------------------------*/ *----------------------------------------------------------*/
@ -1223,9 +1368,14 @@ xTaskHandle xTaskGetIdleTaskHandle( void );
* Called from the real time kernel tick (either preemptive or cooperative), * Called from the real time kernel tick (either preemptive or cooperative),
* this increments the tick count and checks if any tasks that are blocked * this increments the tick count and checks if any tasks that are blocked
* for a finite period required removing from a blocked list and placing on * for a finite period required removing from a blocked list and placing on
* a ready list. * a ready list. If a non-zero value is returned then a context switch is
* required because either:
* + A task was removed from a blocked list because its timeout had expired,
* or
* + Time slicing is in use and there is a task of equal priority to the
* currently running task.
*/ */
void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION; portBASE_TYPE xTaskIncrementTick( void ) PRIVILEGED_FUNCTION;
/* /*
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
@ -1248,7 +1398,7 @@ void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION;
* portTICK_RATE_MS can be used to convert kernel ticks into a real time * portTICK_RATE_MS can be used to convert kernel ticks into a real time
* period. * period.
*/ */
void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; void vTaskPlaceOnEventList( xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
/* /*
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
@ -1263,7 +1413,7 @@ void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicks
* @return pdTRUE if the task being removed has a higher priority than the task * @return pdTRUE if the task being removed has a higher priority than the task
* making the call, otherwise pdFALSE. * making the call, otherwise pdFALSE.
*/ */
void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; void vTaskPlaceOnEventListRestricted( xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
/* /*
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
@ -1324,13 +1474,13 @@ portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;
* Raises the priority of the mutex holder to that of the calling task should * Raises the priority of the mutex holder to that of the calling task should
* the mutex holder have a priority less than the calling task. * the mutex holder have a priority less than the calling task.
*/ */
void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; void vTaskPriorityInherit( xTaskHandle const pxMutexHolder ) PRIVILEGED_FUNCTION;
/* /*
* Set the priority of a task back to its proper priority in the case that it * Set the priority of a task back to its proper priority in the case that it
* inherited a higher priority while it was holding a semaphore. * inherited a higher priority while it was holding a semaphore.
*/ */
void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; void vTaskPriorityDisinherit( xTaskHandle const pxMutexHolder ) PRIVILEGED_FUNCTION;
/* /*
* Generic version of the task creation function which is in turn called by the * Generic version of the task creation function which is in turn called by the
@ -1376,7 +1526,7 @@ eSleepModeStatus eTaskConfirmSleepModeStatus( void );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* TASK_H */ #endif /* INC_TASK_H */

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
@ -80,9 +70,10 @@
#error "include FreeRTOS.h must appear in source files before include timers.h" #error "include FreeRTOS.h must appear in source files before include timers.h"
#endif #endif
#include "portable.h" /*lint -e537 This headers are only multiply included if the application code
#include "list.h" happens to also be including task.h. */
#include "task.h" #include "task.h"
/*lint +e956 */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -91,10 +82,10 @@ extern "C" {
/* IDs for commands that can be sent/received on the timer queue. These are to /* 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, be used solely through the macros that make up the public software timer API,
as defined below. */ as defined below. */
#define tmrCOMMAND_START 0 #define tmrCOMMAND_START ( ( portBASE_TYPE ) 0 )
#define tmrCOMMAND_STOP 1 #define tmrCOMMAND_STOP ( ( portBASE_TYPE ) 1 )
#define tmrCOMMAND_CHANGE_PERIOD 2 #define tmrCOMMAND_CHANGE_PERIOD ( ( portBASE_TYPE ) 2 )
#define tmrCOMMAND_DELETE 3 #define tmrCOMMAND_DELETE ( ( portBASE_TYPE ) 3 )
/*----------------------------------------------------------- /*-----------------------------------------------------------
* MACROS AND DEFINITIONS * MACROS AND DEFINITIONS
@ -158,7 +149,7 @@ typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );
* structures, or the timer period was set to 0) then 0 is returned. * structures, or the timer period was set to 0) then 0 is returned.
* *
* Example usage: * Example usage:
* * @verbatim
* #define NUM_TIMERS 5 * #define NUM_TIMERS 5
* *
* // An array to hold handles to the created timers. * // An array to hold handles to the created timers.
@ -237,6 +228,7 @@ typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );
* // Should not reach here. * // Should not reach here.
* for( ;; ); * for( ;; );
* } * }
* @endverbatim
*/ */
xTimerHandle xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION; xTimerHandle xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION;
@ -282,7 +274,7 @@ void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
* pdFALSE will be returned if the timer is active. * pdFALSE will be returned if the timer is active.
* *
* Example usage: * Example usage:
* * @verbatim
* // This function assumes xTimer has already been created. * // This function assumes xTimer has already been created.
* void vAFunction( xTimerHandle xTimer ) * void vAFunction( xTimerHandle xTimer )
* { * {
@ -295,6 +287,7 @@ void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
* // xTimer is not active, do something else. * // xTimer is not active, do something else.
* } * }
* } * }
* @endverbatim
*/ */
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
@ -447,7 +440,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* configTIMER_TASK_PRIORITY configuration constant. * configTIMER_TASK_PRIORITY configuration constant.
* *
* Example usage: * Example usage:
* * @verbatim
* // This function assumes xTimer has already been created. If the timer * // This function assumes xTimer has already been created. If the timer
* // referenced by xTimer is already active when it is called, then 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 * // is deleted. If the timer referenced by xTimer is not active when it is
@ -477,6 +470,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* } * }
* } * }
* } * }
* @endverbatim
*/ */
#define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) ) #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )
@ -566,7 +560,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* configuration constant. * configuration constant.
* *
* Example usage: * Example usage:
* * @verbatim
* // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass * // 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 * // without a key being pressed, then the LCD back-light is switched off. In
* // this case, the timer is a one-shot timer. * // this case, the timer is a one-shot timer.
@ -638,6 +632,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* // Should not reach here. * // Should not reach here.
* for( ;; ); * for( ;; );
* } * }
* @endverbatim
*/ */
#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) #define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
@ -671,7 +666,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant. * task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
* *
* Example usage: * Example usage:
* * @verbatim
* // This scenario assumes xBacklightTimer has already been created. When a * // This scenario assumes xBacklightTimer has already been created. When a
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass * // 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 * // without a key being pressed, then the LCD back-light is switched off. In
@ -722,6 +717,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* // depends on the FreeRTOS port being used. * // depends on the FreeRTOS port being used.
* } * }
* } * }
* @endverbatim
*/ */
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
@ -754,7 +750,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* priority is set by the configTIMER_TASK_PRIORITY configuration constant. * priority is set by the configTIMER_TASK_PRIORITY configuration constant.
* *
* Example usage: * Example usage:
* * @verbatim
* // This scenario assumes xTimer has already been created and started. When * // This scenario assumes xTimer has already been created and started. When
* // an interrupt occurs, the timer should be simply stopped. * // an interrupt occurs, the timer should be simply stopped.
* *
@ -784,6 +780,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* // depends on the FreeRTOS port being used. * // depends on the FreeRTOS port being used.
* } * }
* } * }
* @endverbatim
*/ */
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U )
@ -826,7 +823,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* priority is set by the configTIMER_TASK_PRIORITY configuration constant. * priority is set by the configTIMER_TASK_PRIORITY configuration constant.
* *
* Example usage: * Example usage:
* * @verbatim
* // This scenario assumes xTimer has already been created and started. When * // This scenario assumes xTimer has already been created and started. When
* // an interrupt occurs, the period of xTimer should be changed to 500ms. * // an interrupt occurs, the period of xTimer should be changed to 500ms.
* *
@ -856,6 +853,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* // depends on the FreeRTOS port being used. * // depends on the FreeRTOS port being used.
* } * }
* } * }
* @endverbatim
*/ */
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
@ -890,7 +888,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant. * task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
* *
* Example usage: * Example usage:
* * @verbatim
* // This scenario assumes xBacklightTimer has already been created. When a * // This scenario assumes xBacklightTimer has already been created. When a
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass * // 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 * // without a key being pressed, then the LCD back-light is switched off. In
@ -941,6 +939,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
* // depends on the FreeRTOS port being used. * // depends on the FreeRTOS port being used.
* } * }
* } * }
* @endverbatim
*/ */
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
@ -81,12 +71,12 @@
* PUBLIC LIST API documented in list.h * PUBLIC LIST API documented in list.h
*----------------------------------------------------------*/ *----------------------------------------------------------*/
void vListInitialise( xList *pxList ) void vListInitialise( xList * const pxList )
{ {
/* The list structure contains a list item which is used to mark the /* The list structure contains a list item which is used to mark the
end of the list. To initialise the list the list end is inserted end of the list. To initialise the list the list end is inserted
as the only list entry. */ as the only list entry. */
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
/* The list end value is the highest possible value in the list to /* The list end value is the highest possible value in the list to
ensure it remains at the end of the list. */ ensure it remains at the end of the list. */
@ -94,35 +84,33 @@ void vListInitialise( xList *pxList )
/* The list end next and previous pointers point to itself so we know /* The list end next and previous pointers point to itself so we know
when the list is empty. */ when the list is empty. */
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd ); pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U; pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInitialiseItem( xListItem *pxItem ) void vListInitialiseItem( xListItem * const pxItem )
{ {
/* Make sure the list item is not recorded as being on a list. */ /* Make sure the list item is not recorded as being on a list. */
pxItem->pvContainer = NULL; pxItem->pvContainer = NULL;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ) void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem )
{ {
volatile xListItem * pxIndex; xListItem * pxIndex;
/* Insert a new list item into pxList, but rather than sort the list, /* Insert a new list item into pxList, but rather than sort the list,
makes the new list item the last item to be removed by a call to makes the new list item the last item to be removed by a call to
pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by pvListGetOwnerOfNextEntry. */
the pxIndex member. */
pxIndex = pxList->pxIndex; pxIndex = pxList->pxIndex;
pxNewListItem->pxNext = pxIndex->pxNext; pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxList->pxIndex; pxNewListItem->pxPrevious = pxIndex->pxPrevious;
pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem; pxIndex->pxPrevious = pxNewListItem;
pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;
/* Remember which list the item is in. */ /* Remember which list the item is in. */
pxNewListItem->pvContainer = ( void * ) pxList; pxNewListItem->pvContainer = ( void * ) pxList;
@ -131,9 +119,9 @@ volatile xListItem * pxIndex;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInsert( xList *pxList, xListItem *pxNewListItem ) void vListInsert( xList * const pxList, xListItem * const pxNewListItem )
{ {
volatile xListItem *pxIterator; xListItem *pxIterator;
portTickType xValueOfInsertion; portTickType xValueOfInsertion;
/* Insert the new list item into the list, sorted in ulListItem order. */ /* Insert the new list item into the list, sorted in ulListItem order. */
@ -161,14 +149,15 @@ portTickType xValueOfInsertion;
interrupt priories, which can seem counter intuitive. See interrupt priories, which can seem counter intuitive. See
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when 3) Calling an API function from within a critical section or when
the scheduler is suspended. the scheduler is suspended, or calling an API function that does
not end in "FromISR" from an interrupt.
4) Using a queue or semaphore before it has been initialised or 4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?). 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 ) for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
{ {
/* There is nothing to do here, we are just iterating to the /* There is nothing to do here, we are just iterating to the
wanted insertion position. */ wanted insertion position. */
@ -176,9 +165,9 @@ portTickType xValueOfInsertion;
} }
pxNewListItem->pxNext = pxIterator->pxNext; pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator; pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem; pxIterator->pxNext = pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the /* Remember which list the item is in. This allows fast removal of the
item later. */ item later. */
@ -188,7 +177,7 @@ portTickType xValueOfInsertion;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove ) unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove )
{ {
xList * pxList; xList * pxList;

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,28 +44,29 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/* /*
* A sample implementation of pvPortMalloc() and vPortFree() that permits * A sample implementation of pvPortMalloc() and vPortFree() that permits
* allocated blocks to be freed, but does not combine adjacent free blocks * allocated blocks to be freed, but does not combine adjacent free blocks
* into a single larger block (and so will fragment memory). See heap_4.c for * into a single larger block (and so will fragment memory). See heap_4.c for
* an aquivalent that does combine adjacent blocks into single larger blocks. * an equivalent that does combine adjacent blocks into single larger blocks.
* *
* See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the
* memory management pages of http://www.FreeRTOS.org for more information. * memory management pages of http://www.FreeRTOS.org for more information.
@ -113,7 +103,7 @@ typedef struct A_BLOCK_LINK
} xBlockLink; } xBlockLink;
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); static const unsigned short heapSTRUCT_SIZE = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
/* Create a couple of list links to mark the start and end of the list. */ /* Create a couple of list links to mark the start and end of the list. */
@ -174,7 +164,7 @@ void *pvReturn = NULL;
xWantedSize += heapSTRUCT_SIZE; xWantedSize += heapSTRUCT_SIZE;
/* Ensure that blocks are always aligned to the required number of bytes. */ /* Ensure that blocks are always aligned to the required number of bytes. */
if( xWantedSize & portBYTE_ALIGNMENT_MASK ) if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 )
{ {
/* Byte alignment required. */ /* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/* /*
@ -95,8 +85,11 @@ task.h is included from an application file. */
/* Block sizes must not get too small. */ /* Block sizes must not get too small. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
/* Assumes 8bit bytes! */
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
/* A few bytes might be lost to byte aligning the heap start address. */ /* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) #define heapADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
/* Allocate the memory for the heap. */ /* Allocate the memory for the heap. */
static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
@ -129,19 +122,23 @@ static void prvHeapInit( void );
/* The size of the structure placed at the beginning of each allocated memory /* The size of the structure placed at the beginning of each allocated memory
block must by correctly byte aligned. */ block must by correctly byte aligned. */
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); static const unsigned short heapSTRUCT_SIZE = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
/* Ensure the pxEnd pointer will end up on the correct byte alignment. */ /* Ensure the pxEnd pointer will end up on the correct byte alignment. */
static const size_t xTotalHeapSize = ( ( size_t ) configADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); static const size_t xTotalHeapSize = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
/* Create a couple of list links to mark the start and end of the list. */ /* Create a couple of list links to mark the start and end of the list. */
static xBlockLink xStart, *pxEnd = NULL; static xBlockLink xStart, *pxEnd = NULL;
/* Keeps track of the number of free bytes remaining, but says nothing about /* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */ fragmentation. */
static size_t xFreeBytesRemaining = ( ( size_t ) configADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); static size_t xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ /* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
member of an xBlockLink structure is set then the block belongs to the
application. When the bit is free the block is still part of the free heap
space. */
static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -159,25 +156,31 @@ void *pvReturn = NULL;
prvHeapInit(); prvHeapInit();
} }
/* Check the requested block size is not so large that the top bit is
set. The top bit of the block size member of the xBlockLink structure
is used to determine who owns the block - the application or the
kernel, so it must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{
/* The wanted size is increased so it can contain a xBlockLink /* The wanted size is increased so it can contain a xBlockLink
structure in addition to the requested amount of bytes. */ structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 ) if( xWantedSize > 0 )
{ {
xWantedSize += heapSTRUCT_SIZE; xWantedSize += heapSTRUCT_SIZE;
/* Ensure that blocks are always aligned to the required number of /* Ensure that blocks are always aligned to the required number
bytes. */ of bytes. */
if( xWantedSize & portBYTE_ALIGNMENT_MASK ) if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{ {
/* Byte alignment required. */ /* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
} }
} }
if( ( xWantedSize > 0 ) && ( xWantedSize < xTotalHeapSize ) ) if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{ {
/* Traverse the list from the start (lowest address) block until one /* Traverse the list from the start (lowest address) block until
of adequate size is found. */ one of adequate size is found. */
pxPreviousBlock = &xStart; pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock; pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
@ -186,28 +189,30 @@ void *pvReturn = NULL;
pxBlock = pxBlock->pxNextFreeBlock; pxBlock = pxBlock->pxNextFreeBlock;
} }
/* If the end marker was reached then a block of adequate size was /* If the end marker was reached then a block of adequate size
not found. */ was not found. */
if( pxBlock != pxEnd ) if( pxBlock != pxEnd )
{ {
/* Return the memory space - jumping over the xBlockLink structure /* Return the memory space pointed to - jumping over the
at its start. */ xBlockLink structure at its start. */
pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
/* This block is being returned for use so must be taken out of /* This block is being returned for use so must be taken out
the list of free blocks. */ of the list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into two. */ /* If the block is larger than required it can be split into
two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{ {
/* This block is to be split into two. Create a new block /* This block is to be split into two. Create a new
following the number of bytes requested. The void cast is block following the number of bytes requested. The void
used to prevent byte alignment warnings from the compiler. */ cast is used to prevent byte alignment warnings from the
compiler. */
pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize );
/* Calculate the sizes of two blocks split from the single /* Calculate the sizes of two blocks split from the
block. */ single block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize; pxBlock->xBlockSize = xWantedSize;
@ -216,6 +221,12 @@ void *pvReturn = NULL;
} }
xFreeBytesRemaining -= pxBlock->xBlockSize; xFreeBytesRemaining -= pxBlock->xBlockSize;
/* The block is being returned - it is allocated and owned
by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
}
} }
} }
} }
@ -249,6 +260,18 @@ xBlockLink *pxLink;
/* This casting is to keep the compiler from issuing warnings. */ /* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc; pxLink = ( void * ) puc;
/* Check the block is actually allocated. */
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
configASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{
if( pxLink->pxNextFreeBlock == NULL )
{
/* The block is being returned to the heap - it is no longer
allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
/* Add this block to the list of free blocks. */ /* Add this block to the list of free blocks. */
@ -257,6 +280,8 @@ xBlockLink *pxLink;
} }
xTaskResumeAll(); xTaskResumeAll();
} }
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -302,6 +327,9 @@ unsigned char *pucHeapEnd, *pucAlignedHeap;
/* The heap now contains pxEnd. */ /* The heap now contains pxEnd. */
xFreeBytesRemaining -= heapSTRUCT_SIZE; xFreeBytesRemaining -= heapSTRUCT_SIZE;
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -88,24 +78,35 @@ task.h is included from an application file. */
#include "croutine.h" #include "croutine.h"
#endif #endif
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
header files above, but not in this file, in order to generate the correct
privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
/* Constants used with the cRxLock and xTxLock structure members. */ /* Constants used with the cRxLock and xTxLock structure members. */
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 ) #define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 ) #define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )
#define queueERRONEOUS_UNBLOCK ( -1 ) /* When the xQUEUE structure is used to represent a base queue its pcHead and
pcTail members are used as pointers into the queue storage area. When the
/* Effectively make a union out of the xQUEUE structure. */ xQUEUE structure is used to represent a mutex pcHead and pcTail pointers are
not necessary, and the pcHead pointer is set to NULL to indicate that the
pcTail pointer actually points to the mutex holder (if any). Map alternative
names to the pcHead and pcTail structure members to ensure the readability of
the code is maintained despite this dual use of two structure members. An
alternative implementation would be to use a union, but use of a union is
against the coding standard (although an exception to the standard has been
permitted where the dual use also significantly changes the type of the
structure member). */
#define pxMutexHolder pcTail #define pxMutexHolder pcTail
#define uxQueueType pcHead #define uxQueueType pcHead
#define uxRecursiveCallCount pcReadFrom
#define queueQUEUE_IS_MUTEX NULL #define queueQUEUE_IS_MUTEX NULL
/* Semaphores do not actually store or copy data, so have an items size of /* Semaphores do not actually store or copy data, so have an item size of
zero. */ zero. */
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 ) #define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )
#define queueDONT_BLOCK ( ( portTickType ) 0U )
#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U ) #define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U )
@ -119,7 +120,12 @@ typedef struct QueueDefinition
signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
signed char *pcWriteTo; /*< Points to the free next place in the storage area. */ signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */
{
signed char *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */
unsigned portBASE_TYPE uxRecursiveCallCount;/*< Maintains a count of the numebr of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */
} u;
xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
@ -163,10 +169,6 @@ typedef struct QueueDefinition
array position being vacant. */ array position being vacant. */
xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
/* Removes a queue from the registry by simply setting the pcQueueName
member to NULL. */
static void prvQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
#endif /* configQUEUE_REGISTRY_SIZE */ #endif /* configQUEUE_REGISTRY_SIZE */
/* /*
@ -202,14 +204,14 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
/* /*
* Copies an item out of a queue. * Copies an item out of a queue.
*/ */
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION; static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer ) PRIVILEGED_FUNCTION;
#if ( configUSE_QUEUE_SETS == 1 ) #if ( configUSE_QUEUE_SETS == 1 )
/* /*
* Checks to see if a queue is a member of a queue set, and if so, notifies * Checks to see if a queue is a member of a queue set, and if so, notifies
* the queue set that the queue contains data. * the queue set that the queue contains data.
*/ */
static portBASE_TYPE prvNotifyQueueSetContainer( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition ); static portBASE_TYPE prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -235,9 +237,8 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue ) portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue )
{ {
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
taskENTER_CRITICAL(); taskENTER_CRITICAL();
@ -245,7 +246,7 @@ xQUEUE *pxQueue;
pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );
pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U; pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
pxQueue->pcWriteTo = pxQueue->pcHead; pxQueue->pcWriteTo = pxQueue->pcHead;
pxQueue->pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize ); pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );
pxQueue->xRxLock = queueUNLOCKED; pxQueue->xRxLock = queueUNLOCKED;
pxQueue->xTxLock = queueUNLOCKED; pxQueue->xTxLock = queueUNLOCKED;
@ -297,7 +298,7 @@ xQueueHandle xReturn = NULL;
{ {
/* Create the list of pointers to queue items. The queue is one byte /* Create the list of pointers to queue items. The queue is one byte
longer than asked for to make wrap checking easier/faster. */ longer than asked for to make wrap checking easier/faster. */
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes ); pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );
if( pxNewQueue->pcHead != NULL ) if( pxNewQueue->pcHead != NULL )
@ -306,7 +307,7 @@ xQueueHandle xReturn = NULL;
queue type is defined. */ queue type is defined. */
pxNewQueue->uxLength = uxQueueLength; pxNewQueue->uxLength = uxQueueLength;
pxNewQueue->uxItemSize = uxItemSize; pxNewQueue->uxItemSize = uxItemSize;
xQueueGenericReset( pxNewQueue, pdTRUE ); ( void ) xQueueGenericReset( pxNewQueue, pdTRUE );
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
{ {
@ -358,7 +359,7 @@ xQueueHandle xReturn = NULL;
/* Queues used as a mutex no data is actually copied into or out /* Queues used as a mutex no data is actually copied into or out
of the queue. */ of the queue. */
pxNewQueue->pcWriteTo = NULL; pxNewQueue->pcWriteTo = NULL;
pxNewQueue->pcReadFrom = NULL; pxNewQueue->u.pcReadFrom = NULL;
/* Each mutex has a length of 1 (like a binary semaphore) and /* 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 an item size of 0 as nothing is actually copied into or out
@ -388,7 +389,7 @@ xQueueHandle xReturn = NULL;
traceCREATE_MUTEX( pxNewQueue ); traceCREATE_MUTEX( pxNewQueue );
/* Start with the semaphore in the expected state. */ /* Start with the semaphore in the expected state. */
xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK ); ( void ) xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK );
} }
else else
{ {
@ -437,9 +438,8 @@ xQueueHandle xReturn = NULL;
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex )
{ {
portBASE_TYPE xReturn; portBASE_TYPE xReturn;
xQUEUE *pxMutex; xQUEUE * const pxMutex = ( xQUEUE * ) xMutex;
pxMutex = ( xQUEUE * ) xMutex;
configASSERT( pxMutex ); configASSERT( pxMutex );
/* If this is the task that holds the mutex then pxMutexHolder will not /* If this is the task that holds the mutex then pxMutexHolder will not
@ -448,7 +448,7 @@ xQueueHandle xReturn = NULL;
this is the only condition we are interested in it does not matter if this is the only condition we are interested in it does not matter if
pxMutexHolder is accessed simultaneously by another task. Therefore no pxMutexHolder is accessed simultaneously by another task. Therefore no
mutual exclusion is required to test the pxMutexHolder variable. */ mutual exclusion is required to test the pxMutexHolder variable. */
if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() ) if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Not a redundant cast as xTaskHandle is a typedef. */
{ {
traceGIVE_MUTEX_RECURSIVE( pxMutex ); traceGIVE_MUTEX_RECURSIVE( pxMutex );
@ -457,14 +457,14 @@ xQueueHandle xReturn = NULL;
uxRecursiveCallCount is only modified by the mutex holder, and as uxRecursiveCallCount is only modified by the mutex holder, and as
there can only be one, no mutual exclusion is required to modify the there can only be one, no mutual exclusion is required to modify the
uxRecursiveCallCount member. */ uxRecursiveCallCount member. */
( pxMutex->uxRecursiveCallCount )--; ( pxMutex->u.uxRecursiveCallCount )--;
/* Have we unwound the call count? */ /* Have we unwound the call count? */
if( pxMutex->uxRecursiveCallCount == 0 ) if( pxMutex->u.uxRecursiveCallCount == ( unsigned portBASE_TYPE ) 0 )
{ {
/* Return the mutex. This will automatically unblock any other /* Return the mutex. This will automatically unblock any other
task that might be waiting to access the mutex. */ task that might be waiting to access the mutex. */
xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );
} }
xReturn = pdPASS; xReturn = pdPASS;
@ -488,9 +488,8 @@ xQueueHandle xReturn = NULL;
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime )
{ {
portBASE_TYPE xReturn; portBASE_TYPE xReturn;
xQUEUE *pxMutex; xQUEUE * const pxMutex = ( xQUEUE * ) xMutex;
pxMutex = ( xQUEUE * ) xMutex;
configASSERT( pxMutex ); configASSERT( pxMutex );
/* Comments regarding mutual exclusion as per those within /* Comments regarding mutual exclusion as per those within
@ -498,9 +497,9 @@ xQueueHandle xReturn = NULL;
traceTAKE_MUTEX_RECURSIVE( pxMutex ); traceTAKE_MUTEX_RECURSIVE( pxMutex );
if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() ) if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */
{ {
( pxMutex->uxRecursiveCallCount )++; ( pxMutex->u.uxRecursiveCallCount )++;
xReturn = pdPASS; xReturn = pdPASS;
} }
else else
@ -511,7 +510,7 @@ xQueueHandle xReturn = NULL;
we may have blocked to reach here. */ we may have blocked to reach here. */
if( xReturn == pdPASS ) if( xReturn == pdPASS )
{ {
( pxMutex->uxRecursiveCallCount )++; ( pxMutex->u.uxRecursiveCallCount )++;
} }
else else
{ {
@ -531,7 +530,7 @@ xQueueHandle xReturn = NULL;
{ {
xQueueHandle xHandle; xQueueHandle xHandle;
xHandle = xQueueGenericCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); xHandle = xQueueGenericCreate( uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE );
if( xHandle != NULL ) if( xHandle != NULL )
{ {
@ -555,11 +554,11 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const
{ {
signed portBASE_TYPE xEntryTimeSet = pdFALSE; signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut; xTimeOutType xTimeOut;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
/* This function relaxes the coding standard somewhat to allow return /* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest statements within the function itself. This is done in the interest
@ -568,9 +567,11 @@ xQUEUE *pxQueue;
{ {
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Is there room on the queue now? To be running we must be /* Is there room on the queue now? The running task must be
the highest priority task wanting to access the queue. */ the highest priority task wanting to access the queue. If
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) the head item in the queue is to be overwritten then it does
not matter if the queue is full. */
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
{ {
traceQUEUE_SEND( pxQueue ); traceQUEUE_SEND( pxQueue );
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
@ -648,6 +649,10 @@ xQUEUE *pxQueue;
vTaskSetTimeOutState( &xTimeOut ); vTaskSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE; xEntryTimeSet = pdTRUE;
} }
else
{
/* Entry time was already set. */
}
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@ -711,9 +716,8 @@ xQUEUE *pxQueue;
{ {
signed portBASE_TYPE xEntryTimeSet = pdFALSE; signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut; xTimeOutType xTimeOut;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
@ -791,9 +795,8 @@ xQUEUE *pxQueue;
signed portBASE_TYPE xEntryTimeSet = pdFALSE; signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut; xTimeOutType xTimeOut;
signed char *pcOriginalReadPosition; signed char *pcOriginalReadPosition;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
@ -804,7 +807,7 @@ xQUEUE *pxQueue;
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{ {
/* Remember our read position in case we are just peeking. */ /* Remember our read position in case we are just peeking. */
pcOriginalReadPosition = pxQueue->pcReadFrom; pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer ); prvCopyDataFromQueue( pxQueue, pvBuffer );
@ -812,7 +815,7 @@ xQUEUE *pxQueue;
{ {
traceQUEUE_RECEIVE( pxQueue ); traceQUEUE_RECEIVE( pxQueue );
/* We are actually removing data. */ /* Data is actually being removed (not just peeked). */
--( pxQueue->uxMessagesWaiting ); --( pxQueue->uxMessagesWaiting );
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
@ -821,7 +824,7 @@ xQUEUE *pxQueue;
{ {
/* Record the information required to implement /* Record the information required to implement
priority inheritance should it become necessary. */ priority inheritance should it become necessary. */
pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle(); pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle();
} }
} }
#endif #endif
@ -840,7 +843,7 @@ xQUEUE *pxQueue;
/* We are not removing the data, so reset our read /* We are not removing the data, so reset our read
pointer. */ pointer. */
pxQueue->pcReadFrom = pcOriginalReadPosition; pxQueue->u.pcReadFrom = pcOriginalReadPosition;
/* The data is being left in the queue, so see if there are /* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */ any other tasks waiting for the data. */
@ -921,11 +924,27 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void *
{ {
signed portBASE_TYPE xReturn; signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus; unsigned portBASE_TYPE uxSavedInterruptStatus;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
/* RTOS ports that support interrupt nesting have the concept of a maximum
system call (or maximum API call) interrupt priority. Interrupts that are
above the maximum system call priority are keep permanently enabled, even
when the RTOS kernel is in a critical section, but cannot make any calls to
FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has been
assigned a priority above the configured maximum system call priority.
Only FreeRTOS functions that end in FromISR can be called from interrupts
that have been assigned a priority at or (logically) below the maximum
system call interrupt priority. FreeRTOS maintains a separate interrupt
safe API to ensure interrupt entry is as fast and as simple as possible.
More information (albeit Cortex-M specific) is provided on the following
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
/* Similar to xQueueGenericSend, except we don't block if there is no room /* 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 in the queue. Also we don't directly wake a task that was blocked on a
@ -934,7 +953,7 @@ xQUEUE *pxQueue;
by this post). */ by this post). */
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{ {
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
{ {
traceQUEUE_SEND_FROM_ISR( pxQueue ); traceQUEUE_SEND_FROM_ISR( pxQueue );
@ -1013,14 +1032,13 @@ xQUEUE *pxQueue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
{ {
signed portBASE_TYPE xEntryTimeSet = pdFALSE; signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut; xTimeOutType xTimeOut;
signed char *pcOriginalReadPosition; signed char *pcOriginalReadPosition;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
@ -1036,8 +1054,9 @@ xQUEUE *pxQueue;
the highest priority task wanting to access the queue. */ the highest priority task wanting to access the queue. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{ {
/* Remember our read position in case we are just peeking. */ /* Remember the read position in case the queue is only being
pcOriginalReadPosition = pxQueue->pcReadFrom; peeked. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer ); prvCopyDataFromQueue( pxQueue, pvBuffer );
@ -1045,7 +1064,7 @@ xQUEUE *pxQueue;
{ {
traceQUEUE_RECEIVE( pxQueue ); traceQUEUE_RECEIVE( pxQueue );
/* We are actually removing data. */ /* Actually removing data, not just peeking. */
--( pxQueue->uxMessagesWaiting ); --( pxQueue->uxMessagesWaiting );
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
@ -1054,7 +1073,7 @@ xQUEUE *pxQueue;
{ {
/* Record the information required to implement /* Record the information required to implement
priority inheritance should it become necessary. */ priority inheritance should it become necessary. */
pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle(); pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle(); /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */
} }
} }
#endif #endif
@ -1073,7 +1092,7 @@ xQUEUE *pxQueue;
/* The data is not being removed, so reset the read /* The data is not being removed, so reset the read
pointer. */ pointer. */
pxQueue->pcReadFrom = pcOriginalReadPosition; pxQueue->u.pcReadFrom = pcOriginalReadPosition;
/* The data is being left in the queue, so see if there are /* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */ any other tasks waiting for the data. */
@ -1109,6 +1128,10 @@ xQUEUE *pxQueue;
vTaskSetTimeOutState( &xTimeOut ); vTaskSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE; xEntryTimeSet = pdTRUE;
} }
else
{
/* Entry time was already set. */
}
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@ -1164,19 +1187,34 @@ xQUEUE *pxQueue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, const void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken )
{ {
signed portBASE_TYPE xReturn; signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus; unsigned portBASE_TYPE uxSavedInterruptStatus;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* RTOS ports that support interrupt nesting have the concept of a maximum
system call (or maximum API call) interrupt priority. Interrupts that are
above the maximum system call priority are keep permanently enabled, even
when the RTOS kernel is in a critical section, but cannot make any calls to
FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has been
assigned a priority above the configured maximum system call priority.
Only FreeRTOS functions that end in FromISR can be called from interrupts
that have been assigned a priority at or (logically) below the maximum
system call interrupt priority. FreeRTOS maintains a separate interrupt
safe API to ensure interrupt entry is as fast and as simple as possible.
More information (albeit Cortex-M specific) is provided on the following
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{ {
/* We cannot block from an ISR, so check there is data available. */ /* Cannot block in an ISR, so check there is data available. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{ {
traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
@ -1184,9 +1222,10 @@ xQUEUE *pxQueue;
prvCopyDataFromQueue( pxQueue, pvBuffer ); prvCopyDataFromQueue( pxQueue, pvBuffer );
--( pxQueue->uxMessagesWaiting ); --( pxQueue->uxMessagesWaiting );
/* If the queue is locked we will not modify the event list. Instead /* If the queue is locked the event list will not be modified.
we update the lock count so the task that unlocks the queue will know Instead update the lock count so the task that unlocks the queue
that an ISR has removed data while the queue was locked. */ will know that an ISR has removed data while the queue was
locked. */
if( pxQueue->xRxLock == queueUNLOCKED ) if( pxQueue->xRxLock == queueUNLOCKED )
{ {
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
@ -1223,6 +1262,59 @@ xQUEUE *pxQueue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
signed portBASE_TYPE xQueuePeekFromISR( xQueueHandle xQueue, const void * const pvBuffer )
{
signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus;
signed char *pcOriginalReadPosition;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* RTOS ports that support interrupt nesting have the concept of a maximum
system call (or maximum API call) interrupt priority. Interrupts that are
above the maximum system call priority are keep permanently enabled, even
when the RTOS kernel is in a critical section, but cannot make any calls to
FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has been
assigned a priority above the configured maximum system call priority.
Only FreeRTOS functions that end in FromISR can be called from interrupts
that have been assigned a priority at or (logically) below the maximum
system call interrupt priority. FreeRTOS maintains a separate interrupt
safe API to ensure interrupt entry is as fast and as simple as possible.
More information (albeit Cortex-M specific) is provided on the following
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Cannot block in an ISR, so check there is data available. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
traceQUEUE_PEEK_FROM_ISR( pxQueue );
/* Remember the read position so it can be reset as nothing is
actually being removed from the queue. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer );
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue );
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
return xReturn;
}
/*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue ) unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue )
{ {
unsigned portBASE_TYPE uxReturn; unsigned portBASE_TYPE uxReturn;
@ -1234,7 +1326,7 @@ unsigned portBASE_TYPE uxReturn;
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
return uxReturn; return uxReturn;
} } /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue ) unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue )
@ -1246,20 +1338,19 @@ unsigned portBASE_TYPE uxReturn;
uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting; uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting;
return uxReturn; return uxReturn;
} } /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vQueueDelete( xQueueHandle xQueue ) void vQueueDelete( xQueueHandle xQueue )
{ {
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
traceQUEUE_DELETE( pxQueue ); traceQUEUE_DELETE( pxQueue );
#if ( configQUEUE_REGISTRY_SIZE > 0 ) #if ( configQUEUE_REGISTRY_SIZE > 0 )
{ {
prvQueueUnregisterQueue( pxQueue ); vQueueUnregisterQueue( pxQueue );
} }
#endif #endif
vPortFree( pxQueue->pcHead ); vPortFree( pxQueue->pcHead );
@ -1310,24 +1401,36 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
pxQueue->pxMutexHolder = NULL; pxQueue->pxMutexHolder = NULL;
} }
} }
#endif #endif /* configUSE_MUTEXES */
} }
else if( xPosition == queueSEND_TO_BACK ) else if( xPosition == queueSEND_TO_BACK )
{ {
memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. */
pxQueue->pcWriteTo += pxQueue->uxItemSize; pxQueue->pcWriteTo += pxQueue->uxItemSize;
if( pxQueue->pcWriteTo >= pxQueue->pcTail ) if( pxQueue->pcWriteTo >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
{ {
pxQueue->pcWriteTo = pxQueue->pcHead; pxQueue->pcWriteTo = pxQueue->pcHead;
} }
} }
else else
{ {
memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); ( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
pxQueue->pcReadFrom -= pxQueue->uxItemSize; pxQueue->u.pcReadFrom -= pxQueue->uxItemSize;
if( pxQueue->pcReadFrom < pxQueue->pcHead ) if( pxQueue->u.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
{ {
pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
}
if( xPosition == queueOVERWRITE )
{
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
/* An item is not being added but overwritten, so subtract
one from the recorded number of items in the queue so when
one is added again below the number of recorded items remains
correct. */
--( pxQueue->uxMessagesWaiting );
}
} }
} }
@ -1335,16 +1438,16 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer )
{ {
if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX ) if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
{ {
pxQueue->pcReadFrom += pxQueue->uxItemSize; pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
if( pxQueue->pcReadFrom >= pxQueue->pcTail ) if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */
{ {
pxQueue->pcReadFrom = pxQueue->pcHead; pxQueue->u.pcReadFrom = pxQueue->pcHead;
} }
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -1454,7 +1557,7 @@ signed portBASE_TYPE xReturn;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
if( pxQueue->uxMessagesWaiting == 0 ) if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
{ {
xReturn = pdTRUE; xReturn = pdTRUE;
} }
@ -1474,7 +1577,7 @@ signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue )
signed portBASE_TYPE xReturn; signed portBASE_TYPE xReturn;
configASSERT( xQueue ); configASSERT( xQueue );
if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == 0 ) if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
{ {
xReturn = pdTRUE; xReturn = pdTRUE;
} }
@ -1484,7 +1587,7 @@ signed portBASE_TYPE xReturn;
} }
return xReturn; return xReturn;
} } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static signed portBASE_TYPE prvIsQueueFull( const xQUEUE *pxQueue ) static signed portBASE_TYPE prvIsQueueFull( const xQUEUE *pxQueue )
@ -1523,7 +1626,7 @@ signed portBASE_TYPE xReturn;
} }
return xReturn; return xReturn;
} } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_CO_ROUTINES == 1 ) #if ( configUSE_CO_ROUTINES == 1 )
@ -1531,9 +1634,7 @@ signed portBASE_TYPE xReturn;
signed portBASE_TYPE xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait ) signed portBASE_TYPE xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait )
{ {
signed portBASE_TYPE xReturn; signed portBASE_TYPE xReturn;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
/* If the queue is already full we may have to block. A critical section /* If the queue is already full we may have to block. A critical section
is required to prevent an interrupt removing something from the queue is required to prevent an interrupt removing something from the queue
@ -1602,9 +1703,7 @@ signed portBASE_TYPE xReturn;
signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait ) signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait )
{ {
signed portBASE_TYPE xReturn; signed portBASE_TYPE xReturn;
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
/* If the queue is already empty we may have to block. A critical section /* If the queue is already empty we may have to block. A critical section
is required to prevent an interrupt adding something to the queue is required to prevent an interrupt adding something to the queue
@ -1637,13 +1736,13 @@ signed portBASE_TYPE xReturn;
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{ {
/* Data is available from the queue. */ /* Data is available from the queue. */
pxQueue->pcReadFrom += pxQueue->uxItemSize; pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
if( pxQueue->pcReadFrom >= pxQueue->pcTail ) if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )
{ {
pxQueue->pcReadFrom = pxQueue->pcHead; pxQueue->u.pcReadFrom = pxQueue->pcHead;
} }
--( pxQueue->uxMessagesWaiting ); --( pxQueue->uxMessagesWaiting );
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
xReturn = pdPASS; xReturn = pdPASS;
@ -1677,9 +1776,7 @@ signed portBASE_TYPE xReturn;
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
{ {
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
/* Cannot block within an ISR so if there is no space on the queue then /* Cannot block within an ISR so if there is no space on the queue then
exit without doing anything. */ exit without doing anything. */
@ -1712,22 +1809,20 @@ signed portBASE_TYPE xReturn;
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken ) signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
{ {
signed portBASE_TYPE xReturn; signed portBASE_TYPE xReturn;
xQUEUE * pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
/* We cannot block from an ISR, so check there is data available. If /* We cannot block from an ISR, so check there is data available. If
not then just leave without doing anything. */ not then just leave without doing anything. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{ {
/* Copy the data from the queue. */ /* Copy the data from the queue. */
pxQueue->pcReadFrom += pxQueue->uxItemSize; pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
if( pxQueue->pcReadFrom >= pxQueue->pcTail ) if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )
{ {
pxQueue->pcReadFrom = pxQueue->pcHead; pxQueue->u.pcReadFrom = pxQueue->pcHead;
} }
--( pxQueue->uxMessagesWaiting ); --( pxQueue->uxMessagesWaiting );
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
if( ( *pxCoRoutineWoken ) == pdFALSE ) if( ( *pxCoRoutineWoken ) == pdFALSE )
{ {
@ -1778,7 +1873,7 @@ signed portBASE_TYPE xReturn;
#if ( configQUEUE_REGISTRY_SIZE > 0 ) #if ( configQUEUE_REGISTRY_SIZE > 0 )
static void prvQueueUnregisterQueue( xQueueHandle xQueue ) void vQueueUnregisterQueue( xQueueHandle xQueue )
{ {
unsigned portBASE_TYPE ux; unsigned portBASE_TYPE ux;
@ -1794,7 +1889,7 @@ signed portBASE_TYPE xReturn;
} }
} }
} } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
#endif /* configQUEUE_REGISTRY_SIZE */ #endif /* configQUEUE_REGISTRY_SIZE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -1803,9 +1898,7 @@ signed portBASE_TYPE xReturn;
void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait ) void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait )
{ {
xQUEUE *pxQueue; xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
pxQueue = ( xQUEUE * ) xQueue;
/* This function should not be called by application code hence the /* 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 'Restricted' in its name. It is not part of the public API. It is
@ -1855,6 +1948,13 @@ signed portBASE_TYPE xReturn;
if( ( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) if( ( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL )
{ {
/* Cannot add a queue/semaphore to more than one queue set. */
xReturn = pdFAIL;
}
else if( ( ( xQUEUE * ) xQueueOrSemaphore )->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 )
{
/* Cannot add a queue/semaphore to a queue set if there are already
items in the queue/semaphore. */
xReturn = pdFAIL; xReturn = pdFAIL;
} }
else else
@ -1878,16 +1978,14 @@ signed portBASE_TYPE xReturn;
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
{ {
portBASE_TYPE xReturn; portBASE_TYPE xReturn;
xQUEUE *pxQueueOrSemaphore; xQUEUE * const pxQueueOrSemaphore = ( xQUEUE * ) xQueueOrSemaphore;
pxQueueOrSemaphore = ( xQUEUE * ) xQueueOrSemaphore;
if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
{ {
/* The queue was not a member of the set. */ /* The queue was not a member of the set. */
xReturn = pdFAIL; xReturn = pdFAIL;
} }
else if( pxQueueOrSemaphore->uxMessagesWaiting != 0 ) else if( pxQueueOrSemaphore->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 )
{ {
/* It is dangerous to remove a queue from a set when the queue is /* It is dangerous to remove a queue from a set when the queue is
not empty because the queue set will still hold pending events for not empty because the queue set will still hold pending events for
@ -1906,7 +2004,7 @@ signed portBASE_TYPE xReturn;
} }
return xReturn; return xReturn;
} } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */
#endif /* configUSE_QUEUE_SETS */ #endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -1917,7 +2015,7 @@ signed portBASE_TYPE xReturn;
{ {
xQueueSetMemberHandle xReturn = NULL; xQueueSetMemberHandle xReturn = NULL;
xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE ); ( void ) xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */
return xReturn; return xReturn;
} }
@ -1930,7 +2028,7 @@ signed portBASE_TYPE xReturn;
{ {
xQueueSetMemberHandle xReturn = NULL; xQueueSetMemberHandle xReturn = NULL;
xQueueReceiveFromISR( ( xQueueHandle ) xQueueSet, &xReturn, NULL ); ( void ) xQueueReceiveFromISR( ( xQueueHandle ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */
return xReturn; return xReturn;
} }
@ -1939,7 +2037,7 @@ signed portBASE_TYPE xReturn;
#if ( configUSE_QUEUE_SETS == 1 ) #if ( configUSE_QUEUE_SETS == 1 )
static portBASE_TYPE prvNotifyQueueSetContainer( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition ) static portBASE_TYPE prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition )
{ {
xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer; xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;
portBASE_TYPE xReturn = pdFALSE; portBASE_TYPE xReturn = pdFALSE;

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,25 +44,25 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -88,7 +77,19 @@ task.h is included from an application file. */
#include "timers.h" #include "timers.h"
#include "StackMacros.h" #include "StackMacros.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
header files above, but not in this file, in order to generate the correct
privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 )
/* At the bottom of this file are two optional functions that can be used
to generate human readable text from the raw data generated by the
uxTaskGetSystemState() function. Note the formatting functions are provided
for convenience only, and are NOT considered part of the kernel. */
#include <stdio.h>
#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */
/* Sanity check the configuration. */ /* Sanity check the configuration. */
#if configUSE_TICKLESS_IDLE != 0 #if configUSE_TICKLESS_IDLE != 0
@ -146,6 +147,17 @@ typedef struct tskTaskControlBlock
unsigned long ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ unsigned long ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
#endif #endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
/* Allocate a Newlib reent structure that is specific to this task.
Note Newlib support has been included by popular demand, but is not
used by the FreeRTOS maintainers themselves. FreeRTOS is not
responsible for resulting newlib operation. User must be familiar with
newlib and must provide system-wide implementations of the necessary
stubs. Be warned that (at the time of writing) the current newlib design
implements a system-wide malloc() that must be provided with locks. */
struct _reent xNewLib_reent;
#endif
} tskTCB; } tskTCB;
@ -157,16 +169,18 @@ typedef struct tskTaskControlBlock
#define static #define static
#endif #endif
/*lint -e956 */ /*lint -e956 A manual analysis and inspection has been used to determine which
static variables must be declared volatile. */
PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL; PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;
/* Lists for ready and blocked tasks. --------------------*/ /* Lists for ready and blocked tasks. --------------------*/
PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */ PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */
PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */ PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */
PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */ PRIVILEGED_DATA static xList * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */
PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */ PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */
#if ( INCLUDE_vTaskDelete == 1 ) #if ( INCLUDE_vTaskDelete == 1 )
@ -187,28 +201,27 @@ PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been r
#endif #endif
/* File private variables. --------------------------------*/ /* Other file private variables. --------------------------------*/
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U; PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U;
PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U; PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U;
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY; PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE; PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE; PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0U; PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxPendedTicks = ( unsigned portBASE_TYPE ) 0U;
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE; PRIVILEGED_DATA static volatile portBASE_TYPE xYieldPending = pdFALSE;
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0; PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U; PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U;
PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY; PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = portMAX_DELAY;
#if ( configGENERATE_RUN_TIME_STATS == 1 ) #if ( configGENERATE_RUN_TIME_STATS == 1 )
PRIVILEGED_DATA static char pcStatsString[ 50 ] ;
PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
PRIVILEGED_DATA static unsigned long ulTotalRunTime; /*< Holds the total amount of execution time as defined by the run time counter clock. */ PRIVILEGED_DATA static unsigned long ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTimeDiv100 ) PRIVILEGED_FUNCTION;
#endif #endif
/*lint +e956 */
/* Debugging and trace facilities private variables and macros. ------------*/ /* Debugging and trace facilities private variables and macros. ------------*/
/* /*
@ -303,78 +316,52 @@ PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = ( portTic
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/*
* Place the task represented by pxTCB into the appropriate ready queue for
* the task. It is inserted at the end of the list. One quirk of this is
* that if the task being inserted is at the same priority as the currently
* executing task, then it will only be rescheduled after the currently
* executing task has been rescheduled.
*/
#define prvAddTaskToReadyQueue( pxTCB ) \
traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick
* Macro that looks at the list of tasks that are currently delayed to see if count overflows. */
* any require waking. #define taskSWITCH_DELAYED_LISTS() \
*
* Tasks are stored in the queue in the order of their wake time - meaning
* once one tasks has been found whose timer has not expired we need not look
* any further down the list.
*/
#define prvCheckDelayedTasks() \
{ \ { \
portTickType xItemValue; \ xList *pxTemp; \
\
/* The delayed tasks list should be empty when the lists are switched. */ \
configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \
\
pxTemp = pxDelayedTaskList; \
pxDelayedTaskList = pxOverflowDelayedTaskList; \
pxOverflowDelayedTaskList = pxTemp; \
xNumOfOverflows++; \
\ \
/* 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 ) \ if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \
{ \ { \
/* The delayed list is empty. Set xNextTaskUnblockTime to the \ /* The new current delayed list is empty. Set \
maximum possible value so it is extremely unlikely that the \ xNextTaskUnblockTime to the maximum possible value so it is \
if( xTickCount >= xNextTaskUnblockTime ) test will pass next \ extremely unlikely that the \
time through. */ \ if( xTickCount >= xNextTaskUnblockTime ) test will pass until \
there is an item in the delayed list. */ \
xNextTaskUnblockTime = portMAX_DELAY; \ xNextTaskUnblockTime = portMAX_DELAY; \
break; \
} \ } \
else \ else \
{ \ { \
/* The delayed list is not empty, get the value of the item at \ /* The new current delayed list is not empty, get the value of \
the head of the delayed list. This is the time at which the \ the item at the head of the delayed list. This is the time at \
task at the head of the delayed list should be removed from \ which the task at the head of the delayed list should be removed \
the Blocked state. */ \ from the Blocked state. */ \
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \ xNextTaskUnblockTime = 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. */ \
uxListRemove( &( pxTCB->xGenericListItem ) ); \
\
/* Is the task waiting on an event also? */ \
if( pxTCB->xEventListItem.pvContainer != NULL ) \
{ \
uxListRemove( &( pxTCB->xEventListItem ) ); \
} \
prvAddTaskToReadyQueue( pxTCB ); \
} \
} \
} \ } \
} }
/*-----------------------------------------------------------*/
/*
* Place the task represented by pxTCB into the appropriate ready list for
* the task. It is inserted at the end of the list.
*/
#define prvAddTaskToReadyList( pxTCB ) \
traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \
vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -449,17 +436,16 @@ static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGE
static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION; static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION;
/* /*
* Called from vTaskList. vListTasks details all the tasks currently under * Fills an xTaskStatusType structure with information on each task that is
* control of the scheduler. The tasks may be in one of a number of lists. * referenced from the pxList list (which may be a ready list, a delayed list,
* prvListTaskWithinSingleList accepts a list and details the tasks from * a suspended list, etc.).
* within just that list.
* *
* THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
* NORMAL APPLICATION CODE. * NORMAL APPLICATION CODE.
*/ */
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) PRIVILEGED_FUNCTION; static unsigned portBASE_TYPE prvListTaskWithinSingleList( xTaskStatusType *pxTaskStatusArray, xList *pxList, eTaskState eState ) PRIVILEGED_FUNCTION;
#endif #endif
@ -470,7 +456,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TY
*/ */
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION; static unsigned short prvTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION;
#endif #endif
@ -489,8 +475,6 @@ static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TY
#endif #endif
/*lint +e956 */
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 ) 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 )
{ {
signed portBASE_TYPE xReturn; signed portBASE_TYPE xReturn;
@ -528,7 +512,7 @@ tskTCB * pxNewTCB;
#if( portSTACK_GROWTH < 0 ) #if( portSTACK_GROWTH < 0 )
{ {
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 ); pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 );
pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */
/* Check the alignment of the calculated top of stack is correct. */ /* Check the alignment of the calculated top of stack is correct. */
configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
@ -564,9 +548,6 @@ tskTCB * pxNewTCB;
} }
#endif /* portUSING_MPU_WRAPPERS */ #endif /* portUSING_MPU_WRAPPERS */
/* Check the alignment of the initialised stack. */
portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
if( ( void * ) pxCreatedTask != NULL ) if( ( void * ) pxCreatedTask != NULL )
{ {
/* Pass the TCB out - in an anonymous way. The calling function/ /* Pass the TCB out - in an anonymous way. The calling function/
@ -575,8 +556,8 @@ tskTCB * pxNewTCB;
*pxCreatedTask = ( xTaskHandle ) pxNewTCB; *pxCreatedTask = ( xTaskHandle ) pxNewTCB;
} }
/* We are going to manipulate the task queues to add this task to a /* Ensure interrupts don't access the task lists while they are being
ready list, so must make sure no interrupts occur. */ updated. */
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
uxCurrentNumberOfTasks++; uxCurrentNumberOfTasks++;
@ -608,13 +589,6 @@ tskTCB * pxNewTCB;
} }
} }
/* Remember the top priority to make context switching faster. Use
the priority in pxNewTCB as this has been capped to a valid value. */
if( pxNewTCB->uxPriority > uxTopUsedPriority )
{
uxTopUsedPriority = pxNewTCB->uxPriority;
}
uxTaskNumber++; uxTaskNumber++;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
@ -625,7 +599,7 @@ tskTCB * pxNewTCB;
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */
traceTASK_CREATE( pxNewTCB ); traceTASK_CREATE( pxNewTCB );
prvAddTaskToReadyQueue( pxNewTCB ); prvAddTaskToReadyList( pxNewTCB );
xReturn = pdPASS; xReturn = pdPASS;
portSETUP_TCB( pxNewTCB ); portSETUP_TCB( pxNewTCB );
@ -663,13 +637,6 @@ tskTCB * pxNewTCB;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Ensure a yield is performed if the current task is being
deleted. */
if( xTaskToDelete == pxCurrentTCB )
{
xTaskToDelete = NULL;
}
/* If null is passed in here then we are deleting ourselves. */ /* If null is passed in here then we are deleting ourselves. */
pxTCB = prvGetTCBFromHandle( xTaskToDelete ); pxTCB = prvGetTCBFromHandle( xTaskToDelete );
@ -677,18 +644,18 @@ tskTCB * pxNewTCB;
This will stop the task from be scheduled. The idle task will check This will stop the task from be scheduled. The idle task will check
the termination list and free up any memory allocated by the the termination list and free up any memory allocated by the
scheduler for the TCB and stack. */ scheduler for the TCB and stack. */
if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
taskRESET_READY_PRIORITY( pxTCB->uxPriority ); taskRESET_READY_PRIORITY( pxTCB->uxPriority );
} }
/* Is the task waiting on an event also? */ /* Is the task waiting on an event also? */
if( pxTCB->xEventListItem.pvContainer != NULL ) if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{ {
uxListRemove( &( pxTCB->xEventListItem ) ); ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
} }
vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) ); vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );
/* Increment the ucTasksDeleted variable so the idle task knows /* Increment the ucTasksDeleted variable so the idle task knows
there is a task that has been deleted and that it should therefore there is a task that has been deleted and that it should therefore
@ -706,7 +673,7 @@ tskTCB * pxNewTCB;
/* Force a reschedule if we have just deleted the current task. */ /* Force a reschedule if we have just deleted the current task. */
if( xSchedulerRunning != pdFALSE ) if( xSchedulerRunning != pdFALSE )
{ {
if( ( void * ) xTaskToDelete == NULL ) if( pxTCB == pxCurrentTCB )
{ {
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
@ -728,17 +695,21 @@ tskTCB * pxNewTCB;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
/* Minor optimisation. The tick count cannot change in this
block. */
const portTickType xConstTickCount = xTickCount;
/* Generate the tick time at which the task wants to wake. */ /* Generate the tick time at which the task wants to wake. */
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
if( xTickCount < *pxPreviousWakeTime ) if( xConstTickCount < *pxPreviousWakeTime )
{ {
/* The tick count has overflowed since this function was /* The tick count has overflowed since this function was
lasted called. In this case the only time we should ever lasted called. In this case the only time we should ever
actually delay is if the wake time has also overflowed, actually delay is if the wake time has also overflowed,
and the wake time is greater than the tick time. When this and the wake time is greater than the tick time. When this
is the case it is as if neither time had overflowed. */ is the case it is as if neither time had overflowed. */
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) ) if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
{ {
xShouldDelay = pdTRUE; xShouldDelay = pdTRUE;
} }
@ -748,7 +719,7 @@ tskTCB * pxNewTCB;
/* The tick time has not overflowed. In this case we will /* The tick time has not overflowed. In this case we will
delay if either the wake time has overflowed, and/or the delay if either the wake time has overflowed, and/or the
tick time is less than the wake time. */ tick time is less than the wake time. */
if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) ) if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
{ {
xShouldDelay = pdTRUE; xShouldDelay = pdTRUE;
} }
@ -764,7 +735,7 @@ tskTCB * pxNewTCB;
/* We must remove ourselves from the ready list before adding /* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for ourselves to the blocked list as the same list item is used for
both lists. */ both lists. */
if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
/* The current task must be in a ready list, so there is /* The current task must be in a ready list, so there is
no need to check, and the port reset macro can be called no need to check, and the port reset macro can be called
@ -817,7 +788,7 @@ tskTCB * pxNewTCB;
/* We must remove ourselves from the ready list before adding /* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for ourselves to the blocked list as the same list item is used for
both lists. */ both lists. */
if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
/* The current task must be in a ready list, so there is /* The current task must be in a ready list, so there is
no need to check, and the port reset macro can be called no need to check, and the port reset macro can be called
@ -846,9 +817,7 @@ tskTCB * pxNewTCB;
{ {
eTaskState eReturn; eTaskState eReturn;
xList *pxStateList; xList *pxStateList;
tskTCB *pxTCB; const tskTCB * const pxTCB = ( tskTCB * ) xTask;
pxTCB = ( tskTCB * ) xTask;
if( pxTCB == pxCurrentTCB ) if( pxTCB == pxCurrentTCB )
{ {
@ -929,61 +898,71 @@ tskTCB * pxNewTCB;
void vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority ) void vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority )
{ {
tskTCB *pxTCB; tskTCB *pxTCB;
unsigned portBASE_TYPE uxCurrentPriority, uxPriorityUsedOnEntry; unsigned portBASE_TYPE uxCurrentBasePriority, uxPriorityUsedOnEntry;
portBASE_TYPE xYieldRequired = pdFALSE; portBASE_TYPE xYieldRequired = pdFALSE;
configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
/* Ensure the new priority is valid. */ /* Ensure the new priority is valid. */
if( uxNewPriority >= configMAX_PRIORITIES ) if( uxNewPriority >= ( unsigned portBASE_TYPE ) configMAX_PRIORITIES )
{ {
uxNewPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; uxNewPriority = ( unsigned portBASE_TYPE ) configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;
} }
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
if( xTask == ( xTaskHandle ) pxCurrentTCB ) /* If null is passed in here then it is the priority of the calling
{ task that is being changed. */
xTask = NULL;
}
/* If null is passed in here then we are changing the
priority of the calling function. */
pxTCB = prvGetTCBFromHandle( xTask ); pxTCB = prvGetTCBFromHandle( xTask );
traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
{ {
uxCurrentPriority = pxTCB->uxBasePriority; uxCurrentBasePriority = pxTCB->uxBasePriority;
} }
#else #else
{ {
uxCurrentPriority = pxTCB->uxPriority; uxCurrentBasePriority = pxTCB->uxPriority;
} }
#endif #endif
if( uxCurrentPriority != uxNewPriority ) if( uxCurrentBasePriority != uxNewPriority )
{ {
/* The priority change may have readied a task of higher /* The priority change may have readied a task of higher
priority than the calling task. */ priority than the calling task. */
if( uxNewPriority > uxCurrentPriority ) if( uxNewPriority > uxCurrentBasePriority )
{ {
if( xTask != NULL ) if( pxTCB != pxCurrentTCB )
{
/* The priority of a task other than the currently
running task is being raised. Is the priority being
raised above that of the running task? */
if( uxNewPriority >= pxCurrentTCB->uxPriority )
{ {
/* The priority of another task is being raised. If we
were raising the priority of the currently running task
there would be no need to switch as it must have already
been the highest priority task. */
xYieldRequired = pdTRUE; xYieldRequired = pdTRUE;
} }
} }
else if( xTask == NULL ) else
{ {
/* Setting our own priority down means there may now be another /* The priority of the running task is being raised,
task of higher priority that is ready to execute. */ but the running task must already be the highest
priority task able to run so no yield is required. */
}
}
else if( pxTCB == pxCurrentTCB )
{
/* Setting the priority of the running task down means
there may now be another task of higher priority that
is ready to execute. */
xYieldRequired = pdTRUE; xYieldRequired = pdTRUE;
} }
else
{
/* Setting the priority of any other task down does not
require a yield as the running task must be above the
new priority of the task being modified. */
}
/* Remember the ready list the task might be referenced from /* Remember the ready list the task might be referenced from
before its uxPriority member is changed so the before its uxPriority member is changed so the
@ -1008,35 +987,38 @@ tskTCB * pxNewTCB;
} }
#endif #endif
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ); listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( portTickType ) configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
/* If the task is in the blocked or suspended list we need do /* If the task is in the blocked or suspended list we need do
nothing more than change it's priority variable. However, if nothing more than change it's priority variable. However, if
the task is in a ready list it needs to be removed and placed the task is in a ready list it needs to be removed and placed
in the queue appropriate to its new priority. */ in the list appropriate to its new priority. */
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) ) if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
{ {
/* The task is currently in its ready list - remove before adding /* The task is currently in its ready list - remove before adding
it to it's new ready list. As we are in a critical section we it to it's new ready list. As we are in a critical section we
can do this even if the scheduler is suspended. */ can do this even if the scheduler is suspended. */
if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
taskRESET_READY_PRIORITY( uxPriorityUsedOnEntry ); /* It is known that the task is in its ready list so
there is no need to check again and the port level
reset macro can be called directly. */
portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority );
} }
prvAddTaskToReadyQueue( pxTCB ); prvAddTaskToReadyList( pxTCB );
} }
if( xYieldRequired == pdTRUE ) if( xYieldRequired == pdTRUE )
{ {
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
/* Remove compiler warning about unused variables when the port
optimised task selection is not being used. */
( void ) uxPriorityUsedOnEntry;
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
/* Remove compiler warning about unused parameter when the port
optimised task selection is not being used. */
( void ) uxPriorityUsedOnEntry;
} }
#endif /* INCLUDE_vTaskPrioritySet */ #endif /* INCLUDE_vTaskPrioritySet */
@ -1050,39 +1032,33 @@ tskTCB * pxNewTCB;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Ensure a yield is performed if the current task is being /* If null is passed in here then it is the running task that is
suspended. */ being suspended. */
if( xTaskToSuspend == ( xTaskHandle ) pxCurrentTCB )
{
xTaskToSuspend = NULL;
}
/* If null is passed in here then we are suspending ourselves. */
pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); pxTCB = prvGetTCBFromHandle( xTaskToSuspend );
traceTASK_SUSPEND( pxTCB ); traceTASK_SUSPEND( pxTCB );
/* Remove task from the ready/delayed list and place in the suspended list. */ /* Remove task from the ready/delayed list and place in the suspended list. */
if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
taskRESET_READY_PRIORITY( pxTCB->uxPriority ); taskRESET_READY_PRIORITY( pxTCB->uxPriority );
} }
/* Is the task waiting on an event also? */ /* Is the task waiting on an event also? */
if( pxTCB->xEventListItem.pvContainer != NULL ) if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{ {
uxListRemove( &( pxTCB->xEventListItem ) ); ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
} }
vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
if( ( void * ) xTaskToSuspend == NULL ) if( pxTCB == pxCurrentTCB )
{ {
if( xSchedulerRunning != pdFALSE ) if( xSchedulerRunning != pdFALSE )
{ {
/* We have just suspended the current task. */ /* The current task has just been suspended. */
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
else else
@ -1124,13 +1100,13 @@ tskTCB * pxNewTCB;
if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
{ {
/* Has the task already been resumed from within an ISR? */ /* Has the task already been resumed from within an ISR? */
if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE ) if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE )
{ {
/* Is it in the suspended list because it is in the /* Is it in the suspended list because it is in the
Suspended state? It is possible to be in the suspended Suspended state? It is possible to be in the suspended
list because it is blocked on a task with no timeout list because it is blocked on a task with no timeout
specified. */ specified. */
if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE ) if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE )
{ {
xReturn = pdTRUE; xReturn = pdTRUE;
} }
@ -1138,7 +1114,7 @@ tskTCB * pxNewTCB;
} }
return xReturn; return xReturn;
} } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */
#endif /* INCLUDE_vTaskSuspend */ #endif /* INCLUDE_vTaskSuspend */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -1147,15 +1123,11 @@ tskTCB * pxNewTCB;
void vTaskResume( xTaskHandle xTaskToResume ) void vTaskResume( xTaskHandle xTaskToResume )
{ {
tskTCB *pxTCB; tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume;
/* It does not make sense to resume the calling task. */ /* It does not make sense to resume the calling task. */
configASSERT( xTaskToResume ); configASSERT( xTaskToResume );
/* Remove the task from whichever list it is currently in, and place
it in the ready list. */
pxTCB = ( tskTCB * ) xTaskToResume;
/* The parameter cannot be NULL as it is impossible to resume the /* The parameter cannot be NULL as it is impossible to resume the
currently executing task. */ currently executing task. */
if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
@ -1168,8 +1140,8 @@ tskTCB * pxNewTCB;
/* As we are in a critical section we can access the ready /* As we are in a critical section we can access the ready
lists even if the scheduler is suspended. */ lists even if the scheduler is suspended. */
uxListRemove( &( pxTCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
prvAddTaskToReadyQueue( pxTCB ); prvAddTaskToReadyList( pxTCB );
/* We may have just resumed a higher priority task. */ /* We may have just resumed a higher priority task. */
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
@ -1193,12 +1165,28 @@ tskTCB * pxNewTCB;
portBASE_TYPE xTaskResumeFromISR( xTaskHandle xTaskToResume ) portBASE_TYPE xTaskResumeFromISR( xTaskHandle xTaskToResume )
{ {
portBASE_TYPE xYieldRequired = pdFALSE; portBASE_TYPE xYieldRequired = pdFALSE;
tskTCB *pxTCB; tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume;
unsigned portBASE_TYPE uxSavedInterruptStatus; unsigned portBASE_TYPE uxSavedInterruptStatus;
configASSERT( xTaskToResume ); configASSERT( xTaskToResume );
pxTCB = ( tskTCB * ) xTaskToResume; /* RTOS ports that support interrupt nesting have the concept of a
maximum system call (or maximum API call) interrupt priority.
Interrupts that are above the maximum system call priority are keep
permanently enabled, even when the RTOS kernel is in a critical section,
but cannot make any calls to FreeRTOS API functions. If configASSERT()
is defined in FreeRTOSConfig.h then
portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has
been assigned a priority above the configured maximum system call
priority. Only FreeRTOS functions that end in FromISR can be called
from interrupts that have been assigned a priority at or (logically)
below the maximum system call interrupt priority. FreeRTOS maintains a
separate interrupt safe API to ensure interrupt entry is as fast and as
simple as possible. More information (albeit Cortex-M specific) is
provided on the following link:
http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{ {
@ -1209,15 +1197,15 @@ tskTCB * pxNewTCB;
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
{ {
xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );
uxListRemove( &( pxTCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
prvAddTaskToReadyQueue( pxTCB ); prvAddTaskToReadyList( pxTCB );
} }
else else
{ {
/* We cannot access the delayed or ready lists, so will hold this /* We cannot access the delayed or ready lists, so will hold this
task pending until the scheduler is resumed, at which point a task pending until the scheduler is resumed, at which point a
yield will be performed if necessary. */ yield will be performed if necessary. */
vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
} }
} }
} }
@ -1238,12 +1226,12 @@ portBASE_TYPE xReturn;
{ {
/* Create the idle task, storing its handle in xIdleTaskHandle so it can /* Create the idle task, storing its handle in xIdleTaskHandle so it can
be returned by the xTaskGetIdleTaskHandle() function. */ be returned by the xTaskGetIdleTaskHandle() function. */
xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
} }
#else #else
{ {
/* Create the idle task without storing its handle. */ /* Create the idle task without storing its handle. */
xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL ); xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
} }
#endif /* INCLUDE_xTaskGetIdleTaskHandle */ #endif /* INCLUDE_xTaskGetIdleTaskHandle */
@ -1347,8 +1335,9 @@ void vTaskSuspendAll( void )
signed portBASE_TYPE xTaskResumeAll( void ) signed portBASE_TYPE xTaskResumeAll( void )
{ {
register tskTCB *pxTCB; tskTCB *pxTCB;
signed portBASE_TYPE xAlreadyYielded = pdFALSE; portBASE_TYPE xAlreadyYielded = pdFALSE;
portBASE_TYPE xYieldRequired = pdFALSE;
/* If uxSchedulerSuspended is zero then this function does not match a /* If uxSchedulerSuspended is zero then this function does not match a
previous call to vTaskSuspendAll(). */ previous call to vTaskSuspendAll(). */
@ -1367,16 +1356,14 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
{ {
if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0U ) if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0U )
{ {
portBASE_TYPE xYieldRequired = pdFALSE;
/* Move any readied tasks from the pending list into the /* Move any readied tasks from the pending list into the
appropriate ready list. */ appropriate ready list. */
while( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE ) while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
{ {
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ); pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) );
uxListRemove( &( pxTCB->xEventListItem ) ); ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
uxListRemove( &( pxTCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
prvAddTaskToReadyQueue( pxTCB ); prvAddTaskToReadyList( pxTCB );
/* If we have moved a task that has a priority higher than /* If we have moved a task that has a priority higher than
the current task then we should yield. */ the current task then we should yield. */
@ -1389,28 +1376,22 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
/* If any ticks occurred while the scheduler was suspended then /* If any ticks occurred while the scheduler was suspended then
they should be processed now. This ensures the tick count does not they should be processed now. This ensures the tick count does not
slip, and that any delayed tasks are resumed at the correct time. */ slip, and that any delayed tasks are resumed at the correct time. */
if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0U ) if( uxPendedTicks > ( unsigned portBASE_TYPE ) 0U )
{ {
while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0U ) while( uxPendedTicks > ( unsigned portBASE_TYPE ) 0U )
{ {
vTaskIncrementTick(); if( xTaskIncrementTick() != pdFALSE )
--uxMissedTicks;
}
/* As we have processed some ticks it is appropriate to yield
to ensure the highest priority task that is ready to run is
the task actually running. */
#if configUSE_PREEMPTION == 1
{ {
xYieldRequired = pdTRUE; xYieldRequired = pdTRUE;
} }
#endif --uxPendedTicks;
}
} }
if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) if( ( xYieldRequired == pdTRUE ) || ( xYieldPending == pdTRUE ) )
{ {
xAlreadyYielded = pdTRUE; xAlreadyYielded = pdTRUE;
xMissedYield = pdFALSE; xYieldPending = pdFALSE;
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
} }
@ -1442,6 +1423,22 @@ portTickType xTaskGetTickCountFromISR( void )
portTickType xReturn; portTickType xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus; unsigned portBASE_TYPE uxSavedInterruptStatus;
/* RTOS ports that support interrupt nesting have the concept of a maximum
system call (or maximum API call) interrupt priority. Interrupts that are
above the maximum system call priority are keep permanently enabled, even
when the RTOS kernel is in a critical section, but cannot make any calls to
FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has been
assigned a priority above the configured maximum system call priority.
Only FreeRTOS functions that end in FromISR can be called from interrupts
that have been assigned a priority at or (logically) below the maximum
system call interrupt priority. FreeRTOS maintains a separate interrupt
safe API to ensure interrupt entry is as fast and as simple as possible.
More information (albeit Cortex-M specific) is provided on the following
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
xReturn = xTickCount; xReturn = xTickCount;
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
@ -1475,142 +1472,70 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vTaskList( signed char *pcWriteBuffer ) unsigned portBASE_TYPE uxTaskGetSystemState( xTaskStatusType *pxTaskStatusArray, unsigned portBASE_TYPE uxArraySize, unsigned long *pulTotalRunTime )
{ {
unsigned portBASE_TYPE uxQueue; unsigned portBASE_TYPE uxTask = 0, uxQueue = configMAX_PRIORITIES;
/* This is a VERY costly function that should be used for debug only.
It leaves interrupts disabled for a LONG time. */
vTaskSuspendAll(); vTaskSuspendAll();
{ {
/* Run through all the lists that could potentially contain a TCB and /* Is there a space in the array for each task in the system? */
report the task name, state and stack high water mark. */ if( uxArraySize >= uxCurrentNumberOfTasks )
{
*pcWriteBuffer = ( signed char ) 0x00; /* Fill in an xTaskStatusType structure with information on each
strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); task in the Ready state. */
uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;
do do
{ {
uxQueue--; uxQueue--;
uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady );
if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE ) } while( uxQueue > ( unsigned portBASE_TYPE ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
{
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );
}
}while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE ) /* Fill in an xTaskStatusType structure with information on each
{ task in the Blocked state. */
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR ); uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( xList * ) pxDelayedTaskList, eBlocked );
} uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( xList * ) pxOverflowDelayedTaskList, eBlocked );
if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )
{
prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );
}
#if( INCLUDE_vTaskDelete == 1 ) #if( INCLUDE_vTaskDelete == 1 )
{ {
if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE ) /* Fill in an xTaskStatusType structure with information on
{ each task that has been deleted but not yet cleaned up. */
prvListTaskWithinSingleList( pcWriteBuffer, &xTasksWaitingTermination, tskDELETED_CHAR ); uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted );
}
} }
#endif #endif
#if ( INCLUDE_vTaskSuspend == 1 ) #if ( INCLUDE_vTaskSuspend == 1 )
{ {
if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) /* Fill in an xTaskStatusType structure with information on
each task in the Suspended state. */
uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended );
}
#endif
#if ( configGENERATE_RUN_TIME_STATS == 1)
{ {
prvListTaskWithinSingleList( pcWriteBuffer, &xSuspendedTaskList, tskSUSPENDED_CHAR ); if( pulTotalRunTime != NULL )
{
*pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
}
}
#else
{
if( pulTotalRunTime != NULL )
{
*pulTotalRunTime = 0;
} }
} }
#endif #endif
} }
xTaskResumeAll(); }
( void ) xTaskResumeAll();
return uxTask;
} }
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
#if ( configGENERATE_RUN_TIME_STATS == 1 )
void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
{
unsigned portBASE_TYPE uxQueue;
unsigned long ulTotalRunTimeDiv100;
/* This is a VERY costly function that should be used for debug only.
It leaves interrupts disabled for a LONG time. */
vTaskSuspendAll();
{
#ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );
#else
ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
#endif
/* Divide ulTotalRunTime by 100 to make the percentage caluclations
simpler in the prvGenerateRunTimeStatsForTasksInList() function. */
ulTotalRunTimeDiv100 = ulTotalRunTime / 100UL;
/* Run through all the lists that could potentially contain a TCB,
generating a table of run timer percentages in the provided
buffer. */
*pcWriteBuffer = ( signed char ) 0x00;
strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );
uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;
do
{
uxQueue--;
if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTimeDiv100 );
}
}while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTimeDiv100 );
}
if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTimeDiv100 );
}
#if ( INCLUDE_vTaskDelete == 1 )
{
if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, &xTasksWaitingTermination, ulTotalRunTimeDiv100 );
}
}
#endif
#if ( INCLUDE_vTaskSuspend == 1 )
{
if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )
{
prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, &xSuspendedTaskList, ulTotalRunTimeDiv100 );
}
}
#endif
}
xTaskResumeAll();
}
#endif /* configGENERATE_RUN_TIME_STATS */
/*-----------------------------------------------------------*/
#if ( INCLUDE_uxTaskGetRunTime == 1 ) #if ( INCLUDE_uxTaskGetRunTime == 1 )
unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask ) unsigned portBASE_TYPE uxTaskGetRunTime( xTaskHandle xTask )
@ -1625,8 +1550,6 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
} }
#endif #endif
/*----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
@ -1649,16 +1572,22 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
void vTaskStepTick( portTickType xTicksToJump ) void vTaskStepTick( portTickType xTicksToJump )
{ {
/* Correct the tick count value after a period during which the tick
was suppressed. Note this does *not* call the tick hook function for
each stepped tick. */
configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime );
xTickCount += xTicksToJump; xTickCount += xTicksToJump;
traceINCREASE_TICK_COUNT( xTicksToJump );
} }
#endif /* configUSE_TICKLESS_IDLE */ #endif /* configUSE_TICKLESS_IDLE */
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
void vTaskIncrementTick( void ) portBASE_TYPE xTaskIncrementTick( void )
{ {
tskTCB * pxTCB; tskTCB * pxTCB;
portTickType xItemValue;
portBASE_TYPE xSwitchRequired = pdFALSE;
/* Called by the portable layer each time a tick interrupt occurs. /* 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 Increments the tick then checks to see if the new tick value will cause any
@ -1666,47 +1595,104 @@ tskTCB * pxTCB;
traceTASK_INCREMENT_TICK( xTickCount ); traceTASK_INCREMENT_TICK( xTickCount );
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
{ {
/* Increment the RTOS tick, switching the delayed and overflowed
delayed lists if it wraps to 0. */
++xTickCount; ++xTickCount;
if( xTickCount == ( portTickType ) 0U )
{ {
xList *pxTemp; /* Minor optimisation. The tick count cannot change in this
block. */
const portTickType xConstTickCount = xTickCount;
/* Tick count has overflowed so we need to swap the delay lists. if( xConstTickCount == ( portTickType ) 0U )
If there are any items in pxDelayedTaskList here then there is {
an error! */ taskSWITCH_DELAYED_LISTS();
configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); }
pxTemp = pxDelayedTaskList;
pxDelayedTaskList = pxOverflowDelayedTaskList;
pxOverflowDelayedTaskList = pxTemp;
xNumOfOverflows++;
/* See if this tick has made a timeout expire. Tasks are stored in the
queue in the order of their wake time - meaning once one tasks has been
found whose block time has not expired there is no need not look any
further down the list. */
if( xConstTickCount >= xNextTaskUnblockTime )
{
for( ;; )
{
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
{ {
/* The new current delayed list is empty. Set /* The delayed list is empty. Set xNextTaskUnblockTime to
xNextTaskUnblockTime to the maximum possible value so it is the maximum possible value so it is extremely unlikely that
extremely unlikely that the the if( xTickCount >= xNextTaskUnblockTime ) test will pass
if( xTickCount >= xNextTaskUnblockTime ) test will pass until next time through. */
there is an item in the delayed list. */
xNextTaskUnblockTime = portMAX_DELAY; xNextTaskUnblockTime = portMAX_DELAY;
break;
} }
else else
{ {
/* The new current delayed list is not empty, get the value of /* The delayed list is not empty, get the value of the item
the item at the head of the delayed list. This is the time at at the head of the delayed list. This is the time at which
which the task at the head of the delayed list should be removed the task at the head of the delayed list must be removed
from the Blocked state. */ from the Blocked state. */
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
if( xConstTickCount < 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 must 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. */
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
/* Is the task waiting on an event also? If so remove it
from the event list. */
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{
( void ) uxListRemove( &( pxTCB->xEventListItem ) );
}
/* Place the unblocked task into the appropriate ready
list. */
prvAddTaskToReadyList( pxTCB );
/* A task being unblocked cannot cause an immediate context
switch if preemption is turned off. */
#if ( configUSE_PREEMPTION == 1 )
{
/* Preemption is on, but a context switch should only
be performed if the unblocked task has a priority that
is equal to or higher than the currently executing
task. */
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
{
xSwitchRequired = pdTRUE;
}
}
#endif /* configUSE_PREEMPTION */
}
}
} }
} }
/* See if this tick has made a timeout expire. */ /* Tasks of equal priority to the currently running task will share
prvCheckDelayedTasks(); processing time (time slice) if preemption is on, and the application
writer has not explicitly turned time slicing off. */
#if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
{
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( unsigned portBASE_TYPE ) 1 )
{
xSwitchRequired = pdTRUE;
}
}
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */
} }
else else
{ {
++uxMissedTicks; ++uxPendedTicks;
/* The tick hook gets called at regular intervals, even if the /* The tick hook gets called at regular intervals, even if the
scheduler is locked. */ scheduler is locked. */
@ -1720,13 +1706,15 @@ tskTCB * pxTCB;
#if ( configUSE_TICK_HOOK == 1 ) #if ( configUSE_TICK_HOOK == 1 )
{ {
/* Guard against the tick hook being called when the missed tick /* Guard against the tick hook being called when the missed tick
count is being unwound (when the scheduler is being unlocked. */ count is being unwound (when the scheduler is being unlocked). */
if( uxMissedTicks == ( unsigned portBASE_TYPE ) 0U ) if( uxPendedTicks == ( unsigned portBASE_TYPE ) 0U )
{ {
vApplicationTickHook(); vApplicationTickHook();
} }
} }
#endif /* configUSE_TICK_HOOK */ #endif /* configUSE_TICK_HOOK */
return xSwitchRequired;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -1823,7 +1811,7 @@ void vTaskSwitchContext( void )
{ {
/* The scheduler is currently suspended - do not allow a context /* The scheduler is currently suspended - do not allow a context
switch. */ switch. */
xMissedYield = pdTRUE; xYieldPending = pdTRUE;
} }
else else
{ {
@ -1837,12 +1825,17 @@ void vTaskSwitchContext( void )
ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
#endif #endif
/* Add the amount of time the task has been running to the accumulated /* Add the amount of time the task has been running to the
time so far. The time the task started running was stored in accumulated time so far. The time the task started running was
ulTaskSwitchedInTime. Note that there is no overflow protection here stored in ulTaskSwitchedInTime. Note that there is no overflow
so count values are only valid until the timer overflows. Generally protection here so count values are only valid until the timer
this will be about 1 hour assuming a 1uS timer increment. */ overflows. The guard against negative values is to protect
against suspect run time stat counter implementations - which
are provided by the application, not the kernel. */
if( ulTotalRunTime > ulTaskSwitchedInTime )
{
pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );
}
ulTaskSwitchedInTime = ulTotalRunTime; ulTaskSwitchedInTime = ulTotalRunTime;
} }
#endif /* configGENERATE_RUN_TIME_STATS */ #endif /* configGENERATE_RUN_TIME_STATS */
@ -1853,11 +1846,19 @@ void vTaskSwitchContext( void )
taskSELECT_HIGHEST_PRIORITY_TASK(); taskSELECT_HIGHEST_PRIORITY_TASK();
traceTASK_SWITCHED_IN(); traceTASK_SWITCHED_IN();
#if ( configUSE_NEWLIB_REENTRANT == 1 )
{
/* Switch Newlib's _impure_ptr variable to point to the _reent
structure specific to this task. */
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
}
#endif /* configUSE_NEWLIB_REENTRANT */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) void vTaskPlaceOnEventList( xList * const pxEventList, portTickType xTicksToWait )
{ {
portTickType xTimeToWake; portTickType xTimeToWake;
@ -1869,12 +1870,12 @@ portTickType xTimeToWake;
/* Place the event list item of the TCB in the appropriate event list. /* Place the event list item of the TCB in the appropriate event list.
This is placed in the list in priority order so the highest priority task This is placed in the list in priority order so the highest priority task
is the first to be woken by the event. */ is the first to be woken by the event. */
vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );
/* We must remove ourselves from the ready list before adding ourselves /* We must remove ourselves from the ready list before adding ourselves
to the blocked list as the same list item is used for both lists. We have to the blocked list as the same list item is used for both lists. We have
exclusive access to the ready lists as the scheduler is locked. */ exclusive access to the ready lists as the scheduler is locked. */
if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
/* The current task must be in a ready list, so there is no need to /* The current task must be in a ready list, so there is no need to
check, and the port reset macro can be called directly. */ check, and the port reset macro can be called directly. */
@ -1888,7 +1889,7 @@ portTickType xTimeToWake;
/* Add ourselves to the suspended task list instead of a delayed task /* Add ourselves to the suspended task list instead of a delayed task
list to ensure we are not woken by a timing event. We will block list to ensure we are not woken by a timing event. We will block
indefinitely. */ indefinitely. */
vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
} }
else else
{ {
@ -1911,7 +1912,7 @@ portTickType xTimeToWake;
#if configUSE_TIMERS == 1 #if configUSE_TIMERS == 1
void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) void vTaskPlaceOnEventListRestricted( xList * const pxEventList, portTickType xTicksToWait )
{ {
portTickType xTimeToWake; portTickType xTimeToWake;
@ -1927,12 +1928,12 @@ portTickType xTimeToWake;
In this case it is assume that this is the only task that is going to 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 be waiting on this event list, so the faster vListInsertEnd() function
can be used in place of vListInsert. */ can be used in place of vListInsert. */
vListInsertEnd( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
/* We must remove this task from the ready list before adding it to the /* 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 blocked list as the same list item is used for both lists. This
function is called form a critical section. */ function is called form a critical section. */
if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
/* The current task must be in a ready list, so there is no need to /* The current task must be in a ready list, so there is no need to
check, and the port reset macro can be called directly. */ check, and the port reset macro can be called directly. */
@ -1970,18 +1971,18 @@ portBASE_TYPE xReturn;
pxEventList is not empty. */ pxEventList is not empty. */
pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
configASSERT( pxUnblockedTCB ); configASSERT( pxUnblockedTCB );
uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
{ {
uxListRemove( &( pxUnblockedTCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );
prvAddTaskToReadyQueue( pxUnblockedTCB ); prvAddTaskToReadyList( pxUnblockedTCB );
} }
else else
{ {
/* We cannot access the delayed or ready lists, so will hold this /* We cannot access the delayed or ready lists, so will hold this
task pending until the scheduler is resumed. */ task pending until the scheduler is resumed. */
vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
} }
if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority ) if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority )
@ -2018,6 +2019,9 @@ portBASE_TYPE xReturn;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Minor optimisation. The tick count cannot change in this block. */
const portTickType xConstTickCount = xTickCount;
#if ( INCLUDE_vTaskSuspend == 1 ) #if ( INCLUDE_vTaskSuspend == 1 )
/* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
the maximum block time then the task should block indefinitely, and the maximum block time then the task should block indefinitely, and
@ -2029,7 +2033,7 @@ portBASE_TYPE xReturn;
else /* We are not blocking indefinitely, perform the checks below. */ else /* We are not blocking indefinitely, perform the checks below. */
#endif #endif
if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) ) if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */
{ {
/* The tick count is greater than the time at which vTaskSetTimeout() /* The tick count is greater than the time at which vTaskSetTimeout()
was called, but has also overflowed since vTaskSetTimeOut() was called. was called, but has also overflowed since vTaskSetTimeOut() was called.
@ -2037,10 +2041,10 @@ portBASE_TYPE xReturn;
passed since vTaskSetTimeout() was called. */ passed since vTaskSetTimeout() was called. */
xReturn = pdTRUE; xReturn = pdTRUE;
} }
else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait ) else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )
{ {
/* Not a genuine timeout. Adjust parameters for time remaining. */ /* Not a genuine timeout. Adjust parameters for time remaining. */
*pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ); *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering );
vTaskSetTimeOutState( pxTimeOut ); vTaskSetTimeOutState( pxTimeOut );
xReturn = pdFALSE; xReturn = pdFALSE;
} }
@ -2057,7 +2061,7 @@ portBASE_TYPE xReturn;
void vTaskMissedYield( void ) void vTaskMissedYield( void )
{ {
xMissedYield = pdTRUE; xYieldPending = pdTRUE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -2168,6 +2172,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
#if ( configUSE_TICKLESS_IDLE != 0 ) #if ( configUSE_TICKLESS_IDLE != 0 )
{ {
portTickType xExpectedIdleTime; portTickType xExpectedIdleTime;
/* It is not desirable to suspend then resume the scheduler on /* It is not desirable to suspend then resume the scheduler on
each iteration of the idle task. Therefore, a preliminary each iteration of the idle task. Therefore, a preliminary
test of the expected idle time is performed without the test of the expected idle time is performed without the
@ -2187,15 +2192,17 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
{ {
traceLOW_POWER_IDLE_BEGIN();
portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
traceLOW_POWER_IDLE_END();
} }
} }
xTaskResumeAll(); ( void ) xTaskResumeAll();
} }
} }
#endif /* configUSE_TICKLESS_IDLE */ #endif /* configUSE_TICKLESS_IDLE */
} }
} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */ }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if configUSE_TICKLESS_IDLE != 0 #if configUSE_TICKLESS_IDLE != 0
@ -2209,7 +2216,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
/* A task was made ready while the scheduler was suspended. */ /* A task was made ready while the scheduler was suspended. */
eReturn = eAbortSleep; eReturn = eAbortSleep;
} }
else if( xMissedYield != pdFALSE ) else if( xYieldPending != pdFALSE )
{ {
/* A yield was pended while the scheduler was suspended. */ /* A yield was pended while the scheduler was suspended. */
eReturn = eAbortSleep; eReturn = eAbortSleep;
@ -2240,20 +2247,31 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth )
{ {
/* Store the function name in the TCB. */ unsigned portBASE_TYPE x;
#if configMAX_TASK_NAME_LEN > 1
/* Store the task name in the TCB. */
for( x = ( unsigned portBASE_TYPE ) 0; x < ( unsigned portBASE_TYPE ) configMAX_TASK_NAME_LEN; x++ )
{ {
/* Don't bring strncpy into the build unnecessarily. */ pxTCB->pcTaskName[ x ] = pcName[ x ];
strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );
/* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than
configMAX_TASK_NAME_LEN characters just in case the memory after the
string is not accessible (extremely unlikely). */
if( pcName[ x ] == 0x00 )
{
break;
} }
#endif /* configMAX_TASK_NAME_LEN */ }
pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = ( signed char ) '\0';
/* Ensure the name string is terminated in the case that the string length
was greater or equal to configMAX_TASK_NAME_LEN. */
pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = ( signed char ) '\0';
/* This is used as an array index so must ensure it's not too large. First /* This is used as an array index so must ensure it's not too large. First
remove the privilege bit if one is present. */ remove the privilege bit if one is present. */
if( uxPriority >= configMAX_PRIORITIES ) if( uxPriority >= ( unsigned portBASE_TYPE ) configMAX_PRIORITIES )
{ {
uxPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; uxPriority = ( unsigned portBASE_TYPE ) configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;
} }
pxTCB->uxPriority = uxPriority; pxTCB->uxPriority = uxPriority;
@ -2271,7 +2289,7 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );
/* Event lists are always in priority order. */ /* Event lists are always in priority order. */
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );
#if ( portCRITICAL_NESTING_IN_TCB == 1 ) #if ( portCRITICAL_NESTING_IN_TCB == 1 )
@ -2302,6 +2320,13 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
( void ) usStackDepth; ( void ) usStackDepth;
} }
#endif /* portUSING_MPU_WRAPPERS */ #endif /* portUSING_MPU_WRAPPERS */
#if ( configUSE_NEWLIB_REENTRANT == 1 )
{
/* Initialise this task's Newlib reent structure. */
_REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) );
}
#endif /* configUSE_NEWLIB_REENTRANT */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -2311,11 +2336,6 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
{ {
tskTCB *pxTCB; tskTCB *pxTCB;
if( xTaskToModify == pxCurrentTCB )
{
xTaskToModify = NULL;
}
/* If null is passed in here then we are deleting ourselves. */ /* If null is passed in here then we are deleting ourselves. */
pxTCB = prvGetTCBFromHandle( xTaskToModify ); pxTCB = prvGetTCBFromHandle( xTaskToModify );
@ -2329,24 +2349,24 @@ static void prvInitialiseTaskLists( void )
{ {
unsigned portBASE_TYPE uxPriority; unsigned portBASE_TYPE uxPriority;
for( uxPriority = ( unsigned portBASE_TYPE ) 0U; uxPriority < configMAX_PRIORITIES; uxPriority++ ) for( uxPriority = ( unsigned portBASE_TYPE ) 0U; uxPriority < ( unsigned portBASE_TYPE ) configMAX_PRIORITIES; uxPriority++ )
{ {
vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) ); vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
} }
vListInitialise( ( xList * ) &xDelayedTaskList1 ); vListInitialise( &xDelayedTaskList1 );
vListInitialise( ( xList * ) &xDelayedTaskList2 ); vListInitialise( &xDelayedTaskList2 );
vListInitialise( ( xList * ) &xPendingReadyList ); vListInitialise( &xPendingReadyList );
#if ( INCLUDE_vTaskDelete == 1 ) #if ( INCLUDE_vTaskDelete == 1 )
{ {
vListInitialise( ( xList * ) &xTasksWaitingTermination ); vListInitialise( &xTasksWaitingTermination );
} }
#endif /* INCLUDE_vTaskDelete */ #endif /* INCLUDE_vTaskDelete */
#if ( INCLUDE_vTaskSuspend == 1 ) #if ( INCLUDE_vTaskSuspend == 1 )
{ {
vListInitialise( ( xList * ) &xSuspendedTaskList ); vListInitialise( &xSuspendedTaskList );
} }
#endif /* INCLUDE_vTaskSuspend */ #endif /* INCLUDE_vTaskSuspend */
@ -2369,7 +2389,7 @@ static void prvCheckTasksWaitingTermination( void )
{ {
vTaskSuspendAll(); vTaskSuspendAll();
xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
xTaskResumeAll(); ( void ) xTaskResumeAll();
if( xListIsEmpty == pdFALSE ) if( xListIsEmpty == pdFALSE )
{ {
@ -2377,8 +2397,8 @@ static void prvCheckTasksWaitingTermination( void )
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) ); pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
uxListRemove( &( pxTCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
--uxCurrentNumberOfTasks; --uxCurrentNumberOfTasks;
--uxTasksDeleted; --uxTasksDeleted;
} }
@ -2400,12 +2420,12 @@ static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake )
if( xTimeToWake < xTickCount ) if( xTimeToWake < xTickCount )
{ {
/* Wake time has overflowed. Place this item in the overflow list. */ /* Wake time has overflowed. Place this item in the overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
} }
else else
{ {
/* The wake time has not overflowed, so we can use the current block list. */ /* The wake time has not overflowed, so we can use the current block list. */
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
/* If the task entering the blocked state was placed at the head of the /* If the task entering the blocked state was placed at the head of the
list of blocked tasks then xNextTaskUnblockTime needs to be updated list of blocked tasks then xNextTaskUnblockTime needs to be updated
@ -2431,7 +2451,7 @@ tskTCB *pxNewTCB;
/* Allocate space for the stack used by the task being created. /* Allocate space for the stack used by the task being created.
The base of the stack memory stored in the TCB so the task can The base of the stack memory stored in the TCB so the task can
be deleted later if required. */ be deleted later if required. */
pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
if( pxNewTCB->pxStack == NULL ) if( pxNewTCB->pxStack == NULL )
{ {
@ -2442,7 +2462,7 @@ tskTCB *pxNewTCB;
else else
{ {
/* Just to help debugging. */ /* Just to help debugging. */
memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( portSTACK_TYPE ) ); ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( portSTACK_TYPE ) );
} }
} }
@ -2452,110 +2472,73 @@ tskTCB *pxNewTCB;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) static unsigned portBASE_TYPE prvListTaskWithinSingleList( xTaskStatusType *pxTaskStatusArray, xList *pxList, eTaskState eState )
{ {
volatile tskTCB *pxNextTCB, *pxFirstTCB; volatile tskTCB *pxNextTCB, *pxFirstTCB;
unsigned short usStackRemaining; unsigned portBASE_TYPE uxTask = 0;
PRIVILEGED_DATA static char pcStatusString[ configMAX_TASK_NAME_LEN + 30 ];
/* Write the details of all the TCB's in pxList into the buffer. */ if( listCURRENT_LIST_LENGTH( pxList ) > ( unsigned portBASE_TYPE ) 0 )
{
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
/* Populate an xTaskStatusType structure within the
pxTaskStatusArray array for each task that is referenced from
pxList. See the definition of xTaskStatusType in task.h for the
meaning of each xTaskStatusType structure member. */
do do
{ {
listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
#if ( portSTACK_GROWTH > 0 )
pxTaskStatusArray[ uxTask ].xHandle = ( xTaskHandle ) pxNextTCB;
pxTaskStatusArray[ uxTask ].pcTaskName = ( const signed char * ) &( pxNextTCB->pcTaskName [ 0 ] );
pxTaskStatusArray[ uxTask ].xTaskNumber = pxNextTCB->uxTCBNumber;
pxTaskStatusArray[ uxTask ].eCurrentState = eState;
pxTaskStatusArray[ uxTask ].uxCurrentPriority = pxNextTCB->uxPriority;
#if ( configUSE_MUTEXES == 1 )
{ {
usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack ); pxTaskStatusArray[ uxTask ].uxBasePriority = pxNextTCB->uxBasePriority;
} }
#else #else
{ {
usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); pxTaskStatusArray[ uxTask ].uxBasePriority = 0;
} }
#endif #endif
sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, ( unsigned int ) usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber ); #if ( configGENERATE_RUN_TIME_STATS == 1 )
strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString ); {
pxTaskStatusArray[ uxTask ].ulRunTimeCounter = pxNextTCB->ulRunTimeCounter;
}
#else
{
pxTaskStatusArray[ uxTask ].ulRunTimeCounter = 0;
}
#endif
#if ( portSTACK_GROWTH > 0 )
{
ppxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack );
}
#else
{
pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack );
}
#endif
uxTask++;
} while( pxNextTCB != pxFirstTCB ); } while( pxNextTCB != pxFirstTCB );
} }
return uxTask;
}
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configGENERATE_RUN_TIME_STATS == 1 )
static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTimeDiv100 )
{
volatile tskTCB *pxNextTCB, *pxFirstTCB;
unsigned long ulStatsAsPercentage;
/* Write the run time stats of all the TCB's in pxList into the buffer. */
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
do
{
/* Get next TCB in from the list. */
listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
/* Divide by zero check. */
if( ulTotalRunTimeDiv100 > 0UL )
{
/* Has the task run at all? */
if( pxNextTCB->ulRunTimeCounter == 0UL )
{
/* The task has used no CPU time at all. */
sprintf( pcStatsString, ( char * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName );
}
else
{
/* What percentage of the total run time has the task used?
This will always be rounded down to the nearest integer.
ulTotalRunTimeDiv100 has already been divided by 100. */
ulStatsAsPercentage = pxNextTCB->ulRunTimeCounter / ulTotalRunTimeDiv100;
if( ulStatsAsPercentage > 0UL )
{
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage );
}
#else
{
/* sizeof( int ) == sizeof( long ) so a smaller
printf() library can be used. */
sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
}
#endif
}
else
{
/* If the percentage is zero here then the task has
consumed less than 1% of the total run time. */
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter );
}
#else
{
/* sizeof( int ) == sizeof( long ) so a smaller
printf() library can be used. */
sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter );
}
#endif
}
}
strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString );
}
} while( pxNextTCB != pxFirstTCB );
}
#endif /* configGENERATE_RUN_TIME_STATS */
/*-----------------------------------------------------------*/
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) static unsigned short prvTaskCheckFreeStackSpace( const unsigned char * pucStackByte )
{ {
register unsigned short usCount = 0U; register unsigned short usCount = 0U;
@ -2571,7 +2554,6 @@ tskTCB *pxNewTCB;
} }
#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */ #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
@ -2594,7 +2576,7 @@ tskTCB *pxNewTCB;
} }
#endif #endif
uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack ); uxReturn = ( unsigned portBASE_TYPE ) prvTaskCheckFreeStackSpace( pcEndOfStack );
return uxReturn; return uxReturn;
} }
@ -2667,7 +2649,7 @@ tskTCB *pxNewTCB;
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) void vTaskPriorityInherit( xTaskHandle const pxMutexHolder )
{ {
tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;
@ -2678,20 +2660,20 @@ tskTCB *pxNewTCB;
if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
{ {
/* Adjust the mutex holder state to account for its new priority. */ /* Adjust the mutex holder state to account for its new priority. */
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority ); listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
/* If the task being modified is in the ready state it will need to /* If the task being modified is in the ready state it will need to
be moved into a new list. */ be moved into a new list. */
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE ) if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
{ {
if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
taskRESET_READY_PRIORITY( pxTCB->uxPriority ); taskRESET_READY_PRIORITY( pxTCB->uxPriority );
} }
/* Inherit the priority before being moved into the new list. */ /* Inherit the priority before being moved into the new list. */
pxTCB->uxPriority = pxCurrentTCB->uxPriority; pxTCB->uxPriority = pxCurrentTCB->uxPriority;
prvAddTaskToReadyQueue( pxTCB ); prvAddTaskToReadyList( pxTCB );
} }
else else
{ {
@ -2709,7 +2691,7 @@ tskTCB *pxNewTCB;
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) void vTaskPriorityDisinherit( xTaskHandle const pxMutexHolder )
{ {
tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;
@ -2719,7 +2701,7 @@ tskTCB *pxNewTCB;
{ {
/* We must be the running task to be able to give the mutex back. /* We must be the running task to be able to give the mutex back.
Remove ourselves from the ready list we currently appear in. */ Remove ourselves from the ready list we currently appear in. */
if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 ) if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{ {
taskRESET_READY_PRIORITY( pxTCB->uxPriority ); taskRESET_READY_PRIORITY( pxTCB->uxPriority );
} }
@ -2728,8 +2710,8 @@ tskTCB *pxNewTCB;
ready list. */ ready list. */
traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );
pxTCB->uxPriority = pxTCB->uxBasePriority; pxTCB->uxPriority = pxTCB->uxBasePriority;
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority ); listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
prvAddTaskToReadyQueue( pxTCB ); prvAddTaskToReadyList( pxTCB );
} }
} }
} }
@ -2773,6 +2755,192 @@ tskTCB *pxNewTCB;
#endif /* portCRITICAL_NESTING_IN_TCB */ #endif /* portCRITICAL_NESTING_IN_TCB */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )
void vTaskList( signed char *pcWriteBuffer )
{
xTaskStatusType *pxTaskStatusArray;
volatile unsigned portBASE_TYPE uxArraySize, x;
char cStatus;
/*
* PLEASE NOTE:
*
* This function is provided for convenience only, and is used by many
* of the demo applications. Do not consider it to be part of the
* scheduler.
*
* vTaskList() calls uxTaskGetSystemState(), then formats part of the
* uxTaskGetSystemState() output into a human readable table that
* displays task names, states and stack usage.
*
* vTaskList() has a dependency on the sprintf() C library function that
* might bloat the code size, use a lot of stack, and provide different
* results on different platforms. An alternative, tiny, third party,
* and limited functionality implementation of sprintf() is provided in
* many of the FreeRTOS/Demo sub-directories in a file called
* printf-stdarg.c (note printf-stdarg.c does not provide a full
* snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState()
* directly to get access to raw stats data, rather than indirectly
* through a call to vTaskList().
*/
/* Make sure the write buffer does not contain a string. */
*pcWriteBuffer = 0x00;
/* Take a snapshot of the number of tasks in case it changes while this
function is executing. */
uxArraySize = uxCurrentNumberOfTasks;
/* Allocate an array index for each task. */
pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) );
if( pxTaskStatusArray != NULL )
{
/* Generate the (binary) data. */
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL );
/* Create a human readable table from the binary data. */
for( x = 0; x < uxArraySize; x++ )
{
switch( pxTaskStatusArray[ x ].eCurrentState )
{
case eReady: cStatus = tskREADY_CHAR;
break;
case eBlocked: cStatus = tskBLOCKED_CHAR;
break;
case eSuspended: cStatus = tskSUSPENDED_CHAR;
break;
case eDeleted: cStatus = tskDELETED_CHAR;
break;
default: /* Should not get here, but it is included
to prevent static checking errors. */
cStatus = 0x00;
break;
}
sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxTaskStatusArray[ x ].pcTaskName, cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
}
/* Free the array again. */
vPortFree( pxTaskStatusArray );
}
}
#endif /* configUSE_TRACE_FACILITY */
/*----------------------------------------------------------*/
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )
void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
{
xTaskStatusType *pxTaskStatusArray;
volatile unsigned portBASE_TYPE uxArraySize, x;
unsigned long ulTotalTime, ulStatsAsPercentage;
/*
* PLEASE NOTE:
*
* This function is provided for convenience only, and is used by many
* of the demo applications. Do not consider it to be part of the
* scheduler.
*
* vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part
* of the uxTaskGetSystemState() output into a human readable table that
* displays the amount of time each task has spent in the Running state
* in both absolute and percentage terms.
*
* vTaskGetRunTimeStats() has a dependency on the sprintf() C library
* function that might bloat the code size, use a lot of stack, and
* provide different results on different platforms. An alternative,
* tiny, third party, and limited functionality implementation of
* sprintf() is provided in many of the FreeRTOS/Demo sub-directories in
* a file called printf-stdarg.c (note printf-stdarg.c does not provide
* a full snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState()
* directly to get access to raw stats data, rather than indirectly
* through a call to vTaskGetRunTimeStats().
*/
/* Make sure the write buffer does not contain a string. */
*pcWriteBuffer = 0x00;
/* Take a snapshot of the number of tasks in case it changes while this
function is executing. */
uxArraySize = uxCurrentNumberOfTasks;
/* Allocate an array index for each task. */
pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) );
if( pxTaskStatusArray != NULL )
{
/* Generate the (binary) data. */
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime );
/* For percentage calculations. */
ulTotalTime /= 100UL;
/* Avoid divide by zero errors. */
if( ulTotalTime > 0 )
{
/* Create a human readable table from the binary data. */
for( x = 0; x < uxArraySize; x++ )
{
/* What percentage of the total run time has the task used?
This will always be rounded down to the nearest integer.
ulTotalRunTimeDiv100 has already been divided by 100. */
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
if( ulStatsAsPercentage > 0UL )
{
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
}
#else
{
/* sizeof( int ) == sizeof( long ) so a smaller
printf() library can be used. */
sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
}
#endif
}
else
{
/* If the percentage is zero here then the task has
consumed less than 1% of the total run time. */
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
}
#else
{
/* sizeof( int ) == sizeof( long ) so a smaller
printf() library can be used. */
sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter );
}
#endif
}
pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
}
}
/* Free the array again. */
vPortFree( pxTaskStatusArray );
}
}
#endif /* configGENERATE_RUN_TIME_STATS */

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,23 +44,27 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/* Standard includes. */
#include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining /* 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 all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */ task.h is included from an application file. */
@ -82,7 +75,12 @@ task.h is included from an application file. */
#include "queue.h" #include "queue.h"
#include "timers.h" #include "timers.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
header files above, but not in this file, in order to generate the correct
privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
/* This entire source file will be skipped if the application is not configured /* 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 to include software timer functionality. This #if is closed at the very bottom
@ -113,6 +111,8 @@ typedef struct tmrTimerQueueMessage
xTIMER * pxTimer; /*<< The timer to which the command will be applied. */ xTIMER * pxTimer; /*<< The timer to which the command will be applied. */
} xTIMER_MESSAGE; } xTIMER_MESSAGE;
/*lint -e956 A manual analysis and inspection has been used to determine which
static variables must be declared volatile. */
/* The list in which active timers are stored. Timers are referenced in expire /* 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 time order, with the nearest expiry time at the front of the list. Only the
@ -131,6 +131,8 @@ PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;
#endif #endif
/*lint +e956 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -320,7 +322,7 @@ portBASE_TYPE xResult;
/* Remove the timer from the list of active timers. A check has already /* Remove the timer from the list of active timers. A check has already
been performed to ensure the list is not empty. */ been performed to ensure the list is not empty. */
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
uxListRemove( &( pxTimer->xTimerListItem ) ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
traceTIMER_EXPIRED( pxTimer ); traceTIMER_EXPIRED( pxTimer );
/* If the timer is an auto reload timer then calculate the next /* If the timer is an auto reload timer then calculate the next
@ -390,7 +392,7 @@ portBASE_TYPE xTimerListsWereSwitched;
/* The tick count has not overflowed, has the timer expired? */ /* The tick count has not overflowed, has the timer expired? */
if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
{ {
xTaskResumeAll(); ( void ) xTaskResumeAll();
prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
} }
else else
@ -415,7 +417,7 @@ portBASE_TYPE xTimerListsWereSwitched;
} }
else else
{ {
xTaskResumeAll(); ( void ) xTaskResumeAll();
} }
} }
} }
@ -450,7 +452,7 @@ portTickType xNextExpireTime;
static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched )
{ {
portTickType xTimeNow; portTickType xTimeNow;
PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U; PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U; /*lint !e956 Variable is only accessible to one task. */
xTimeNow = xTaskGetTickCount(); xTimeNow = xTaskGetTickCount();
@ -481,7 +483,7 @@ portBASE_TYPE xProcessTimerNow = pdFALSE;
{ {
/* Has the expiry time elapsed between the command to start/reset a /* Has the expiry time elapsed between the command to start/reset a
timer was issued, and the time the command was processed? */ timer was issued, and the time the command was processed? */
if( ( ( portTickType ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks )
{ {
/* The time between a command being issued and the command being /* The time between a command being issued and the command being
processed actually exceeds the timers period. */ processed actually exceeds the timers period. */
@ -518,14 +520,14 @@ xTIMER *pxTimer;
portBASE_TYPE xTimerListsWereSwitched, xResult; portBASE_TYPE xTimerListsWereSwitched, xResult;
portTickType xTimeNow; portTickType xTimeNow;
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */
{ {
pxTimer = xMessage.pxTimer; pxTimer = xMessage.pxTimer;
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
{ {
/* The timer is in a list, remove it. */ /* The timer is in a list, remove it. */
uxListRemove( &( pxTimer->xTimerListItem ) ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
} }
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue ); traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue );
@ -565,7 +567,7 @@ portTickType xTimeNow;
case tmrCOMMAND_CHANGE_PERIOD : case tmrCOMMAND_CHANGE_PERIOD :
pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue; pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
break; break;
case tmrCOMMAND_DELETE : case tmrCOMMAND_DELETE :
@ -602,7 +604,7 @@ portBASE_TYPE xResult;
/* Remove the timer from the list. */ /* Remove the timer from the list. */
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
uxListRemove( &( pxTimer->xTimerListItem ) ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
/* Execute its callback, then send a command to restart the timer if /* 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 it is an auto-reload timer. It cannot be restarted here as the lists

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
@ -95,26 +85,38 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) )
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) )
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) ) #define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
/* ...then bits in the registers. */ /* ...then bits in the registers. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
/* Constants required to set up the initial stack. */ /* Constants required to check the validity of an interrupt priority. */
#define portINITIAL_XPSR ( 0x01000000 ) #define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
#define portPRIGROUP_SHIFT ( 8UL )
/* The priority used by the kernel is assigned to a variable to make access /* Constants required to set up the initial stack. */
from inline assembler easier. */ #define portINITIAL_XPSR ( 0x01000000UL )
const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
/* The systick is a 24-bit counter. */
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle
calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL )
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ variable. */
@ -145,8 +147,8 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
* The number of SysTick increments that make up one tick period. * The number of SysTick increments that make up one tick period.
*/ */
#if configUSE_TICKLESS_IDLE == 1 #if configUSE_TICKLESS_IDLE == 1
static unsigned long ulTimerReloadValueForOneTick = 0; static unsigned long ulTimerCountsForOneTick = 0;
#endif #endif /* configUSE_TICKLESS_IDLE */
/* /*
* The maximum number of tick periods that can be suppressed is limited by the * The maximum number of tick periods that can be suppressed is limited by the
@ -164,6 +166,17 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #endif /* configUSE_TICKLESS_IDLE */
/*
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
* FreeRTOS API functions are not called from interrupts that have been assigned
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
*/
#if ( configASSERT_DEFINED == 1 )
static unsigned char ucMaxSysCallPriority = 0;
static unsigned long ulMaxPRIGROUPValue = 0;
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
#endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -229,7 +242,51 @@ portBASE_TYPE xPortStartScheduler( void )
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */ #if( configASSERT_DEFINED == 1 )
{
volatile unsigned long ulOriginalPriority;
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile unsigned char ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible.
Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pcFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all
possible bits. */
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
/* Use the same mask on the maximum system call priority. */
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number
of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
ulMaxPRIGROUPValue--;
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
}
/* Shift the priority group value back to its position within the AIRCR
register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original
value. */
*pcFirstUserPriorityRegister = ulOriginalPriority;
}
#endif /* conifgASSERT_DEFINED */
/* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
@ -255,10 +312,15 @@ void vPortEndScheduler( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortYieldFromISR( void ) void vPortYield( void )
{ {
/* Set a PendSV to request a context switch. */ /* Set a PendSV to request a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
/* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */
__asm volatile( "dsb" );
__asm volatile( "isb" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -266,6 +328,8 @@ void vPortEnterCritical( void )
{ {
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
uxCriticalNesting++; uxCriticalNesting++;
__asm volatile( "dsb" );
__asm volatile( "isb" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -347,22 +411,19 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void ) void xPortSysTickHandler( void )
{ {
/* If using preemption, also force a context switch. */ /* The SysTick runs at the lowest interrupt priority, so when this interrupt
#if configUSE_PREEMPTION == 1 executes all interrupts must be unmasked. There is therefore no need to
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; save and then restore the interrupt mask value as its value is already
#endif known. */
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
1. If it is set to 0 tickless idle is not being used. If it is set to a
value other than 0 or 1 then a timer other than the SysTick is being used
to generate the tick interrupt. */
#if configUSE_TICKLESS_IDLE == 1
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;
#endif
( void ) portSET_INTERRUPT_MASK_FROM_ISR(); ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{ {
vTaskIncrementTick(); /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
} }
@ -372,7 +433,7 @@ void xPortSysTickHandler( void )
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime ) __attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
{ {
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements; unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
portTickType xModifiableIdleTime; portTickType xModifiableIdleTime;
/* Make sure the SysTick reload value does not overflow the counter. */ /* Make sure the SysTick reload value does not overflow the counter. */
@ -381,25 +442,20 @@ void xPortSysTickHandler( void )
xExpectedIdleTime = xMaximumPossibleSuppressedTicks; xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
} }
/* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way
through one of the tick periods, and the fraction of a tick period is
accounted for later. */
ulReloadValue = ( ulTimerReloadValueForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation )
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Stop the SysTick momentarily. The time the SysTick is stopped for /* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */ kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
/* Adjust the reload value to take into account that the current time /* Calculate the reload value required to wait xExpectedIdleTime
slice is already partially complete. */ tick periods. -1 is used because this code will execute part way
ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) ); through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation )
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ method as that will mask interrupts that should exit sleep mode. */
@ -437,7 +493,9 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile( "dsb" );
__asm volatile( "wfi" ); __asm volatile( "wfi" );
__asm volatile( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
@ -454,10 +512,10 @@ void xPortSysTickHandler( void )
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
/* The tick interrupt has already executed, and the SysTick /* The tick interrupt has already executed, and the SysTick
count reloaded with the portNVIC_SYSTICK_LOAD_REG value. count reloaded with ulReloadValue. Reset the
Reset the portNVIC_SYSTICK_LOAD_REG with whatever remains of portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
this tick period. */ period. */
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* The tick interrupt handler will already have pended the tick /* The tick interrupt handler will already have pended the tick
processing in the kernel. As the pending tick will be processing in the kernel. As the pending tick will be
@ -469,25 +527,33 @@ void xPortSysTickHandler( void )
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted. */ Work out how long the sleep lasted rounded to complete tick
ulCompletedSysTickIncrements = ( xExpectedIdleTime * ulTimerReloadValueForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; periods (not the ulReload value which accounted for part
ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickIncrements / ulTimerReloadValueForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerReloadValueForOneTick ) - ulCompletedSysTickIncrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. */ value. The critical section is used to ensure the tick interrupt
can only execute once in the case that the reload register is near
zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portENTER_CRITICAL();
{
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); vTaskStepTick( ulCompleteTickPeriods );
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
}
portEXIT_CRITICAL();
} }
} }
@ -503,9 +569,9 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
/* Calculate the constants required to configure the tick interrupt. */ /* Calculate the constants required to configure the tick interrupt. */
#if configUSE_TICKLESS_IDLE == 1 #if configUSE_TICKLESS_IDLE == 1
{ {
ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
xMaximumPossibleSuppressedTicks = 0xffffffUL / ( ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
ulStoppedTimerCompensation = 45UL / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
} }
#endif /* configUSE_TICKLESS_IDLE */ #endif /* configUSE_TICKLESS_IDLE */
@ -514,4 +580,84 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority( void )
{
unsigned long ulCurrentInterrupt;
unsigned char ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
/* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
{
/* Look up the interrupt's priority. */
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid.
FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible.
The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
}
/* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority).
If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredicable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}
#endif /* configASSERT_DEFINED */

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
@ -111,17 +101,18 @@ extern "C" {
/* Architecture specifics. */ /* Architecture specifics. */
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) #define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8 // APCS 8 bytes aligned stack for external calls #define portBYTE_ALIGNMENT 8
#define portBYTE_HEAP_ALIGNMENT 4 // this value is used to allocate heap #define portBYTE_HEAP_ALIGNMENT 4 // this value is used to allocate heap
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
extern void *pvPortMallocGeneric( size_t xWantedSize, size_t alignment);
#define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMallocGeneric( ( x ) , portBYTE_ALIGNMENT) ) : ( puxStackBuffer ) )
/* Scheduler utilities. */ /* Scheduler utilities. */
extern void vPortYieldFromISR( void ); extern void vPortYield( void );
#define portYIELD() vPortYieldFromISR() #define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR() #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */
@ -180,6 +171,11 @@ not necessary for to use this port. They are defined so the common demo files
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef configASSERT
void vPortValidateInterruptPriority( void );
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
#endif
/* portNOP() is not required by this port. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -331,7 +331,7 @@ static void PIOS_USART_generic_irq_handler(uint32_t usart_id)
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (rx_need_yield || tx_need_yield) { if (rx_need_yield || tx_need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
} }

View File

@ -240,7 +240,7 @@ static void PIOS_USB_CDC_SendData(struct pios_usb_cdc_dev *usb_cdc_dev)
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
} }
@ -328,7 +328,7 @@ static void PIOS_USB_CDC_DATA_EP_OUT_Callback(void)
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
} }

View File

@ -198,7 +198,7 @@ static void PIOS_USB_HID_SendReport(struct pios_usb_hid_dev *usb_hid_dev)
#ifdef PIOS_INCLUDE_FREERTOS #ifdef PIOS_INCLUDE_FREERTOS
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
} }
@ -365,7 +365,7 @@ static void PIOS_USB_HID_EP_OUT_Callback(void)
#ifdef PIOS_INCLUDE_FREERTOS #ifdef PIOS_INCLUDE_FREERTOS
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
} }

View File

@ -143,7 +143,7 @@ static void PIOS_USB_RCTX_SendReport(struct pios_usb_rctx_dev *usb_rctx_dev)
#ifdef PIOS_INCLUDE_FREERTOS #ifdef PIOS_INCLUDE_FREERTOS
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
} }

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
@ -92,20 +82,28 @@
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) )
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) )
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) ) #define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
/* ...then bits in the registers. */ /* ...then bits in the registers. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
/* Constants required to check the validity of an interrupt priority. */
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
#define portPRIGROUP_SHIFT ( 8UL )
/* Constants required to manipulate the VFP. */ /* Constants required to manipulate the VFP. */
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */ #define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
@ -114,9 +112,13 @@
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
#define portINITIAL_EXEC_RETURN ( 0xfffffffd ) #define portINITIAL_EXEC_RETURN ( 0xfffffffd )
/* The priority used by the kernel is assigned to a variable to make access /* The systick is a 24-bit counter. */
from inline assembler easier. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL )
const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
/* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle
calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL )
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ variable. */
@ -152,8 +154,8 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
* The number of SysTick increments that make up one tick period. * The number of SysTick increments that make up one tick period.
*/ */
#if configUSE_TICKLESS_IDLE == 1 #if configUSE_TICKLESS_IDLE == 1
static unsigned long ulTimerReloadValueForOneTick = 0; static unsigned long ulTimerCountsForOneTick = 0;
#endif #endif /* configUSE_TICKLESS_IDLE */
/* /*
* The maximum number of tick periods that can be suppressed is limited by the * The maximum number of tick periods that can be suppressed is limited by the
@ -171,6 +173,17 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #endif /* configUSE_TICKLESS_IDLE */
/*
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
* FreeRTOS API functions are not called from interrupts that have been assigned
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
*/
#if ( configASSERT_DEFINED == 1 )
static unsigned char ucMaxSysCallPriority = 0;
static unsigned long ulMaxPRIGROUPValue = 0;
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
#endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -247,7 +260,51 @@ portBASE_TYPE xPortStartScheduler( void )
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */ #if( configASSERT_DEFINED == 1 )
{
volatile unsigned long ulOriginalPriority;
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile unsigned char ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible.
Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pcFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all
possible bits. */
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
/* Use the same mask on the maximum system call priority. */
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number
of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
ulMaxPRIGROUPValue--;
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
}
/* Shift the priority group value back to its position within the AIRCR
register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original
value. */
*pcFirstUserPriorityRegister = ulOriginalPriority;
}
#endif /* conifgASSERT_DEFINED */
/* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
@ -279,10 +336,15 @@ void vPortEndScheduler( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortYieldFromISR( void ) void vPortYield( void )
{ {
/* Set a PendSV to request a context switch. */ /* Set a PendSV to request a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
/* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */
__asm volatile( "dsb" );
__asm volatile( "isb" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -290,6 +352,8 @@ void vPortEnterCritical( void )
{ {
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
uxCriticalNesting++; uxCriticalNesting++;
__asm volatile( "dsb" );
__asm volatile( "isb" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -382,22 +446,19 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void ) void xPortSysTickHandler( void )
{ {
/* If using preemption, also force a context switch. */ /* The SysTick runs at the lowest interrupt priority, so when this interrupt
#if configUSE_PREEMPTION == 1 executes all interrupts must be unmasked. There is therefore no need to
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; save and then restore the interrupt mask value as its value is already
#endif known. */
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
1. If it is set to 0 tickless idle is not being used. If it is set to a
value other than 0 or 1 then a timer other than the SysTick is being used
to generate the tick interrupt. */
#if configUSE_TICKLESS_IDLE == 1
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;
#endif
( void ) portSET_INTERRUPT_MASK_FROM_ISR(); ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{ {
vTaskIncrementTick(); /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
} }
@ -407,7 +468,7 @@ void xPortSysTickHandler( void )
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime ) __attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
{ {
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements; unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
portTickType xModifiableIdleTime; portTickType xModifiableIdleTime;
/* Make sure the SysTick reload value does not overflow the counter. */ /* Make sure the SysTick reload value does not overflow the counter. */
@ -416,25 +477,20 @@ void xPortSysTickHandler( void )
xExpectedIdleTime = xMaximumPossibleSuppressedTicks; xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
} }
/* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way
through one of the tick periods, and the fraction of a tick period is
accounted for later. */
ulReloadValue = ( ulTimerReloadValueForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation )
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Stop the SysTick momentarily. The time the SysTick is stopped for /* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */ kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
/* Adjust the reload value to take into account that the current time /* Calculate the reload value required to wait xExpectedIdleTime
slice is already partially complete. */ tick periods. -1 is used because this code will execute part way
ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) ); through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation )
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ method as that will mask interrupts that should exit sleep mode. */
@ -472,7 +528,9 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile( "dsb" );
__asm volatile( "wfi" ); __asm volatile( "wfi" );
__asm volatile( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
@ -489,10 +547,10 @@ void xPortSysTickHandler( void )
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
/* The tick interrupt has already executed, and the SysTick /* The tick interrupt has already executed, and the SysTick
count reloaded with the portNVIC_SYSTICK_LOAD_REG value. count reloaded with ulReloadValue. Reset the
Reset the portNVIC_SYSTICK_LOAD_REG with whatever remains of portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
this tick period. */ period. */
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* The tick interrupt handler will already have pended the tick /* The tick interrupt handler will already have pended the tick
processing in the kernel. As the pending tick will be processing in the kernel. As the pending tick will be
@ -504,25 +562,33 @@ void xPortSysTickHandler( void )
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted. */ Work out how long the sleep lasted rounded to complete tick
ulCompletedSysTickIncrements = ( xExpectedIdleTime * ulTimerReloadValueForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; periods (not the ulReload value which accounted for part
ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickIncrements / ulTimerReloadValueForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerReloadValueForOneTick ) - ulCompletedSysTickIncrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. */ value. The critical section is used to ensure the tick interrupt
can only execute once in the case that the reload register is near
zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portENTER_CRITICAL();
{
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); vTaskStepTick( ulCompleteTickPeriods );
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
}
portEXIT_CRITICAL();
} }
} }
@ -538,9 +604,9 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
/* Calculate the constants required to configure the tick interrupt. */ /* Calculate the constants required to configure the tick interrupt. */
#if configUSE_TICKLESS_IDLE == 1 #if configUSE_TICKLESS_IDLE == 1
{ {
ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
xMaximumPossibleSuppressedTicks = 0xffffffUL / ( ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
ulStoppedTimerCompensation = 45UL / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
} }
#endif /* configUSE_TICKLESS_IDLE */ #endif /* configUSE_TICKLESS_IDLE */
@ -563,4 +629,66 @@ static void vPortEnableVFP( void )
" bx r14 " " bx r14 "
); );
} }
/*-----------------------------------------------------------*/
#if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority( void )
{
unsigned long ulCurrentInterrupt;
unsigned char ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
/* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
{
/* Look up the interrupt's priority. */
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid.
FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible.
The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
}
/* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority).
If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredicable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}
#endif /* configASSERT_DEFINED */

View File

@ -1,48 +1,37 @@
/* /*
FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
*************************************************************************** ***************************************************************************
* * * *
* FreeRTOS tutorial books are available in pdf and paperback. * * FreeRTOS provides completely free yet professionally developed, *
* Complete, revised, and edited pdf reference manuals are also * * robust, strictly quality controlled, supported, and cross *
* available. * * platform software that has become a de facto standard. *
* * * *
* Purchasing FreeRTOS documentation will not only help you, by * * Help yourself get started quickly and support the FreeRTOS *
* ensuring you get running as quickly as possible and with an * * project by purchasing a FreeRTOS tutorial book, reference *
* in-depth knowledge of how to use FreeRTOS, it will also help * * manual, or both from: http://www.FreeRTOS.org/Documentation *
* 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! *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* * * *
*************************************************************************** ***************************************************************************
This file is part of the FreeRTOS distribution. This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to >>! NOTE: The modification to the GPL is included to allow you to distribute
distribute a combined work that includes FreeRTOS without being obliged to >>! a combined work that includes FreeRTOS without being obliged to provide
provide the source code for proprietary components outside of the FreeRTOS >>! the source code for proprietary components outside of the FreeRTOS
kernel. >>! kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. Full license text is available from the following
details. You should have received a copy of the GNU General Public License link: http://www.freertos.org/a00114.html
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces! 1 tab == 4 spaces!
@ -55,21 +44,22 @@
* * * *
*************************************************************************** ***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions, http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details. license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fully thread aware and reentrant UDP/IP stack. compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support, Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
indemnification and middleware, under the OpenRTOS brand. licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability. mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
@ -111,14 +101,18 @@ extern "C" {
/* Architecture specifics. */ /* Architecture specifics. */
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) #define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8 // APCS 8 bytes aligned stack for external calls #define portBYTE_ALIGNMENT 8
#define portBYTE_HEAP_ALIGNMENT 4 // this value is used to allocate heap
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Scheduler utilities. */ /* Scheduler utilities. */
extern void vPortYieldFromISR( void ); extern void vPortYield( void );
#define portYIELD() vPortYieldFromISR() #define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR() #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */
@ -133,10 +127,6 @@ extern void vPortClearInterruptMask( unsigned long ulNewMaskValue );
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/* There are an uneven number of items on the initial stack, so
portALIGNMENT_ASSERT_pxCurrentTCB() will trigger false positive asserts. */
#define portALIGNMENT_ASSERT_pxCurrentTCB ( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
@ -182,6 +172,11 @@ not necessary for to use this port. They are defined so the common demo files
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef configASSERT
void vPortValidateInterruptPriority( void );
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
#endif
/* portNOP() is not required by this port. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -353,7 +353,7 @@ static void PIOS_USART_generic_irq_handler(uint32_t usart_id)
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (rx_need_yield || tx_need_yield) { if (rx_need_yield || tx_need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
} }

View File

@ -235,7 +235,7 @@ static bool PIOS_USB_CDC_SendData(struct pios_usb_cdc_dev *usb_cdc_dev)
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
@ -673,7 +673,7 @@ static bool PIOS_USB_CDC_DATA_EP_OUT_Callback(
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */

View File

@ -228,7 +228,7 @@ static bool PIOS_USB_HID_SendReport(struct pios_usb_hid_dev *usb_hid_dev)
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */
@ -542,7 +542,7 @@ static bool PIOS_USB_HID_EP_OUT_Callback(uint32_t usb_hid_id, __attribute__((unu
#if defined(PIOS_INCLUDE_FREERTOS) #if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) { if (need_yield) {
vPortYieldFromISR(); vPortYield();
} }
#endif /* PIOS_INCLUDE_FREERTOS */ #endif /* PIOS_INCLUDE_FREERTOS */