mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 09:38:32 -04:00
+ New feature added: Task notifications.
+ Optimise Cortex-M4F ports by inlining some critical section macros. + Original ports used a #define to set the path to portmacro.h - that method has been obsolete for years and now all the old definitions have been moved into a separate header files called deprecated_definitions.h. + Cortex-M port now check the active vector bits against 0xff when determining if a function is called from an interrupt - previously only a subset of the bits (0x1f) were checked. + Add in new standard demo/test files TaskNotify.c/h and include the files in the simulator demos. + Update trace recorder code, and some demos to use the new version (more to do). + Introduce uxTaskPriorityGetFromISR(). + Minor typo corrections. + Update MingW simulator demo to match the MSVC simulator demo.
This commit is contained in:
parent
ca22607d14
commit
85fb1cc024
65 changed files with 5524 additions and 4527 deletions
|
|
@ -276,6 +276,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
|||
|
||||
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||
itself, and that at least one bit is being requested. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
configASSERT( uxBitsToWaitFor != 0 );
|
||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||
|
|
@ -421,6 +422,7 @@ EventBits_t uxReturn;
|
|||
|
||||
/* Check the user is not attempting to clear the bits used by the kernel
|
||||
itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
|
|
@ -482,6 +484,7 @@ BaseType_t xMatchFound = pdFALSE;
|
|||
|
||||
/* Check the user is not attempting to set the bits used by the kernel
|
||||
itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||
|
|
|
|||
|
|
@ -723,6 +723,10 @@ extern "C" {
|
|||
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_TASK_NOTIFICATIONS
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#endif
|
||||
|
||||
/* Definitions to allow backward compatibility with FreeRTOS versions prior to
|
||||
V8 if desired. */
|
||||
#ifndef configENABLE_BACKWARD_COMPATIBILITY
|
||||
|
|
|
|||
317
FreeRTOS/Source/include/deprecated_definitions.h
Normal file
317
FreeRTOS/Source/include/deprecated_definitions.h
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
FreeRTOS V8.1.2 - Copyright (C) 2014 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.
|
||||
|
||||
>>! 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
|
||||
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!
|
||||
*/
|
||||
|
||||
#ifndef DEPRECATED_DEFINITIONS_H
|
||||
#define DEPRECATED_DEFINITIONS_H
|
||||
|
||||
|
||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||
pre-processor definition was used to ensure the pre-processor found the correct
|
||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||
of setting the compiler's include path such that it found the correct
|
||||
portmacro.h file - removing the need for the constant and allowing the
|
||||
portmacro.h file to be located anywhere in relation to the port being used. The
|
||||
definitions below remain in the code for backward compatibility only. New
|
||||
projects should not use them. */
|
||||
|
||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MEGA_AVR
|
||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC24_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_DSPIC_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC18F_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC32MX_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _FEDPICC
|
||||
#include "libFreeRTOS/Include/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDCC_CYGNAL
|
||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7
|
||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7_ECLIPSE
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_LPC23xx
|
||||
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MSP430
|
||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MSP430
|
||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_MSP430
|
||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_GCC
|
||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM9XE_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPC2000_IAR
|
||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR71X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_GCC
|
||||
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR91X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_H8S
|
||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_AT91FR40008
|
||||
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef RVDS_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARM_CM3
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARMCM3_LM
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef HCS12_CODE_WARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MICROBLAZE_GCC
|
||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef TERN_EE
|
||||
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_HCS12
|
||||
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MCF5235
|
||||
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_GCC
|
||||
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC405
|
||||
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC440
|
||||
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _16FX_SOFTUNE
|
||||
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef BCC_FLASH_LITE_186_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __AVR32_AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __ICCAVR32__
|
||||
#ifdef __CORE__
|
||||
#if __CORE__ == __AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __91467D
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __96340
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __IAR_V850ES_Fx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3_L__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Hx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3L__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||
|
||||
|
|
@ -70,253 +70,22 @@
|
|||
#ifndef PORTABLE_H
|
||||
#define PORTABLE_H
|
||||
|
||||
/* Include the macro file relevant to the port being used.
|
||||
NOTE: The following definitions are *DEPRECATED* as it is preferred to instead
|
||||
just add the path to the correct portmacro.h header file to the compiler's
|
||||
include path. */
|
||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||
pre-processor definition was used to ensure the pre-processor found the correct
|
||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||
of setting the compiler's include path such that it found the correct
|
||||
portmacro.h file - removing the need for the constant and allowing the
|
||||
portmacro.h file to be located anywhere in relation to the port being used.
|
||||
Purely for reasons of backward compatibility the old method is still valid, but
|
||||
to make it clear that new projects should not use it, support for the port
|
||||
specific constants has been moved into the deprecated_definitions.h header
|
||||
file. */
|
||||
#include "deprecated_definitions.h"
|
||||
|
||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MEGA_AVR
|
||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC24_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_DSPIC_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC18F_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC32MX_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _FEDPICC
|
||||
#include "libFreeRTOS/Include/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDCC_CYGNAL
|
||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7
|
||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7_ECLIPSE
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_LPC23xx
|
||||
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MSP430
|
||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MSP430
|
||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_MSP430
|
||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_GCC
|
||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM9XE_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPC2000_IAR
|
||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR71X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_GCC
|
||||
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR91X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_H8S
|
||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_AT91FR40008
|
||||
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef RVDS_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARM_CM3
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARMCM3_LM
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef HCS12_CODE_WARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MICROBLAZE_GCC
|
||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef TERN_EE
|
||||
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_HCS12
|
||||
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MCF5235
|
||||
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_GCC
|
||||
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC405
|
||||
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC440
|
||||
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _16FX_SOFTUNE
|
||||
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef BCC_FLASH_LITE_186_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __AVR32_AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __ICCAVR32__
|
||||
#ifdef __CORE__
|
||||
#if __CORE__ == __AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __91467D
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __96340
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __IAR_V850ES_Fx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3_L__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Hx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3L__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
/* Catch all to ensure portmacro.h is included in the build. Newer demos
|
||||
have the path as part of the project options, rather than as relative from
|
||||
the project location. If portENTER_CRITICAL() has not been defined then
|
||||
portmacro.h has not yet been included - as every portmacro.h provides a
|
||||
portENTER_CRITICAL() definition. Check the demo application for your demo
|
||||
to find the path to the correct portmacro.h file. */
|
||||
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
||||
did not result in a portmacro.h header file being included - and it should be
|
||||
included here. In this case the path to the correct portmacro.h header file
|
||||
must be set in the compiler's include path. */
|
||||
#ifndef portENTER_CRITICAL
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
|
@ -370,15 +139,15 @@ typedef struct HeapRegion
|
|||
size_t xSizeInBytes;
|
||||
} HeapRegion_t;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Used to define multiple heap regions for use by heap_5.c. This function
|
||||
* must be called before any calls to pvPortMalloc() - not creating a task,
|
||||
* queue, semaphore, mutex, software timer, event group, etc. will result in
|
||||
* pvPortMalloc being called.
|
||||
*
|
||||
* pxHeapRegions passes in an array of HeapRegion_t structures - each of which
|
||||
* defines a region of memory that can be used as the heap. The array is
|
||||
* terminated by a HeapRegions_t structure that has a size of 0. The region
|
||||
* defines a region of memory that can be used as the heap. The array is
|
||||
* terminated by a HeapRegions_t structure that has a size of 0. The region
|
||||
* with the lowest start address must appear first in the array.
|
||||
*/
|
||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions );
|
||||
|
|
|
|||
|
|
@ -114,13 +114,23 @@ typedef enum
|
|||
eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */
|
||||
} eTaskState;
|
||||
|
||||
/* Actions that can be performed when vTaskNotify() is called. */
|
||||
typedef enum
|
||||
{
|
||||
eNoAction, /* Notify the task without updating its notify value. */
|
||||
eSetBits, /* Set bits in the task's notification value. */
|
||||
eIncrement, /* Increment the task's notification value. */
|
||||
eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */
|
||||
eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
|
||||
} eNotifyAction;
|
||||
|
||||
/*
|
||||
* Used internally only.
|
||||
*/
|
||||
typedef struct xTIME_OUT
|
||||
{
|
||||
BaseType_t xOverflowCount;
|
||||
TickType_t xTimeOnEntering;
|
||||
TickType_t xTimeOnEntering;
|
||||
} TimeOut_t;
|
||||
|
||||
/*
|
||||
|
|
@ -1358,6 +1368,432 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
|
|||
*/
|
||||
void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );</PRE>
|
||||
*
|
||||
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||
* available.
|
||||
*
|
||||
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||
*
|
||||
* Events can be sent to a task using an intermediary object. Examples of such
|
||||
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||
* are a method of sending an event directly to a task without the need for such
|
||||
* an intermediary object.
|
||||
*
|
||||
* A notification sent to a task can optionally perform an action, such as
|
||||
* update, overwrite or increment the task's notification value. In that way
|
||||
* task notifications can be used to send data to a task, or be used as light
|
||||
* weight and fast binary or counting semaphores.
|
||||
*
|
||||
* A notification sent to a task will remain pending until it is cleared by the
|
||||
* task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
|
||||
* already in the Blocked state to wait for a notification when the notification
|
||||
* arrives then the task will automatically be removed from the Blocked state
|
||||
* (unblocked) and the notification cleared.
|
||||
*
|
||||
* A task can use xTaskNotifyWait() to [optionally] block to wait for a
|
||||
* notification to be pending, or xTaskNotifyTake() to [optionally] block
|
||||
* to wait for its notification value to have a non-zero value. The task does
|
||||
* not consume any CPU time while it is in the Blocked state.
|
||||
*
|
||||
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||
* it is best to use a task notification to send an event to a task compared to
|
||||
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||
* mutex or event group) to send an event to a task.
|
||||
*
|
||||
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||
* task can be returned from the xTaskCreate() API function used to create the
|
||||
* task, and the handle of the currently running task can be obtained by calling
|
||||
* xTaskGetCurrentTaskHandle().
|
||||
*
|
||||
* @param ulValue Data that can be sent with the notification. How the data is
|
||||
* used depends on the value of the eAction parameter.
|
||||
*
|
||||
* @param eAction Specifies how the notification updates the task's notification
|
||||
* value, if at all. Valid values for eAction are as follows:
|
||||
*
|
||||
* eSetBits -
|
||||
* The task's notification value is bitwise ORed with ulValue. xTaskNofify()
|
||||
* always returns pdPASS in this case.
|
||||
*
|
||||
* eIncrement -
|
||||
* The task's notification value is incremented. ulValue is not used and
|
||||
* xTaskNotify() always returns pdPASS in this case.
|
||||
*
|
||||
* eSetValueWithOverwrite -
|
||||
* The task's notification value is set to the value of ulValue, even if the
|
||||
* task being notified had not yet processed the previous notification (the
|
||||
* task already had a notification pending). xTaskNotify() always returns
|
||||
* pdPASS in this case.
|
||||
*
|
||||
* eSetValueWithoutOverwrite -
|
||||
* If the task being notified did not already have a notification pending then
|
||||
* the task's notification value is set to ulValue and xTaskNotify() will
|
||||
* return pdPASS. If the task being notified already had a notification
|
||||
* pending then no action is performed and pdFAIL is returned.
|
||||
*
|
||||
* eNoAction -
|
||||
* The task receives a notification without its notification value being
|
||||
* updated. ulValue is not used and xTaskNotify() always returns pdPASS in
|
||||
* this case.
|
||||
*
|
||||
* @return Dependent on the value of eAction. See the description of the
|
||||
* eAction parameter.
|
||||
*
|
||||
* \defgroup xTaskNotify xTaskNotify
|
||||
* \ingroup TaskNotifications
|
||||
*/
|
||||
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );</PRE>
|
||||
*
|
||||
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||
* available.
|
||||
*
|
||||
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||
*
|
||||
* A version of xTaskNotify() that can be used from an interrupt service routine
|
||||
* (ISR).
|
||||
*
|
||||
* Events can be sent to a task using an intermediary object. Examples of such
|
||||
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||
* are a method of sending an event directly to a task without the need for such
|
||||
* an intermediary object.
|
||||
*
|
||||
* A notification sent to a task can optionally perform an action, such as
|
||||
* update, overwrite or increment the task's notification value. In that way
|
||||
* task notifications can be used to send data to a task, or be used as light
|
||||
* weight and fast binary or counting semaphores.
|
||||
*
|
||||
* A notification sent to a task will remain pending until it is cleared by the
|
||||
* task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
|
||||
* already in the Blocked state to wait for a notification when the notification
|
||||
* arrives then the task will automatically be removed from the Blocked state
|
||||
* (unblocked) and the notification cleared.
|
||||
*
|
||||
* A task can use xTaskNotifyWait() to [optionally] block to wait for a
|
||||
* notification to be pending, or xTaskNotifyTake() to [optionally] block
|
||||
* to wait for its notification value to have a non-zero value. The task does
|
||||
* not consume any CPU time while it is in the Blocked state.
|
||||
*
|
||||
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||
* it is best to use a task notification to send an event to a task compared to
|
||||
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||
* mutex or event group) to send an event to a task.
|
||||
*
|
||||
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||
* task can be returned from the xTaskCreate() API function used to create the
|
||||
* task, and the handle of the currently running task can be obtained by calling
|
||||
* xTaskGetCurrentTaskHandle().
|
||||
*
|
||||
* @param ulValue Data that can be sent with the notification. How the data is
|
||||
* used depends on the value of the eAction parameter.
|
||||
*
|
||||
* @param eAction Specifies how the notification updates the task's notification
|
||||
* value, if at all. Valid values for eAction are as follows:
|
||||
*
|
||||
* eSetBits -
|
||||
* The task's notification value is bitwise ORed with ulValue. xTaskNofify()
|
||||
* always returns pdPASS in this case.
|
||||
*
|
||||
* eIncrement -
|
||||
* The task's notification value is incremented. ulValue is not used and
|
||||
* xTaskNotify() always returns pdPASS in this case.
|
||||
*
|
||||
* eSetValueWithOverwrite -
|
||||
* The task's notification value is set to the value of ulValue, even if the
|
||||
* task being notified had not yet processed the previous notification (the
|
||||
* task already had a notification pending). xTaskNotify() always returns
|
||||
* pdPASS in this case.
|
||||
*
|
||||
* eSetValueWithoutOverwrite -
|
||||
* If the task being notified did not already have a notification pending then
|
||||
* the task's notification value is set to ulValue and xTaskNotify() will
|
||||
* return pdPASS. If the task being notified already had a notification
|
||||
* pending then no action is performed and pdFAIL is returned.
|
||||
*
|
||||
* eNoAction -
|
||||
* The task receives a notification without its notification value being
|
||||
* updated. ulValue is not used and xTaskNotify() always returns pdPASS in
|
||||
* this case.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set
|
||||
* *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
|
||||
* task to which the notification was sent to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently running task. If
|
||||
* xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should
|
||||
* be requested before the interrupt is exited. How a context switch is
|
||||
* requested from an ISR is dependent on the port - see the documentation page
|
||||
* for the port in use.
|
||||
*
|
||||
* @return Dependent on the value of eAction. See the description of the
|
||||
* eAction parameter.
|
||||
*
|
||||
* \defgroup xTaskNotify xTaskNotify
|
||||
* \ingroup TaskNotifications
|
||||
*/
|
||||
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, BaseType_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );</pre>
|
||||
*
|
||||
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||
* available.
|
||||
*
|
||||
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||
*
|
||||
* Events can be sent to a task using an intermediary object. Examples of such
|
||||
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||
* are a method of sending an event directly to a task without the need for such
|
||||
* an intermediary object.
|
||||
*
|
||||
* A notification sent to a task can optionally perform an action, such as
|
||||
* update, overwrite or increment the task's notification value. In that way
|
||||
* task notifications can be used to send data to a task, or be used as light
|
||||
* weight and fast binary or counting semaphores.
|
||||
*
|
||||
* A notification sent to a task will remain pending until it is cleared by the
|
||||
* task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
|
||||
* already in the Blocked state to wait for a notification when the notification
|
||||
* arrives then the task will automatically be removed from the Blocked state
|
||||
* (unblocked) and the notification cleared.
|
||||
*
|
||||
* A task can use xTaskNotifyWait() to [optionally] block to wait for a
|
||||
* notification to be pending, or xTaskNotifyTake() to [optionally] block
|
||||
* to wait for its notification value to have a non-zero value. The task does
|
||||
* not consume any CPU time while it is in the Blocked state.
|
||||
*
|
||||
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||
* it is best to use a task notification to send an event to a task compared to
|
||||
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||
* mutex or event group) to send an event to a task.
|
||||
*
|
||||
* @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value
|
||||
* will be cleared in the calling task's notification value before the task
|
||||
* checks to see if any notifications are pending, and optionally blocks if no
|
||||
* notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if
|
||||
* limits.h is included) or 0xffffffffUL (if limits.h is not included) will have
|
||||
* the effect of resetting the task's notification value to 0. Setting
|
||||
* ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged.
|
||||
*
|
||||
* @param ulBitsToClearOnExit If a notification is pending or received before
|
||||
* the calling task exits the xTaskNotifyWait() function then the task's
|
||||
* notification value (see the xTaskNotify() API function) is passed out using
|
||||
* the pulNotificationValue parameter. Then any bits that are set in
|
||||
* ulBitsToClearOnExit will be cleared in the task's notification value (note
|
||||
* *pulNotificationValue is set before any bits are cleared). Setting
|
||||
* ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL
|
||||
* (if limits.h is not included) will have the effect of resetting the task's
|
||||
* notification value to 0 before the function exits. Setting
|
||||
* ulBitsToClearOnExit to 0 will leave the task's notification value unchanged
|
||||
* when the function exits (in which case the value passed out in
|
||||
* pulNotificationValue will match the task's notification value).
|
||||
*
|
||||
* @param pulNotificationValue Used to pass the task's notification value out
|
||||
* of the function. Note the value passed out will not be effected by the
|
||||
* clearing of any bits caused by ulBitsToClearOnExit being non-zero.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time that the task should wait in
|
||||
* the Blocked state for a notification to be received, should a notification
|
||||
* not already be pending when xTaskNotifyWait() was called. The task
|
||||
* will not consume any processing time while it is in the Blocked state. This
|
||||
* is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be
|
||||
* used to convert a time specified in milliseconds to a time specified in
|
||||
* ticks.
|
||||
*
|
||||
* @return If a notification was received (including notifications that were
|
||||
* already pending when xTaskNotifyWait was called) then pdPASS is
|
||||
* returned. Otherwise pdFAIL is returned.
|
||||
*
|
||||
* \defgroup xTaskNotifyWait xTaskNotifyWait
|
||||
* \ingroup TaskNotifications
|
||||
*/
|
||||
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, BaseType_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>BaseType_t xTaskNotifyGive( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
*
|
||||
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this macro to be
|
||||
* available.
|
||||
*
|
||||
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||
*
|
||||
* Events can be sent to a task using an intermediary object. Examples of such
|
||||
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||
* are a method of sending an event directly to a task without the need for such
|
||||
* an intermediary object.
|
||||
*
|
||||
* A notification sent to a task can optionally perform an action, such as
|
||||
* update, overwrite or increment the task's notification value. In that way
|
||||
* task notifications can be used to send data to a task, or be used as light
|
||||
* weight and fast binary or counting semaphores.
|
||||
*
|
||||
* xTaskNotifyGive() is a helper macro intended for use when task notifications
|
||||
* are used as light weight and faster binary or counting semaphore equivalents.
|
||||
* Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function,
|
||||
* the equivalent action that instead uses a task notification is
|
||||
* xTaskNotifyGive().
|
||||
*
|
||||
* When task notifications are being used as a binary or counting semaphore
|
||||
* equivalent then the task being notified should wait for the notification
|
||||
* using the ulTaskNotificationTake() API function rather than the
|
||||
* xTaskNotifyWait() API function.
|
||||
*
|
||||
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for more details.
|
||||
*
|
||||
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||
* task can be returned from the xTaskCreate() API function used to create the
|
||||
* task, and the handle of the currently running task can be obtained by calling
|
||||
* xTaskGetCurrentTaskHandle().
|
||||
*
|
||||
* @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the
|
||||
* eAction parameter set to eIncrement - so pdPASS is always returned.
|
||||
*
|
||||
* \defgroup xTaskNotifyGive xTaskNotifyGive
|
||||
* \ingroup TaskNotifications
|
||||
*/
|
||||
#define xTaskNotifyGive( xTaskToNotify ) xTaskNotify( ( xTaskToNotify ), 0, eIncrement );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>BaseType_t xTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
*
|
||||
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this macro to be
|
||||
* available.
|
||||
*
|
||||
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||
*
|
||||
* A version of xTaskNotifyGive() that can be called from an interrupt service
|
||||
* routine (ISR).
|
||||
*
|
||||
* Events can be sent to a task using an intermediary object. Examples of such
|
||||
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||
* are a method of sending an event directly to a task without the need for such
|
||||
* an intermediary object.
|
||||
*
|
||||
* A notification sent to a task can optionally perform an action, such as
|
||||
* update, overwrite or increment the task's notification value. In that way
|
||||
* task notifications can be used to send data to a task, or be used as light
|
||||
* weight and fast binary or counting semaphores.
|
||||
*
|
||||
* xTaskNotifyGiveFromISR() is a helper macro intended for use when task
|
||||
* notifications are used as light weight and faster binary or counting
|
||||
* semaphore equivalents. Actual FreeRTOS semaphores are given from an ISR
|
||||
* using the xSemaphoreGiveFromISR() API function, the equivalent action that
|
||||
* instead uses a task notification is xTaskNotifyGiveFromISR().
|
||||
*
|
||||
* When task notifications are being used as a binary or counting semaphore
|
||||
* equivalent then the task being notified should wait for the notification
|
||||
* using the ulTaskNotificationTake() API function rather than the
|
||||
* xTaskNotifyWait() API function.
|
||||
*
|
||||
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for more details.
|
||||
*
|
||||
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||
* task can be returned from the xTaskCreate() API function used to create the
|
||||
* task, and the handle of the currently running task can be obtained by calling
|
||||
* xTaskGetCurrentTaskHandle().
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken xTaskNotifyGiveFromISR() will set
|
||||
* *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
|
||||
* task to which the notification was sent to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently running task. If
|
||||
* xTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
|
||||
* should be requested before the interrupt is exited. How a context switch is
|
||||
* requested from an ISR is dependent on the port - see the documentation page
|
||||
* for the port in use.
|
||||
*
|
||||
* @return xTaskNotifyGiveFromISR() is a macro that calls xTaskNotifyFromISR()
|
||||
* with the eAction parameter set to eIncrement - so pdPASS is always returned.
|
||||
*
|
||||
* \defgroup xTaskNotifyWait xTaskNotifyWait
|
||||
* \ingroup TaskNotifications
|
||||
*/
|
||||
#define xTaskNotifyGiveFromISR( xTaskToNotify, pxHigherPriorityTaskWoken ) xTaskNotifyFromISR( ( xTaskToNotify ), 0, eIncrement, ( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );</pre>
|
||||
*
|
||||
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||
* available.
|
||||
*
|
||||
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||
*
|
||||
* Events can be sent to a task using an intermediary object. Examples of such
|
||||
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||
* are a method of sending an event directly to a task without the need for such
|
||||
* an intermediary object.
|
||||
*
|
||||
* A notification sent to a task can optionally perform an action, such as
|
||||
* update, overwrite or increment the task's notification value. In that way
|
||||
* task notifications can be used to send data to a task, or be used as light
|
||||
* weight and fast binary or counting semaphores.
|
||||
*
|
||||
* ulTaskNotifyTake() is intended for use when a task notification is used as a
|
||||
* faster and lighter weight binary or counting semaphore alternative. Actual
|
||||
* FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the
|
||||
* equivalent action that instead uses a task notification is
|
||||
* xTaskNotifyTake().
|
||||
*
|
||||
* When a task is using its notification value as a binary or counting semaphore
|
||||
* other tasks should send notifications to it using the xTaskNotifyGive()
|
||||
* macro, or xTaskNotify() function with the eAction parameter set to
|
||||
* eIncrement.
|
||||
*
|
||||
* xTaskNotifyTake() can either clear the task's notification value to
|
||||
* zero on exit, in which case the notification value acts like a binary
|
||||
* semaphore, or decrement the task's notification value on exit, in which case
|
||||
* the notification value acts like a counting semaphore.
|
||||
*
|
||||
* A task can use xTaskNotifyTake() to [optionally] block to wait for a
|
||||
* the tasks notification value to be non-zero. The task does not consume any
|
||||
* CPU time while it is in the Blocked state.
|
||||
*
|
||||
* Where as xTaskNotifyWait() will return when a notification is pending,
|
||||
* xTaskNotifyTake() will return when the task's notification value is
|
||||
* not zero.
|
||||
*
|
||||
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||
* it is best to use a task notification to send an event to a task compared to
|
||||
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||
* mutex or event group) to send an event to a task.
|
||||
*
|
||||
* @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's
|
||||
* notification value is decremented when the function exits. In this way the
|
||||
* notification value acts like a counting semaphore. If xClearCountOnExit is
|
||||
* not pdFALSE then the task's notification value is cleared to zero when the
|
||||
* function exits. In this way the notification value acts like a binary
|
||||
* semaphore.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time that the task should wait in
|
||||
* the Blocked state for the task's notification value to be greater than zero,
|
||||
* should the count not already be greater than zero when
|
||||
* xTaskNotifyTake() was called. The task will not consume any processing
|
||||
* time while it is in the Blocked state. This is specified in kernel ticks,
|
||||
* the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time
|
||||
* specified in milliseconds to a time specified in ticks.
|
||||
*
|
||||
* @return The task's notification count before it is either cleared to zero or
|
||||
* decremented (see the xClearCountOnExit parameter).
|
||||
*
|
||||
* \defgroup ulTaskNotifyTake ulTaskNotifyTake
|
||||
* \ingroup TaskNotifications
|
||||
*/
|
||||
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
|
||||
*----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -125,13 +125,12 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
|
||||
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||
|
||||
If the list already contains a list item with the same item value then
|
||||
the new list item should be placed after it. This ensures that TCB's which
|
||||
are stored in ready lists (all of which have the same xItemValue value)
|
||||
get an equal share of the CPU. However, if the xItemValue is the same as
|
||||
the back marker the iteration loop below will not end. This means we need
|
||||
to guard against this by checking the value first and modifying the
|
||||
algorithm slightly if necessary. */
|
||||
If the list already contains a list item with the same item value then the
|
||||
new list item should be placed after it. This ensures that TCB's which are
|
||||
stored in ready lists (all of which have the same xItemValue value) get a
|
||||
share of the CPU. However, if the xItemValue is the same as the back marker
|
||||
the iteration loop below will not end. Therefore the value is checked
|
||||
first, and the algorithm slightly modified if necessary. */
|
||||
if( xValueOfInsertion == portMAX_DELAY )
|
||||
{
|
||||
pxIterator = pxList->xListEnd.pxPrevious;
|
||||
|
|
@ -139,27 +138,31 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
else
|
||||
{
|
||||
/* *** NOTE ***********************************************************
|
||||
If you find your application is crashing here then likely causes are:
|
||||
If you find your application is crashing here then likely causes are
|
||||
listed below. In addition see http://www.freertos.org/FAQHelp.html for
|
||||
more tips, and ensure configASSERT() is defined!
|
||||
http://www.freertos.org/a00110.html#configASSERT
|
||||
|
||||
1) Stack overflow -
|
||||
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||
2) Incorrect interrupt priority assignment, especially on Cortex-M3
|
||||
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||
parts where numerically high priority values denote low actual
|
||||
interrupt priorities, which can seem counter intuitive. See
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||
http://www.freertos.org/a00110.html
|
||||
3) Calling an API function from within a critical section or when
|
||||
the scheduler is suspended, or calling an API function that does
|
||||
not end in "FromISR" from an interrupt.
|
||||
4) Using a queue or semaphore before it has been initialised or
|
||||
before the scheduler has been started (are interrupts firing
|
||||
before vTaskStartScheduler() has been called?).
|
||||
See http://www.freertos.org/FAQHelp.html for more tips, and ensure
|
||||
configASSERT() is defined! http://www.freertos.org/a00110.html#configASSERT
|
||||
**********************************************************************/
|
||||
|
||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
{
|
||||
/* There is nothing to do here, we are just iterating to the
|
||||
wanted insertion position. */
|
||||
/* There is nothing to do here, just iterating to the wanted
|
||||
insertion position. */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,8 +167,8 @@ the CPU itself before modifying certain hardware registers. */
|
|||
{ \
|
||||
portCPU_IRQ_DISABLE(); \
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||
__asm( "DSB \n" \
|
||||
"ISB \n" ); \
|
||||
__asm volatile ( "DSB \n" \
|
||||
"ISB \n" ); \
|
||||
portCPU_IRQ_ENABLE(); \
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
|||
#define portPRIGROUP_SHIFT ( 8UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000UL )
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@
|
|||
#define portPRIGROUP_SHIFT ( 8UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to manipulate the VFP. */
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||
|
|
@ -384,27 +384,13 @@ void vPortEndScheduler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__asm volatile( "dsb" );
|
||||
__asm volatile( "isb" );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
__asm volatile( "dsb" );
|
||||
__asm volatile( "isb" );
|
||||
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
|
|
@ -426,37 +412,6 @@ void vPortExitCritical( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__(( naked )) uint32_t ulPortSetInterruptMask( void )
|
||||
{
|
||||
__asm volatile \
|
||||
( \
|
||||
" mrs r0, basepri \n" \
|
||||
" mov r1, %0 \n" \
|
||||
" msr basepri, r1 \n" \
|
||||
" bx lr \n" \
|
||||
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1" \
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
warnings. */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__(( naked )) void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile \
|
||||
( \
|
||||
" msr basepri, r0 \n" \
|
||||
" bx lr \n" \
|
||||
:::"r0" \
|
||||
);
|
||||
|
||||
/* Just to avoid compiler warnings. */
|
||||
( void ) ulNewMaskValue;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void xPortPendSVHandler( void )
|
||||
{
|
||||
/* This is a naked function. */
|
||||
|
|
@ -480,6 +435,8 @@ void xPortPendSVHandler( void )
|
|||
" stmdb sp!, {r3} \n"
|
||||
" mov r0, %0 \n"
|
||||
" msr basepri, r0 \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n"
|
||||
|
|
|
|||
|
|
@ -109,25 +109,21 @@ typedef unsigned long UBaseType_t;
|
|||
#define portBYTE_ALIGNMENT 8
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield( void );
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern uint32_t ulPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0)
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||
#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
|
|
@ -188,6 +184,53 @@ not necessary for to use this port. They are defined so the common demo files
|
|||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" msr basepri, %1 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 " :: "r" ( ulNewMaskValue )
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__asm volatile( "dsb" );
|
||||
__asm volatile( "isb" );
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ typedef struct PORT_REGISTER_DUMP
|
|||
/* The human readable name of the task that was running at the time the
|
||||
exception occurred. This is the name that was given to the task when the
|
||||
task was created using the FreeRTOS xTaskCreate() API function. */
|
||||
int8_t *pcCurrentTaskName;
|
||||
char *pcCurrentTaskName;
|
||||
|
||||
/* The handle of the task that was running a the time the exception
|
||||
occurred. */
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@
|
|||
#define portPRIGROUP_SHIFT ( 8UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
|
@ -327,9 +327,9 @@ void vPortEnterCritical( void )
|
|||
uxCriticalNesting++;
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@
|
|||
#define portPRIGROUP_SHIFT ( 8UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to manipulate the VFP. */
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||
|
|
@ -335,27 +335,13 @@ void vPortEndScheduler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@
|
|||
EXTERN vTaskSwitchContext
|
||||
|
||||
PUBLIC xPortPendSVHandler
|
||||
PUBLIC ulPortSetInterruptMask
|
||||
PUBLIC vPortClearInterruptMask
|
||||
PUBLIC vPortSVCHandler
|
||||
PUBLIC vPortStartFirstTask
|
||||
PUBLIC vPortEnableVFP
|
||||
|
|
@ -102,6 +100,8 @@ xPortPendSVHandler:
|
|||
stmdb sp!, {r3}
|
||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
msr basepri, r0
|
||||
dsb
|
||||
isb
|
||||
bl vTaskSwitchContext
|
||||
mov r0, #0
|
||||
msr basepri, r0
|
||||
|
|
@ -134,20 +134,6 @@ xPortPendSVHandler:
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
ulPortSetInterruptMask:
|
||||
mrs r0, basepri
|
||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
msr basepri, r1
|
||||
bx r14
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortClearInterruptMask:
|
||||
msr basepri, r0
|
||||
bx r14
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortSVCHandler:
|
||||
/* Get the location of the current TCB. */
|
||||
ldr r3, =pxCurrentTCB
|
||||
|
|
|
|||
|
|
@ -110,11 +110,10 @@ typedef unsigned long UBaseType_t;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield( void );
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -145,15 +144,13 @@ extern void vPortYield( void );
|
|||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern uint32_t ulPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( uint32_t ulNewMask );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x )
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
|
|
@ -179,6 +176,51 @@ not necessary for to use this port. They are defined so the common demo files
|
|||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE _Pragma("inline=forced")
|
||||
#endif
|
||||
|
||||
portFORCE_INLINE static void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n" \
|
||||
" mov r1, %1 \n" \
|
||||
" msr basepri, r1 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
:"=r" (ulOriginalBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r1"
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 " :: "r" ( ulNewMaskValue )
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||
the source code because to do so would cause other compilers to generate
|
||||
warnings. */
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ is defined. */
|
|||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ is defined. */
|
|||
#define portPRIGROUP_SHIFT ( 8UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to manipulate the VFP. */
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||
|
|
@ -134,9 +134,6 @@ is defined. */
|
|||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
#define portINITIAL_EXEC_RETURN ( 0xfffffffd )
|
||||
|
||||
/* Constants used with memory barrier intrinsics. */
|
||||
#define portSY_FULL_READ_WRITE ( 15 )
|
||||
|
||||
/* The systick is a 24-bit counter. */
|
||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||
|
||||
|
|
@ -401,24 +398,10 @@ void vPortEndScheduler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__dsb( portSY_FULL_READ_WRITE );
|
||||
__isb( portSY_FULL_READ_WRITE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
__dsb( portSY_FULL_READ_WRITE );
|
||||
__isb( portSY_FULL_READ_WRITE );
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
|
|
@ -471,6 +454,8 @@ __asm void xPortPendSVHandler( void )
|
|||
stmdb sp!, {r3}
|
||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
msr basepri, r0
|
||||
dsb
|
||||
isb
|
||||
bl vTaskSwitchContext
|
||||
mov r0, #0
|
||||
msr basepri, r0
|
||||
|
|
@ -702,26 +687,6 @@ void xPortSysTickHandler( void )
|
|||
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__asm uint32_t ulPortSetInterruptMask( void )
|
||||
{
|
||||
PRESERVE8
|
||||
|
||||
mrs r0, basepri
|
||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
msr basepri, r1
|
||||
bx r14
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__asm void vPortClearInterruptMask( uint32_t ulNewMask )
|
||||
{
|
||||
PRESERVE8
|
||||
|
||||
msr basepri, r0
|
||||
bx r14
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__asm uint32_t vPortGetIPSR( void )
|
||||
{
|
||||
PRESERVE8
|
||||
|
|
|
|||
|
|
@ -107,29 +107,30 @@ typedef unsigned long UBaseType_t;
|
|||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
|
||||
/* Constants used with memory barrier intrinsics. */
|
||||
#define portSY_FULL_READ_WRITE ( 15 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield( void );
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern uint32_t ulPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( uint32_t ulNewMask );
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -178,6 +179,53 @@ not necessary for to use this port. They are defined so the common demo files
|
|||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE __forceinline
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
/* Barrier instructions are not used as this function is only used to
|
||||
lower the BASEPRI value. */
|
||||
msr basepri, ulBASEPRI
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||
|
||||
__asm
|
||||
{
|
||||
/* Set BASEPRI to the max syscall priority to effect a critical
|
||||
section. */
|
||||
mrs ulReturn, basepri
|
||||
msr basepri, ulNewBASEPRI
|
||||
dsb
|
||||
isb
|
||||
}
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portFORCE_INLINE void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__dsb( portSY_FULL_READ_WRITE );
|
||||
__isb( portSY_FULL_READ_WRITE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to manipulate the VFP. */
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||
|
|
|
|||
|
|
@ -1377,8 +1377,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Is there data in the queue now? To be running we must be
|
||||
the highest priority task wanting to access the queue. */
|
||||
/* 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( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* Remember the read position in case the queue is only being
|
||||
|
|
|
|||
|
|
@ -114,6 +114,14 @@ functions but without including stdio.h here. */
|
|||
#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
||||
#endif
|
||||
|
||||
/* Value that can be assigned to the eNotifyState member of the TCB. */
|
||||
typedef enum
|
||||
{
|
||||
eNotWaitingNotification,
|
||||
eWaitingNotification,
|
||||
eNotified
|
||||
} eNotifyValue;
|
||||
|
||||
/*
|
||||
* Task control block. A task control block (TCB) is allocated for each task,
|
||||
* and stores task state information, including a pointer to the task's context
|
||||
|
|
@ -170,6 +178,11 @@ typedef struct tskTaskControlBlock
|
|||
struct _reent xNewLib_reent;
|
||||
#endif
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
uint32_t ulNotifiedValue;
|
||||
eNotifyValue eNotifyState;
|
||||
#endif
|
||||
|
||||
} tskTCB;
|
||||
|
||||
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
||||
|
|
@ -228,8 +241,8 @@ PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U;
|
|||
PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = portMAX_DELAY;
|
||||
|
||||
/* Context switches are held pending while the scheduler is suspended. Also,
|
||||
interrupts must not manipulate the xStateListItem of a TCB, or any of the
|
||||
lists the xStateListItem can be referenced from, if the scheduler is suspended.
|
||||
interrupts must not manipulate the xGenericListItem of a TCB, or any of the
|
||||
lists the xGenericListItem can be referenced from, if the scheduler is suspended.
|
||||
If an interrupt needs to unblock a task while the scheduler is suspended then it
|
||||
moves the task's event list item into the xPendingReadyList, ready for the
|
||||
kernel to move the task from the pending ready list into the real ready list
|
||||
|
|
@ -515,6 +528,15 @@ static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t *
|
|||
*/
|
||||
static void prvResetNextTaskUnblockTime( void );
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||
|
||||
/*
|
||||
* Helper function used to pad task names with spaces when printing out
|
||||
* human readable tables of task information.
|
||||
*/
|
||||
static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName );
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
|
@ -995,7 +1017,7 @@ TCB_t * pxNewTCB;
|
|||
}
|
||||
#endif
|
||||
|
||||
else
|
||||
else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */
|
||||
{
|
||||
/* If the task is not in any other state, it must be in the
|
||||
Ready (including pending ready) state. */
|
||||
|
|
@ -1031,6 +1053,46 @@ TCB_t * pxNewTCB;
|
|||
#endif /* INCLUDE_uxTaskPriorityGet */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_uxTaskPriorityGet == 1 )
|
||||
|
||||
UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask )
|
||||
{
|
||||
TCB_t *pxTCB;
|
||||
UBaseType_t uxReturn, uxSavedInterruptState;
|
||||
|
||||
/* RTOS ports that support interrupt nesting have the concept of a
|
||||
maximum system call (or maximum API call) interrupt priority.
|
||||
Interrupts that are above the maximum system call priority are keep
|
||||
permanently enabled, even when the RTOS kernel is in a critical section,
|
||||
but cannot make any calls to FreeRTOS API functions. If configASSERT()
|
||||
is defined in FreeRTOSConfig.h then
|
||||
portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
|
||||
failure if a FreeRTOS API function is called from an interrupt that has
|
||||
been assigned a priority above the configured maximum system call
|
||||
priority. Only FreeRTOS functions that end in FromISR can be called
|
||||
from interrupts that have been assigned a priority at or (logically)
|
||||
below the maximum system call interrupt priority. FreeRTOS maintains a
|
||||
separate interrupt safe API to ensure interrupt entry is as fast and as
|
||||
simple as possible. More information (albeit Cortex-M specific) is
|
||||
provided on the following link:
|
||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html */
|
||||
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
|
||||
|
||||
uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
/* If null is passed in here then we are changing the
|
||||
priority of the calling function. */
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
uxReturn = pxTCB->uxPriority;
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState );
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_uxTaskPriorityGet */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_vTaskPrioritySet == 1 )
|
||||
|
||||
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
|
||||
|
|
@ -1614,8 +1676,8 @@ BaseType_t xAlreadyYielded = pdFALSE;
|
|||
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
|
||||
/* If we have moved a task that has a priority higher than
|
||||
the current task then we should yield. */
|
||||
/* If the moved task has a priority higher than the current
|
||||
task then a yield must be performed. */
|
||||
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
|
||||
{
|
||||
xYieldPending = pdTRUE;
|
||||
|
|
@ -1884,7 +1946,7 @@ BaseType_t xSwitchRequired = pdFALSE;
|
|||
/* See if this tick has made a timeout expire. Tasks are stored in
|
||||
the queue in the order of their wake time - meaning once one task
|
||||
has been found whose block time has not expired there is no need to
|
||||
look any further down the list. */
|
||||
look any further down the list. */
|
||||
if( xConstTickCount >= xNextTaskUnblockTime )
|
||||
{
|
||||
for( ;; )
|
||||
|
|
@ -2395,6 +2457,20 @@ BaseType_t xReturn;
|
|||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
{
|
||||
/* If a task is blocked on a kernel object then xNextTaskUnblockTime
|
||||
might be set to the blocked task's time out time. If the task is
|
||||
unblocked for a reason other than a timeout xNextTaskUnblockTime is
|
||||
normally left unchanged, because it is automatically get reset to a new
|
||||
value when the tick count equals xNextTaskUnblockTime. However if
|
||||
tickless idling is used it might be more important to enter sleep mode
|
||||
at the earliest possible time - so reset xNextTaskUnblockTime here to
|
||||
ensure it is updated at the earliest possible time. */
|
||||
prvResetNextTaskUnblockTime();
|
||||
}
|
||||
#endif
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -2788,6 +2864,13 @@ UBaseType_t x;
|
|||
}
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
{
|
||||
pxTCB->ulNotifiedValue = 0;
|
||||
pxTCB->eNotifyState = eNotWaitingNotification;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
||||
{
|
||||
/* Initialise this task's Newlib reent structure. */
|
||||
|
|
@ -3416,6 +3499,32 @@ TCB_t *pxTCB;
|
|||
#endif /* portCRITICAL_NESTING_IN_TCB */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||
|
||||
static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName )
|
||||
{
|
||||
BaseType_t x;
|
||||
|
||||
/* Start by copying the entire string. */
|
||||
strcpy( pcBuffer, pcTaskName );
|
||||
|
||||
/* Pad the end of the string with spaces to ensure columns line up when
|
||||
printed out. */
|
||||
for( x = strlen( pcBuffer ); x < configMAX_TASK_NAME_LEN; x++ )
|
||||
{
|
||||
pcBuffer[ x ] = ' ';
|
||||
}
|
||||
|
||||
/* Terminate. */
|
||||
pcBuffer[ x ] = 0x00;
|
||||
|
||||
/* Return the new end of string. */
|
||||
return &( pcBuffer[ x ] );
|
||||
}
|
||||
|
||||
#endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||
|
||||
void vTaskList( char * pcWriteBuffer )
|
||||
|
|
@ -3487,7 +3596,12 @@ TCB_t *pxTCB;
|
|||
break;
|
||||
}
|
||||
|
||||
sprintf( pcWriteBuffer, "%s\t\t%c\t%u\t%u\t%u\r\n", pxTaskStatusArray[ x ].pcTaskName, cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
|
||||
/* Write the task name to the string, padding with spaces so it
|
||||
can be printed in tabular form more easily. */
|
||||
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
|
||||
|
||||
/* Write the rest of the string. */
|
||||
sprintf( pcWriteBuffer, "\t\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
|
||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||
}
|
||||
|
||||
|
|
@ -3573,15 +3687,20 @@ TCB_t *pxTCB;
|
|||
|
||||
if( ulStatsAsPercentage > 0UL )
|
||||
{
|
||||
/* Write the task name to the string, padding with
|
||||
spaces so it can be printed in tabular form more
|
||||
easily. */
|
||||
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
|
||||
|
||||
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
|
||||
{
|
||||
sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
|
||||
sprintf( pcWriteBuffer, "\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* sizeof( int ) == sizeof( long ) so a smaller
|
||||
printf() library can be used. */
|
||||
sprintf( pcWriteBuffer, "%s\t\t%u\t\t%u%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
|
||||
sprintf( pcWriteBuffer, "\t\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -3651,7 +3770,433 @@ TickType_t uxReturn;
|
|||
}
|
||||
|
||||
#endif /* configUSE_MUTEXES */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
|
||||
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
uint32_t ulReturn;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Only block if the notification count is not already non-zero. */
|
||||
if( pxCurrentTCB->ulNotifiedValue == 0UL )
|
||||
{
|
||||
/* Mark this task as waiting for a notification. */
|
||||
pxCurrentTCB->eNotifyState = eWaitingNotification;
|
||||
|
||||
if( xTicksToWait > 0 )
|
||||
{
|
||||
/* The task is going to block. First it must be removed
|
||||
from the ready list. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is
|
||||
no need to check, and the port reset macro can be called
|
||||
directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( xTicksToWait == portMAX_DELAY )
|
||||
{
|
||||
/* Add the task to the suspended task list instead
|
||||
of a delayed task list to ensure the task is not
|
||||
woken by a timing event. It will block
|
||||
indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the time at which the task should be
|
||||
woken if no notification events occur. This may
|
||||
overflow but this doesn't matter, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#else /* INCLUDE_vTaskSuspend */
|
||||
{
|
||||
/* Calculate the time at which the task should be
|
||||
woken if the event does not occur. This may
|
||||
overflow but this doesn't matter, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
|
||||
/* All ports are written to allow a yield in a critical
|
||||
section (some will yield immediately, others wait until the
|
||||
critical section exits) - but it is not something that
|
||||
application code should ever do. */
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
ulReturn = pxCurrentTCB->ulNotifiedValue;
|
||||
|
||||
if( ulReturn != 0 )
|
||||
{
|
||||
if( xClearCountOnExit != pdFALSE )
|
||||
{
|
||||
pxCurrentTCB->ulNotifiedValue = 0UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
( pxCurrentTCB->ulNotifiedValue )--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
pxCurrentTCB->eNotifyState = eNotWaitingNotification;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
|
||||
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, BaseType_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
BaseType_t xReturn;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Only block if a notification is not already pending. */
|
||||
if( pxCurrentTCB->eNotifyState != eNotified )
|
||||
{
|
||||
/* Clear bits in the task's notification value as bits may get
|
||||
set by the notifying task or interrupt. This can be used to
|
||||
clear the value to zero. */
|
||||
pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;
|
||||
|
||||
/* Mark this task as waiting for a notification. */
|
||||
pxCurrentTCB->eNotifyState = eWaitingNotification;
|
||||
|
||||
if( xTicksToWait > 0 )
|
||||
{
|
||||
/* The task is going to block. First it must be removed
|
||||
from the ready list. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is
|
||||
no need to check, and the port reset macro can be called
|
||||
directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( xTicksToWait == portMAX_DELAY )
|
||||
{
|
||||
/* Add the task to the suspended task list instead
|
||||
of a delayed task list to ensure the task is not
|
||||
woken by a timing event. It will block
|
||||
indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the time at which the task should be
|
||||
woken if no notification events occur. This may
|
||||
overflow but this doesn't matter, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#else /* INCLUDE_vTaskSuspend */
|
||||
{
|
||||
/* Calculate the time at which the task should be
|
||||
woken if the event does not occur. This may
|
||||
overflow but this doesn't matter, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
|
||||
/* All ports are written to allow a yield in a critical
|
||||
section (some will yield immediately, others wait until the
|
||||
critical section exits) - but it is not something that
|
||||
application code should ever do. */
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
if( pulNotificationValue != NULL )
|
||||
{
|
||||
/* Output the current notification value, which may or may not
|
||||
have changed. */
|
||||
*pulNotificationValue = pxCurrentTCB->ulNotifiedValue;
|
||||
}
|
||||
|
||||
/* If eNotifyValue is set then either the task never entered the
|
||||
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->eNotifyState == eWaitingNotification )
|
||||
{
|
||||
/* A notification was not received. */
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A notification was already pending or a notification was
|
||||
received while the task was waiting. */
|
||||
pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
pxCurrentTCB->eNotifyState = eNotWaitingNotification;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
|
||||
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
eNotifyValue eOriginalNotifyState;
|
||||
BaseType_t xReturn = pdPASS;
|
||||
|
||||
configASSERT( xTaskToNotify );
|
||||
pxTCB = ( TCB_t * ) xTaskToNotify;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
eOriginalNotifyState = pxTCB->eNotifyState;
|
||||
|
||||
pxTCB->eNotifyState = eNotified;
|
||||
|
||||
switch( eAction )
|
||||
{
|
||||
case eSetBits :
|
||||
pxTCB->ulNotifiedValue |= ulValue;
|
||||
break;
|
||||
|
||||
case eIncrement :
|
||||
( pxTCB->ulNotifiedValue )++;
|
||||
break;
|
||||
|
||||
case eSetValueWithOverwrite :
|
||||
pxTCB->ulNotifiedValue = ulValue;
|
||||
break;
|
||||
|
||||
case eSetValueWithoutOverwrite :
|
||||
if( eOriginalNotifyState != eNotified )
|
||||
{
|
||||
pxTCB->ulNotifiedValue = ulValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The value could not be written to the task. */
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
/* The task is being notified without its notify value being
|
||||
updated. */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* If the task is in the blocked state specifically to wait for a
|
||||
notification then unblock it now. */
|
||||
if( eOriginalNotifyState == eWaitingNotification )
|
||||
{
|
||||
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
|
||||
/* The task should not have been on an event list. */
|
||||
configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
|
||||
|
||||
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||
{
|
||||
/* The notified task has a priority above the currently
|
||||
executing task so a yield is required. */
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
|
||||
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
eNotifyValue eOriginalNotifyState;
|
||||
BaseType_t xReturn = pdPASS;
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
|
||||
configASSERT( xTaskToNotify );
|
||||
|
||||
/* RTOS ports that support interrupt nesting have the concept of a
|
||||
maximum system call (or maximum API call) interrupt priority.
|
||||
Interrupts that are above the maximum system call priority are keep
|
||||
permanently enabled, even when the RTOS kernel is in a critical section,
|
||||
but cannot make any calls to FreeRTOS API functions. If configASSERT()
|
||||
is defined in FreeRTOSConfig.h then
|
||||
portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
|
||||
failure if a FreeRTOS API function is called from an interrupt that has
|
||||
been assigned a priority above the configured maximum system call
|
||||
priority. Only FreeRTOS functions that end in FromISR can be called
|
||||
from interrupts that have been assigned a priority at or (logically)
|
||||
below the maximum system call interrupt priority. FreeRTOS maintains a
|
||||
separate interrupt safe API to ensure interrupt entry is as fast and as
|
||||
simple as possible. More information (albeit Cortex-M specific) is
|
||||
provided on the following link:
|
||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html */
|
||||
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
|
||||
|
||||
pxTCB = ( TCB_t * ) xTaskToNotify;
|
||||
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
eOriginalNotifyState = pxTCB->eNotifyState;
|
||||
|
||||
pxTCB->eNotifyState = eNotified;
|
||||
|
||||
switch( eAction )
|
||||
{
|
||||
case eSetBits :
|
||||
pxTCB->ulNotifiedValue |= ulValue;
|
||||
break;
|
||||
|
||||
case eIncrement :
|
||||
( pxTCB->ulNotifiedValue )++;
|
||||
break;
|
||||
|
||||
case eSetValueWithOverwrite :
|
||||
pxTCB->ulNotifiedValue = ulValue;
|
||||
break;
|
||||
|
||||
case eSetValueWithoutOverwrite :
|
||||
if( eOriginalNotifyState != eNotified )
|
||||
{
|
||||
pxTCB->ulNotifiedValue = ulValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The value could not be written to the task. */
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
/* The task is being notified without its notify value being
|
||||
updated. */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* If the task is in the blocked state specifically to wait for a
|
||||
notification then unblock it now. */
|
||||
if( eOriginalNotifyState == eWaitingNotification )
|
||||
{
|
||||
/* The task should not have been on an event list. */
|
||||
configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
|
||||
|
||||
if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
|
||||
{
|
||||
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The delayed and ready lists cannot be accessed, so hold
|
||||
this task pending until the scheduler is resumed. */
|
||||
vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
|
||||
}
|
||||
|
||||
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||
{
|
||||
/* The notified task has a priority above the currently
|
||||
executing task so a yield is required. */
|
||||
if( pxHigherPriorityTaskWoken != NULL )
|
||||
{
|
||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef FREERTOS_MODULE_TEST
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue