FreeRTOS 9.0.1
This commit is contained in:
parent
5583543f14
commit
17eb160be7
26 changed files with 1347 additions and 615 deletions
|
@ -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).
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 ) )
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
20
FreeRTOS/Source/portable/readme.txt
Normal file
20
FreeRTOS/Source/portable/readme.txt
Normal 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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue