\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
* 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
*/\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
* 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
* @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
// 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
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
{\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
// 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
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
{\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
{\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
{\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
{\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
* \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
<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
<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
<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
* 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
* 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
* \page xTaskGetTickCount xTaskGetTickCount\r
* \ingroup TaskUtils\r
*/\r
-portTickType xTaskGetTickCount( void );\r
+portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;\r
\r
/**\r
* task. h\r
* \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
* \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
* \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
* \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
* \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
* @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
* 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
*\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
* 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
* 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
* 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
* @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
* 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
* 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