task. h
BaseType_t xTaskCreateRestricted(
TaskParameters_t *pxTaskDefinition,
TaskHandle_t *pxCreatedTask );
Create a new Memory Protection Unit (MPU) restricted task and add it to the list of tasks that are ready to run.
xTaskCreateRestricted() is intended for use with
FreeRTOS-MPU, the
demo applications for which contain
comprehensive and documented examples of xTaskCreateRestricted() being used.
- Parameters:
-
pxTaskDefinition | Pointer to a structure that defines the task. The structure
is described on this page. |
pxCreatedTask | Used to pass back a handle by which the created task can be referenced. |
- Returns:
- pdPASS if the task was successfully created and added to a ready list, otherwise an error code defined in the file projdefs.h
Tasks that include MPU support require even more parameters to create than those that don't. Passing each parameter to
xTaskCreateRestricted() individually would be unwieldy so instead the structure TaskParameters_t is used to
allow the parameters to be configured statically at compile time. The structure is defined in task.h as:
typedef struct xTASK_PARAMETERS
{
TaskFunction_t pvTaskCode;
const signed char * const pcName;
unsigned short usStackDepth;
void *pvParameters;
UBaseType_t uxPriority;
portSTACK_TYPE *puxStackBuffer;
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
} TaskParameters_t;
....where MemoryRegion_t is defined as:
typedef struct xMEMORY_REGION
{
void *pvBaseAddress;
unsigned long ulLengthInBytes;
unsigned long ulParameters;
} MemoryRegion_t;
Following is a description of each structure member:
- pvTaskCode to uxPriority
These members are exactly the same as the parameters to xTaskCreate() of the same name.
In particular uxPriority is used to set both the priority of the task and the mode in which the task will execute.
For example, to create a User mode task at priority 2 simply set uxPriority to 2, to create a Privileged mode task
at priority 2 set uxPriority to ( 2 | portPRIVILEGE_BIT ).
- puxStackBuffer
Each time a task is switched in the MPU is dynamically re-configured to define a region that provides the task
read and write access to its own stack.
MPU regions must meet a number of constraints - in particular, the
size and alignment of each region must both be equal to the same power of two value.
Standard FreeRTOS ports use pvPortMalloc() to allocate a new stacks each time a task is created. Providing
a pvPortMalloc() implementation that took care of the MPU data alignment requirements would be possible but
would also be complex and inefficient in its RAM usage. To remove the need for this complexity FreeRTOS-MPU
allows stacks to be declared statically at compile time. This allows the alignment to be managed using compiler
extensions and RAM usage efficiency to be managed by the linker. For example, if using GCC a stack could be
declared and correctly aligned using the following code:
char cTaskStack[ 1024 ] __attribute__((align(1024));
puxStackBuffer would normally be set to the address of the statically declared stack. As an alternative
puxStackBuffer can be set to NULL - in which case pvPortMallocAligned() will be called to allocate the task
stack and it is the application writers responsibility to provide an implementation of pvPortMallocAligned()
that meets the alignment requirements of the MPU.
- xMemoryRegions
xRegions is an array of MemoryRegion_t structures, each of which defines a single user definable
memory region for use by the task being created. The ARM Cortex-M3 FreeRTOS-MPU port defines
portNUM_CONFIGURABLE_REGIONS to be 3.
The pvBaseAddress and ulLengthInBytes members are self explanatory as the start of the memory
region and the length of the memory region respectively. ulParameters defines how the task is
permitted to access the memory region and can take the bitwise OR of the following values:
portMPU_REGION_READ_WRITE
portMPU_REGION_PRIVILEGED_READ_ONLY
portMPU_REGION_READ_ONLY
portMPU_REGION_PRIVILEGED_READ_WRITE
portMPU_REGION_CACHEABLE_BUFFERABLE
portMPU_REGION_EXECUTE_NEVER
Example usage (please refer to the FreeRTOS-MPU demo applications
for a much more complete and comprehensive example):
/* Declare the stack that will be used by the task. The stack alignment must
match its size and be a power of 2, so if 128 words are reserved for the stack
then it must be aligned to ( 128 * 4 ) bytes. This example used GCC syntax. */
static portSTACK_TYPE xTaskStack[ 128 ] __attribute__((aligned(128*4)));
/* Declare an array that will be accessed by the task. The task should only
be able to read from the array, and not write to it. */
char cReadOnlyArray[ 512 ] __attribute__((aligned(512)));
/* Fill in a TaskParameters_t structure to define the task - this is the
structure passed to the xTaskCreateRestricted() function. */
static const TaskParameters_t xTaskDefinition =
{
vTaskFunction, /* pvTaskCode */
"A task", /* pcName */
128, /* usStackDepth - defined in words, not bytes. */
NULL, /* pvParameters */
1, /* uxPriority - priority 1, start in User mode. */
xTaskStack, /* puxStackBuffer - the array to use as the task stack. */
/* xRegions - In this case only one of the three user definable regions is
actually used. The parameters are used to set the region to read only. */
{
/* Base address Length Parameters */
{ cReadOnlyArray, mainREAD_ONLY_ALIGN_SIZE, portMPU_REGION_READ_ONLY },
{ 0, 0, 0 },
{ 0, 0, 0 },
}
};
void main( void )
{
/* Create the task defined by xTaskDefinition. NULL is used as the second
parameter as a task handle is not required. */
xTaskCreateRestricted( &xTaskDefinition, NULL );
/* Start the RTOS scheduler. */
vTaskStartScheduler();
/* Should not reach here! */
}
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|