X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=Source%2Finclude%2Ftask.h;h=3f462ff3ee8e947041650d7b34eb210e523d9cf2;hb=3ffe89d18ef2c06d06203b1b1091e65a98a395d2;hp=40964e52b553f52170bc21e74c51062fbf8cb888;hpb=0423cf7239e75cedd6c89edb6a8c4fa3993909de;p=freertos diff --git a/Source/include/task.h b/Source/include/task.h index 40964e52b..3f462ff3e 100644 --- a/Source/include/task.h +++ b/Source/include/task.h @@ -1,65 +1,90 @@ /* - FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry. + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! - This file is part of the FreeRTOS.org distribution. - - FreeRTOS.org is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - FreeRTOS.org 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. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with FreeRTOS.org; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - A special exception to the GPL can be applied should you wish to distribute - a combined work that includes FreeRTOS.org, without being obliged to provide - the source code for any proprietary components. See the licensing section - of http://www.FreeRTOS.org for full details of how and when the exception - can be applied. - - *************************************************************************** - - Please ensure to read the configuration and relevant port sections of the - online documentation. - - +++ http://www.FreeRTOS.org +++ - Documentation, latest information, license and contact details. - - +++ http://www.SafeRTOS.com +++ - A version that is certified for use in safety critical systems. - - +++ http://www.OpenRTOS.com +++ - Commercial support, development, porting, licensing and training services. + + *************************************************************************** + * * + * 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, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - Selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. */ -/* -Changes since V4.3.1: - - + Added xTaskGetSchedulerState() function. -*/ #ifndef TASK_H #define TASK_H +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + #include "portable.h" #include "list.h" #ifdef __cplusplus extern "C" { #endif + /*----------------------------------------------------------- * MACROS AND DEFINITIONS *----------------------------------------------------------*/ -#define tskKERNEL_VERSION_NUMBER "V4.7.1" +#define tskKERNEL_VERSION_NUMBER "V7.1.1" /** * task. h @@ -78,16 +103,40 @@ typedef void * xTaskHandle; */ typedef struct xTIME_OUT { - portBASE_TYPE xOverflowCount; - portTickType xTimeOnEntering; + portBASE_TYPE xOverflowCount; + portTickType xTimeOnEntering; } xTimeOutType; +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + unsigned long ulLengthInBytes; + unsigned long ulParameters; +} xMemoryRegion; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMTERS +{ + pdTASK_CODE pvTaskCode; + const signed char * const pcName; + unsigned short usStackDepth; + void *pvParameters; + unsigned portBASE_TYPE uxPriority; + portSTACK_TYPE *puxStackBuffer; + xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ]; +} xTaskParameters; + /* * Defines the priority used by the idle task. This must not be modified. * * \ingroup TaskUtils */ -#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 ) +#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0U ) /** * task. h @@ -160,16 +209,21 @@ typedef struct xTIME_OUT * task. h *
  portBASE_TYPE xTaskCreate(
-                              pdTASK_CODE pvTaskCode,
-                              const portCHAR * const pcName,
-                              unsigned portSHORT usStackDepth,
-                              void *pvParameters,
-                              unsigned portBASE_TYPE uxPriority,
-                              xTaskHandle *pvCreatedTask
-                          );
+ pdTASK_CODE pvTaskCode, + const char * const pcName, + unsigned short usStackDepth, + void *pvParameters, + unsigned portBASE_TYPE uxPriority, + xTaskHandle *pvCreatedTask + ); * * Create a new task and add it to the list of tasks that are ready to run. * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * * @param pvTaskCode Pointer to the task entry function. Tasks * must be implemented to never return (i.e. continuous loop). * @@ -185,7 +239,11 @@ typedef struct xTIME_OUT * @param pvParameters Pointer that will be used as the parameter for the task * being created. * - * @param uxPriority The priority at which the task should run. + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). * * @param pvCreatedTask Used to pass back a handle by which the created task * can be referenced. @@ -198,29 +256,149 @@ typedef struct xTIME_OUT // Task to be created. void vTaskCode( void * pvParameters ) { - for( ;; ) - { - // Task code goes here. - } + for( ;; ) + { + // Task code goes here. + } } // Function that creates a task. void vOtherFunction( void ) { - unsigned char ucParameterToPass; + static unsigned char ucParameterToPass; xTaskHandle xHandle; - - // Create the task, storing the handle. - xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle ); - - // Use the handle to delete the task. - vTaskDelete( xHandle ); + + // Create the task, storing the handle. Note that the passed parameter ucParameterToPass + // must exist for the lifetime of the task, so in this case is declared static. If it was just an + // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time + // the new task attempts to access it. + xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle ); + + // Use the handle to delete the task. + vTaskDelete( xHandle ); } * \defgroup xTaskCreate xTaskCreate * \ingroup Tasks */ -signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask ); +#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) ) + +/** + * task. h + *
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );
+ * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file errors. h + * + * Example usage: +
+// Create an xTaskParameters structure that defines the task to be created.
+static const xTaskParameters xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{											
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+xTaskHandle xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) + +/** + * task. h + *
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an xMemoryRegion structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of xMemoryRegion structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{											
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+	
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION; /** * task. h @@ -250,19 +428,18 @@ signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR void vOtherFunction( void ) { xTaskHandle xHandle; - - // Create the task, storing the handle. - xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); - - // Use the handle to delete the task. - vTaskDelete( xHandle ); + + // Create the task, storing the handle. + xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + + // Use the handle to delete the task. + vTaskDelete( xHandle ); } * \defgroup vTaskDelete vTaskDelete * \ingroup Tasks */ -void vTaskDelete( xTaskHandle pxTask ); - +void vTaskDelete( xTaskHandle pxTaskToDelete ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * TASK CONTROL API @@ -280,42 +457,43 @@ void vTaskDelete( xTaskHandle pxTask ); * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. * See the configuration section for more information. * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a cyclical task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * * @param xTicksToDelay The amount of time, in tick periods, that * the calling task should block. * * Example usage: -
- // Wait 10 ticks before performing an action.
- // NOTE:
- // This is for demonstration only and would be better achieved
- // using vTaskDelayUntil ().
+
  void vTaskFunction( void * pvParameters )
  {
- portTickType xDelay, xNextTime;
-
-     // Calc the time at which we want to perform the action
-     // next.
-     xNextTime = xTaskGetTickCount () + ( portTickType ) 10;
-
-     for( ;; )
-     {
-         xDelay = xNextTime - xTaskGetTickCount ();
-         xNextTime += ( portTickType ) 10;
-
-         // Guard against overflow
-         if( xDelay <= ( portTickType ) 10 )
-         {
-             vTaskDelay( xDelay );
-         }
-
-         // Perform action here.
-     }
+ void vTaskFunction( void * pvParameters )
+ {
+ // Block for 500ms.
+ const portTickType xDelay = 500 / portTICK_RATE_MS;
+
+	 for( ;; )
+	 {
+		 // Simply toggle the LED every 500ms, blocking between each toggle.
+		 vToggleLED();
+		 vTaskDelay( xDelay );
+	 }
  }
-   
+ * \defgroup vTaskDelay vTaskDelay * \ingroup TaskCtrl */ -void vTaskDelay( portTickType xTicksToDelay ); +void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION; /** * task. h @@ -360,21 +538,21 @@ void vTaskDelay( portTickType xTicksToDelay ); portTickType xLastWakeTime; const portTickType xFrequency = 10; - // Initialise the xLastWakeTime variable with the current time. - xLastWakeTime = xTaskGetTickCount (); - for( ;; ) - { - // Wait for the next cycle. - vTaskDelayUntil( &xLastWakeTime, xFrequency ); + // Initialise the xLastWakeTime variable with the current time. + xLastWakeTime = xTaskGetTickCount (); + for( ;; ) + { + // Wait for the next cycle. + vTaskDelayUntil( &xLastWakeTime, xFrequency ); - // Perform action here. - } + // Perform action here. + } } * \defgroup vTaskDelayUntil vTaskDelayUntil * \ingroup TaskCtrl */ -void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ); +void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION; /** * task. h @@ -395,33 +573,33 @@ void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTim void vAFunction( void ) { xTaskHandle xHandle; - - // Create a task, storing the handle. - xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); - - // ... - - // Use the handle to obtain the priority of the created task. - // It was created with tskIDLE_PRIORITY, but may have changed - // it itself. - if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY ) - { - // The task has changed it's priority. - } - - // ... - - // Is our priority higher than the created task? - if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) ) - { - // Our priority (obtained using NULL handle) is higher. - } + + // Create a task, storing the handle. + xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + + // ... + + // Use the handle to obtain the priority of the created task. + // It was created with tskIDLE_PRIORITY, but may have changed + // it itself. + if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY ) + { + // The task has changed it's priority. + } + + // ... + + // Is our priority higher than the created task? + if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) ) + { + // Our priority (obtained using NULL handle) is higher. + } } * \defgroup uxTaskPriorityGet uxTaskPriorityGet * \ingroup TaskCtrl */ -unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ); +unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION; /** * task. h @@ -445,25 +623,25 @@ unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ); void vAFunction( void ) { xTaskHandle xHandle; - - // Create a task, storing the handle. - xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); - // ... + // Create a task, storing the handle. + xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + + // ... - // Use the handle to raise the priority of the created task. - vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 ); + // Use the handle to raise the priority of the created task. + vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 ); - // ... + // ... - // Use a NULL handle to raise our priority to the same value. - vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); + // Use a NULL handle to raise our priority to the same value. + vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); } * \defgroup vTaskPrioritySet vTaskPrioritySet * \ingroup TaskCtrl */ -void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ); +void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION; /** * task. h @@ -487,34 +665,34 @@ void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority void vAFunction( void ) { xTaskHandle xHandle; - - // Create a task, storing the handle. - xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); - - // ... - - // Use the handle to suspend the created task. - vTaskSuspend( xHandle ); - - // ... - - // The created task will not run during this period, unless - // another task calls vTaskResume( xHandle ). - - //... - - - // Suspend ourselves. - vTaskSuspend( NULL ); - - // We cannot get here unless another task calls vTaskResume - // with our handle as the parameter. + + // Create a task, storing the handle. + xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + + // ... + + // Use the handle to suspend the created task. + vTaskSuspend( xHandle ); + + // ... + + // The created task will not run during this period, unless + // another task calls vTaskResume( xHandle ). + + //... + + + // Suspend ourselves. + vTaskSuspend( NULL ); + + // We cannot get here unless another task calls vTaskResume + // with our handle as the parameter. } * \defgroup vTaskSuspend vTaskSuspend * \ingroup TaskCtrl */ -void vTaskSuspend( xTaskHandle pxTaskToSuspend ); +void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION; /** * task. h @@ -536,40 +714,40 @@ void vTaskSuspend( xTaskHandle pxTaskToSuspend ); void vAFunction( void ) { xTaskHandle xHandle; - - // Create a task, storing the handle. - xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); - - // ... - // Use the handle to suspend the created task. - vTaskSuspend( xHandle ); + // Create a task, storing the handle. + xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); - // ... - - // The created task will not run during this period, unless - // another task calls vTaskResume( xHandle ). - - //... - + // ... + + // Use the handle to suspend the created task. + vTaskSuspend( xHandle ); + + // ... - // Resume the suspended task ourselves. - vTaskResume( xHandle ); + // The created task will not run during this period, unless + // another task calls vTaskResume( xHandle ). - // The created task will once again get microcontroller processing - // time in accordance with it priority within the system. + //... + + + // Resume the suspended task ourselves. + vTaskResume( xHandle ); + + // The created task will once again get microcontroller processing + // time in accordance with it priority within the system. } * \defgroup vTaskResume vTaskResume * \ingroup TaskCtrl */ -void vTaskResume( xTaskHandle pxTaskToResume ); +void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION; /** * task. h *
void xTaskResumeFromISR( xTaskHandle pxTaskToResume );
* - * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be * available. See the configuration section for more information. * * An implementation of vTaskResume() that can be called from within an ISR. @@ -583,7 +761,7 @@ void vTaskResume( xTaskHandle pxTaskToResume ); * \defgroup vTaskResumeFromISR vTaskResumeFromISR * \ingroup TaskCtrl */ -portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ); +portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER CONTROL @@ -608,20 +786,20 @@ portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume );
  void vAFunction( void )
  {
-     // Create at least one task before starting the kernel.
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
 
-     // Start the real time kernel with preemption.
-     vTaskStartScheduler ();
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
 
-     // Will not get here unless a task calls vTaskEndScheduler ()
+	 // Will not get here unless a task calls vTaskEndScheduler ()
  }
    
* * \defgroup vTaskStartScheduler vTaskStartScheduler * \ingroup SchedulerControl */ -void vTaskStartScheduler( void ); +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; /** * task. h @@ -647,34 +825,34 @@ void vTaskStartScheduler( void );
  void vTaskCode( void * pvParameters )
  {
-     for( ;; )
-     {
-         // Task code goes here.
-
-         // At some point we want to end the real time kernel processing
-         // so call ...
-         vTaskEndScheduler ();
-     }
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
  }
 
  void vAFunction( void )
  {
-     // Create at least one task before starting the kernel.
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
 
-     // Start the real time kernel with preemption.
-     vTaskStartScheduler ();
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
 
-     // Will only get here when the vTaskCode () task has called
-     // vTaskEndScheduler ().  When we get here we are back to single task
-     // execution.
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
  }
    
* * \defgroup vTaskEndScheduler vTaskEndScheduler * \ingroup SchedulerControl */ -void vTaskEndScheduler( void ); +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; /** * task. h @@ -687,94 +865,108 @@ void vTaskEndScheduler( void ); * without risk of being swapped out until a call to xTaskResumeAll () has been * made. * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * * Example usage:
  void vTask1( void * pvParameters )
  {
-     for( ;; )
-     {
-         // Task code goes here.
+	 for( ;; )
+	 {
+		 // Task code goes here.
 
-         // ...
+		 // ...
 
-         // At some point the task wants to perform a long operation during
-         // which it does not want to get swapped out.  It cannot use
-         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
-         // operation may cause interrupts to be missed - including the
-         // ticks.
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
 
-         // Prevent the real time kernel swapping out the task.
-         vTaskSuspendAll ();
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
 
-         // Perform the operation here.  There is no need to use critical
-         // sections as we have all the microcontroller processing time.
-         // During this time interrupts will still operate and the kernel
-         // tick count will be maintained.
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
 
-         // ...
+		 // ...
 
-         // The operation is complete.  Restart the kernel.
-         xTaskResumeAll ();
-     }
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
  }
    
* \defgroup vTaskSuspendAll vTaskSuspendAll * \ingroup SchedulerControl */ -void vTaskSuspendAll( void ); +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; /** * task. h - *
portCHAR xTaskResumeAll( void );
+ *
char xTaskResumeAll( void );
* * Resumes real time kernel activity following a call to vTaskSuspendAll (). * After a call to vTaskSuspendAll () the kernel will take control of which * task is executing at any time. * * @return If resuming the scheduler caused a context switch then pdTRUE is - * returned, otherwise pdFALSE is returned. + * returned, otherwise pdFALSE is returned. * * Example usage:
  void vTask1( void * pvParameters )
  {
-     for( ;; )
-     {
-         // Task code goes here.
-
-         // ...
-
-         // At some point the task wants to perform a long operation during
-         // which it does not want to get swapped out.  It cannot use
-         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
-         // operation may cause interrupts to be missed - including the
-         // ticks.
-
-         // Prevent the real time kernel swapping out the task.
-         vTaskSuspendAll ();
-
-         // Perform the operation here.  There is no need to use critical
-         // sections as we have all the microcontroller processing time.
-         // During this time interrupts will still operate and the real
-         // time kernel tick count will be maintained.
-
-         // ...
-
-         // The operation is complete.  Restart the kernel.  We want to force
-         // a context switch - but there is no point if resuming the scheduler
-         // caused a context switch already.
-         if( !xTaskResumeAll () )
-         {
-              taskYIELD ();
-         }
-     }
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
  }
    
* \defgroup xTaskResumeAll xTaskResumeAll * \ingroup SchedulerControl */ -signed portBASE_TYPE xTaskResumeAll( void ); +signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION; +/** + * task. h + *
signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );
+ * + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + * + */ +signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * TASK UTILITIES @@ -782,18 +974,34 @@ signed portBASE_TYPE xTaskResumeAll( void ); /** * task. h - *
volatile portTickType xTaskGetTickCount( void );
+ *
portTickType xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \page xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
portTickType xTaskGetTickCountFromISR( void );
* * @return The count of ticks since vTaskStartScheduler was called. * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that portTickType is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * * \page xTaskGetTickCount xTaskGetTickCount * \ingroup TaskUtils */ -portTickType xTaskGetTickCount( void ); +portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; /** * task. h - *
unsigned portSHORT uxTaskGetNumberOfTasks( void );
+ *
unsigned short uxTaskGetNumberOfTasks( void );
* * @return The number of tasks that the real time kernel is currently managing. * This includes all ready, blocked and suspended tasks. A task that @@ -803,15 +1011,28 @@ portTickType xTaskGetTickCount( void ); * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks * \ingroup TaskUtils */ -unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ); +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; /** * task. h - *
void vTaskList( portCHAR *pcWriteBuffer );
+ *
signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );
* - * configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and INCLUDE_vTaskSuspend - * must all be defined as 1 for this function to be available. - * See the configuration section for more information. + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQueury. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be + * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available. + * + * \page pcTaskGetTaskName pcTaskGetTaskName + * \ingroup TaskUtils + */ +signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery ); + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. * * NOTE: This function will disable interrupts for its duration. It is * not intended for normal application runtime use but as a debug aid. @@ -830,11 +1051,43 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ); * \page vTaskList vTaskList * \ingroup TaskUtils */ -void vTaskList( signed portCHAR *pcWriteBuffer ); +void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /** * task. h - *
void vTaskStartTrace( portCHAR * pcBuffer, unsigned portBASE_TYPE uxBufferSize );
+ *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ * + * configGENERATE_RUN_TIME_STATS must be defined as 1 for this function + * to be available. The application must also then provide definitions + * for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter + * and return the timers current count value respectively. The counter + * should be at least 10 times the frequency of the tick count. + * + * NOTE: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ascii form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \page vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskStartTrace( char * pcBuffer, unsigned portBASE_TYPE uxBufferSize );
* * Starts a real time kernel activity trace. The trace logs the identity of * which task is running when. @@ -851,11 +1104,11 @@ void vTaskList( signed portCHAR *pcWriteBuffer ); * \page vTaskStartTrace vTaskStartTrace * \ingroup TaskUtils */ -void vTaskStartTrace( signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize ); +void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) PRIVILEGED_FUNCTION; /** * task. h - *
unsigned portLONG ulTaskEndTrace( void );
+ *
unsigned long ulTaskEndTrace( void );
* * Stops a kernel activity trace. See vTaskStartTrace (). * @@ -864,8 +1117,76 @@ void vTaskStartTrace( signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize * \page usTaskEndTrace usTaskEndTrace * \ingroup TaskUtils */ -unsigned portLONG ulTaskEndTrace( void ); +unsigned long ulTaskEndTrace( void ) PRIVILEGED_FUNCTION; +/** + * task.h + *
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in bytes) + * since the task referenced by xTask was created. + */ +unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include tasks.h before +FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( xTaskHandle xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. + */ + pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +/** + * task.h + *
portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. + */ +portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +xTaskHandle xTaskGetIdleTaskHandle( void ); /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES @@ -881,7 +1202,7 @@ unsigned portLONG ulTaskEndTrace( void ); * for a finite period required removing from a blocked list and placing on * a ready list. */ -inline void vTaskIncrementTick( void ); +void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN @@ -904,7 +1225,7 @@ inline void vTaskIncrementTick( void ); * portTICK_RATE_MS can be used to convert kernel ticks into a real time * period. */ -void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ); +void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN @@ -912,29 +1233,31 @@ void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicks * * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. * - * Removes a task from both the specified event list and the list of blocked - * tasks, and places it on a ready queue. - * - * xTaskRemoveFromEventList () will be called if either an event occurs to - * unblock a task, or the block timeout period expires. + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. * * @return pdTRUE if the task being removed has a higher priority than the task * making the call, otherwise pdFALSE. */ -signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ); +void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. * - * INCLUDE_vTaskCleanUpResources and INCLUDE_vTaskSuspend must be defined as 1 - * for this function to be available. - * See the configuration section for more information. + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList () will be called if either an event occurs to + * unblock a task, or the block timeout period expires. * - * Empties the ready and delayed queues of task control blocks, freeing the - * memory allocated for the task control block and task stacks as it goes. + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. */ -void vTaskCleanUpResources( void ); +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY @@ -944,47 +1267,65 @@ void vTaskCleanUpResources( void ); * Sets the pointer to the current TCB to the TCB of the highest priority task * that is ready to run. */ -inline void vTaskSwitchContext( void ); +void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; /* * Return the handle of the calling task. */ -xTaskHandle xTaskGetCurrentTaskHandle( void ); +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; /* * Capture the current time status for future reference. */ -void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ); +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION; /* * Compare the time status now with that previously captured to see if the * timeout has expired. */ -portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ); +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION; /* * Shortcut used by the queue implementation to prevent unnecessary call to * taskYIELD(); */ -void vTaskMissedYield( void ); +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; /* * Returns the scheduler state as taskSCHEDULER_RUNNING, * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. */ -portBASE_TYPE xTaskGetSchedulerState( void ); +portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; /* * Raises the priority of the mutex holder to that of the calling task should * the mutex holder have a priority less than the calling task. */ -void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ); +void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; /* * Set the priority of a task back to its proper priority in the case that it * inherited a higher priority while it was holding a semaphore. */ -void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ); +void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Generic version of the task creation function which is in turn called by the + * xTaskCreate() and xTaskCreateRestricted() macros. + */ +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask ); + +/* + * Set the uxTCBNumber of the task referenced by the xTask parameter to + * ucHandle. + */ +void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ); + #ifdef __cplusplus }