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
|
||||
License (GPL), text provided below. 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 FreeRTOS open source license covers the FreeRTOS source files,
|
||||
which are located in the /FreeRTOS/Source directory of the official FreeRTOS
|
||||
download. It also covers most of the source files in the demo application
|
||||
projects, which are located in the /FreeRTOS/Demo directory of the official
|
||||
FreeRTOS download. The demo projects may also include third party software that
|
||||
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
|
||||
of each source and header file for license and copyright information.
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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. */
|
||||
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. */
|
||||
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
|
||||
that is was unblocked due to its required bits matching, rather
|
||||
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
|
||||
|
@ -633,9 +643,9 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
|||
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* Unblock the task, returning 0 as the event list is being deleted
|
||||
and cannot therefore have any bits set. */
|
||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||
( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
and cannot therefore have any bits set. */
|
||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
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.
|
||||
#endif
|
||||
|
||||
#if configMAX_PRIORITIES < 1
|
||||
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
|
||||
#endif
|
||||
|
||||
#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.
|
||||
#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.
|
||||
#endif
|
||||
|
||||
#ifndef configMAX_PRIORITIES
|
||||
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_CO_ROUTINES
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#endif
|
||||
|
@ -408,6 +408,14 @@ extern "C" {
|
|||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#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. */
|
||||
|
||||
#ifndef traceMOVED_TASK_TO_READY_STATE
|
||||
|
@ -708,6 +716,10 @@ extern "C" {
|
|||
#define configUSE_TICKLESS_IDLE 0
|
||||
#endif
|
||||
|
||||
#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING
|
||||
#define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x )
|
||||
#endif
|
||||
|
||||
#ifndef configPRE_SLEEP_PROCESSING
|
||||
#define configPRE_SLEEP_PROCESSING( x )
|
||||
#endif
|
||||
|
@ -724,6 +736,10 @@ extern "C" {
|
|||
#define portTASK_USES_FLOATING_POINT()
|
||||
#endif
|
||||
|
||||
#ifndef portTASK_CALLS_SECURE_FUNCTIONS
|
||||
#define portTASK_CALLS_SECURE_FUNCTIONS()
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_TIME_SLICING
|
||||
#define configUSE_TIME_SLICING 1
|
||||
#endif
|
||||
|
@ -782,6 +798,12 @@ extern "C" {
|
|||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#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. */
|
||||
#if( configUSE_TICKLESS_IDLE != 0 )
|
||||
#if( INCLUDE_vTaskSuspend != 1 )
|
||||
|
@ -797,6 +819,10 @@ extern "C" {
|
|||
#error configUSE_MUTEXES must be set to 1 to use recursive mutexes
|
||||
#endif
|
||||
|
||||
#ifndef configINITIAL_TICK_COUNT
|
||||
#define configINITIAL_TICK_COUNT 0
|
||||
#endif
|
||||
|
||||
#if( portTICK_TYPE_IS_ATOMIC == 0 )
|
||||
/* Either variables of tick type cannot be read atomically, or
|
||||
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
|
||||
|
@ -917,7 +943,7 @@ typedef struct xSTATIC_TCB
|
|||
UBaseType_t uxDummy5;
|
||||
void *pxDummy6;
|
||||
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
|
||||
void *pxDummy8;
|
||||
#endif
|
||||
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||
|
@ -945,10 +971,14 @@ typedef struct xSTATIC_TCB
|
|||
uint32_t ulDummy18;
|
||||
uint8_t ucDummy19;
|
||||
#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;
|
||||
#endif
|
||||
|
||||
#if( INCLUDE_xTaskAbortDelay == 1 )
|
||||
uint8_t ucDummy21;
|
||||
#endif
|
||||
|
||||
} 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
|
||||
FreeRTOSConfig.h file in your program directory.
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
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.
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
The "blink" example in "examples/blink" provides an example of how
|
||||
to do this.
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. 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
|
||||
#define __DEFAULT_FREERTOS_CONFIG_H
|
||||
|
||||
|
@ -47,7 +70,7 @@
|
|||
#define configTICK_RATE_HZ ( ( TickType_t ) 100 )
|
||||
#endif
|
||||
#ifndef configMAX_PRIORITIES
|
||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 )
|
||||
#define configMAX_PRIORITIES ( 15 )
|
||||
#endif
|
||||
#ifndef configMINIMAL_STACK_SIZE
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short )256 )
|
||||
|
@ -108,6 +131,10 @@
|
|||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_NEWLIB_REENTRANT
|
||||
#define configUSE_NEWLIB_REENTRANT 1
|
||||
#endif
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#ifndef INCLUDE_vTaskPrioritySet
|
||||
|
@ -144,5 +171,10 @@ to exclude the API function. */
|
|||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||
#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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
{
|
||||
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 (). */
|
||||
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. */
|
||||
|
|
|
@ -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
|
||||
|
||||
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 );
|
||||
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_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
|
||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete );
|
||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay );
|
||||
|
@ -124,7 +125,9 @@ BaseType_t MPU_xTaskGetSchedulerState( void );
|
|||
|
||||
/* 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_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_uxQueueSpacesAvailable( const 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
|
||||
|
||||
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. */
|
||||
#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 uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
|
||||
#define vQueueDelete MPU_vQueueDelete
|
||||
|
@ -177,8 +179,11 @@ only for ports that are using the MPU. */
|
|||
#define xEventGroupSync MPU_xEventGroupSync
|
||||
#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_DATA __attribute__((section("privileged_data")))
|
||||
|
||||
#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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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>
|
||||
BaseType_t xQueuePeek(
|
||||
QueueHandle_t xQueue,
|
||||
void *pvBuffer,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait
|
||||
);</pre>
|
||||
*
|
||||
* This is a macro that calls the xQueueGenericReceive() function.
|
||||
*
|
||||
* Receive an item from a queue without removing the item from the queue.
|
||||
* The item is received by copy so a buffer of adequate size must be
|
||||
* provided. The number of bytes copied into the buffer was defined when
|
||||
|
@ -782,10 +780,10 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQ
|
|||
// ... Rest of task code.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueReceive xQueueReceive
|
||||
* \defgroup xQueuePeek xQueuePeek
|
||||
* \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
|
||||
|
@ -829,8 +827,6 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
|
|||
TickType_t xTicksToWait
|
||||
);</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
|
||||
* adequate size must be provided. The number of bytes copied into the buffer
|
||||
* was defined when the queue was created.
|
||||
|
@ -911,106 +907,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
|
|||
* \defgroup xQueueReceive xQueueReceive
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
void* xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
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
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
|
||||
|
||||
/**
|
||||
* semphr. h
|
||||
|
@ -392,23 +392,23 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
|||
|
||||
// ...
|
||||
// For some reason due to the nature of the code further calls to
|
||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||
// code these would not be just sequential calls as this would make
|
||||
// no sense. Instead the calls are likely to be buried inside
|
||||
// a more complex call structure.
|
||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||
// code these would not be just sequential calls as this would make
|
||||
// no sense. Instead the calls are likely to be buried inside
|
||||
// a more complex call structure.
|
||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
|
||||
// The mutex has now been 'taken' three times, so will not be
|
||||
// available to another task until it has also been given back
|
||||
// three times. Again it is unlikely that real code would have
|
||||
// these calls sequentially, but instead buried in a more complex
|
||||
// call structure. This is just for illustrative purposes.
|
||||
// available to another task until it has also been given back
|
||||
// three times. Again it is unlikely that real code would have
|
||||
// these calls sequentially, but instead buried in a more complex
|
||||
// call structure. This is just for illustrative purposes.
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
|
||||
// Now the mutex can be taken by other tasks.
|
||||
// Now the mutex can be taken by other tasks.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1154,6 +1154,17 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
|||
*/
|
||||
#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
|
||||
* <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
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
@ -160,6 +160,9 @@ typedef struct xTASK_PARAMETERS
|
|||
UBaseType_t uxPriority;
|
||||
StackType_t *puxStackBuffer;
|
||||
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
|
||||
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
StaticTask_t * const pxTaskBuffer;
|
||||
#endif
|
||||
} TaskParameters_t;
|
||||
|
||||
/* Used with the uxTaskGetSystemState() function to return the state of each task
|
||||
|
@ -269,7 +272,7 @@ is used in assert() statements. */
|
|||
BaseType_t xTaskCreate(
|
||||
TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
uint16_t usStackDepth,
|
||||
configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void *pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t *pvCreatedTask
|
||||
|
@ -358,11 +361,11 @@ is used in assert() statements. */
|
|||
*/
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint16_t usStackDepth,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
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
|
||||
|
||||
/**
|
||||
|
@ -474,12 +477,12 @@ is used in assert() statements. */
|
|||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
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,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
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 */
|
||||
|
||||
/**
|
||||
|
@ -487,6 +490,8 @@ is used in assert() statements. */
|
|||
*<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
|
||||
* implementation.
|
||||
*
|
||||
|
@ -494,6 +499,9 @@ is used in assert() statements. */
|
|||
* The function parameters define the memory regions and associated access
|
||||
* 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
|
||||
* for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
|
||||
* 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;
|
||||
#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
|
||||
*<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
|
||||
* 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
|
||||
* expires.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* priority. In this case the event list item value is updated to the value
|
||||
* passed in the xItemValue parameter.
|
||||
|
@ -2157,7 +2253,7 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi
|
|||
* making the call, otherwise pdFALSE.
|
||||
*/
|
||||
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
|
||||
|
@ -2207,7 +2303,7 @@ BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;
|
|||
* 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.
|
||||
*/
|
||||
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
|
||||
|
@ -2215,6 +2311,16 @@ void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTIO
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -2258,6 +2364,13 @@ eSleepModeStatus eTaskConfirmSleepModeStatus( 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
|
||||
}
|
||||
#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
|
||||
|
||||
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"
|
||||
#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. */
|
||||
#include "task.h"
|
||||
/*lint +e537 */
|
||||
/*lint -restore */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -266,11 +266,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
|||
* @endverbatim
|
||||
*/
|
||||
#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 UBaseType_t uxAutoReload,
|
||||
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
|
||||
|
||||
/**
|
||||
|
@ -396,12 +396,12 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
|||
* @endverbatim
|
||||
*/
|
||||
#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 UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
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 */
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
||||
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.
|
||||
|
||||
|
@ -73,10 +73,12 @@
|
|||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtensa_ops.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "xtensa_rtos.h"
|
||||
|
||||
unsigned cpu_sr;
|
||||
|
@ -91,6 +93,13 @@ char level1_int_disabled;
|
|||
*/
|
||||
void *xPortSupervisorStackPointer;
|
||||
|
||||
void vAssertCalled(const char * pcFile, unsigned long ulLine)
|
||||
{
|
||||
printf("rtos assert %s %lu\n", pcFile, ulLine);
|
||||
abort();
|
||||
//for (;;);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stack initialization
|
||||
*/
|
||||
|
@ -100,7 +109,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, TaskFunctio
|
|||
portSTACK_TYPE *sp, *tp;
|
||||
|
||||
/* 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) */
|
||||
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_maclayer_sv;
|
||||
|
||||
/* PendSV is called in place of vPortYield() to request a supervisor
|
||||
call.
|
||||
|
||||
The portYIELD macro calls pendSV if it's a software request.
|
||||
|
||||
The libpp and libudhcp libraries also call this function, assuming
|
||||
always with arg==2 (but maybe sometimes with arg==1?)
|
||||
|
||||
In the original esp_iot_rtos_sdk implementation, arg was a char. Using an
|
||||
enum is ABI-compatible, though.
|
||||
*/
|
||||
/*
|
||||
* 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
|
||||
* are enabled which might be after exiting the critical region below.
|
||||
*
|
||||
* The wdev NMI calls this function from pp_post() with SVC_MACLayer to set a
|
||||
* pending interrupt service callback which flushs the queue of messages that
|
||||
* the NMI stashes away. This interrupt will be triggered after the return from
|
||||
* the NMI and when interrupts are enabled. The NMI can not touch the FreeRTOS
|
||||
* 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)
|
||||
{
|
||||
vPortEnterCritical();
|
||||
|
||||
if(req == SVC_Software)
|
||||
{
|
||||
pending_soft_sv = 1;
|
||||
}
|
||||
else if(req == SVC_MACLayer)
|
||||
pending_maclayer_sv= 1;
|
||||
|
||||
WSR(BIT(INUM_SOFT), interrupt);
|
||||
vPortExitCritical();
|
||||
if (req == SVC_Software) {
|
||||
vPortEnterCritical();
|
||||
pending_soft_sv = 1;
|
||||
WSR(BIT(INUM_SOFT), interrupt);
|
||||
vPortExitCritical();
|
||||
} else if (req == SVC_MACLayer) {
|
||||
pending_maclayer_sv= 1;
|
||||
WSR(BIT(INUM_SOFT), interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE ;
|
||||
if(pending_maclayer_sv)
|
||||
{
|
||||
xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl();
|
||||
pending_maclayer_sv = 0;
|
||||
}
|
||||
if( xHigherPriorityTaskWoken || pending_soft_sv)
|
||||
{
|
||||
sdk__xt_timer_int1();
|
||||
pending_soft_sv = 0;
|
||||
}
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE ;
|
||||
if (pending_maclayer_sv) {
|
||||
xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl();
|
||||
pending_maclayer_sv = 0;
|
||||
}
|
||||
if (xHigherPriorityTaskWoken || pending_soft_sv) {
|
||||
sdk__xt_timer_int1();
|
||||
pending_soft_sv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void xPortSysTickHandle (void)
|
||||
{
|
||||
//CloseNMI();
|
||||
{
|
||||
if(xTaskIncrementTick() !=pdFALSE )
|
||||
{
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
}
|
||||
//OpenNMI();
|
||||
if (xTaskIncrementTick() != pdFALSE) {
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -221,8 +222,10 @@ size_t xPortGetFreeHeapSize( void )
|
|||
uint32_t brk_val = (uint32_t) sbrk(0);
|
||||
|
||||
intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
|
||||
if(sp == 0) /* scheduler not started */
|
||||
if (sp == 0) {
|
||||
/* scheduler not started */
|
||||
SP(sp);
|
||||
}
|
||||
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;
|
||||
|
||||
/* 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
|
||||
* with a save/restore of interrupt level, although it's difficult as
|
||||
* 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();
|
||||
uxCriticalNesting++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void IRAM vPortExitCritical( void )
|
||||
{
|
||||
void IRAM vPortExitCritical(void) {
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == 0 )
|
||||
portENABLE_INTERRUPTS();
|
||||
if (uxCriticalNesting == 0)
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
|
||||
/* Backward compatibility with libmain.a and libpp.a and can remove when these are open. */
|
||||
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 )
|
||||
{
|
||||
(void)puxStackBuffer; (void)xRegions;
|
||||
return xTaskCreate( pxTaskCode, (const char * const)pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask);
|
||||
/* 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) {
|
||||
(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.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
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.
|
||||
***************************************************************************
|
||||
>>! 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 from the following
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
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 portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE unsigned portLONG
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portPOINTER_SIZE_TYPE unsigned portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef unsigned portBASE_TYPE UBaseType_t;
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffff
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
|
@ -156,6 +119,9 @@ extern unsigned cpu_sr;
|
|||
prefer to _xt_disable_interrupts & _xt_enable_interrupts and store
|
||||
the ps value in a local variable - that approach is recursive-safe
|
||||
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)
|
||||
{
|
||||
|
@ -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. */
|
||||
#define portTASK_FUNCTION_PROTO( 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
|
||||
|
|
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
|
||||
|
||||
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;
|
||||
#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 );
|
||||
}
|
||||
else
|
||||
{
|
||||
traceQUEUE_CREATE_FAILED( ucQueueType );
|
||||
}
|
||||
|
||||
return pxNewQueue;
|
||||
}
|
||||
|
@ -422,6 +436,10 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
|
||||
prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue );
|
||||
}
|
||||
else
|
||||
{
|
||||
traceQUEUE_CREATE_FAILED( ucQueueType );
|
||||
}
|
||||
|
||||
return pxNewQueue;
|
||||
}
|
||||
|
@ -567,6 +585,32 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
|
|||
#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 )
|
||||
|
||||
BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex )
|
||||
|
@ -643,7 +687,7 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
|
|||
}
|
||||
else
|
||||
{
|
||||
xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE );
|
||||
xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait );
|
||||
|
||||
/* pdPASS will only be returned if the mutex was successfully
|
||||
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
|
||||
configure the timeout structure. */
|
||||
vTaskSetTimeOutState( &xTimeOut );
|
||||
vTaskInternalSetTimeOutState( &xTimeOut );
|
||||
xEntryTimeSet = pdTRUE;
|
||||
}
|
||||
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
|
||||
priority disinheritance is needed. Simply increase the count of
|
||||
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
|
||||
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;
|
||||
TimeOut_t xTimeOut;
|
||||
int8_t *pcOriginalReadPosition;
|
||||
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
|
||||
configASSERT( pxQueue );
|
||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||
/* 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. */
|
||||
|
@ -1263,44 +1313,19 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
must be the highest priority task wanting to access the queue. */
|
||||
if( uxMessagesWaiting > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* Remember the read position in case the queue is only being
|
||||
peeked. */
|
||||
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
|
||||
|
||||
/* Data available, remove one item. */
|
||||
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 );
|
||||
|
||||
/* Actually removing data, not just peeking. */
|
||||
pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1;
|
||||
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
|
||||
{
|
||||
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 */
|
||||
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
|
||||
{
|
||||
queueYIELD_IF_USING_PREEMPTION();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
queueYIELD_IF_USING_PREEMPTION();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1309,30 +1334,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
}
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
taskEXIT_CRITICAL();
|
||||
|
@ -1352,7 +1354,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
/* The queue was empty and a block time was specified so
|
||||
configure the timeout structure. */
|
||||
vTaskSetTimeOutState( &xTimeOut );
|
||||
vTaskInternalSetTimeOutState( &xTimeOut );
|
||||
xEntryTimeSet = pdTRUE;
|
||||
}
|
||||
else
|
||||
|
@ -1373,6 +1375,182 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
/* Update the timeout state to see if it has expired yet. */
|
||||
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 )
|
||||
{
|
||||
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
|
||||
|
@ -1383,7 +1561,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
|
||||
xInheritanceOccurred = xTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
@ -1407,13 +1585,193 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Try again. */
|
||||
/* There was no timeout and the semaphore count was not 0, so
|
||||
attempt to take the semaphore again. */
|
||||
prvUnlockQueue( pxQueue );
|
||||
( void ) xTaskResumeAll();
|
||||
}
|
||||
}
|
||||
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 );
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
|
@ -1468,7 +1826,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
|
||||
|
||||
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.
|
||||
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 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#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 )
|
||||
{
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
@ -1767,7 +2152,7 @@ UBaseType_t uxMessagesWaiting;
|
|||
}
|
||||
}
|
||||
|
||||
pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1;
|
||||
pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1;
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
@ -2316,7 +2701,7 @@ BaseType_t xReturn;
|
|||
}
|
||||
|
||||
return pcReturn;
|
||||
}
|
||||
} /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */
|
||||
|
||||
#endif /* configQUEUE_REGISTRY_SIZE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -2395,7 +2780,7 @@ BaseType_t xReturn;
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -2478,7 +2863,7 @@ BaseType_t xReturn;
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +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.
|
||||
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
|
||||
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 FreeRTOS/Source/include directory contains the real time kernel header
|
||||
files.
|
||||
+ 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.
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
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 ) )
|
||||
a statically allocated stack and a dynamically allocated TCB.
|
||||
!!!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 tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 )
|
||||
#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.
|
||||
*/
|
||||
|
@ -153,6 +164,12 @@ a statically allocated stack and a dynamically allocated TCB. */
|
|||
#define static
|
||||
#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 is 0 then task selection is
|
||||
|
@ -304,8 +321,8 @@ typedef struct tskTaskControlBlock
|
|||
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. */
|
||||
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */
|
||||
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
|
||||
StackType_t *pxEndOfStack; /*< Points to the highest valid address for the stack. */
|
||||
#endif
|
||||
|
||||
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||
|
@ -327,7 +344,7 @@ typedef struct tskTaskControlBlock
|
|||
#endif
|
||||
|
||||
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
|
||||
void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
||||
void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
||||
#endif
|
||||
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
|
@ -352,7 +369,7 @@ typedef struct tskTaskControlBlock
|
|||
|
||||
/* See the comments above the definition of
|
||||
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. */
|
||||
#endif
|
||||
|
||||
|
@ -366,8 +383,8 @@ typedef struct tskTaskControlBlock
|
|||
below to enable the use of older kernel aware debuggers. */
|
||||
typedef tskTCB TCB_t;
|
||||
|
||||
/*lint -e956 A manual analysis and inspection has been used to determine which
|
||||
static variables must be declared volatile. */
|
||||
/*lint -save -e956 A manual analysis and inspection has been used to determine
|
||||
which static variables must be declared volatile. */
|
||||
|
||||
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. --------------------------------*/
|
||||
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 BaseType_t xSchedulerRunning = pdFALSE;
|
||||
PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U;
|
||||
|
@ -421,21 +438,27 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t
|
|||
|
||||
#endif
|
||||
|
||||
/*lint +e956 */
|
||||
/*lint -restore */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Callback function prototypes. --------------------------*/
|
||||
#if( configCHECK_FOR_STACK_OVERFLOW > 0 )
|
||||
|
||||
extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName );
|
||||
|
||||
#endif
|
||||
|
||||
#if( configUSE_TICK_HOOK > 0 )
|
||||
|
||||
extern void vApplicationTickHook( void );
|
||||
|
||||
#endif
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
|
||||
|
||||
#endif
|
||||
|
||||
/* File private functions. --------------------------------*/
|
||||
|
@ -446,7 +469,9 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t
|
|||
* is in any other state.
|
||||
*/
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
|
||||
static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
|
||||
/*
|
||||
|
@ -565,13 +590,13 @@ static void prvResetNextTaskUnblockTime( void );
|
|||
* dynamically to fill in the structure's members.
|
||||
*/
|
||||
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,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
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
|
||||
|
@ -579,17 +604,28 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
|||
*/
|
||||
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 )
|
||||
|
||||
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,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
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;
|
||||
TaskHandle_t xReturn;
|
||||
|
@ -597,6 +633,17 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
configASSERT( puxStackBuffer != 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 ) )
|
||||
{
|
||||
/* 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->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
|
||||
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 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#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 )
|
||||
{
|
||||
|
@ -674,11 +767,11 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint16_t usStackDepth,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
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;
|
||||
BaseType_t xReturn;
|
||||
|
@ -741,7 +834,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
|
||||
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
|
||||
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,
|
||||
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,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
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;
|
||||
UBaseType_t x;
|
||||
|
@ -791,12 +884,12 @@ UBaseType_t x;
|
|||
#endif /* portUSING_MPU_WRAPPERS == 1 */
|
||||
|
||||
/* 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. */
|
||||
( 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
|
||||
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. */
|
||||
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 */
|
||||
{
|
||||
|
@ -936,7 +1037,7 @@ UBaseType_t x;
|
|||
/* 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
|
||||
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 )
|
||||
{
|
||||
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
|
||||
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
|
||||
in the list appropriate to its new priority. */
|
||||
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE )
|
||||
{
|
||||
/* The task is currently in its ready list - remove before adding
|
||||
it to it's new ready list. As we are in a critical section we
|
||||
can do this even if the scheduler is suspended. */
|
||||
/* The task is currently in its ready list - remove before
|
||||
adding it to it's new ready list. As we are in a critical
|
||||
section we can do this even if the scheduler is suspended. */
|
||||
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* 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 ) );
|
||||
|
||||
#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();
|
||||
|
||||
|
@ -1672,7 +1784,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
|
|||
{
|
||||
/* Is it in the suspended list because it is in the Suspended
|
||||
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;
|
||||
}
|
||||
|
@ -1716,12 +1828,12 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
|
|||
{
|
||||
traceTASK_RESUME( pxTCB );
|
||||
|
||||
/* As we are in a critical section we can access the ready
|
||||
lists even if the scheduler is suspended. */
|
||||
/* The ready list can be accessed even if the scheduler is
|
||||
suspended because this is inside a critical section. */
|
||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||
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 )
|
||||
{
|
||||
/* 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. */
|
||||
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
|
||||
xIdleTaskHandle = xTaskCreateStatic( prvIdleTask,
|
||||
"IDLE",
|
||||
configIDLE_TASK_NAME,
|
||||
ulIdleTaskStackSize,
|
||||
( void * ) NULL,
|
||||
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
|
||||
( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
|
||||
pxIdleTaskStackBuffer,
|
||||
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. */
|
||||
xReturn = xTaskCreate( prvIdleTask,
|
||||
"IDLE", configMINIMAL_STACK_SIZE,
|
||||
configIDLE_TASK_NAME,
|
||||
configMINIMAL_STACK_SIZE,
|
||||
( void * ) NULL,
|
||||
( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
|
||||
&xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
||||
|
@ -1880,6 +1993,15 @@ BaseType_t xReturn;
|
|||
|
||||
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
|
||||
before or during the call to xPortStartScheduler(). The stacks of
|
||||
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
|
||||
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();
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
TCB_t *pxTCB = ( TCB_t * ) xTask;
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
BaseType_t xReturn;
|
||||
|
||||
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. */
|
||||
if( eTaskGetState( xTask ) == eBlocked )
|
||||
{
|
||||
xReturn = pdPASS;
|
||||
|
||||
/* Remove the reference to the task from the blocked list. An
|
||||
interrupt won't touch the xStateListItem because the
|
||||
scheduler is suspended. */
|
||||
|
@ -2485,10 +2612,10 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
|
|||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
}
|
||||
xTaskResumeAll();
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
@ -2510,13 +2637,13 @@ BaseType_t xSwitchRequired = pdFALSE;
|
|||
{
|
||||
/* Minor optimisation. The tick count cannot change in this
|
||||
block. */
|
||||
const TickType_t xConstTickCount = xTickCount + 1;
|
||||
const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
|
||||
|
||||
/* Increment the RTOS tick, switching the delayed and overflowed
|
||||
delayed lists if it wraps to 0. */
|
||||
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();
|
||||
}
|
||||
|
@ -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;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
|
||||
the event flags implementation. */
|
||||
|
@ -2985,28 +3111,30 @@ BaseType_t xReturn;
|
|||
|
||||
if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||
{
|
||||
/* Return true if the task removed from the event list has
|
||||
a higher priority than the calling task. This allows
|
||||
the calling task to know if it should force a context
|
||||
switch now. */
|
||||
xReturn = pdTRUE;
|
||||
|
||||
/* Mark that a yield is pending in case the user is not using the
|
||||
"xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
|
||||
/* The unblocked task has a priority above that of the calling task, so
|
||||
a context switch is required. This function is called with the
|
||||
scheduler suspended so xYieldPending is set so the context switch
|
||||
occurs immediately that the scheduler is resumed (unsuspended). */
|
||||
xYieldPending = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTaskSetTimeOutState( TimeOut_t * const 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->xTimeOnEntering = xTickCount;
|
||||
}
|
||||
|
@ -3023,6 +3151,7 @@ BaseType_t xReturn;
|
|||
{
|
||||
/* Minor optimisation. The tick count cannot change in this block. */
|
||||
const TickType_t xConstTickCount = xTickCount;
|
||||
const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering;
|
||||
|
||||
#if( INCLUDE_xTaskAbortDelay == 1 )
|
||||
if( pxCurrentTCB->ucDelayAborted != pdFALSE )
|
||||
|
@ -3055,11 +3184,11 @@ BaseType_t xReturn;
|
|||
was called. */
|
||||
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. */
|
||||
*pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering );
|
||||
vTaskSetTimeOutState( pxTimeOut );
|
||||
*pxTicksToWait -= xElapsedTime;
|
||||
vTaskInternalSetTimeOutState( pxTimeOut );
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
|
@ -3136,6 +3265,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
|||
/** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE
|
||||
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( ;; )
|
||||
{
|
||||
/* 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 );
|
||||
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 )
|
||||
{
|
||||
traceLOW_POWER_IDLE_BEGIN();
|
||||
|
@ -3369,37 +3508,22 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
|
||||
#if ( INCLUDE_vTaskDelete == 1 )
|
||||
{
|
||||
BaseType_t xListIsEmpty;
|
||||
TCB_t *pxTCB;
|
||||
|
||||
/* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
|
||||
too often in the idle task. */
|
||||
/* uxDeletedTasksWaitingCleanUp is used to prevent vTaskSuspendAll()
|
||||
being called too often in the idle task. */
|
||||
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 )
|
||||
{
|
||||
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();
|
||||
}
|
||||
prvDeleteTCB( pxTCB );
|
||||
}
|
||||
}
|
||||
#endif /* INCLUDE_vTaskDelete */
|
||||
|
@ -3421,25 +3545,6 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
pxTaskStatus->pxStackBase = pxTCB->pxStack;
|
||||
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 )
|
||||
{
|
||||
pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority;
|
||||
|
@ -3460,12 +3565,38 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Obtaining the task state is a little fiddly, so is only done if the value
|
||||
of eState passed into this function is eInvalid - otherwise the state is
|
||||
just set to whatever is passed in. */
|
||||
/* Obtaining the task state is a little fiddly, so is only done if the
|
||||
value of eState passed into this function is eInvalid - otherwise the
|
||||
state is just set to whatever is passed in. */
|
||||
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
|
||||
{
|
||||
|
@ -3499,7 +3630,7 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
|
||||
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;
|
||||
|
||||
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
|
||||
|
@ -3600,7 +3731,7 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
vPortFree( pxTCB->pxStack );
|
||||
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
|
||||
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
|
||||
nothing needs to be freed. */
|
||||
configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB )
|
||||
configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB );
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
|
@ -3703,25 +3834,27 @@ TCB_t *pxTCB;
|
|||
|
||||
#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
|
||||
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 the holder of the mutex has a priority below the priority of
|
||||
the task attempting to obtain the mutex then it will temporarily
|
||||
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
|
||||
priority. 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 )
|
||||
not being used for anything else. */
|
||||
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
|
||||
{
|
||||
|
@ -3730,11 +3863,11 @@ TCB_t *pxTCB;
|
|||
|
||||
/* If the task being modified is in the ready state it will need
|
||||
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
|
||||
{
|
||||
|
@ -3742,26 +3875,45 @@ TCB_t *pxTCB;
|
|||
}
|
||||
|
||||
/* Inherit the priority before being moved into the new list. */
|
||||
pxTCB->uxPriority = pxCurrentTCB->uxPriority;
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority;
|
||||
prvAddTaskToReadyList( pxMutexHolderTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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
|
||||
{
|
||||
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
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_MUTEXES */
|
||||
|
@ -3781,7 +3933,6 @@ TCB_t *pxTCB;
|
|||
interrupt, and if a mutex is given by the holding task then it must
|
||||
be the running state task. */
|
||||
configASSERT( pxTCB == pxCurrentTCB );
|
||||
|
||||
configASSERT( pxTCB->uxMutexesHeld );
|
||||
( pxTCB->uxMutexesHeld )--;
|
||||
|
||||
|
@ -3795,8 +3946,8 @@ TCB_t *pxTCB;
|
|||
/* 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
|
||||
given from an interrupt, and if a mutex is given by the
|
||||
holding task then it must be the running state task. Remove
|
||||
the holding task from the ready list. */
|
||||
holding task then it must be the running state task. Remove
|
||||
the holding task from the ready list. */
|
||||
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
taskRESET_READY_PRIORITY( pxTCB->uxPriority );
|
||||
|
@ -3848,6 +3999,108 @@ TCB_t *pxTCB;
|
|||
#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 )
|
||||
|
||||
void vTaskEnterCritical( void )
|
||||
|
@ -3937,7 +4190,7 @@ TCB_t *pxTCB;
|
|||
#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 )
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 )
|
||||
|
@ -4240,7 +4493,7 @@ TickType_t uxReturn;
|
|||
}
|
||||
else
|
||||
{
|
||||
pxCurrentTCB->ulNotifiedValue = ulReturn - 1;
|
||||
pxCurrentTCB->ulNotifiedValue = ulReturn - ( uint32_t ) 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4315,7 +4568,7 @@ TickType_t uxReturn;
|
|||
blocked state (because a notification was already pending) or the
|
||||
task unblocked because of a notification. Otherwise the task
|
||||
unblocked because of a timeout. */
|
||||
if( pxCurrentTCB->ucNotifyState == taskWAITING_NOTIFICATION )
|
||||
if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED )
|
||||
{
|
||||
/* A notification was not received. */
|
||||
xReturn = pdFALSE;
|
||||
|
@ -4800,8 +5053,24 @@ const TickType_t xConstTickCount = xTickCount;
|
|||
#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
|
||||
#include "tasks_test_access_functions.h"
|
||||
#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
|
||||
|
||||
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. */
|
||||
#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. */
|
||||
typedef struct tmrTimerControl
|
||||
{
|
||||
|
@ -158,8 +164,8 @@ typedef struct tmrTimerQueueMessage
|
|||
} u;
|
||||
} DaemonTaskMessage_t;
|
||||
|
||||
/*lint -e956 A manual analysis and inspection has been used to determine which
|
||||
static variables must be declared volatile. */
|
||||
/*lint -save -e956 A manual analysis and inspection has been used to determine
|
||||
which static variables must be declared volatile. */
|
||||
|
||||
/* The list in which active timers are stored. Timers are referenced in expire
|
||||
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 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
|
||||
* 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 UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
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 )
|
||||
|
@ -276,7 +282,7 @@ BaseType_t xReturn = pdFAIL;
|
|||
|
||||
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
|
||||
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
|
||||
"Tmr Svc",
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
ulTimerTaskStackSize,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
|
@ -291,7 +297,7 @@ BaseType_t xReturn = pdFAIL;
|
|||
#else
|
||||
{
|
||||
xReturn = xTaskCreate( prvTimerTask,
|
||||
"Tmr Svc",
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
configTIMER_TASK_STACK_DEPTH,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
|
@ -311,11 +317,11 @@ BaseType_t xReturn = pdFAIL;
|
|||
|
||||
#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 UBaseType_t uxAutoReload,
|
||||
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;
|
||||
|
||||
|
@ -343,12 +349,12 @@ BaseType_t xReturn = pdFAIL;
|
|||
|
||||
#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 UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
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;
|
||||
|
||||
|
@ -356,7 +362,7 @@ BaseType_t xReturn = pdFAIL;
|
|||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
variable of type StaticTimer_t equals the size of the real timer
|
||||
structures. */
|
||||
structure. */
|
||||
volatile size_t xSize = sizeof( StaticTimer_t );
|
||||
configASSERT( xSize == sizeof( Timer_t ) );
|
||||
}
|
||||
|
@ -385,12 +391,12 @@ BaseType_t xReturn = pdFAIL;
|
|||
#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 UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
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. */
|
||||
configASSERT( ( xTimerPeriodInTicks > 0 ) );
|
||||
|
@ -760,7 +766,7 @@ TickType_t xTimeNow;
|
|||
software timer. */
|
||||
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. */
|
||||
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
|
||||
|
@ -945,10 +951,10 @@ static void prvCheckForValidListAndQueue( void )
|
|||
{
|
||||
/* The timer queue is allocated statically in case
|
||||
configSUPPORT_DYNAMIC_ALLOCATION is 0. */
|
||||
static StaticQueue_t xStaticTimerQueue;
|
||||
static uint8_t ucStaticTimerQueueStorage[ configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ];
|
||||
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[ ( 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
|
||||
{
|
||||
|
@ -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
|
||||
it is referenced from either the current or the overflow timer lists in
|
||||
one go, but the logic has to be reversed, hence the '!'. */
|
||||
xTimerIsInActiveList = ( 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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue