FreeRTOS 9.0.1

This commit is contained in:
Our Air Quality 2017-07-05 14:17:41 +10:00
parent 5583543f14
commit 17eb160be7
26 changed files with 1347 additions and 615 deletions

View file

@ -1,65 +1,61 @@
The FreeRTOS.org source code is licensed by the *modified* GNU General Public The FreeRTOS open source license covers the FreeRTOS source files,
License (GPL), text provided below. A special exception to the GPL is which are located in the /FreeRTOS/Source directory of the official FreeRTOS
included to allow you to distribute a combined work that includes FreeRTOS download. It also covers most of the source files in the demo application
without being obliged to provide the source code for any proprietary projects, which are located in the /FreeRTOS/Demo directory of the official
components. See the licensing section of http://www.FreeRTOS.org for full FreeRTOS download. The demo projects may also include third party software that
details. The exception text is also included at the bottom of this file. is not part of FreeRTOS and is licensed separately to FreeRTOS. Examples of
third party software includes header files provided by chip or tools vendors,
linker scripts, peripheral drivers, etc. All the software in subdirectories of
the /FreeRTOS directory is either open source or distributed with permission,
and is free for use. For the avoidance of doubt, refer to the comments at the
top of each source file.
The FreeRTOS download also includes demo application source code, some of ----------------------------------------------------------------------------
which is provided by third parties AND IS LICENSED SEPARATELY FROM FREERTOS.
For the avoidance of any doubt refer to the comment included at the top NOTE: The modification to the GPL is included to allow you to distribute a
of each source and header file for license and copyright information. combined work that includes FreeRTOS without being obliged to provide the source
code for proprietary components.
This is a list of files for which Real Time Engineers Ltd are not the ----------------------------------------------------------------------------
copyright owner and are NOT COVERED BY THE GPL.
Applying to FreeRTOS V8.2.3 up to the latest version, the FreeRTOS GPL Exception
Text follows:
Any FreeRTOS *source code*, whether modified or in it's original release form,
or whether in whole or in part, can only be distributed by you under the terms
of the GNU General Public License plus this exception. An independent module is
a module which is not derived from or based on FreeRTOS.
Clause 1:
Linking FreeRTOS with other modules is making a combined work based on FreeRTOS.
Thus, the terms and conditions of the GNU General Public License V2 cover the
whole combination.
As a special exception, the copyright holders of FreeRTOS give you permission to
link FreeRTOS with independent modules to produce a statically linked
executable, regardless of the license terms of these independent modules, and to
copy and distribute the resulting executable under terms of your choice,
provided that you also meet, for each linked independent module, the terms and
conditions of the license of that module. An independent module is a module
which is not derived from or based on FreeRTOS.
Clause 2:
FreeRTOS may not be used for any competitive or comparative purpose, including
the publication of any form of run time or compile time metric, without the
express permission of Real Time Engineers Ltd. (this is the norm within the
industry and is intended to ensure information accuracy).
1) Various header files provided by silicon manufacturers and tool vendors
that define processor specific memory addresses and utility macros.
Permission has been granted by the various copyright holders for these
files to be included in the FreeRTOS download. Users must ensure license
conditions are adhered to for any use other than compilation of the
FreeRTOS demo applications.
2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels.
Users must ensure the open source license conditions stated at the top
of each uIP source file is understood and adhered to.
3) The lwIP TCP/IP stack the copyright of which is held by the Swedish
Institute of Computer Science. Users must ensure the open source license
conditions stated at the top of each lwIP source file is understood and
adhered to.
4) Various peripheral driver source files and binaries provided by silicon
manufacturers and tool vendors. Permission has been granted by the
various copyright holders for these files to be included in the FreeRTOS
download. Users must ensure license conditions are adhered to for any
use other than compilation of the FreeRTOS demo applications.
5) The files contained within FreeRTOS\Demo\WizNET_DEMO_TERN_186\tern_code,
which are slightly modified versions of code provided by and copyright to
Tern Inc.
Errors and omissions should be reported to Richard Barry, contact details for
whom can be obtained from http://www.FreeRTOS.org.
The GPL license text follows.
A special exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details. The exception text is also
included at the bottom of this file.
-------------------------------------------------------------------- --------------------------------------------------------------------
The standard GPL V2 text:
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
@ -401,40 +397,3 @@ consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General library. If this is what you want to do, use the GNU Library General
Public License instead of this License. Public License instead of this License.
----------------------------------------------------------------------------
The FreeRTOS GPL Exception Text:
Any FreeRTOS source code, whether modified or in it's original release form,
or whether in whole or in part, can only be distributed by you under the terms
of the GNU General Public License plus this exception. An independent module is
a module which is not derived from or based on FreeRTOS.
Clause 1:
Linking FreeRTOS statically or dynamically with other modules is making a
combined work based on FreeRTOS. Thus, the terms and conditions of the GNU
General Public License cover the whole combination.
As a special exception, the copyright holder of FreeRTOS gives you permission
to link FreeRTOS with independent modules that communicate with FreeRTOS
solely through the FreeRTOS API interface, regardless of the license terms of
these independent modules, and to copy and distribute the resulting combined
work under terms of your choice, provided that
+ Every copy of the combined work is accompanied by a written statement that
details to the recipient the version of FreeRTOS used and an offer by yourself
to provide the FreeRTOS source code (including any modifications you may have
made) should the recipient request it.
+ The combined work is not itself an RTOS, scheduler, kernel or related product.
+ The independent modules add significant and primary functionality to FreeRTOS
and do not merely extend the existing functionality already present in FreeRTOS.
Clause 2:
FreeRTOS may not be used for any competitive or comparative purpose, including the
publication of any form of run time or compile time metric, without the express
permission of Real Time Engineers Ltd. (this is the norm within the industry and
is intended to ensure information accuracy).

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -139,6 +139,16 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
/* A StaticEventGroup_t object must be provided. */ /* A StaticEventGroup_t object must be provided. */
configASSERT( pxEventGroupBuffer ); configASSERT( pxEventGroupBuffer );
#if( configASSERT_DEFINED == 1 )
{
/* Sanity check that the size of the structure used to declare a
variable of type StaticEventGroup_t equals the size of the real
event group structure. */
volatile size_t xSize = sizeof( StaticEventGroup_t );
configASSERT( xSize == sizeof( EventGroup_t ) );
}
#endif /* configASSERT_DEFINED */
/* The user has provided a statically allocated event group - use it. */ /* The user has provided a statically allocated event group - use it. */
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
@ -602,7 +612,7 @@ BaseType_t xMatchFound = pdFALSE;
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
that is was unblocked due to its required bits matching, rather that is was unblocked due to its required bits matching, rather
than because it timed out. */ than because it timed out. */
( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
} }
/* Move onto the next list item. Note pxListItem->pxNext is not /* Move onto the next list item. Note pxListItem->pxNext is not
@ -633,9 +643,9 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
{ {
/* Unblock the task, returning 0 as the event list is being deleted /* Unblock the task, returning 0 as the event list is being deleted
and cannot therefore have any bits set. */ and cannot therefore have any bits set. */
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
} }
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -126,6 +126,10 @@ extern "C" {
#error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details.
#endif #endif
#if configMAX_PRIORITIES < 1
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
#endif
#ifndef configUSE_PREEMPTION #ifndef configUSE_PREEMPTION
#error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif #endif
@ -142,10 +146,6 @@ extern "C" {
#error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif #endif
#ifndef configMAX_PRIORITIES
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
#endif
#ifndef configUSE_CO_ROUTINES #ifndef configUSE_CO_ROUTINES
#define configUSE_CO_ROUTINES 0 #define configUSE_CO_ROUTINES 0
#endif #endif
@ -408,6 +408,14 @@ extern "C" {
#define configCHECK_FOR_STACK_OVERFLOW 0 #define configCHECK_FOR_STACK_OVERFLOW 0
#endif #endif
#ifndef configRECORD_STACK_HIGH_ADDRESS
#define configRECORD_STACK_HIGH_ADDRESS 0
#endif
#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H
#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0
#endif
/* The following event macros are embedded in the kernel API calls. */ /* The following event macros are embedded in the kernel API calls. */
#ifndef traceMOVED_TASK_TO_READY_STATE #ifndef traceMOVED_TASK_TO_READY_STATE
@ -708,6 +716,10 @@ extern "C" {
#define configUSE_TICKLESS_IDLE 0 #define configUSE_TICKLESS_IDLE 0
#endif #endif
#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING
#define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x )
#endif
#ifndef configPRE_SLEEP_PROCESSING #ifndef configPRE_SLEEP_PROCESSING
#define configPRE_SLEEP_PROCESSING( x ) #define configPRE_SLEEP_PROCESSING( x )
#endif #endif
@ -724,6 +736,10 @@ extern "C" {
#define portTASK_USES_FLOATING_POINT() #define portTASK_USES_FLOATING_POINT()
#endif #endif
#ifndef portTASK_CALLS_SECURE_FUNCTIONS
#define portTASK_CALLS_SECURE_FUNCTIONS()
#endif
#ifndef configUSE_TIME_SLICING #ifndef configUSE_TIME_SLICING
#define configUSE_TIME_SLICING 1 #define configUSE_TIME_SLICING 1
#endif #endif
@ -782,6 +798,12 @@ extern "C" {
#define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1
#endif #endif
#ifndef configSTACK_DEPTH_TYPE
/* Defaults to uint16_t for backward compatibility, but can be overridden
in FreeRTOSConfig.h if uint16_t is too restrictive. */
#define configSTACK_DEPTH_TYPE uint16_t
#endif
/* Sanity check the configuration. */ /* Sanity check the configuration. */
#if( configUSE_TICKLESS_IDLE != 0 ) #if( configUSE_TICKLESS_IDLE != 0 )
#if( INCLUDE_vTaskSuspend != 1 ) #if( INCLUDE_vTaskSuspend != 1 )
@ -797,6 +819,10 @@ extern "C" {
#error configUSE_MUTEXES must be set to 1 to use recursive mutexes #error configUSE_MUTEXES must be set to 1 to use recursive mutexes
#endif #endif
#ifndef configINITIAL_TICK_COUNT
#define configINITIAL_TICK_COUNT 0
#endif
#if( portTICK_TYPE_IS_ATOMIC == 0 ) #if( portTICK_TYPE_IS_ATOMIC == 0 )
/* Either variables of tick type cannot be read atomically, or /* Either variables of tick type cannot be read atomically, or
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
@ -917,7 +943,7 @@ typedef struct xSTATIC_TCB
UBaseType_t uxDummy5; UBaseType_t uxDummy5;
void *pxDummy6; void *pxDummy6;
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
#if ( portSTACK_GROWTH > 0 ) #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
void *pxDummy8; void *pxDummy8;
#endif #endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 ) #if ( portCRITICAL_NESTING_IN_TCB == 1 )
@ -945,10 +971,14 @@ typedef struct xSTATIC_TCB
uint32_t ulDummy18; uint32_t ulDummy18;
uint8_t ucDummy19; uint8_t ucDummy19;
#endif #endif
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) #if( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) || ( portUSING_MPU_WRAPPERS == 1 ) )
uint8_t uxDummy20; uint8_t uxDummy20;
#endif #endif
#if( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDummy21;
#endif
} StaticTask_t; } StaticTask_t;
/* /*

View file

@ -1,15 +1,38 @@
/* Default esp-open-sdk FreeRTOSConfig file. /*
FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved
You can override settings in here by creating your own VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
FreeRTOSConfig.h file in your program directory.
You could just copy this file there and edit it, but it's This file is part of the FreeRTOS distribution.
recommended you instead define whatever you want to override and
then use #include_next<FreeRTOSConfig.h> to pick up these defaults.
The "blink" example in "examples/blink" provides an example of how FreeRTOS is free software; you can redistribute it and/or modify it under
to do this. the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
For esp-open-rtos, you can override settings in here by creating your own
FreeRTOSConfig.h file in your program directory. You could just copy this
file there and edit it, but it's recommended you instead define whatever you
want to override and then use #include_next<FreeRTOSConfig.h> to pick up
these defaults. The "blink" example in "examples/blink" provides an example
of how to do this.
1 tab == 4 spaces!
*/ */
#ifndef __DEFAULT_FREERTOS_CONFIG_H #ifndef __DEFAULT_FREERTOS_CONFIG_H
#define __DEFAULT_FREERTOS_CONFIG_H #define __DEFAULT_FREERTOS_CONFIG_H
@ -47,7 +70,7 @@
#define configTICK_RATE_HZ ( ( TickType_t ) 100 ) #define configTICK_RATE_HZ ( ( TickType_t ) 100 )
#endif #endif
#ifndef configMAX_PRIORITIES #ifndef configMAX_PRIORITIES
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 ) #define configMAX_PRIORITIES ( 15 )
#endif #endif
#ifndef configMINIMAL_STACK_SIZE #ifndef configMINIMAL_STACK_SIZE
#define configMINIMAL_STACK_SIZE ( ( unsigned short )256 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short )256 )
@ -108,6 +131,10 @@
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#endif #endif
#ifndef configUSE_NEWLIB_REENTRANT
#define configUSE_NEWLIB_REENTRANT 1
#endif
/* Set the following definitions to 1 to include the API function, or zero /* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */ to exclude the API function. */
#ifndef INCLUDE_vTaskPrioritySet #ifndef INCLUDE_vTaskPrioritySet
@ -144,5 +171,10 @@ to exclude the API function. */
#define configENABLE_BACKWARD_COMPATIBILITY 0 #define configENABLE_BACKWARD_COMPATIBILITY 0
#endif #endif
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
void vAssertCalled(const char * pcFile, unsigned long ulLine);
#define configASSERT(x) if((x) == 0) vAssertCalled(__FILE__, __LINE__);
#endif /* __DEFAULT_FREERTOS_CONFIG_H */ #endif /* __DEFAULT_FREERTOS_CONFIG_H */

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -205,7 +205,7 @@ typedef struct xMINI_LIST_ITEM MiniListItem_t;
typedef struct xLIST typedef struct xLIST
{ {
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
configLIST_VOLATILE UBaseType_t uxNumberOfItems; volatile UBaseType_t uxNumberOfItems;
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
MiniListItem_t 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. */ MiniListItem_t 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. */
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -83,6 +83,7 @@
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ); BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask );
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ); TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer );
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ); BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ); void MPU_vTaskDelete( TaskHandle_t xTaskToDelete );
void MPU_vTaskDelay( const TickType_t xTicksToDelay ); void MPU_vTaskDelay( const TickType_t xTicksToDelay );
@ -124,7 +125,9 @@ BaseType_t MPU_xTaskGetSchedulerState( void );
/* MPU versions of queue.h API function. */ /* MPU versions of queue.h API function. */
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ); BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition );
BaseType_t MPU_xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ); BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait );
BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait );
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait );
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ); UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue );
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ); UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue );
void MPU_vQueueDelete( QueueHandle_t xQueue ); void MPU_vQueueDelete( QueueHandle_t xQueue );

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -130,7 +130,9 @@ only for ports that are using the MPU. */
/* Map standard queue.h API functions to the MPU equivalents. */ /* Map standard queue.h API functions to the MPU equivalents. */
#define xQueueGenericSend MPU_xQueueGenericSend #define xQueueGenericSend MPU_xQueueGenericSend
#define xQueueGenericReceive MPU_xQueueGenericReceive #define xQueueReceive MPU_xQueueReceive
#define xQueuePeek MPU_xQueuePeek
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
#define vQueueDelete MPU_vQueueDelete #define vQueueDelete MPU_vQueueDelete
@ -177,8 +179,11 @@ only for ports that are using the MPU. */
#define xEventGroupSync MPU_xEventGroupSync #define xEventGroupSync MPU_xEventGroupSync
#define vEventGroupDelete MPU_vEventGroupDelete #define vEventGroupDelete MPU_vEventGroupDelete
/* Remove the privileged function macro. */ /* Remove the privileged function macro, but keep the PRIVILEGED_DATA
macro so applications can place data in privileged access sections
(useful when using statically allocated objects). */
#define PRIVILEGED_FUNCTION #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -696,12 +696,10 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQ
* <pre> * <pre>
BaseType_t xQueuePeek( BaseType_t xQueuePeek(
QueueHandle_t xQueue, QueueHandle_t xQueue,
void *pvBuffer, void * const pvBuffer,
TickType_t xTicksToWait TickType_t xTicksToWait
);</pre> );</pre>
* *
* This is a macro that calls the xQueueGenericReceive() function.
*
* Receive an item from a queue without removing the item from the queue. * 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 * 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 * provided. The number of bytes copied into the buffer was defined when
@ -782,10 +780,10 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQ
// ... Rest of task code. // ... Rest of task code.
} }
</pre> </pre>
* \defgroup xQueueReceive xQueueReceive * \defgroup xQueuePeek xQueuePeek
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
@ -829,8 +827,6 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
TickType_t xTicksToWait TickType_t xTicksToWait
);</pre> );</pre>
* *
* This is a macro that calls the xQueueGenericReceive() function.
*
* Receive an item from a queue. The item is received by copy so a buffer of * Receive an item from a queue. The item is received by copy so a buffer of
* adequate size must be provided. The number of bytes copied into the buffer * adequate size must be provided. The number of bytes copied into the buffer
* was defined when the queue was created. * was defined when the queue was created.
@ -911,106 +907,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
* \defgroup xQueueReceive xQueueReceive * \defgroup xQueueReceive xQueueReceive
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/**
* queue. h
* <pre>
BaseType_t xQueueGenericReceive(
QueueHandle_t xQueue,
void *pvBuffer,
TickType_t xTicksToWait
BaseType_t xJustPeek
);</pre>
*
* It is preferred that the macro xQueueReceive() be used rather than calling
* this function directly.
*
* Receive an item from a queue. The item is received by copy so a buffer of
* adequate size must be provided. The number of bytes copied into the buffer
* was defined when the queue was created.
*
* This function must not be used in an interrupt service routine. See
* xQueueReceiveFromISR for an alternative that can.
*
* @param 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.
*
* @param xTicksToWait The maximum amount of time the task should block
* waiting for an item to receive should the queue be empty at the time
* of the call. The time is defined in tick periods so the constant
* portTICK_PERIOD_MS should be used to convert to real time if this is required.
* xQueueGenericReceive() will return immediately if the queue is empty and
* xTicksToWait is 0.
*
* @param xJustPeek When set to true, the item received from the queue is not
* actually removed from the queue - meaning a subsequent call to
* xQueueReceive() will return the same item. When set to false, the item
* being received from the queue is also removed from the queue.
*
* @return pdTRUE if an item was successfully received from the queue,
* otherwise pdFALSE.
*
* Example usage:
<pre>
struct AMessage
{
char ucMessageID;
char ucData[ 20 ];
} xMessage;
QueueHandle_t xQueue;
// Task to create a queue and post a value.
void vATask( void *pvParameters )
{
struct AMessage *pxMessage;
// Create a queue capable of containing 10 pointers to AMessage structures.
// These should be passed by pointer as they contain a lot of data.
xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
if( xQueue == 0 )
{
// Failed to create the queue.
}
// ...
// Send a pointer to a struct AMessage object. Don't block if the
// queue is already full.
pxMessage = & xMessage;
xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
// ... Rest of task code.
}
// Task to receive from the queue.
void vADifferentTask( void *pvParameters )
{
struct AMessage *pxRxedMessage;
if( xQueue != 0 )
{
// Receive a message on the created queue. Block for 10 ticks if a
// message is not immediately available.
if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
{
// pcRxedMessage now points to the struct AMessage variable posted
// by vATask.
}
}
// ... Rest of task code.
}
</pre>
* \defgroup xQueueReceive xQueueReceive
* \ingroup QueueManagement
*/
BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ) PRIVILEGED_FUNCTION;
/** /**
* queue. h * queue. h
@ -1560,7 +1457,9 @@ QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION
QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION;
QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;
QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION;
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
void* xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
/* /*
* For internal use only. Use xSemaphoreTakeMutexRecursive() or * For internal use only. Use xSemaphoreTakeMutexRecursive() or

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -328,7 +328,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup xSemaphoreTake xSemaphoreTake * \defgroup xSemaphoreTake xSemaphoreTake
* \ingroup Semaphores * \ingroup Semaphores
*/ */
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
/** /**
* semphr. h * semphr. h
@ -392,23 +392,23 @@ typedef QueueHandle_t SemaphoreHandle_t;
// ... // ...
// For some reason due to the nature of the code further calls to // For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real // xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make // code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside // no sense. Instead the calls are likely to be buried inside
// a more complex call structure. // a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
// The mutex has now been 'taken' three times, so will not be // The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back // available to another task until it has also been given back
// three times. Again it is unlikely that real code would have // three times. Again it is unlikely that real code would have
// these calls sequentially, but instead buried in a more complex // these calls sequentially, but instead buried in a more complex
// call structure. This is just for illustrative purposes. // call structure. This is just for illustrative purposes.
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex ); xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
// Now the mutex can be taken by other tasks. // Now the mutex can be taken by other tasks.
} }
else else
{ {
@ -1154,6 +1154,17 @@ typedef QueueHandle_t SemaphoreHandle_t;
*/ */
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
/**
* semphr.h
* <pre>TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );</pre>
*
* If xMutex is indeed a mutex type semaphore, return the current mutex holder.
* If xMutex is not a mutex type semaphore, or the mutex is available (not held
* by a task), return NULL.
*
*/
#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) )
/** /**
* semphr.h * semphr.h
* <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre> * <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -160,6 +160,9 @@ typedef struct xTASK_PARAMETERS
UBaseType_t uxPriority; UBaseType_t uxPriority;
StackType_t *puxStackBuffer; StackType_t *puxStackBuffer;
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
StaticTask_t * const pxTaskBuffer;
#endif
} TaskParameters_t; } TaskParameters_t;
/* Used with the uxTaskGetSystemState() function to return the state of each task /* Used with the uxTaskGetSystemState() function to return the state of each task
@ -269,7 +272,7 @@ is used in assert() statements. */
BaseType_t xTaskCreate( BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode, TaskFunction_t pvTaskCode,
const char * const pcName, const char * const pcName,
uint16_t usStackDepth, configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters, void *pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
TaskHandle_t *pvCreatedTask TaskHandle_t *pvCreatedTask
@ -358,11 +361,11 @@ is used in assert() statements. */
*/ */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint16_t usStackDepth, const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif #endif
/** /**
@ -474,12 +477,12 @@ is used in assert() statements. */
*/ */
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #if( configSUPPORT_STATIC_ALLOCATION == 1 )
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth, const uint32_t ulStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
StackType_t * const puxStackBuffer, StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION;
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
/** /**
@ -487,6 +490,8 @@ is used in assert() statements. */
*<pre> *<pre>
BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );</pre> BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );</pre>
* *
* Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1.
*
* xTaskCreateRestricted() should only be used in systems that include an MPU * xTaskCreateRestricted() should only be used in systems that include an MPU
* implementation. * implementation.
* *
@ -494,6 +499,9 @@ is used in assert() statements. */
* The function parameters define the memory regions and associated access * The function parameters define the memory regions and associated access
* permissions allocated to the task. * permissions allocated to the task.
* *
* See xTaskCreateRestrictedStatic() for a version that does not use any
* dynamic memory allocation.
*
* @param pxTaskDefinition Pointer to a structure that contains a member * @param pxTaskDefinition Pointer to a structure that contains a member
* for each of the normal xTaskCreate() parameters (see the xTaskCreate() API * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
* documentation) plus an optional stack buffer and the memory region * documentation) plus an optional stack buffer and the memory region
@ -553,6 +561,94 @@ TaskHandle_t xHandle;
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif #endif
/**
* task. h
*<pre>
BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );</pre>
*
* Only available when configSUPPORT_STATIC_ALLOCATION is set to 1.
*
* xTaskCreateRestrictedStatic() should only be used in systems that include an
* MPU implementation.
*
* Internally, within the FreeRTOS implementation, tasks use two blocks of
* memory. The first block is used to hold the task's data structures. The
* second block is used by the task as its stack. If a task is created using
* xTaskCreateRestricted() then the stack is provided by the application writer,
* and the memory used to hold the task's data structure is automatically
* dynamically allocated inside the xTaskCreateRestricted() function. If a task
* is created using xTaskCreateRestrictedStatic() then the application writer
* must provide the memory used to hold the task's data structures too.
* xTaskCreateRestrictedStatic() therefore allows a memory protected task to be
* created without using any dynamic memory allocation.
*
* @param pxTaskDefinition Pointer to a structure that contains a member
* for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
* documentation) plus an optional stack buffer and the memory region
* definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure
* contains an additional member, which is used to point to a variable of type
* StaticTask_t - which is then used to hold the task's data structure.
*
* @param pxCreatedTask Used to pass back a handle by which the created task
* can be referenced.
*
* @return pdPASS if the task was successfully created and added to a ready
* list, otherwise an error code defined in the file projdefs.h
*
* Example usage:
<pre>
// Create an TaskParameters_t structure that defines the task to be created.
// The StaticTask_t variable is only included in the structure when
// configSUPPORT_STATIC_ALLOCATION is set to 1. The PRIVILEGED_DATA macro can
// be used to force the variable into the RTOS kernel's privileged data area.
static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
static const TaskParameters_t xCheckTaskParameters =
{
vATask, // pvTaskCode - the function that implements the task.
"ATask", // pcName - just a text name for the task to assist debugging.
100, // usStackDepth - the stack size DEFINED IN WORDS.
NULL, // pvParameters - passed into the task function as the function parameters.
( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
// xRegions - Allocate up to three separate memory regions for access by
// the task, with appropriate access permissions. Different processors have
// different memory alignment requirements - refer to the FreeRTOS documentation
// for full information.
{
// Base address Length Parameters
{ cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
{ cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
{ cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
}
&xTaskBuffer; // Holds the task's data structure.
};
int main( void )
{
TaskHandle_t xHandle;
// Create a task from the const structure defined above. The task handle
// is requested (the second parameter is not NULL) but in this case just for
// demonstration purposes as its not actually used.
xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
// Start the scheduler.
vTaskStartScheduler();
// Will only get here if there was insufficient memory to create the idle
// and/or timer task.
for( ;; );
}
</pre>
* \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic
* \ingroup Tasks
*/
#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif
/** /**
* task. h * task. h
*<pre> *<pre>
@ -2141,14 +2237,14 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi
* Removes a task from both the specified event list and the list of blocked * Removes a task from both the specified event list and the list of blocked
* tasks, and places it on a ready queue. * tasks, and places it on a ready queue.
* *
* xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called
* if either an event occurs to unblock a task, or the block timeout period * if either an event occurs to unblock a task, or the block timeout period
* expires. * expires.
* *
* xTaskRemoveFromEventList() is used when the event list is in task priority * xTaskRemoveFromEventList() is used when the event list is in task priority
* order. It removes the list item from the head of the event list as that will * order. It removes the list item from the head of the event list as that will
* have the highest priority owning task of all the tasks on the event list. * have the highest priority owning task of all the tasks on the event list.
* xTaskRemoveFromUnorderedEventList() is used when the event list is not * vTaskRemoveFromUnorderedEventList() is used when the event list is not
* ordered and the event list items hold something other than the owning tasks * ordered and the event list items hold something other than the owning tasks
* priority. In this case the event list item value is updated to the value * priority. In this case the event list item value is updated to the value
* passed in the xItemValue parameter. * passed in the xItemValue parameter.
@ -2157,7 +2253,7 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi
* making the call, otherwise pdFALSE. * making the call, otherwise pdFALSE.
*/ */
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION;
BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION;
/* /*
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
@ -2207,7 +2303,7 @@ BaseType_t 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( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; BaseType_t xTaskPriorityInherit( TaskHandle_t 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
@ -2215,6 +2311,16 @@ void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTIO
*/ */
BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;
/*
* If a higher priority task attempting to obtain a mutex caused a lower
* priority task to inherit the higher priority task's priority - but the higher
* priority task then timed out without obtaining the mutex, then the lower
* priority task will disinherit the priority again - but only down as far as
* the highest priority task that is still waiting for the mutex (if there were
* more than one task waiting for the mutex).
*/
void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION;
/* /*
* Get the uxTCBNumber assigned to the task referenced by the xTask parameter. * Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
*/ */
@ -2258,6 +2364,13 @@ eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;
*/ */
void *pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; void *pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
/*
* For internal use only. Same as vTaskSetTimeOutState(), but without a critial
* section.
*/
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -75,10 +75,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
/*lint -e537 This headers are only multiply included if the application code /*lint -save -e537 This headers are only multiply included if the application code
happens to also be including task.h. */ happens to also be including task.h. */
#include "task.h" #include "task.h"
/*lint +e537 */ /*lint -restore */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -266,11 +266,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* @endverbatim * @endverbatim
*/ */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreate( const char * const pcTimerName, TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
#endif #endif
/** /**
@ -396,12 +396,12 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* @endverbatim * @endverbatim
*/ */
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #if( configSUPPORT_STATIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION;
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
/** /**

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -73,10 +73,12 @@
#include <malloc.h> #include <malloc.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <xtensa_ops.h> #include <xtensa_ops.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "queue.h"
#include "xtensa_rtos.h" #include "xtensa_rtos.h"
unsigned cpu_sr; unsigned cpu_sr;
@ -91,6 +93,13 @@ char level1_int_disabled;
*/ */
void *xPortSupervisorStackPointer; void *xPortSupervisorStackPointer;
void vAssertCalled(const char * pcFile, unsigned long ulLine)
{
printf("rtos assert %s %lu\n", pcFile, ulLine);
abort();
//for (;;);
}
/* /*
* Stack initialization * Stack initialization
*/ */
@ -100,7 +109,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, TaskFunctio
portSTACK_TYPE *sp, *tp; portSTACK_TYPE *sp, *tp;
/* Create interrupt stack frame aligned to 16 byte boundary */ /* Create interrupt stack frame aligned to 16 byte boundary */
sp = (portSTACK_TYPE*) (((uint32_t)(pxTopOfStack+1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf); sp = (portSTACK_TYPE*) (((uint32_t)(pxTopOfStack + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
/* Clear the entire frame (do not use memset() because we don't depend on C library) */ /* Clear the entire frame (do not use memset() because we don't depend on C library) */
for (tp = sp; tp <= pxTopOfStack; ++tp) for (tp = sp; tp <= pxTopOfStack; ++tp)
@ -121,30 +130,29 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, TaskFunctio
static int pending_soft_sv; static int pending_soft_sv;
static int pending_maclayer_sv; static int pending_maclayer_sv;
/* PendSV is called in place of vPortYield() to request a supervisor /*
call. * The portYIELD macro calls PendSV with SVC_Software to set a pending interrupt
* service callback that allows a task switch, and this occur when interrupts
The portYIELD macro calls pendSV if it's a software request. * are enabled which might be after exiting the critical region below.
*
The libpp and libudhcp libraries also call this function, assuming * The wdev NMI calls this function from pp_post() with SVC_MACLayer to set a
always with arg==2 (but maybe sometimes with arg==1?) * pending interrupt service callback which flushs the queue of messages that
* the NMI stashes away. This interrupt will be triggered after the return from
In the original esp_iot_rtos_sdk implementation, arg was a char. Using an * the NMI and when interrupts are enabled. The NMI can not touch the FreeRTOS
enum is ABI-compatible, though. * queues itself. The NMI must not touch the interrupt masks so that path must
*/ * not call vPortEnterCritical and vPortExitCritical.
*/
void IRAM PendSV(enum SVC_ReqType req) void IRAM PendSV(enum SVC_ReqType req)
{ {
vPortEnterCritical(); if (req == SVC_Software) {
vPortEnterCritical();
if(req == SVC_Software) pending_soft_sv = 1;
{ WSR(BIT(INUM_SOFT), interrupt);
pending_soft_sv = 1; vPortExitCritical();
} } else if (req == SVC_MACLayer) {
else if(req == SVC_MACLayer) pending_maclayer_sv= 1;
pending_maclayer_sv= 1; WSR(BIT(INUM_SOFT), interrupt);
}
WSR(BIT(INUM_SOFT), interrupt);
vPortExitCritical();
} }
/* This MAC layer ISR handler is defined in libpp.a, and is called /* This MAC layer ISR handler is defined in libpp.a, and is called
@ -155,29 +163,22 @@ extern portBASE_TYPE sdk_MacIsrSigPostDefHdl(void);
void IRAM SV_ISR(void *arg) void IRAM SV_ISR(void *arg)
{ {
portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE ; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE ;
if(pending_maclayer_sv) if (pending_maclayer_sv) {
{ xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl();
xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl(); pending_maclayer_sv = 0;
pending_maclayer_sv = 0; }
} if (xHigherPriorityTaskWoken || pending_soft_sv) {
if( xHigherPriorityTaskWoken || pending_soft_sv) sdk__xt_timer_int1();
{ pending_soft_sv = 0;
sdk__xt_timer_int1(); }
pending_soft_sv = 0;
}
} }
void xPortSysTickHandle (void) void xPortSysTickHandle (void)
{ {
//CloseNMI(); if (xTaskIncrementTick() != pdFALSE) {
{ vTaskSwitchContext();
if(xTaskIncrementTick() !=pdFALSE ) }
{
vTaskSwitchContext();
}
}
//OpenNMI();
} }
/* /*
@ -221,8 +222,10 @@ size_t xPortGetFreeHeapSize( void )
uint32_t brk_val = (uint32_t) sbrk(0); uint32_t brk_val = (uint32_t) sbrk(0);
intptr_t sp = (intptr_t)xPortSupervisorStackPointer; intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
if(sp == 0) /* scheduler not started */ if (sp == 0) {
/* scheduler not started */
SP(sp); SP(sp);
}
return sp - brk_val + mi.fordblks; return sp - brk_val + mi.fordblks;
} }
@ -233,8 +236,6 @@ void vPortEndScheduler( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting
variable. */
static unsigned portBASE_TYPE uxCriticalNesting = 0; static unsigned portBASE_TYPE uxCriticalNesting = 0;
/* These nested vPortEnter/ExitCritical macros are called by SDK /* These nested vPortEnter/ExitCritical macros are called by SDK
@ -243,26 +244,42 @@ static unsigned portBASE_TYPE uxCriticalNesting = 0;
* It may be possible to replace the global nesting count variable * It may be possible to replace the global nesting count variable
* with a save/restore of interrupt level, although it's difficult as * with a save/restore of interrupt level, although it's difficult as
* the functions have no return value. * the functions have no return value.
*
* These should not be called from the NMI in regular operation and
* the NMI must not touch the interrupt mask, but that might occur in
* exceptional paths such as aborts and debug code.
*/ */
void IRAM vPortEnterCritical( void ) void IRAM vPortEnterCritical(void) {
{
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
uxCriticalNesting++; uxCriticalNesting++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void IRAM vPortExitCritical( void ) void IRAM vPortExitCritical(void) {
{
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if (uxCriticalNesting == 0)
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
/* Backward compatibility with libmain.a and libpp.a and can remove when these are open. */ /* Backward compatibility, for the sdk library. */
signed portBASE_TYPE xTaskGenericCreate( TaskFunction_t pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, TaskHandle_t *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const MemoryRegion_t * const xRegions )
{ signed portBASE_TYPE xTaskGenericCreate(TaskFunction_t pxTaskCode,
(void)puxStackBuffer; (void)xRegions; const signed char * const pcName,
return xTaskCreate( pxTaskCode, (const char * const)pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask); unsigned short usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
TaskHandle_t *pxCreatedTask,
portSTACK_TYPE *puxStackBuffer,
const MemoryRegion_t * const xRegions) {
(void)puxStackBuffer;
(void)xRegions;
return xTaskCreate(pxTaskCode, (const char * const)pcName, usStackDepth,
pvParameters, uxPriority, pxCreatedTask);
} }
BaseType_t xQueueGenericReceive(QueueHandle_t xQueue, void * const pvBuffer,
TickType_t xTicksToWait, const BaseType_t xJustPeeking) {
configASSERT(xJustPeeking == 0);
return xQueueReceive(xQueue, pvBuffer, xTicksToWait);
}

View file

@ -1,65 +1,29 @@
/* /*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution. 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 distribute ***************************************************************************
>>! a combined work that includes FreeRTOS without being obliged to provide >>! NOTE: The modification to the GPL is included to allow you to !<<
>>! the source code for proprietary components outside of the FreeRTOS >>! distribute a combined work that includes FreeRTOS without being !<<
>>! kernel. >>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 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. Full license text is available from the following FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html link: http://www.freertos.org/a00114.html
1 tab == 4 spaces! 1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/ */
@ -92,16 +56,15 @@ extern "C" {
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE unsigned portLONG #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
#define portPOINTER_SIZE_TYPE unsigned portLONG
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef portBASE_TYPE BaseType_t; typedef portBASE_TYPE BaseType_t;
typedef unsigned portBASE_TYPE UBaseType_t; typedef unsigned portBASE_TYPE UBaseType_t;
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffff #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* Architecture specifics. */ /* Architecture specifics. */
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
@ -156,6 +119,9 @@ extern unsigned cpu_sr;
prefer to _xt_disable_interrupts & _xt_enable_interrupts and store prefer to _xt_disable_interrupts & _xt_enable_interrupts and store
the ps value in a local variable - that approach is recursive-safe the ps value in a local variable - that approach is recursive-safe
and generally better. and generally better.
The NMI must not touch the interrupt mask and it should not in
regular operation, but there is a guard here just in case.
*/ */
inline static __attribute__((always_inline)) void portDISABLE_INTERRUPTS(void) inline static __attribute__((always_inline)) void portDISABLE_INTERRUPTS(void)
{ {
@ -185,6 +151,10 @@ not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* FreeRTOS API functions should not be called from the NMI handler. */
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT(sdk_NMIIrqIsOn == 0)
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -0,0 +1,20 @@
Each real time kernel port consists of three files that contain the core kernel
components and are common to every port, and one or more files that are
specific to a particular microcontroller and/or compiler.
+ The FreeRTOS/Source/Portable/MemMang directory contains the five sample
memory allocators as described on the http://www.FreeRTOS.org WEB site.
+ The other directories each contain files specific to a particular
microcontroller or compiler, where the directory name denotes the compiler
specific files the directory contains.
For example, if you are interested in the [compiler] port for the [architecture]
microcontroller, then the port specific files are contained in
FreeRTOS/Source/Portable/[compiler]/[architecture] directory. If this is the
only port you are interested in then all the other directories can be
ignored.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -255,6 +255,16 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION;
#endif #endif
#if( configUSE_MUTEXES == 1 )
/*
* If a task waiting for a mutex causes the mutex holder to inherit a
* priority, but the waiting task times out, then the holder should
* disinherit the priority - but only down to the highest priority of any
* other tasks that are waiting for the same mutex. This function returns
* that priority.
*/
static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;
#endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -374,6 +384,10 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue );
} }
else
{
traceQUEUE_CREATE_FAILED( ucQueueType );
}
return pxNewQueue; return pxNewQueue;
} }
@ -422,6 +436,10 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue );
} }
else
{
traceQUEUE_CREATE_FAILED( ucQueueType );
}
return pxNewQueue; return pxNewQueue;
} }
@ -567,6 +585,32 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
void* xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore )
{
void *pxReturn;
configASSERT( xSemaphore );
/* Mutexes cannot be used in interrupt service routines, so the mutex
holder should not change in an ISR, and therefore a critical section is
not required here. */
if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX )
{
pxReturn = ( void * ) ( ( Queue_t * ) xSemaphore )->pxMutexHolder;
}
else
{
pxReturn = NULL;
}
return pxReturn;
} /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */
#endif
/*-----------------------------------------------------------*/
#if ( configUSE_RECURSIVE_MUTEXES == 1 ) #if ( configUSE_RECURSIVE_MUTEXES == 1 )
BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex )
@ -643,7 +687,7 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
} }
else else
{ {
xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE ); xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait );
/* pdPASS will only be returned if the mutex was successfully /* pdPASS will only be returned if the mutex was successfully
obtained. The calling task may have entered the Blocked state obtained. The calling task may have entered the Blocked state
@ -855,7 +899,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
{ {
/* The queue was full and a block time was specified so /* The queue was full and a block time was specified so
configure the timeout structure. */ configure the timeout structure. */
vTaskSetTimeOutState( &xTimeOut ); vTaskInternalSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE; xEntryTimeSet = pdTRUE;
} }
else else
@ -1127,7 +1171,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
can be assumed there is no mutex holder and no need to determine if can be assumed there is no mutex holder and no need to determine if
priority disinheritance is needed. Simply increase the count of priority disinheritance is needed. Simply increase the count of
messages (semaphores) available. */ messages (semaphores) available. */
pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1; pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1;
/* The event list is not altered if the queue is locked. This will /* The event list is not altered if the queue is locked. This will
be done when the queue is unlocked later. */ be done when the queue is unlocked later. */
@ -1234,21 +1278,27 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeeking ) BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )
{ {
BaseType_t xEntryTimeSet = pdFALSE; BaseType_t xEntryTimeSet = pdFALSE;
TimeOut_t xTimeOut; TimeOut_t xTimeOut;
int8_t *pcOriginalReadPosition;
Queue_t * const pxQueue = ( Queue_t * ) xQueue; Queue_t * const pxQueue = ( Queue_t * ) xQueue;
configASSERT( pxQueue ); /* Check the pointer is not NULL. */
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); configASSERT( ( pxQueue ) );
/* The buffer into which data is received can only be NULL if the data size
is zero (so no data is copied into the buffer. */
configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );
/* Cannot block if the scheduler is suspended. */
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
{ {
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
} }
#endif #endif
/* 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
of execution time efficiency. */ of execution time efficiency. */
@ -1263,44 +1313,19 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
must be the highest priority task wanting to access the queue. */ must be the highest priority task wanting to access the queue. */
if( uxMessagesWaiting > ( UBaseType_t ) 0 ) if( uxMessagesWaiting > ( UBaseType_t ) 0 )
{ {
/* Remember the read position in case the queue is only being /* Data available, remove one item. */
peeked. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer ); prvCopyDataFromQueue( pxQueue, pvBuffer );
traceQUEUE_RECEIVE( pxQueue );
pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;
if( xJustPeeking == pdFALSE ) /* There is now space in the queue, were any tasks waiting to
post to the queue? If so, unblock the highest priority waiting
task. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{ {
traceQUEUE_RECEIVE( pxQueue ); if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
/* Actually removing data, not just peeking. */
pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1;
#if ( configUSE_MUTEXES == 1 )
{ {
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) queueYIELD_IF_USING_PREEMPTION();
{
/* Record the information required to implement
priority inheritance should it become necessary. */
pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* configUSE_MUTEXES */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
queueYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
} }
else else
{ {
@ -1309,30 +1334,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
} }
else else
{ {
traceQUEUE_PEEK( pxQueue ); mtCOVERAGE_TEST_MARKER();
/* The data is not being removed, so reset the read
pointer. */
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
/* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority than this task. */
queueYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@ -1352,7 +1354,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
{ {
/* The queue was empty and a block time was specified so /* The queue was empty and a block time was specified so
configure the timeout structure. */ configure the timeout structure. */
vTaskSetTimeOutState( &xTimeOut ); vTaskInternalSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE; xEntryTimeSet = pdTRUE;
} }
else else
@ -1373,6 +1375,182 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
/* Update the timeout state to see if it has expired yet. */ /* Update the timeout state to see if it has expired yet. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
{ {
/* The timeout has not expired. If the queue is still empty place
the task on the list of tasks waiting to receive from the queue. */
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
prvUnlockQueue( pxQueue );
if( xTaskResumeAll() == pdFALSE )
{
portYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
/* The queue contains data again. Loop back to try and read the
data. */
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
}
}
else
{
/* Timed out. If there is no data in the queue exit, otherwise loop
back and attempt to read the data. */
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
}
/*-----------------------------------------------------------*/
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait )
{
BaseType_t xEntryTimeSet = pdFALSE;
TimeOut_t xTimeOut;
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
#if( configUSE_MUTEXES == 1 )
BaseType_t xInheritanceOccurred = pdFALSE;
#endif
/* Check the queue pointer is not NULL. */
configASSERT( ( pxQueue ) );
/* Check this really is a semaphore, in which case the item size will be
0. */
configASSERT( pxQueue->uxItemSize == 0 );
/* Cannot block if the scheduler is suspended. */
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
{
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
}
#endif
/* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest
of execution time efficiency. */
for( ;; )
{
taskENTER_CRITICAL();
{
/* Semaphores are queues with an item size of 0, and where the
number of messages in the queue is the semaphore's count value. */
const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting;
/* Is there data in the queue now? To be running the calling task
must be the highest priority task wanting to access the queue. */
if( uxSemaphoreCount > ( UBaseType_t ) 0 )
{
traceQUEUE_RECEIVE( pxQueue );
/* Semaphores are queues with a data size of zero and where the
messages waiting is the semaphore's count. Reduce the count. */
pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1;
#if ( configUSE_MUTEXES == 1 )
{
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
{
/* Record the information required to implement
priority inheritance should it become necessary. */
pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* configUSE_MUTEXES */
/* Check to see if other tasks are blocked waiting to give the
semaphore, and if so, unblock the highest priority such task. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
queueYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
taskEXIT_CRITICAL();
return pdPASS;
}
else
{
if( xTicksToWait == ( TickType_t ) 0 )
{
/* For inheritance to have occurred there must have been an
initial timeout, and an adjusted timeout cannot become 0, as
if it were 0 the function would have exited. */
#if( configUSE_MUTEXES == 1 )
{
configASSERT( xInheritanceOccurred == pdFALSE );
}
#endif /* configUSE_MUTEXES */
/* The semaphore count was 0 and no block time is specified
(or the block time has expired) so exit now. */
taskEXIT_CRITICAL();
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
else if( xEntryTimeSet == pdFALSE )
{
/* The semaphore count was 0 and a block time was specified
so configure the timeout structure ready to block. */
vTaskInternalSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE;
}
else
{
/* Entry time was already set. */
mtCOVERAGE_TEST_MARKER();
}
}
}
taskEXIT_CRITICAL();
/* Interrupts and other tasks can give to and take from the semaphore
now the critical section has been exited. */
vTaskSuspendAll();
prvLockQueue( pxQueue );
/* Update the timeout state to see if it has expired yet. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
{
/* A block time is specified and not expired. If the semaphore
count is 0 then enter the Blocked state to wait for a semaphore to
become available. As semaphores are implemented with queues the
queue being empty is equivalent to the semaphore count being 0. */
if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{ {
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
@ -1383,7 +1561,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
{ {
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); xInheritanceOccurred = xTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
@ -1407,13 +1585,193 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
} }
else else
{ {
/* Try again. */ /* There was no timeout and the semaphore count was not 0, so
attempt to take the semaphore again. */
prvUnlockQueue( pxQueue ); prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll(); ( void ) xTaskResumeAll();
} }
} }
else else
{ {
/* Timed out. */
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
/* If the semaphore count is 0 exit now as the timeout has
expired. Otherwise return to attempt to take the semaphore that is
known to be available. As semaphores are implemented by queues the
queue being empty is equivalent to the semaphore count being 0. */
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{
#if ( configUSE_MUTEXES == 1 )
{
/* xInheritanceOccurred could only have be set if
pxQueue->uxQueueType == queueQUEUE_IS_MUTEX so no need to
test the mutex type again to check it is actually a mutex. */
if( xInheritanceOccurred != pdFALSE )
{
taskENTER_CRITICAL();
{
UBaseType_t uxHighestWaitingPriority;
/* This task blocking on the mutex caused another
task to inherit this task's priority. Now this task
has timed out the priority should be disinherited
again, but only as low as the next highest priority
task that is waiting for the same mutex. */
uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue );
vTaskPriorityDisinheritAfterTimeout( ( void * ) pxQueue->pxMutexHolder, uxHighestWaitingPriority );
}
taskEXIT_CRITICAL();
}
}
#endif /* configUSE_MUTEXES */
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
}
/*-----------------------------------------------------------*/
BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )
{
BaseType_t xEntryTimeSet = pdFALSE;
TimeOut_t xTimeOut;
int8_t *pcOriginalReadPosition;
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
/* Check the pointer is not NULL. */
configASSERT( ( pxQueue ) );
/* The buffer into which data is received can only be NULL if the data size
is zero (so no data is copied into the buffer. */
configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );
/* Cannot block if the scheduler is suspended. */
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
{
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
}
#endif
/* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest
of execution time efficiency. */
for( ;; )
{
taskENTER_CRITICAL();
{
const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting;
/* Is there data in the queue now? To be running the calling task
must be the highest priority task wanting to access the queue. */
if( uxMessagesWaiting > ( UBaseType_t ) 0 )
{
/* Remember the read position so it can be reset after the data
is read from the queue as this function is only peeking the
data, not removing it. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer );
traceQUEUE_PEEK( pxQueue );
/* The data is not being removed, so reset the read pointer. */
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
/* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority than this task. */
queueYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
taskEXIT_CRITICAL();
return pdPASS;
}
else
{
if( xTicksToWait == ( TickType_t ) 0 )
{
/* The queue was empty and no block time is specified (or
the block time has expired) so leave now. */
taskEXIT_CRITICAL();
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
else if( xEntryTimeSet == pdFALSE )
{
/* The queue was empty and a block time was specified so
configure the timeout structure ready to enter the blocked
state. */
vTaskInternalSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE;
}
else
{
/* Entry time was already set. */
mtCOVERAGE_TEST_MARKER();
}
}
}
taskEXIT_CRITICAL();
/* Interrupts and other tasks can send to and receive from the queue
now the critical section has been exited. */
vTaskSuspendAll();
prvLockQueue( pxQueue );
/* Update the timeout state to see if it has expired yet. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
{
/* Timeout has not expired yet, check to see if there is data in the
queue now, and if not enter the Blocked state to wait for data. */
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
prvUnlockQueue( pxQueue );
if( xTaskResumeAll() == pdFALSE )
{
portYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
/* There is data in the queue now, so don't enter the blocked
state, instead return to try and obtain the data. */
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
}
}
else
{
/* The timeout has expired. If there is still no data in the queue
exit, otherwise go back and try to read the data again. */
prvUnlockQueue( pxQueue ); prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll(); ( void ) xTaskResumeAll();
@ -1468,7 +1826,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
prvCopyDataFromQueue( pxQueue, pvBuffer ); prvCopyDataFromQueue( pxQueue, pvBuffer );
pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1; pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;
/* If the queue is locked the event list will not be modified. /* If the queue is locked the event list will not be modified.
Instead update the lock count so the task that unlocks the queue Instead update the lock count so the task that unlocks the queue
@ -1694,6 +2052,33 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( configUSE_MUTEXES == 1 )
static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue )
{
UBaseType_t uxHighestPriorityOfWaitingTasks;
/* If a task waiting for a mutex causes the mutex holder to inherit a
priority, but the waiting task times out, then the holder should
disinherit the priority - but only down to the highest priority of any
other tasks that are waiting for the same mutex. For this purpose,
return the priority of the highest priority task that is waiting for the
mutex. */
if( listCURRENT_LIST_LENGTH( &( pxQueue->xTasksWaitingToReceive ) ) > 0 )
{
uxHighestPriorityOfWaitingTasks = configMAX_PRIORITIES - listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( pxQueue->xTasksWaitingToReceive ) );
}
else
{
uxHighestPriorityOfWaitingTasks = tskIDLE_PRIORITY;
}
return uxHighestPriorityOfWaitingTasks;
}
#endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/
static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition )
{ {
BaseType_t xReturn = pdFALSE; BaseType_t xReturn = pdFALSE;
@ -1767,7 +2152,7 @@ UBaseType_t uxMessagesWaiting;
} }
} }
pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1; pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1;
return xReturn; return xReturn;
} }
@ -2316,7 +2701,7 @@ BaseType_t xReturn;
} }
return pcReturn; return pcReturn;
} } /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */
#endif /* configQUEUE_REGISTRY_SIZE */ #endif /* configQUEUE_REGISTRY_SIZE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -2395,7 +2780,7 @@ BaseType_t xReturn;
{ {
QueueSetHandle_t pxQueue; QueueSetHandle_t pxQueue;
pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET );
return pxQueue; return pxQueue;
} }
@ -2478,7 +2863,7 @@ BaseType_t xReturn;
{ {
QueueSetMemberHandle_t xReturn = NULL; QueueSetMemberHandle_t xReturn = NULL;
( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */ ( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */
return xReturn; return xReturn;
} }

View file

@ -1,17 +1,20 @@
Each real time kernel port consists of three files that contain the core kernel Each real time kernel port consists of three files that contain the core kernel
components and are common to every port, and one or more files that are components and are common to every port, and one or more files that are
specific to a particular microcontroller and or compiler. specific to a particular microcontroller and/or compiler.
+ The FreeRTOS/Source directory contains the three files that are common to
every port - list.c, queue.c and tasks.c. The kernel is contained within these
three files. croutine.c implements the optional co-routine functionality - which
is normally only used on very memory limited systems.
+ The FreeRTOS/Source/Portable directory contains the files that are specific to + The FreeRTOS/Source/Portable/MemMang directory contains the five sample
a particular microcontroller and or compiler. memory allocators as described on the http://www.FreeRTOS.org WEB site.
+ The FreeRTOS/Source/include directory contains the real time kernel header + The other directories each contain files specific to a particular
files. microcontroller or compiler, where the directory name denotes the compiler
specific files the directory contains.
For example, if you are interested in the [compiler] port for the [architecture]
microcontroller, then the port specific files are contained in
FreeRTOS/Source/Portable/[compiler]/[architecture] directory. If this is the
only port you are interested in then all the other directories can be
ignored.
See the readme file in the FreeRTOS/Source/Portable directory for more
information.

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -131,12 +131,23 @@ made to free the RAM that was allocated statically.
tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a
task to be created using either statically or dynamically allocated RAM. Note task to be created using either statically or dynamically allocated RAM. Note
that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with
a statically allocated stack and a dynamically allocated TCB. */ a statically allocated stack and a dynamically allocated TCB.
#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) || ( portUSING_MPU_WRAPPERS == 1 ) ) !!!NOTE!!! If the definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is
changed then the definition of StaticTask_t must also be updated. */
#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) #define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 )
#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) #define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 )
#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) #define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 )
/* If any of the following are set then task stacks are filled with a known
value so the high water mark can be determined. If none of the following are
set then don't fill the stack so there is no unnecessary dependency on memset. */
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
#define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1
#else
#define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0
#endif
/* /*
* Macros used by vListTask to indicate which state a task is in. * Macros used by vListTask to indicate which state a task is in.
*/ */
@ -153,6 +164,12 @@ a statically allocated stack and a dynamically allocated TCB. */
#define static #define static
#endif #endif
/* The name allocated to the Idle task. This can be overridden by defining
configIDLE_TASK_NAME in FreeRTOSConfig.h. */
#ifndef configIDLE_TASK_NAME
#define configIDLE_TASK_NAME "IDLE"
#endif
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
@ -304,8 +321,8 @@ typedef struct tskTaskControlBlock
StackType_t *pxStack; /*< Points to the start of the stack. */ StackType_t *pxStack; /*< Points to the start of the stack. */
char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#if ( portSTACK_GROWTH > 0 ) #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */ StackType_t *pxEndOfStack; /*< Points to the highest valid address for the stack. */
#endif #endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 ) #if ( portCRITICAL_NESTING_IN_TCB == 1 )
@ -327,7 +344,7 @@ typedef struct tskTaskControlBlock
#endif #endif
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif #endif
#if( configGENERATE_RUN_TIME_STATS == 1 ) #if( configGENERATE_RUN_TIME_STATS == 1 )
@ -352,7 +369,7 @@ typedef struct tskTaskControlBlock
/* See the comments above the definition of /* See the comments above the definition of
tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 Macro has been consolidated for readability reasons. */
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */
#endif #endif
@ -366,8 +383,8 @@ typedef struct tskTaskControlBlock
below to enable the use of older kernel aware debuggers. */ below to enable the use of older kernel aware debuggers. */
typedef tskTCB TCB_t; typedef tskTCB TCB_t;
/*lint -e956 A manual analysis and inspection has been used to determine which /*lint -save -e956 A manual analysis and inspection has been used to determine
static variables must be declared volatile. */ which static variables must be declared volatile. */
PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL;
@ -394,7 +411,7 @@ PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been r
/* Other file private variables. --------------------------------*/ /* Other file private variables. --------------------------------*/
PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;
PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT;
PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY;
PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE;
PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U;
@ -421,21 +438,27 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t
#endif #endif
/*lint +e956 */ /*lint -restore */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Callback function prototypes. --------------------------*/ /* Callback function prototypes. --------------------------*/
#if( configCHECK_FOR_STACK_OVERFLOW > 0 ) #if( configCHECK_FOR_STACK_OVERFLOW > 0 )
extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ); extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName );
#endif #endif
#if( configUSE_TICK_HOOK > 0 ) #if( configUSE_TICK_HOOK > 0 )
extern void vApplicationTickHook( void ); extern void vApplicationTickHook( void );
#endif #endif
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #if( configSUPPORT_STATIC_ALLOCATION == 1 )
extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
#endif #endif
/* File private functions. --------------------------------*/ /* File private functions. --------------------------------*/
@ -446,7 +469,9 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t
* is in any other state. * is in any other state.
*/ */
#if ( INCLUDE_vTaskSuspend == 1 ) #if ( INCLUDE_vTaskSuspend == 1 )
static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
#endif /* INCLUDE_vTaskSuspend */ #endif /* INCLUDE_vTaskSuspend */
/* /*
@ -565,13 +590,13 @@ static void prvResetNextTaskUnblockTime( void );
* dynamically to fill in the structure's members. * dynamically to fill in the structure's members.
*/ */
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth, const uint32_t ulStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask, TaskHandle_t * const pxCreatedTask,
TCB_t *pxNewTCB, TCB_t *pxNewTCB,
const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION;
/* /*
* Called after a new task has been created and initialised to place the task * Called after a new task has been created and initialised to place the task
@ -579,17 +604,28 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
*/ */
static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION; static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
/*
* freertos_tasks_c_additions_init() should only be called if the user definable
* macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro
* called by the function.
*/
#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT
static void freertos_tasks_c_additions_init( void ) PRIVILEGED_FUNCTION;
#endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #if( configSUPPORT_STATIC_ALLOCATION == 1 )
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth, const uint32_t ulStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
StackType_t * const puxStackBuffer, StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ StaticTask_t * const pxTaskBuffer )
{ {
TCB_t *pxNewTCB; TCB_t *pxNewTCB;
TaskHandle_t xReturn; TaskHandle_t xReturn;
@ -597,6 +633,17 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
configASSERT( puxStackBuffer != NULL ); configASSERT( puxStackBuffer != NULL );
configASSERT( pxTaskBuffer != NULL ); configASSERT( pxTaskBuffer != NULL );
#if( configASSERT_DEFINED == 1 )
{
/* Sanity check that the size of the structure used to declare a
variable of type StaticTask_t equals the size of the real task
structure. */
volatile size_t xSize = sizeof( StaticTask_t );
configASSERT( xSize == sizeof( TCB_t ) );
}
#endif /* configASSERT_DEFINED */
if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) ) if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
{ {
/* The memory used for the task's TCB and stack are passed into this /* The memory used for the task's TCB and stack are passed into this
@ -604,7 +651,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 Macro has been consolidated for readability reasons. */
{ {
/* Tasks can be created statically or dynamically, so note this /* Tasks can be created statically or dynamically, so note this
task was created statically in case the task is later deleted. */ task was created statically in case the task is later deleted. */
@ -626,7 +673,53 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
#endif /* SUPPORT_STATIC_ALLOCATION */ #endif /* SUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( portUSING_MPU_WRAPPERS == 1 ) #if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask )
{
TCB_t *pxNewTCB;
BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
configASSERT( pxTaskDefinition->puxStackBuffer != NULL );
configASSERT( pxTaskDefinition->pxTaskBuffer != NULL );
if( ( pxTaskDefinition->puxStackBuffer != NULL ) && ( pxTaskDefinition->pxTaskBuffer != NULL ) )
{
/* Allocate space for the TCB. Where the memory comes from depends
on the implementation of the port malloc function and whether or
not static allocation is being used. */
pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer;
/* Store the stack location in the TCB. */
pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer;
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
{
/* Tasks can be created statically or dynamically, so note this
task was created statically in case the task is later deleted. */
pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
prvInitialiseNewTask( pxTaskDefinition->pvTaskCode,
pxTaskDefinition->pcName,
( uint32_t ) pxTaskDefinition->usStackDepth,
pxTaskDefinition->pvParameters,
pxTaskDefinition->uxPriority,
pxCreatedTask, pxNewTCB,
pxTaskDefinition->xRegions );
prvAddNewTaskToReadyList( pxNewTCB );
xReturn = pdPASS;
}
return xReturn;
}
#endif /* ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) )
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask )
{ {
@ -674,11 +767,11 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint16_t usStackDepth, const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ TaskHandle_t * const pxCreatedTask )
{ {
TCB_t *pxNewTCB; TCB_t *pxNewTCB;
BaseType_t xReturn; BaseType_t xReturn;
@ -741,7 +834,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
if( pxNewTCB != NULL ) if( pxNewTCB != NULL )
{ {
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 Macro has been consolidated for readability reasons. */
{ {
/* Tasks can be created statically or dynamically, so note this /* Tasks can be created statically or dynamically, so note this
task was created dynamically in case it is later deleted. */ task was created dynamically in case it is later deleted. */
@ -765,13 +858,13 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth, const uint32_t ulStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask, TaskHandle_t * const pxCreatedTask,
TCB_t *pxNewTCB, TCB_t *pxNewTCB,
const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const MemoryRegion_t * const xRegions )
{ {
StackType_t *pxTopOfStack; StackType_t *pxTopOfStack;
UBaseType_t x; UBaseType_t x;
@ -791,12 +884,12 @@ UBaseType_t x;
#endif /* portUSING_MPU_WRAPPERS == 1 */ #endif /* portUSING_MPU_WRAPPERS == 1 */
/* Avoid dependency on memset() if it is not required. */ /* Avoid dependency on memset() if it is not required. */
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 )
{ {
/* Fill the stack with a known value to assist debugging. */ /* Fill the stack with a known value to assist debugging. */
( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) );
} }
#endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */ #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */
/* Calculate the top of stack address. This depends on whether the stack /* Calculate the top of stack address. This depends on whether the stack
grows from high memory to low (as per the 80x86) or vice versa. grows from high memory to low (as per the 80x86) or vice versa.
@ -809,6 +902,14 @@ UBaseType_t x;
/* Check the alignment of the calculated top of stack is correct. */ /* Check the alignment of the calculated top of stack is correct. */
configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
#if( configRECORD_STACK_HIGH_ADDRESS == 1 )
{
/* Also record the stack's high address, which may assist
debugging. */
pxNewTCB->pxEndOfStack = pxTopOfStack;
}
#endif /* configRECORD_STACK_HIGH_ADDRESS */
} }
#else /* portSTACK_GROWTH */ #else /* portSTACK_GROWTH */
{ {
@ -936,7 +1037,7 @@ UBaseType_t x;
/* Initialize the TCB stack to look as if the task was already running, /* Initialize the TCB stack to look as if the task was already running,
but had been interrupted by the scheduler. The return address is set but had been interrupted by the scheduler. The return address is set
to the start of the task function. Once the stack has been initialised to the start of the task function. Once the stack has been initialised
the top of stack variable is updated. */ the top of stack variable is updated. */
#if( portUSING_MPU_WRAPPERS == 1 ) #if( portUSING_MPU_WRAPPERS == 1 )
{ {
pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
@ -1515,14 +1616,14 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
} }
/* 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 its 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 list appropriate to its new priority. */ in the list appropriate to its new priority. */
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE )
{ {
/* The task is currently in its ready list - remove before adding /* The task is currently in its ready list - remove before
it to it's new ready list. As we are in a critical section we adding it to it's new ready list. As we are in a critical
can do this even if the scheduler is suspended. */ section we can do this even if the scheduler is suspended. */
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{ {
/* It is known that the task is in its ready list so /* It is known that the task is in its ready list so
@ -1597,6 +1698,17 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
} }
vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ); vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );
#if( configUSE_TASK_NOTIFICATIONS == 1 )
{
if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION )
{
/* The task was blocked to wait for a notification, but is
now suspended, so no notification was received. */
pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;
}
}
#endif
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@ -1672,7 +1784,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
{ {
/* Is it in the suspended list because it is in the Suspended /* Is it in the suspended list because it is in the Suspended
state, or because is is blocked with no timeout? */ state, or because is is blocked with no timeout? */
if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) /*lint !e961. The cast is only redundant when NULL is used. */
{ {
xReturn = pdTRUE; xReturn = pdTRUE;
} }
@ -1716,12 +1828,12 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
{ {
traceTASK_RESUME( pxTCB ); traceTASK_RESUME( pxTCB );
/* As we are in a critical section we can access the ready /* The ready list can be accessed even if the scheduler is
lists even if the scheduler is suspended. */ suspended because this is inside a critical section. */
( void ) uxListRemove( &( pxTCB->xStateListItem ) ); ( void ) uxListRemove( &( pxTCB->xStateListItem ) );
prvAddTaskToReadyList( pxTCB ); prvAddTaskToReadyList( pxTCB );
/* We may have just resumed a higher priority task. */ /* A higher priority task may have just been resumed. */
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
{ {
/* This yield may not cause the task just resumed to run, /* This yield may not cause the task just resumed to run,
@ -1838,9 +1950,9 @@ BaseType_t xReturn;
address of the RAM then create the idle task. */ address of the RAM then create the idle task. */
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, xIdleTaskHandle = xTaskCreateStatic( prvIdleTask,
"IDLE", configIDLE_TASK_NAME,
ulIdleTaskStackSize, ulIdleTaskStackSize,
( void * ) NULL, ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
pxIdleTaskStackBuffer, pxIdleTaskStackBuffer,
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
@ -1858,7 +1970,8 @@ BaseType_t xReturn;
{ {
/* The Idle task is being created using dynamically allocated RAM. */ /* The Idle task is being created using dynamically allocated RAM. */
xReturn = xTaskCreate( prvIdleTask, xReturn = xTaskCreate( prvIdleTask,
"IDLE", configMINIMAL_STACK_SIZE, configIDLE_TASK_NAME,
configMINIMAL_STACK_SIZE,
( void * ) NULL, ( void * ) NULL,
( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
&xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
@ -1880,6 +1993,15 @@ BaseType_t xReturn;
if( xReturn == pdPASS ) if( xReturn == pdPASS )
{ {
/* freertos_tasks_c_additions_init() should only be called if the user
definable macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is
the only macro called by the function. */
#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT
{
freertos_tasks_c_additions_init();
}
#endif
/* Interrupts are turned off here, to ensure a tick does not occur /* Interrupts are turned off here, to ensure a tick does not occur
before or during the call to xPortStartScheduler(). The stacks of before or during the call to xPortStartScheduler(). The stacks of
the created tasks contain a status word with interrupts switched on the created tasks contain a status word with interrupts switched on
@ -1901,7 +2023,10 @@ BaseType_t xReturn;
/* If configGENERATE_RUN_TIME_STATS is defined then the following /* If configGENERATE_RUN_TIME_STATS is defined then the following
macro must be defined to configure the timer/counter used to generate macro must be defined to configure the timer/counter used to generate
the run time counter time base. */ the run time counter time base. NOTE: If configGENERATE_RUN_TIME_STATS
is set to 0 and the following line fails to build then ensure you do not
have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your
FreeRTOSConfig.h file. */
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
/* Setting up the timer tick is hardware specific and thus in the /* Setting up the timer tick is hardware specific and thus in the
@ -2427,7 +2552,7 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) BaseType_t xTaskAbortDelay( TaskHandle_t xTask )
{ {
TCB_t *pxTCB = ( TCB_t * ) xTask; TCB_t *pxTCB = ( TCB_t * ) xTask;
BaseType_t xReturn = pdFALSE; BaseType_t xReturn;
configASSERT( pxTCB ); configASSERT( pxTCB );
@ -2437,6 +2562,8 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
it is actually in the Blocked state. */ it is actually in the Blocked state. */
if( eTaskGetState( xTask ) == eBlocked ) if( eTaskGetState( xTask ) == eBlocked )
{ {
xReturn = pdPASS;
/* Remove the reference to the task from the blocked list. An /* Remove the reference to the task from the blocked list. An
interrupt won't touch the xStateListItem because the interrupt won't touch the xStateListItem because the
scheduler is suspended. */ scheduler is suspended. */
@ -2485,10 +2612,10 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); xReturn = pdFAIL;
} }
} }
xTaskResumeAll(); ( void ) xTaskResumeAll();
return xReturn; return xReturn;
} }
@ -2510,13 +2637,13 @@ BaseType_t xSwitchRequired = pdFALSE;
{ {
/* Minor optimisation. The tick count cannot change in this /* Minor optimisation. The tick count cannot change in this
block. */ block. */
const TickType_t xConstTickCount = xTickCount + 1; const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
/* Increment the RTOS tick, switching the delayed and overflowed /* Increment the RTOS tick, switching the delayed and overflowed
delayed lists if it wraps to 0. */ delayed lists if it wraps to 0. */
xTickCount = xConstTickCount; xTickCount = xConstTickCount;
if( xConstTickCount == ( TickType_t ) 0U ) if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */
{ {
taskSWITCH_DELAYED_LISTS(); taskSWITCH_DELAYED_LISTS();
} }
@ -2959,10 +3086,9 @@ BaseType_t xReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue )
{ {
TCB_t *pxUnblockedTCB; TCB_t *pxUnblockedTCB;
BaseType_t xReturn;
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
the event flags implementation. */ the event flags implementation. */
@ -2985,28 +3111,30 @@ BaseType_t xReturn;
if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
{ {
/* Return true if the task removed from the event list has /* The unblocked task has a priority above that of the calling task, so
a higher priority than the calling task. This allows a context switch is required. This function is called with the
the calling task to know if it should force a context scheduler suspended so xYieldPending is set so the context switch
switch now. */ occurs immediately that the scheduler is resumed (unsuspended). */
xReturn = pdTRUE;
/* Mark that a yield is pending in case the user is not using the
"xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
xYieldPending = pdTRUE; xYieldPending = pdTRUE;
} }
else
{
xReturn = pdFALSE;
}
return xReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut )
{ {
configASSERT( pxTimeOut ); configASSERT( pxTimeOut );
taskENTER_CRITICAL();
{
pxTimeOut->xOverflowCount = xNumOfOverflows;
pxTimeOut->xTimeOnEntering = xTickCount;
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut )
{
/* For internal use only as it does not use a critical section. */
pxTimeOut->xOverflowCount = xNumOfOverflows; pxTimeOut->xOverflowCount = xNumOfOverflows;
pxTimeOut->xTimeOnEntering = xTickCount; pxTimeOut->xTimeOnEntering = xTickCount;
} }
@ -3023,6 +3151,7 @@ BaseType_t xReturn;
{ {
/* Minor optimisation. The tick count cannot change in this block. */ /* Minor optimisation. The tick count cannot change in this block. */
const TickType_t xConstTickCount = xTickCount; const TickType_t xConstTickCount = xTickCount;
const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering;
#if( INCLUDE_xTaskAbortDelay == 1 ) #if( INCLUDE_xTaskAbortDelay == 1 )
if( pxCurrentTCB->ucDelayAborted != pdFALSE ) if( pxCurrentTCB->ucDelayAborted != pdFALSE )
@ -3055,11 +3184,11 @@ BaseType_t xReturn;
was called. */ was called. */
xReturn = pdTRUE; xReturn = pdTRUE;
} }
else if( ( ( TickType_t ) ( xConstTickCount - pxTimeOut->xTimeOnEntering ) ) < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */ else if( xElapsedTime < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */
{ {
/* Not a genuine timeout. Adjust parameters for time remaining. */ /* Not a genuine timeout. Adjust parameters for time remaining. */
*pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering ); *pxTicksToWait -= xElapsedTime;
vTaskSetTimeOutState( pxTimeOut ); vTaskInternalSetTimeOutState( pxTimeOut );
xReturn = pdFALSE; xReturn = pdFALSE;
} }
else else
@ -3136,6 +3265,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
/** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE
SCHEDULER IS STARTED. **/ SCHEDULER IS STARTED. **/
/* In case a task that has a secure context deletes itself, in which case
the idle task is responsible for deleting the task's secure context, if
any. */
portTASK_CALLS_SECURE_FUNCTIONS();
for( ;; ) for( ;; )
{ {
/* See if any tasks have deleted themselves - if so then the idle task /* See if any tasks have deleted themselves - if so then the idle task
@ -3212,6 +3346,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
configASSERT( xNextTaskUnblockTime >= xTickCount ); configASSERT( xNextTaskUnblockTime >= xTickCount );
xExpectedIdleTime = prvGetExpectedIdleTime(); xExpectedIdleTime = prvGetExpectedIdleTime();
/* Define the following macro to set xExpectedIdleTime to 0
if the application does not want
portSUPPRESS_TICKS_AND_SLEEP() to be called. */
configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime );
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
{ {
traceLOW_POWER_IDLE_BEGIN(); traceLOW_POWER_IDLE_BEGIN();
@ -3369,37 +3508,22 @@ static void prvCheckTasksWaitingTermination( void )
#if ( INCLUDE_vTaskDelete == 1 ) #if ( INCLUDE_vTaskDelete == 1 )
{ {
BaseType_t xListIsEmpty; TCB_t *pxTCB;
/* ucTasksDeleted is used to prevent vTaskSuspendAll() being called /* uxDeletedTasksWaitingCleanUp is used to prevent vTaskSuspendAll()
too often in the idle task. */ being called too often in the idle task. */
while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
{ {
vTaskSuspendAll(); taskENTER_CRITICAL();
{ {
xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
--uxCurrentNumberOfTasks;
--uxDeletedTasksWaitingCleanUp;
} }
( void ) xTaskResumeAll(); taskEXIT_CRITICAL();
if( xListIsEmpty == pdFALSE ) prvDeleteTCB( pxTCB );
{
TCB_t *pxTCB;
taskENTER_CRITICAL();
{
pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
--uxCurrentNumberOfTasks;
--uxDeletedTasksWaitingCleanUp;
}
taskEXIT_CRITICAL();
prvDeleteTCB( pxTCB );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
} }
} }
#endif /* INCLUDE_vTaskDelete */ #endif /* INCLUDE_vTaskDelete */
@ -3421,25 +3545,6 @@ static void prvCheckTasksWaitingTermination( void )
pxTaskStatus->pxStackBase = pxTCB->pxStack; pxTaskStatus->pxStackBase = pxTCB->pxStack;
pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber; pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber;
#if ( INCLUDE_vTaskSuspend == 1 )
{
/* If the task is in the suspended list then there is a chance it is
actually just blocked indefinitely - so really it should be reported as
being in the Blocked state. */
if( pxTaskStatus->eCurrentState == eSuspended )
{
vTaskSuspendAll();
{
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{
pxTaskStatus->eCurrentState = eBlocked;
}
}
xTaskResumeAll();
}
}
#endif /* INCLUDE_vTaskSuspend */
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
{ {
pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority; pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority;
@ -3460,12 +3565,38 @@ static void prvCheckTasksWaitingTermination( void )
} }
#endif #endif
/* Obtaining the task state is a little fiddly, so is only done if the value /* Obtaining the task state is a little fiddly, so is only done if the
of eState passed into this function is eInvalid - otherwise the state is value of eState passed into this function is eInvalid - otherwise the
just set to whatever is passed in. */ state is just set to whatever is passed in. */
if( eState != eInvalid ) if( eState != eInvalid )
{ {
pxTaskStatus->eCurrentState = eState; if( pxTCB == pxCurrentTCB )
{
pxTaskStatus->eCurrentState = eRunning;
}
else
{
pxTaskStatus->eCurrentState = eState;
#if ( INCLUDE_vTaskSuspend == 1 )
{
/* If the task is in the suspended list then there is a
chance it is actually just blocked indefinitely - so really
it should be reported as being in the Blocked state. */
if( eState == eSuspended )
{
vTaskSuspendAll();
{
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{
pxTaskStatus->eCurrentState = eBlocked;
}
}
( void ) xTaskResumeAll();
}
}
#endif /* INCLUDE_vTaskSuspend */
}
} }
else else
{ {
@ -3499,7 +3630,7 @@ static void prvCheckTasksWaitingTermination( void )
static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState )
{ {
volatile TCB_t *pxNextTCB, *pxFirstTCB; configLIST_VOLATILE TCB_t *pxNextTCB, *pxFirstTCB;
UBaseType_t uxTask = 0; UBaseType_t uxTask = 0;
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
@ -3600,7 +3731,7 @@ static void prvCheckTasksWaitingTermination( void )
vPortFree( pxTCB->pxStack ); vPortFree( pxTCB->pxStack );
vPortFree( pxTCB ); vPortFree( pxTCB );
} }
#elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 ) #elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 Macro has been consolidated for readability reasons. */
{ {
/* The task could have been allocated statically or dynamically, so /* The task could have been allocated statically or dynamically, so
check what was statically allocated before trying to free the check what was statically allocated before trying to free the
@ -3622,7 +3753,7 @@ static void prvCheckTasksWaitingTermination( void )
{ {
/* Neither the stack nor the TCB were allocated dynamically, so /* Neither the stack nor the TCB were allocated dynamically, so
nothing needs to be freed. */ nothing needs to be freed. */
configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ) configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB );
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
@ -3703,25 +3834,27 @@ TCB_t *pxTCB;
#if ( configUSE_MUTEXES == 1 ) #if ( configUSE_MUTEXES == 1 )
void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder )
{ {
TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder; TCB_t * const pxMutexHolderTCB = ( TCB_t * ) pxMutexHolder;
BaseType_t xReturn = pdFALSE;
/* If the mutex was given back by an interrupt while the queue was /* If the mutex was given back by an interrupt while the queue was
locked then the mutex holder might now be NULL. */ locked then the mutex holder might now be NULL. _RB_ Is this still
needed as interrupts can no longer use mutexes? */
if( pxMutexHolder != NULL ) if( pxMutexHolder != NULL )
{ {
/* If the holder of the mutex has a priority below the priority of /* If the holder of the mutex has a priority below the priority of
the task attempting to obtain the mutex then it will temporarily the task attempting to obtain the mutex then it will temporarily
inherit the priority of the task attempting to obtain the mutex. */ inherit the priority of the task attempting to obtain the mutex. */
if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) if( pxMutexHolderTCB->uxPriority < pxCurrentTCB->uxPriority )
{ {
/* Adjust the mutex holder state to account for its new /* Adjust the mutex holder state to account for its new
priority. Only reset the event list item value if the value is priority. Only reset the event list item value if the value is
not being used for anything else. */ not being used for anything else. */
if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL )
{ {
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
} }
else else
{ {
@ -3730,11 +3863,11 @@ TCB_t *pxTCB;
/* If the task being modified is in the ready state it will need /* If the task being modified is in the ready state it will need
to be moved into a new list. */ to be moved into a new list. */
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxMutexHolderTCB->uxPriority ] ), &( pxMutexHolderTCB->xStateListItem ) ) != pdFALSE )
{ {
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) if( uxListRemove( &( pxMutexHolderTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{ {
taskRESET_READY_PRIORITY( pxTCB->uxPriority ); taskRESET_READY_PRIORITY( pxMutexHolderTCB->uxPriority );
} }
else else
{ {
@ -3742,26 +3875,45 @@ TCB_t *pxTCB;
} }
/* Inherit the priority before being moved into the new list. */ /* Inherit the priority before being moved into the new list. */
pxTCB->uxPriority = pxCurrentTCB->uxPriority; pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority;
prvAddTaskToReadyList( pxTCB ); prvAddTaskToReadyList( pxMutexHolderTCB );
} }
else else
{ {
/* Just inherit the priority. */ /* Just inherit the priority. */
pxTCB->uxPriority = pxCurrentTCB->uxPriority; pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority;
} }
traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority ); traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxCurrentTCB->uxPriority );
/* Inheritance occurred. */
xReturn = pdTRUE;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); if( pxMutexHolderTCB->uxBasePriority < pxCurrentTCB->uxPriority )
{
/* The base priority of the mutex holder is lower than the
priority of the task attempting to take the mutex, but the
current priority of the mutex holder is not lower than the
priority of the task attempting to take the mutex.
Therefore the mutex holder must have already inherited a
priority, but inheritance would have occurred if that had
not been the case. */
xReturn = pdTRUE;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
return xReturn;
} }
#endif /* configUSE_MUTEXES */ #endif /* configUSE_MUTEXES */
@ -3781,7 +3933,6 @@ TCB_t *pxTCB;
interrupt, and if a mutex is given by the holding task then it must interrupt, and if a mutex is given by the holding task then it must
be the running state task. */ be the running state task. */
configASSERT( pxTCB == pxCurrentTCB ); configASSERT( pxTCB == pxCurrentTCB );
configASSERT( pxTCB->uxMutexesHeld ); configASSERT( pxTCB->uxMutexesHeld );
( pxTCB->uxMutexesHeld )--; ( pxTCB->uxMutexesHeld )--;
@ -3795,8 +3946,8 @@ TCB_t *pxTCB;
/* A task can only have an inherited priority if it holds /* A task can only have an inherited priority if it holds
the mutex. If the mutex is held by a task then it cannot be the mutex. If the mutex is held by a task then it cannot be
given from an interrupt, and if a mutex is given by the given from an interrupt, and if a mutex is given by the
holding task then it must be the running state task. Remove holding task then it must be the running state task. Remove
the holding task from the ready list. */ the holding task from the ready list. */
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{ {
taskRESET_READY_PRIORITY( pxTCB->uxPriority ); taskRESET_READY_PRIORITY( pxTCB->uxPriority );
@ -3848,6 +3999,108 @@ TCB_t *pxTCB;
#endif /* configUSE_MUTEXES */ #endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_MUTEXES == 1 )
void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask )
{
TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
UBaseType_t uxPriorityUsedOnEntry, uxPriorityToUse;
const UBaseType_t uxOnlyOneMutexHeld = ( UBaseType_t ) 1;
if( pxMutexHolder != NULL )
{
/* If pxMutexHolder is not NULL then the holder must hold at least
one mutex. */
configASSERT( pxTCB->uxMutexesHeld );
/* Determine the priority to which the priority of the task that
holds the mutex should be set. This will be the greater of the
holding task's base priority and the priority of the highest
priority task that is waiting to obtain the mutex. */
if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask )
{
uxPriorityToUse = uxHighestPriorityWaitingTask;
}
else
{
uxPriorityToUse = pxTCB->uxBasePriority;
}
/* Does the priority need to change? */
if( pxTCB->uxPriority != uxPriorityToUse )
{
/* Only disinherit if no other mutexes are held. This is a
simplification in the priority inheritance implementation. If
the task that holds the mutex is also holding other mutexes then
the other mutexes may have caused the priority inheritance. */
if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld )
{
/* If a task has timed out because it already holds the
mutex it was trying to obtain then it cannot of inherited
its own priority. */
configASSERT( pxTCB != pxCurrentTCB );
/* Disinherit the priority, remembering the previous
priority to facilitate determining the subject task's
state. */
traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );
uxPriorityUsedOnEntry = pxTCB->uxPriority;
pxTCB->uxPriority = uxPriorityToUse;
/* Only reset the event list item value if the value is not
being used for anything else. */
if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL )
{
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* If the running task is not the task that holds the mutex
then the task that holds the mutex could be in either the
Ready, Blocked or Suspended states. Only remove the task
from its current state list if it is in the Ready state as
the task's priority is going to change and there is one
Ready list per priority. */
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE )
{
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{
taskRESET_READY_PRIORITY( pxTCB->uxPriority );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
prvAddTaskToReadyList( pxTCB );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/
#if ( portCRITICAL_NESTING_IN_TCB == 1 ) #if ( portCRITICAL_NESTING_IN_TCB == 1 )
void vTaskEnterCritical( void ) void vTaskEnterCritical( void )
@ -3937,7 +4190,7 @@ TCB_t *pxTCB;
#endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */ #endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
void vTaskList( char * pcWriteBuffer ) void vTaskList( char * pcWriteBuffer )
{ {
@ -4029,10 +4282,10 @@ TCB_t *pxTCB;
} }
} }
#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
void vTaskGetRunTimeStats( char *pcWriteBuffer ) void vTaskGetRunTimeStats( char *pcWriteBuffer )
{ {
@ -4156,7 +4409,7 @@ TCB_t *pxTCB;
} }
} }
#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ #endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
TickType_t uxTaskResetEventItemValue( void ) TickType_t uxTaskResetEventItemValue( void )
@ -4240,7 +4493,7 @@ TickType_t uxReturn;
} }
else else
{ {
pxCurrentTCB->ulNotifiedValue = ulReturn - 1; pxCurrentTCB->ulNotifiedValue = ulReturn - ( uint32_t ) 1;
} }
} }
else else
@ -4315,7 +4568,7 @@ TickType_t uxReturn;
blocked state (because a notification was already pending) or the blocked state (because a notification was already pending) or the
task unblocked because of a notification. Otherwise the task task unblocked because of a notification. Otherwise the task
unblocked because of a timeout. */ unblocked because of a timeout. */
if( pxCurrentTCB->ucNotifyState == taskWAITING_NOTIFICATION ) if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED )
{ {
/* A notification was not received. */ /* A notification was not received. */
xReturn = pdFALSE; xReturn = pdFALSE;
@ -4800,8 +5053,24 @@ const TickType_t xConstTickCount = xTickCount;
#endif /* INCLUDE_vTaskSuspend */ #endif /* INCLUDE_vTaskSuspend */
} }
/* Code below here allows additional code to be inserted into this source file,
especially where access to file scope functions and data is needed (for example
when performing module tests). */
#ifdef FREERTOS_MODULE_TEST #ifdef FREERTOS_MODULE_TEST
#include "tasks_test_access_functions.h" #include "tasks_test_access_functions.h"
#endif #endif
#if( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 )
#include "freertos_tasks_c_additions.h"
static void freertos_tasks_c_additions_init( void )
{
#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT
FREERTOS_TASKS_C_ADDITIONS_INIT();
#endif
}
#endif

View file

@ -1,5 +1,5 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.
All rights reserved All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -100,6 +100,12 @@ configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
/* Misc definitions. */ /* Misc definitions. */
#define tmrNO_DELAY ( TickType_t ) 0U #define tmrNO_DELAY ( TickType_t ) 0U
/* The name assigned to the timer service task. This can be overridden by
defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
#ifndef configTIMER_SERVICE_TASK_NAME
#define configTIMER_SERVICE_TASK_NAME "Tmr Svc"
#endif
/* The definition of the timers themselves. */ /* The definition of the timers themselves. */
typedef struct tmrTimerControl typedef struct tmrTimerControl
{ {
@ -158,8 +164,8 @@ typedef struct tmrTimerQueueMessage
} u; } u;
} DaemonTaskMessage_t; } DaemonTaskMessage_t;
/*lint -e956 A manual analysis and inspection has been used to determine which /*lint -save -e956 A manual analysis and inspection has been used to determine
static variables must be declared volatile. */ 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
@ -173,7 +179,7 @@ PRIVILEGED_DATA static List_t *pxOverflowTimerList;
PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
/*lint +e956 */ /*lint -restore */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -248,12 +254,12 @@ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseTy
* Called after a Timer_t structure has been allocated either statically or * Called after a Timer_t structure has been allocated either statically or
* dynamically to fill in the structure's members. * dynamically to fill in the structure's members.
*/ */
static void prvInitialiseNewTimer( const char * const pcTimerName, static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, TimerCallbackFunction_t pxCallbackFunction,
Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xTimerCreateTimerTask( void ) BaseType_t xTimerCreateTimerTask( void )
@ -276,7 +282,7 @@ BaseType_t xReturn = pdFAIL;
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
"Tmr Svc", configTIMER_SERVICE_TASK_NAME,
ulTimerTaskStackSize, ulTimerTaskStackSize,
NULL, NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
@ -291,7 +297,7 @@ BaseType_t xReturn = pdFAIL;
#else #else
{ {
xReturn = xTaskCreate( prvTimerTask, xReturn = xTaskCreate( prvTimerTask,
"Tmr Svc", configTIMER_SERVICE_TASK_NAME,
configTIMER_TASK_STACK_DEPTH, configTIMER_TASK_STACK_DEPTH,
NULL, NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
@ -311,11 +317,11 @@ BaseType_t xReturn = pdFAIL;
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreate( const char * const pcTimerName, TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ TimerCallbackFunction_t pxCallbackFunction )
{ {
Timer_t *pxNewTimer; Timer_t *pxNewTimer;
@ -343,12 +349,12 @@ BaseType_t xReturn = pdFAIL;
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #if( configSUPPORT_STATIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ StaticTimer_t *pxTimerBuffer )
{ {
Timer_t *pxNewTimer; Timer_t *pxNewTimer;
@ -356,7 +362,7 @@ BaseType_t xReturn = pdFAIL;
{ {
/* Sanity check that the size of the structure used to declare a /* Sanity check that the size of the structure used to declare a
variable of type StaticTimer_t equals the size of the real timer variable of type StaticTimer_t equals the size of the real timer
structures. */ structure. */
volatile size_t xSize = sizeof( StaticTimer_t ); volatile size_t xSize = sizeof( StaticTimer_t );
configASSERT( xSize == sizeof( Timer_t ) ); configASSERT( xSize == sizeof( Timer_t ) );
} }
@ -385,12 +391,12 @@ BaseType_t xReturn = pdFAIL;
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvInitialiseNewTimer( const char * const pcTimerName, static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, TimerCallbackFunction_t pxCallbackFunction,
Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ Timer_t *pxNewTimer )
{ {
/* 0 is not a valid value for xTimerPeriodInTicks. */ /* 0 is not a valid value for xTimerPeriodInTicks. */
configASSERT( ( xTimerPeriodInTicks > 0 ) ); configASSERT( ( xTimerPeriodInTicks > 0 ) );
@ -760,7 +766,7 @@ TickType_t xTimeNow;
software timer. */ software timer. */
pxTimer = xMessage.u.xTimerParameters.pxTimer; pxTimer = xMessage.u.xTimerParameters.pxTimer;
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */
{ {
/* The timer is in a list, remove it. */ /* The timer is in a list, remove it. */
( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
@ -945,10 +951,10 @@ static void prvCheckForValidListAndQueue( void )
{ {
/* The timer queue is allocated statically in case /* The timer queue is allocated statically in case
configSUPPORT_DYNAMIC_ALLOCATION is 0. */ configSUPPORT_DYNAMIC_ALLOCATION is 0. */
static StaticQueue_t xStaticTimerQueue; static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
static uint8_t ucStaticTimerQueueStorage[ configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue );
} }
#else #else
{ {
@ -991,7 +997,7 @@ Timer_t *pxTimer = ( Timer_t * ) xTimer;
/* Checking to see if it is in the NULL list in effect checks to see if /* Checking to see if it is in the NULL list in effect checks to see if
it is referenced from either the current or the overflow timer lists in it is referenced from either the current or the overflow timer lists in
one go, but the logic has to be reversed, hence the '!'. */ one go, but the logic has to be reversed, hence the '!'. */
xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); /*lint !e961. Cast is only redundant when NULL is passed into the macro. */
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();