]> git.sur5r.net Git - freertos/commitdiff
First version that includes the FreeRTOS-MPU implementation.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 30 Sep 2009 20:12:31 +0000 (20:12 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 30 Sep 2009 20:12:31 +0000 (20:12 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@885 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/include/task.h

index e0f156bc5c92d1d9c2296aa30a1108629242bfea..9eff36f995b1f2a052a6916d49369a04e35a0dd8 100644 (file)
@@ -3,14 +3,14 @@
 \r
        This file is part of the FreeRTOS distribution.\r
 \r
-       FreeRTOS is free software; you can redistribute it and/or modify it     under \r
-       the terms of the GNU General Public License (version 2) as published by the \r
+       FreeRTOS is free software; you can redistribute it and/or modify it     under\r
+       the terms of the GNU General Public License (version 2) as published by the\r
        Free Software Foundation and modified by the FreeRTOS exception.\r
        **NOTE** The exception to the GPL is included to allow you to distribute a\r
-       combined work that includes FreeRTOS without being obliged to provide the \r
-       source code for proprietary components outside of the FreeRTOS kernel.  \r
-       Alternative commercial license and support terms are also available upon \r
-       request.  See the licensing section of http://www.FreeRTOS.org for full \r
+       combined work that includes FreeRTOS without being obliged to provide the\r
+       source code for proprietary components outside of the FreeRTOS kernel.\r
+       Alternative commercial license and support terms are also available upon\r
+       request.  See the licensing section of http://www.FreeRTOS.org for full\r
        license details.\r
 \r
        FreeRTOS is distributed in the hope that it will be useful,     but WITHOUT\r
 \r
 \r
        ***************************************************************************\r
-       *                                                                         *\r
-       * Looking for a quick start?  Then check out the FreeRTOS eBook!          *\r
-       * See http://www.FreeRTOS.org/Documentation for details                   *\r
-       *                                                                         *\r
+       *                                                                                                                                                *\r
+       * Looking for a quick start?  Then check out the FreeRTOS eBook!                  *\r
+       * See http://www.FreeRTOS.org/Documentation for details                            *\r
+       *                                                                                                                                                *\r
        ***************************************************************************\r
 \r
        1 tab == 4 spaces!\r
@@ -66,7 +66,7 @@ extern "C" {
  * MACROS AND DEFINITIONS\r
  *----------------------------------------------------------*/\r
 \r
-#define tskKERNEL_VERSION_NUMBER "V5.4.0"\r
+#define tskKERNEL_VERSION_NUMBER "V5.4.2"\r
 \r
 /**\r
  * task. h\r
@@ -85,10 +85,34 @@ typedef void * xTaskHandle;
  */\r
 typedef struct xTIME_OUT\r
 {\r
-    portBASE_TYPE xOverflowCount;\r
-    portTickType  xTimeOnEntering;\r
+       portBASE_TYPE xOverflowCount;\r
+       portTickType  xTimeOnEntering;\r
 } xTimeOutType;\r
 \r
+/*\r
+ * Defines the memory ranges allocated to the task when an MPU is used.\r
+ */\r
+typedef struct xMEMORY_REGION\r
+{\r
+       void *pvBaseAddress;\r
+       unsigned portLONG ulLengthInBytes;\r
+       unsigned portLONG ulParameters;\r
+} xMemoryRegion;\r
+\r
+/*\r
+ * Parameters required to create an MPU protected task.\r
+ */\r
+typedef struct xTASK_PARAMTERS\r
+{\r
+       pdTASK_CODE pvTaskCode;\r
+       const signed portCHAR * const pcName;\r
+       unsigned portSHORT usStackDepth;\r
+       void *pvParameters;\r
+       unsigned portBASE_TYPE uxPriority;\r
+       portSTACK_TYPE *puxStackBuffer;\r
+       xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ];\r
+} xTaskParameters;\r
+\r
 /*\r
  * Defines the priority used by the idle task.  This must not be modified.\r
  *\r
@@ -167,15 +191,20 @@ typedef struct xTIME_OUT
  * task. h\r
  *<pre>\r
  portBASE_TYPE xTaskCreate(\r
-                              pdTASK_CODE pvTaskCode,\r
-                              const portCHAR * const pcName,\r
-                              unsigned portSHORT usStackDepth,\r
-                              void *pvParameters,\r
-                              unsigned portBASE_TYPE uxPriority,\r
-                              xTaskHandle *pvCreatedTask\r
-                          );</pre>\r
+                                                         pdTASK_CODE pvTaskCode,\r
+                                                         const portCHAR * const pcName,\r
+                                                         unsigned portSHORT usStackDepth,\r
+                                                         void *pvParameters,\r
+                                                         unsigned portBASE_TYPE uxPriority,\r
+                                                         xTaskHandle *pvCreatedTask\r
+                                                 );</pre>\r
  *\r
  * Create a new task and add it to the list of tasks that are ready to run.\r
+ * \r
+ * xTaskCreate() can only be used to create a task that has unrestricted\r
+ * access to the entire microcontroller memory map.  Systems that include MPU\r
+ * support can alternatively create an MPU constrained task using \r
+ * xTaskCreateRestricted().\r
  *\r
  * @param pvTaskCode Pointer to the task entry function.  Tasks\r
  * must be implemented to never return (i.e. continuous loop).\r
@@ -192,7 +221,11 @@ typedef struct xTIME_OUT
  * @param pvParameters Pointer that will be used as the parameter for the task\r
  * being created.\r
  *\r
- * @param uxPriority The priority at which the task should run.\r
+ * @param uxPriority The priority at which the task should run.  Systems that\r
+ * include MPU support can optionally create tasks in a privileged (system)\r
+ * mode by setting bit portPRIVILEGE_BIT of the priority parameter.  For\r
+ * example, to create a privileged task at priority 2 the uxPriority parameter\r
+ * should be set to ( 2 | portPRIVILEGE_BIT ).\r
  *\r
  * @param pvCreatedTask Used to pass back a handle by which the created task\r
  * can be referenced.\r
@@ -205,10 +238,10 @@ typedef struct xTIME_OUT
  // Task to be created.\r
  void vTaskCode( void * pvParameters )\r
  {\r
-     for( ;; )\r
-     {\r
-         // Task code goes here.\r
-     }\r
+        for( ;; )\r
+        {\r
+                // Task code goes here.\r
+        }\r
  }\r
 \r
  // Function that creates a task.\r
@@ -217,20 +250,141 @@ typedef struct xTIME_OUT
  static unsigned char ucParameterToPass;\r
  xTaskHandle xHandle;\r
 \r
-     // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass\r
-     // must exist for the lifetime of the task, so in this case is declared static.  If it was just an\r
-     // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time\r
-     // the new time attempts to access it.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );\r
+        // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass\r
+        // must exist for the lifetime of the task, so in this case is declared static.  If it was just an\r
+        // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time\r
+        // the new time attempts to access it.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );\r
 \r
-     // Use the handle to delete the task.\r
-     vTaskDelete( xHandle );\r
+        // Use the handle to delete the task.\r
+        vTaskDelete( xHandle );\r
  }\r
    </pre>\r
  * \defgroup xTaskCreate xTaskCreate\r
  * \ingroup Tasks\r
  */\r
-signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask );\r
+#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )\r
+\r
+/**\r
+ * task. h\r
+ *<pre>\r
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle pxCreatedTask );</pre>\r
+ *\r
+ * xTaskCreateRestricted() should only be used in systems that include an MPU\r
+ * implementation.\r
+ *\r
+ * Create a new task and add it to the list of tasks that are ready to run.\r
+ * The function parameters define the memory regions and associated access\r
+ * permissions allocated to the task.\r
+ *\r
+ * @param pxTaskDefinition Pointer to a structure that contains a member\r
+ * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API\r
+ * documentation) plus an optional stack buffer and the memory region \r
+ * definitions.\r
+ *\r
+ * @param pcName A descriptive name for the task.  This is mainly used to\r
+ * facilitate debugging.  Max length defined by tskMAX_TASK_NAME_LEN - default\r
+ * is 16.\r
+ *\r
+ * @param pxCreatedTask Used to pass back a handle by which the created task\r
+ * can be referenced.\r
+ *\r
+ * @return pdPASS if the task was successfully created and added to a ready\r
+ * list, otherwise an error code defined in the file errors. h\r
+ *\r
+ * Example usage:\r
+   <pre>\r
+// Create an xTaskParameters structure that defines the task to be created.\r
+static const xTaskParameters xCheckTaskParameters =\r
+{\r
+       vATask,         // pvTaskCode - the function that implements the task.\r
+       "ATask",        // pcName - just a text name for the task to assist debugging.\r
+       100,            // usStackDepth - the stack size DEFINED IN WORDS.\r
+       NULL,           // pvParameters - passed into the task function as the function parameters.\r
+       ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.\r
+       cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.\r
+\r
+       // xRegions - Allocate up to three separate memory regions for access by\r
+       // the task, with appropriate access permissions.  Different processors have\r
+       // different memory alignment requirements - refer to the FreeRTOS documentation\r
+       // for full information.\r
+       {                                                                                       \r
+               // Base address                                 Length  Parameters\r
+        { cReadWriteArray,                             32,             portMPU_REGION_READ_WRITE },\r
+        { cReadOnlyArray,                              32,             portMPU_REGION_READ_ONLY },\r
+        { cPrivilegedOnlyAccessArray,  128,    portMPU_REGION_PRIVILEGED_READ_WRITE }\r
+       }\r
+};\r
+\r
+int main( void )\r
+{\r
+xTaskHandle xHandle;\r
+\r
+       // Create a task from the const structure defined above.  The task handle\r
+       // is requested (the second parameter is not NULL) but in this case just for\r
+       // demonstration purposes as its not actually used.\r
+       xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );\r
+\r
+       // Start the scheduler.\r
+       vTaskStartScheduler();\r
+\r
+       // Will only get here if there was insufficient memory to create the idle\r
+       // task.\r
+       for( ;; );\r
+}\r
+   </pre>\r
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
+ * \ingroup Tasks\r
+ */\r
+#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) )\r
+\r
+/**\r
+ * task. h\r
+ *<pre>\r
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );</pre>\r
+ *\r
+ * Memory regions are assigned to a restricted task when the task is created by\r
+ * a call to xTaskCreateRestricted().  These regions can be redefined using\r
+ * vTaskAllocateMPURegions().\r
+ * \r
+ * @param xTask The handle of the task being updated.\r
+ *\r
+ * @param xRegions A pointer to an xMemoryRegion structure that contains the\r
+ * new memory region definitions.\r
+ *\r
+ * Example usage:\r
+   <pre>\r
+// Define an array of xMemoryRegion structures that configures an MPU region\r
+// allowing read/write access for 1024 bytes starting at the beginning of the\r
+// ucOneKByte array.  The other two of the maximum 3 definable regions are\r
+// unused so set to zero.\r
+static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =\r
+{                                                                                      \r
+       // Base address         Length          Parameters\r
+       { ucOneKByte,           1024,           portMPU_REGION_READ_WRITE },\r
+       { 0,                            0,                      0 },\r
+       { 0,                            0,                      0 }\r
+};\r
+\r
+void vATask( void *pvParameters )\r
+{\r
+       // This task was created such that it has access to certain regions of\r
+       // memory as defined by the MPU configuration.  At some point it is \r
+       // desired that these MPU regions are replaced with that defined in the\r
+       // xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()\r
+       // for this purpose.  NULL is used as the task handle to indicate that this\r
+       // function should modify the MPU regions of the calling task.\r
+       vTaskAllocateMPURegions( NULL, xAltRegions );\r
+       \r
+       // Now the task can continue its function, but from this point on can only\r
+       // access its stack and the ucOneKByte array (unless any other statically\r
+       // defined or shared regions have been declared elsewhere).\r
+}\r
+   </pre>\r
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
+ * \ingroup Tasks\r
+ */\r
+void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -261,17 +415,17 @@ signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR
  {\r
  xTaskHandle xHandle;\r
 \r
-     // Create the task, storing the handle.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+        // Create the task, storing the handle.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
 \r
-     // Use the handle to delete the task.\r
-     vTaskDelete( xHandle );\r
+        // Use the handle to delete the task.\r
+        vTaskDelete( xHandle );\r
  }\r
    </pre>\r
  * \defgroup vTaskDelete vTaskDelete\r
  * \ingroup Tasks\r
  */\r
-void vTaskDelete( xTaskHandle pxTask );\r
+void vTaskDelete( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;\r
 \r
 \r
 /*-----------------------------------------------------------\r
@@ -315,18 +469,18 @@ void vTaskDelete( xTaskHandle pxTask );
  // Block for 500ms.\r
  const portTickType xDelay = 500 / portTICK_RATE_MS;\r
 \r
-     for( ;; )\r
-     {\r
-         // Simply toggle the LED every 500ms, blocking between each toggle.\r
-         vToggleLED();\r
-         vTaskDelay( xDelay );\r
-     }\r
+        for( ;; )\r
+        {\r
+                // Simply toggle the LED every 500ms, blocking between each toggle.\r
+                vToggleLED();\r
+                vTaskDelay( xDelay );\r
+        }\r
  }\r
 \r
  * \defgroup vTaskDelay vTaskDelay\r
  * \ingroup TaskCtrl\r
  */\r
-void vTaskDelay( portTickType xTicksToDelay );\r
+void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -371,21 +525,21 @@ void vTaskDelay( portTickType xTicksToDelay );
  portTickType xLastWakeTime;\r
  const portTickType xFrequency = 10;\r
 \r
-     // Initialise the xLastWakeTime variable with the current time.\r
-     xLastWakeTime = xTaskGetTickCount ();\r
-     for( ;; )\r
-     {\r
-         // Wait for the next cycle.\r
-         vTaskDelayUntil( &xLastWakeTime, xFrequency );\r
+        // Initialise the xLastWakeTime variable with the current time.\r
+        xLastWakeTime = xTaskGetTickCount ();\r
+        for( ;; )\r
+        {\r
+                // Wait for the next cycle.\r
+                vTaskDelayUntil( &xLastWakeTime, xFrequency );\r
 \r
-         // Perform action here.\r
-     }\r
+                // Perform action here.\r
+        }\r
  }\r
    </pre>\r
  * \defgroup vTaskDelayUntil vTaskDelayUntil\r
  * \ingroup TaskCtrl\r
  */\r
-void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement );\r
+void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -407,32 +561,32 @@ void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTim
  {\r
  xTaskHandle xHandle;\r
 \r
-     // Create a task, storing the handle.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+        // Create a task, storing the handle.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // Use the handle to obtain the priority of the created task.\r
-     // It was created with tskIDLE_PRIORITY, but may have changed\r
-     // it itself.\r
-     if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )\r
-     {\r
-         // The task has changed it's priority.\r
-     }\r
+        // Use the handle to obtain the priority of the created task.\r
+        // It was created with tskIDLE_PRIORITY, but may have changed\r
+        // it itself.\r
+        if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )\r
+        {\r
+                // The task has changed it's priority.\r
+        }\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // Is our priority higher than the created task?\r
-     if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )\r
-     {\r
-         // Our priority (obtained using NULL handle) is higher.\r
-     }\r
+        // Is our priority higher than the created task?\r
+        if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )\r
+        {\r
+                // Our priority (obtained using NULL handle) is higher.\r
+        }\r
  }\r
    </pre>\r
  * \defgroup uxTaskPriorityGet uxTaskPriorityGet\r
  * \ingroup TaskCtrl\r
  */\r
-unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );\r
+unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -457,24 +611,24 @@ unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );
  {\r
  xTaskHandle xHandle;\r
 \r
-     // Create a task, storing the handle.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+        // Create a task, storing the handle.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // Use the handle to raise the priority of the created task.\r
-     vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );\r
+        // Use the handle to raise the priority of the created task.\r
+        vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // Use a NULL handle to raise our priority to the same value.\r
-     vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );\r
+        // Use a NULL handle to raise our priority to the same value.\r
+        vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );\r
  }\r
    </pre>\r
  * \defgroup vTaskPrioritySet vTaskPrioritySet\r
  * \ingroup TaskCtrl\r
  */\r
-void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );\r
+void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -499,33 +653,33 @@ void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority
  {\r
  xTaskHandle xHandle;\r
 \r
-     // Create a task, storing the handle.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+        // Create a task, storing the handle.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // Use the handle to suspend the created task.\r
-     vTaskSuspend( xHandle );\r
+        // Use the handle to suspend the created task.\r
+        vTaskSuspend( xHandle );\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // The created task will not run during this period, unless\r
-     // another task calls vTaskResume( xHandle ).\r
+        // The created task will not run during this period, unless\r
+        // another task calls vTaskResume( xHandle ).\r
 \r
-     //...\r
+        //...\r
 \r
 \r
-     // Suspend ourselves.\r
-     vTaskSuspend( NULL );\r
+        // Suspend ourselves.\r
+        vTaskSuspend( NULL );\r
 \r
-     // We cannot get here unless another task calls vTaskResume\r
-     // with our handle as the parameter.\r
+        // We cannot get here unless another task calls vTaskResume\r
+        // with our handle as the parameter.\r
  }\r
    </pre>\r
  * \defgroup vTaskSuspend vTaskSuspend\r
  * \ingroup TaskCtrl\r
  */\r
-void vTaskSuspend( xTaskHandle pxTaskToSuspend );\r
+void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -548,33 +702,33 @@ void vTaskSuspend( xTaskHandle pxTaskToSuspend );
  {\r
  xTaskHandle xHandle;\r
 \r
-     // Create a task, storing the handle.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+        // Create a task, storing the handle.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // Use the handle to suspend the created task.\r
-     vTaskSuspend( xHandle );\r
+        // Use the handle to suspend the created task.\r
+        vTaskSuspend( xHandle );\r
 \r
-     // ...\r
+        // ...\r
 \r
-     // The created task will not run during this period, unless\r
-     // another task calls vTaskResume( xHandle ).\r
+        // The created task will not run during this period, unless\r
+        // another task calls vTaskResume( xHandle ).\r
 \r
-     //...\r
+        //...\r
 \r
 \r
-     // Resume the suspended task ourselves.\r
-     vTaskResume( xHandle );\r
+        // Resume the suspended task ourselves.\r
+        vTaskResume( xHandle );\r
 \r
-     // The created task will once again get microcontroller processing\r
-     // time in accordance with it priority within the system.\r
+        // The created task will once again get microcontroller processing\r
+        // time in accordance with it priority within the system.\r
  }\r
    </pre>\r
  * \defgroup vTaskResume vTaskResume\r
  * \ingroup TaskCtrl\r
  */\r
-void vTaskResume( xTaskHandle pxTaskToResume );\r
+void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -594,7 +748,7 @@ void vTaskResume( xTaskHandle pxTaskToResume );
  * \defgroup vTaskResumeFromISR vTaskResumeFromISR\r
  * \ingroup TaskCtrl\r
  */\r
-portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume );\r
+portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;\r
 \r
 /*-----------------------------------------------------------\r
  * SCHEDULER CONTROL\r
@@ -619,20 +773,20 @@ portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume );
    <pre>\r
  void vAFunction( void )\r
  {\r
-     // Create at least one task before starting the kernel.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+        // Create at least one task before starting the kernel.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
 \r
-     // Start the real time kernel with preemption.\r
-     vTaskStartScheduler ();\r
+        // Start the real time kernel with preemption.\r
+        vTaskStartScheduler ();\r
 \r
-     // Will not get here unless a task calls vTaskEndScheduler ()\r
+        // Will not get here unless a task calls vTaskEndScheduler ()\r
  }\r
    </pre>\r
  *\r
  * \defgroup vTaskStartScheduler vTaskStartScheduler\r
  * \ingroup SchedulerControl\r
  */\r
-void vTaskStartScheduler( void );\r
+void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -658,34 +812,34 @@ void vTaskStartScheduler( void );
    <pre>\r
  void vTaskCode( void * pvParameters )\r
  {\r
-     for( ;; )\r
-     {\r
-         // Task code goes here.\r
-\r
-         // At some point we want to end the real time kernel processing\r
-         // so call ...\r
-         vTaskEndScheduler ();\r
-     }\r
+        for( ;; )\r
+        {\r
+                // Task code goes here.\r
+\r
+                // At some point we want to end the real time kernel processing\r
+                // so call ...\r
+                vTaskEndScheduler ();\r
+        }\r
  }\r
 \r
  void vAFunction( void )\r
  {\r
-     // Create at least one task before starting the kernel.\r
-     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+        // Create at least one task before starting the kernel.\r
+        xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
 \r
-     // Start the real time kernel with preemption.\r
-     vTaskStartScheduler ();\r
+        // Start the real time kernel with preemption.\r
+        vTaskStartScheduler ();\r
 \r
-     // Will only get here when the vTaskCode () task has called\r
-     // vTaskEndScheduler ().  When we get here we are back to single task\r
-     // execution.\r
+        // Will only get here when the vTaskCode () task has called\r
+        // vTaskEndScheduler ().  When we get here we are back to single task\r
+        // execution.\r
  }\r
    </pre>\r
  *\r
  * \defgroup vTaskEndScheduler vTaskEndScheduler\r
  * \ingroup SchedulerControl\r
  */\r
-void vTaskEndScheduler( void );\r
+void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -706,37 +860,37 @@ void vTaskEndScheduler( void );
    <pre>\r
  void vTask1( void * pvParameters )\r
  {\r
-     for( ;; )\r
-     {\r
-         // Task code goes here.\r
+        for( ;; )\r
+        {\r
+                // Task code goes here.\r
 \r
-         // ...\r
+                // ...\r
 \r
-         // At some point the task wants to perform a long operation during\r
-         // which it does not want to get swapped out.  It cannot use\r
-         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
-         // operation may cause interrupts to be missed - including the\r
-         // ticks.\r
+                // At some point the task wants to perform a long operation during\r
+                // which it does not want to get swapped out.  It cannot use\r
+                // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
+                // operation may cause interrupts to be missed - including the\r
+                // ticks.\r
 \r
-         // Prevent the real time kernel swapping out the task.\r
-         vTaskSuspendAll ();\r
+                // Prevent the real time kernel swapping out the task.\r
+                vTaskSuspendAll ();\r
 \r
-         // Perform the operation here.  There is no need to use critical\r
-         // sections as we have all the microcontroller processing time.\r
-         // During this time interrupts will still operate and the kernel\r
-         // tick count will be maintained.\r
+                // Perform the operation here.  There is no need to use critical\r
+                // sections as we have all the microcontroller processing time.\r
+                // During this time interrupts will still operate and the kernel\r
+                // tick count will be maintained.\r
 \r
-         // ...\r
+                // ...\r
 \r
-         // The operation is complete.  Restart the kernel.\r
-         xTaskResumeAll ();\r
-     }\r
+                // The operation is complete.  Restart the kernel.\r
+                xTaskResumeAll ();\r
+        }\r
  }\r
    </pre>\r
  * \defgroup vTaskSuspendAll vTaskSuspendAll\r
  * \ingroup SchedulerControl\r
  */\r
-void vTaskSuspendAll( void );\r
+void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -747,48 +901,48 @@ void vTaskSuspendAll( void );
  * task is executing at any time.\r
  *\r
  * @return If resuming the scheduler caused a context switch then pdTRUE is\r
- *         returned, otherwise pdFALSE is returned.\r
+ *               returned, otherwise pdFALSE is returned.\r
  *\r
  * Example usage:\r
    <pre>\r
  void vTask1( void * pvParameters )\r
  {\r
-     for( ;; )\r
-     {\r
-         // Task code goes here.\r
-\r
-         // ...\r
-\r
-         // At some point the task wants to perform a long operation during\r
-         // which it does not want to get swapped out.  It cannot use\r
-         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
-         // operation may cause interrupts to be missed - including the\r
-         // ticks.\r
-\r
-         // Prevent the real time kernel swapping out the task.\r
-         vTaskSuspendAll ();\r
-\r
-         // Perform the operation here.  There is no need to use critical\r
-         // sections as we have all the microcontroller processing time.\r
-         // During this time interrupts will still operate and the real\r
-         // time kernel tick count will be maintained.\r
-\r
-         // ...\r
-\r
-         // The operation is complete.  Restart the kernel.  We want to force\r
-         // a context switch - but there is no point if resuming the scheduler\r
-         // caused a context switch already.\r
-         if( !xTaskResumeAll () )\r
-         {\r
-              taskYIELD ();\r
-         }\r
-     }\r
+        for( ;; )\r
+        {\r
+                // Task code goes here.\r
+\r
+                // ...\r
+\r
+                // At some point the task wants to perform a long operation during\r
+                // which it does not want to get swapped out.  It cannot use\r
+                // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
+                // operation may cause interrupts to be missed - including the\r
+                // ticks.\r
+\r
+                // Prevent the real time kernel swapping out the task.\r
+                vTaskSuspendAll ();\r
+\r
+                // Perform the operation here.  There is no need to use critical\r
+                // sections as we have all the microcontroller processing time.\r
+                // During this time interrupts will still operate and the real\r
+                // time kernel tick count will be maintained.\r
+\r
+                // ...\r
+\r
+                // The operation is complete.  Restart the kernel.  We want to force\r
+                // a context switch - but there is no point if resuming the scheduler\r
+                // caused a context switch already.\r
+                if( !xTaskResumeAll () )\r
+                {\r
+                         taskYIELD ();\r
+                }\r
+        }\r
  }\r
    </pre>\r
  * \defgroup xTaskResumeAll xTaskResumeAll\r
  * \ingroup SchedulerControl\r
  */\r
-signed portBASE_TYPE xTaskResumeAll( void );\r
+signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -799,7 +953,7 @@ signed portBASE_TYPE xTaskResumeAll( void );
  * is in any other state.\r
  *\r
  */\r
-signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );\r
+signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
 \r
 /*-----------------------------------------------------------\r
  * TASK UTILITIES\r
@@ -814,7 +968,7 @@ signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );
  * \page xTaskGetTickCount xTaskGetTickCount\r
  * \ingroup TaskUtils\r
  */\r
-portTickType xTaskGetTickCount( void );\r
+portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -828,7 +982,7 @@ portTickType xTaskGetTickCount( void );
  * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks\r
  * \ingroup TaskUtils\r
  */\r
-unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void );\r
+unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -854,7 +1008,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void );
  * \page vTaskList vTaskList\r
  * \ingroup TaskUtils\r
  */\r
-void vTaskList( signed portCHAR *pcWriteBuffer );\r
+void vTaskList( signed portCHAR *pcWriteBuffer ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -886,7 +1040,7 @@ void vTaskList( signed portCHAR *pcWriteBuffer );
  * \page vTaskGetRunTimeStats vTaskGetRunTimeStats\r
  * \ingroup TaskUtils\r
  */\r
-void vTaskGetRunTimeStats( signed portCHAR *pcWriteBuffer );\r
+void vTaskGetRunTimeStats( signed portCHAR *pcWriteBuffer ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -907,7 +1061,7 @@ void vTaskGetRunTimeStats( signed portCHAR *pcWriteBuffer );
  * \page vTaskStartTrace vTaskStartTrace\r
  * \ingroup TaskUtils\r
  */\r
-void vTaskStartTrace( signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize );\r
+void vTaskStartTrace( signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task. h\r
@@ -920,7 +1074,7 @@ void vTaskStartTrace( signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize
  * \page usTaskEndTrace usTaskEndTrace\r
  * \ingroup TaskUtils\r
  */\r
-unsigned portLONG ulTaskEndTrace( void );\r
+unsigned portLONG ulTaskEndTrace( void ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task.h\r
@@ -940,7 +1094,7 @@ unsigned portLONG ulTaskEndTrace( void );
  * @return The smallest amount of free stack space there has been (in bytes)\r
  * since the task referenced by xTask was created.\r
  */\r
-unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );\r
+unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task.h\r
@@ -950,7 +1104,7 @@ unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
  * Passing xTask as NULL has the effect of setting the calling tasks hook\r
  * function.\r
  */\r
-void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );\r
+void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task.h\r
@@ -958,7 +1112,7 @@ void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunct
  *\r
  * Returns the pxHookFunction value assigned to the task xTask.\r
  */\r
-pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask );\r
+pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
 \r
 /**\r
  * task.h\r
@@ -970,7 +1124,7 @@ pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask );
  * pvParameter is passed to the hook function for the task to interpret as it\r
  * wants.\r
  */\r
-portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter );\r
+portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION;\r
 \r
 \r
 /*-----------------------------------------------------------\r
@@ -987,7 +1141,7 @@ portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter
  * for a finite period required removing from a blocked list and placing on\r
  * a ready list.\r
  */\r
-void vTaskIncrementTick( void );\r
+void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN\r
@@ -1010,7 +1164,7 @@ void vTaskIncrementTick( void );
  * portTICK_RATE_MS can be used to convert kernel ticks into a real time\r
  * period.\r
  */\r
-void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait );\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN\r
@@ -1027,7 +1181,7 @@ void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicks
  * @return pdTRUE if the task being removed has a higher priority than the task\r
  * making the call, otherwise pdFALSE.\r
  */\r
-signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList );\r
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN\r
@@ -1040,7 +1194,7 @@ signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )
  * Empties the ready and delayed queues of task control blocks, freeing the\r
  * memory allocated for the task control block and task stacks as it goes.\r
  */\r
-void vTaskCleanUpResources( void );\r
+void vTaskCleanUpResources( void ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS ONLY\r
@@ -1050,47 +1204,53 @@ void vTaskCleanUpResources( void );
  * Sets the pointer to the current TCB to the TCB of the highest priority task\r
  * that is ready to run.\r
  */\r
-void vTaskSwitchContext( void );\r
+void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Return the handle of the calling task.\r
  */\r
-xTaskHandle xTaskGetCurrentTaskHandle( void );\r
+xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Capture the current time status for future reference.\r
  */\r
-void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut );\r
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Compare the time status now with that previously captured to see if the\r
  * timeout has expired.\r
  */\r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait );\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Shortcut used by the queue implementation to prevent unnecessary call to\r
  * taskYIELD();\r
  */\r
-void vTaskMissedYield( void );\r
+void vTaskMissedYield( void ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Returns the scheduler state as taskSCHEDULER_RUNNING,\r
  * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.\r
  */\r
-portBASE_TYPE xTaskGetSchedulerState( void );\r
+portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Raises the priority of the mutex holder to that of the calling task should\r
  * the mutex holder have a priority less than the calling task.\r
  */\r
-void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder );\r
+void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Set the priority of a task back to its proper priority in the case that it\r
  * inherited a higher priority while it was holding a semaphore.\r
  */\r
-void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder );\r
+void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Generic version of the task creation function which is in turn called by the\r
+ * xTaskCreate() and xTaskCreateProtected() macros.\r
+ */\r
+signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION;\r
 \r
 #ifdef __cplusplus\r
 }\r