|
|
Component
FreeRTOS
FreeRTOS
Methods:
(Methods are user-callable functions/subroutines intended for
the component functions control. Please see the Embedded Components page for more information.)
-
xTaskCreate
- Create a new task and add it to the list of tasks that are ready to run.
ANSIC prototype: portBASE_TYPE xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask)
- pvTaskCode:byte - Pointer to the task entry function. Tasks must be implemented to never return (i.e. continuous loop).
- pcName:byte - A descriptive name for the task. This is mainly used to facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN.
- usStackDepth:byte - The size of the task stack specified as the number of variables the stack can hold - not the number of bytes. For example, if the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes will be allocated for stack storage. The stack depth multiplied by the stack width must not exceed the maximum value that can be contained in a variable of type size_t.
- pvParameters:byte - Pointer that will be used as the parameter for the task being created.
- uxPriority:byte - The priority at which the task should run.
- pvCreatedTask:byte - Used to pass back a handle by which the created task can be referenced.
- Return value:portBASE_TYPE - pdPASS if the task was successfully created and added to a ready list, otherwise an error code defined in the file projdefs.h
-
vTaskDelete
- Remove a task from the RTOS real time kernels management. The task being deleted will be removed from all ready, blocked, suspended and event lists.
NOTE: The idle task is responsible for freeing the kernel allocated memory from tasks that have been deleted. It is therefore important that the idle task is not starved of microcontroller processing time if your application makes any calls to vTaskDelete (). Memory allocated by the task code is not automatically freed, and should be freed before the task is deleted.
ANSIC prototype: void vTaskDelete(xTaskHandle pxTask)
- pxTask:xTaskHandle - The handle of the task to be deleted. Passing NULL will cause the calling task to be deleted.
-
vTaskStartScheduler
- Starts the real time kernel tick processing. After calling the kernel has control over which tasks are executed and when.
The idle task is created automatically when vTaskStartScheduler() is called. If vTaskStartScheduler() is successful the function will not return until an executing task calls vTaskEndScheduler(). The function might fail and return immediately if there is insufficient RAM available for the idle task to be created.
ANSIC prototype: void vTaskStartScheduler(void)
-
vTaskEndScheduler
- Stops the real time kernel tick. All created tasks will be automatically deleted and multitasking (either preemptive or cooperative) will stop. Execution then resumes from the point where vTaskStartScheduler() was called, as if vTaskStartScheduler() had just returned.
See the demo application file main. c in the demo/PC directory for an example that uses vTaskEndScheduler ().
vTaskEndScheduler () requires an exit function to be defined within the portable layer (see vPortEndScheduler () in port. c for the PC port). This performs hardware specific operations such as stopping the kernel tick.
vTaskEndScheduler () will cause all of the resources allocated by the kernel to be freed - but will not free resources allocated by application tasks.
ANSIC prototype: void vTaskEndScheduler(void)
-
vTaskSuspend
- Suspend any task. When suspended a task will never get any microcontroller processing time, no matter what its priority. Calls to vTaskSuspend are not accumulative - i.e. calling vTaskSuspend() twice on the same task still only requires one call to vTaskResume() to ready the suspended task.
ANSIC prototype: void vTaskSuspend(xTaskHandle pxTaskToSuspend)
- pxTaskToSuspend:xTaskHandle - Handle to the task being suspended. Passing a NULL handle will cause the calling task to be suspended.
-
vTaskSuspendAll
- Suspends all real time kernel activity while keeping interrupts (including the kernel tick) enabled.
After calling vTaskSuspendAll () the calling task will continue to execute 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.
ANSIC prototype: void vTaskSuspendAll(void)
-
vTaskResume
- Resumes a suspended task. A task that has been suspended by one of more calls to vTaskSuspend() will be made available for running again by a single call to vTaskResume().
ANSIC prototype: void vTaskResume(xTaskHandle pxTaskToResume)
- pxTaskToResume:xTaskHandle - Handle to the task being readied.
-
xTaskResumeAll
- Resumes real time kernel activity following a call to vTaskSuspendAll (). After a call to xTaskSuspendAll () the kernel will take control of which task is executing at any time.
ANSIC prototype: portBASE_TYPE xTaskResumeAll(void)
- Return value:portBASE_TYPE - If resuming the scheduler caused a context switch then pdTRUE is returned, otherwise pdFALSE is returned.
-
taskYIELD
- Macro for forcing a context switch.
ANSIC prototype: void taskYIELD(void)
-
taskENTER_CRITICAL
- Macro to mark the start of a critical code region. Preemptive context switches cannot occur when in a critical region.
NOTE: This may alter the stack (depending on the portable implementation) so must be used with care!
ANSIC prototype: void taskENTER_CRITICAL(void)
-
taskEXIT_CRITICAL
- Macro to mark the end of a critical code region. Preemptive context switches cannot occur when in a critical region.
NOTE: This may alter the stack (depending on the portable implementation) so must be used with care!
ANSIC prototype: void taskEXIT_CRITICAL(void)
-
taskDISABLE_INTERRUPTS
- Macro to disable all maskable interrupts.
ANSIC prototype: void taskDISABLE_INTERRUPTS(void)
-
taskENABLE_INTERRUPTS
- Macro to enable microcontroller interrupts.
ANSIC prototype: void taskENABLE_INTERRUPTS(void)
-
vTaskDelay
- Delay a task for a given number of ticks. The actual time that the task remains blocked depends on the tick rate. The constant portTICK_RATE_MS can be used to calculate real time from the tick rate - with the resolution of one tick period.
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.
ANSIC prototype: void vTaskDelay(portTickType xTicksToDelay)
- xTicksToDelay:byte - The amount of time, in tick periods, that the calling task should block.
-
vTaskDelayUntil
- Delay a task until a specified time. This function can be used by cyclical tasks to ensure a constant execution frequency.
This function differs from vTaskDelay() in one important aspect: vTaskDelay() specifies a time at which the task wishes to unblock relative to the time at which vTaskDelay() is called, whereas vTaskDelayUntil() specifies an absolute time at which the task wishes to unblock.
vTaskDelay() will cause a task to block for the specified number of ticks from the time vTaskDelay() is called. It is therefore difficult to use vTaskDelay() by itself to generate a fixed execution frequency as the time between a task unblocking following a call to vTaskDelay() and that task next calling vTaskDelay() may not be fixed [the task may take a different path though the code between calls, or may get interrupted or preempted a different number of times each time it executes].
Whereas vTaskDelay() specifies a wake time relative to the time at which the function is called, vTaskDelayUntil() specifies the absolute (exact) time at which it wishes to unblock.
It should be noted that vTaskDelayUntil() will return immediately (without blocking) if it is used to specify a wake time that is already in the past. Therefore a task using vTaskDelayUntil() to execute periodically will have to re-calculate its required wake time if the periodic execution is halted for any reason (for example, the task is temporarily placed into the Suspended state) causing the task to miss one or more periodic executions. This can be detected by checking the variable passed by reference as the pxPreviousWakeTime parameter against the current tick count. This is however not necessary under most usage scenarios.
The constant portTICK_RATE_MS can be used to calculate real time from the tick rate - with the resolution of one tick period.
This function must not be called while the scheduler has been suspended by a call to vTaskSuspendAll().
ANSIC prototype: void vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType xTimeIncrement)
- pxPreviousWakeTime:byte - Pointer to a variable that holds the time at which the task was last unblocked. The variable must be initialised with the current time prior to its first use (see the example below). Following this the variable is automatically updated within vTaskDelayUntil().
- xTimeIncrement:byte - The cycle time period. The task will be unblocked at time (*pxPreviousWakeTime + xTimeIncrement). Calling vTaskDelayUntil with the same xTimeIncrement parameter value will cause the task to execute with a fixed interval period.
-
uxTaskPriorityGet
- Obtain the priority of any task.
ANSIC prototype: unsigned_portBASE_TYPE uxTaskPriorityGet(xTaskHandle pxTask)
- pxTask:byte - Handle of the task to be queried. Passing a NULL handle results in the priority of the calling task being returned.
- Return value:unsigned_portBASE_TYPE - The priority of pxTask.
-
vTaskPrioritySet
- Set the priority of any task.
ANSIC prototype: void vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE uxNewPriority)
- pxTask:xTaskHandle - Handle to the task for which the priority is being set. Passing a NULL handle results in the priority of the calling task being set.
- uxNewPriority:unsigned_portBASE_TYPE - The priority to which the task will be set.
-
xTaskGetTickCount
- Return the count of ticks since vTaskStartScheduler was called.
ANSIC prototype: portTickType xTaskGetTickCount(void)
- Return value:portTickType - tick count
-
xSemaphoreCreateRecursiveMutex
- Macro that implements a recursive mutex by using the existing queue mechanism.
Mutexes created using this macro can be accessed using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The xSemaphoreTake() and xSemaphoreGive() macros should not be used. A mutex used recursively can be 'taken' repeatedly by the owner. The mutex doesn't become available again until the owner has called xSemaphoreGiveRecursive() for each successful 'take' request. For example, if a task successfully 'takes' the same mutex 5 times then the mutex will not be available to any other task until it has also 'given' the mutex back exactly five times. This type of semaphore uses a priority inheritance mechanism so a task 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the semaphore it is no longer required. Mutex type semaphores cannot be used from within interrupt service routines. See vSemaphoreCreateBinary() for an alternative implementation that can be used for pure synchronisation (where one task or interrupt always 'gives' the semaphore and another always 'takes' the semaphore) and from within interrupt service routines.
ANSIC prototype: xSemaphoreHandle xSemaphoreCreateRecursiveMutex(void)
- Return value:xSemaphoreHandle - Handle to the created mutex semaphore. Should be of type xSemaphoreHandle.
-
xSemaphoreTakeRecursive
- Macro to recursively obtain, or 'take', a mutex type semaphore. The mutex must have previously been created using a call to xSemaphoreCreateRecursiveMutex();
This macro must not be used on mutexes created using xSemaphoreCreateMutex(). A mutex used recursively can be 'taken' repeatedly by the owner. The mutex doesn't become available again until the owner has called xSemaphoreGiveRecursive() for each successful 'take' request. For example, if a task successfully 'takes' the same mutex 5 times then the mutex will not be available to any other task until it has also 'given' the mutex back exactly five times.
ANSIC prototype: bool xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType xBlockTime)
- xMutex:xSemaphoreHandle - A handle to the mutex being obtained. This is the handle returned by xSemaphoreCreateRecursiveMutex();
- xBlockTime:byte - The time in ticks to wait for the semaphore to become available. The macro portTICK_RATE_MS can be used to convert this to a real time. A block time of zero can be used to poll the semaphore. If the task already owns the semaphore then xSemaphoreTakeRecursive() will return immediately no matter what the value of xBlockTime.
- Return value:bool - Returns pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime expired without the semaphore becoming available.
-
xSemaphoreGiveRecursive
- Macro to recursively release, or 'give', a mutex type semaphore. The mutex must have previously been created using a call to xSemaphoreCreateRecursiveMutex();
This macro must not be used on mutexes created using xSemaphoreCreateMutex(). A mutex used recursively can be 'taken' repeatedly by the owner. The mutex doesn't become available again until the owner has called xSemaphoreGiveRecursive() for each successful 'take' request. For example, if a task successfully 'takes' the same mutex 5 times then the mutex will not be available to any other task until it has also 'given' the mutex back exactly five times.
ANSIC prototype: bool xSemaphoreGiveRecursive(xSemaphoreHandle xMutex)
- xMutex:xSemaphoreHandle - A handle to the mutex being released, or 'given'. This is the handle returned by xSemaphoreCreateMutex();
- Return value:bool - Returns pdTRUE if the semaphore was given.
-
xSemaphoreCreateMutex
- Macro that creates a mutex semaphore by using the existing queue mechanism.
Mutexes created using this macro can be accessed using the xSemaphoreTake() and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros should not be used.
Mutexes and binary semaphores are very similar but have some subtle differences: Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes binary semaphores the better choice for implementing synchronisation (between tasks or between tasks and an interrupt), and mutexes the better choice for implementing simple mutual exclusion.
The priority of a task that 'takes' a mutex can potentially be raised if another task of higher priority attempts to obtain the same mutex. The task that owns the mutex 'inherits' the priority of the task attempting to 'take' the same mutex. This means the mutex must always be 'given' back - otherwise the higher priority task will never be able to obtain the mutex, and the lower priority task will never 'disinherit' the priority. An example of a mutex being used to implement mutual exclusion is provided on the xSemaphoreTake() documentation page.
A binary semaphore need not be given back once obtained, so task synchronisation can be implemented by one task/interrupt continuously 'giving' the semaphore while another continuously 'takes' the semaphore. This is demonstrated by the sample code on the xSemaphoreGiveFromISR() documentation page.
Both mutex and binary semaphores are assigned to variables of type xSemaphoreHandle and can be used in any API function that takes a parameter of this type.
ANSIC prototype: xSemaphoreHandle xSemaphoreCreateMutex(void)
- Return value:xSemaphoreHandle - Handle to the created mutex semaphore. Should be of type xSemaphoreHandle.
-
xSemaphoreTake
- Macro to obtain a semaphore. The semaphore must have previously been created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or xSemaphoreCreateCounting().
This macro must not be called from an ISR. xQueueReceiveFromISR() can be used to take a semaphore from within an interrupt if required, although this would not be a normal operation. Semaphores use queues as their underlying mechanism, so functions are to some extent interoperable.
xSemaphoreTake() is part of the fully featured intertask communications API. xSemaphoreAltTake() is the alternative API equivalent. Both versions require the same parameters and return the same values.
ANSIC prototype: bool xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime)
- xMutex:xSemaphoreHandle - A handle to the mutex being obtained. This is the handle returned by xSemaphoreCreateMutex();
- xBlockTime:byte - The time in ticks to wait for the semaphore to become available. The macro portTICK_RATE_MS can be used to convert this to a real time. A block time of zero can be used to poll the semaphore. If the task already owns the semaphore then xSemaphoreTakeRecursive() will return immediately no matter what the value of xBlockTime. Specifying the block time as portMAX_DELAY will cause the task to block indefinitely (without a timeout).
- Return value:bool - Returns pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime expired without the semaphore becoming available.
-
xSemaphoreGive
- Macro to release a semaphore. The semaphore must have previously been created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or xSemaphoreCreateCounting(), and obtained using sSemaphoreTake().
This must not be used from an ISR. See xSemaphoreGiveFromISR() for an alternative which can be used from an ISR.
This macro must also not be used on semaphores created using xSemaphoreCreateRecursiveMutex().
xSemaphoreGive() is part of the fully featured intertask communications API. xSemaphoreAltGive() is the alternative API equivalent. Both versions require the same parameters and return the same values.
ANSIC prototype: bool xSemaphoreGive(xSemaphoreHandle xMutex)
- xMutex:xSemaphoreHandle - A handle to the mutex being released, or 'given'. This is the handle returned by xSemaphoreCreateMutex();
- Return value:bool - Returns pdTRUE if the semaphore was given.
-
vSemaphoreCreateBinary
- Macro that creates a semaphore by using the existing queue mechanism. The queue length is 1 as this is a binary semaphore. The data size is 0 as we don't want to actually store any data - we just want to know if the queue is empty or full.
Binary semaphores and mutexes are very similar but have some subtle differences: Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes binary semaphores the better choice for implementing synchronisation (between tasks or between tasks and an interrupt), and mutexes the better choice for implementing simple mutual exclusion.
A binary semaphore need not be given back once obtained, so task synchronisation can be implemented by one task/interrupt continuously 'giving' the semaphore while another continuously 'takes' the semaphore. This is demonstrated by the sample code on the xSemaphoreGiveFromISR() documentation page.
The priority of a task that 'takes' a mutex can potentially be raised if another task of higher priority attempts to obtain the same mutex. The task that owns the mutex 'inherits' the priority of the task attempting to 'take' the same mutex. This means the mutex must always be 'given' back - otherwise the higher priority task will never be able to obtain the mutex, and the lower priority task will never 'disinherit' the priority. An example of a mutex being used to implement mutual exclusion is provided on the xSemaphoreTake() documentation page.
Both mutex and binary semaphores are assigned to variables of type xSemaphoreHandle and can be used in any API function that takes a parameter of this type.
ANSIC prototype: void vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore)
- xSemaphore:xSemaphoreHandle - Handle to the created semaphore. Should be of type xSemaphoreHandle.
-
vSemaphoreCreateCounting
- Macro that creates a counting semaphore by using the existing queue mechanism.
Counting semaphores are typically used for two things:
1. Counting events. In this usage scenario an event handler will 'give' a semaphore each time an event occurs (incrementing the semaphore count value), and a handler task will 'take' a semaphore each time it processes an event (decrementing the semaphore count value). The count value is therefore the difference between the number of events that have occurred and the number that have been processed. In this case it is desirable for the initial count value to be zero.
2. Resource management. In this usage scenario the count value indicates the number of resources available. To obtain control of a resource a task must first obtain a semaphore - decrementing the semaphore count value. When the count value reaches zero there are no free resources. When a task finishes with the resource it 'gives' the semaphore back - incrementing the semaphore count value. In this case it is desirable for the initial count value to be equal to the maximum count value, indicating that all resources are free.
ANSIC prototype: void vSemaphoreCreateCounting(unsigned_portBASE_TYPE uxMaxCount, unsigned_portBASE_TYPE uxInitialCount)
- uxMaxCount:unsigned_portBASE_TYPE - The maximum count value that can be reached. When the semaphore reaches this value it can no longer be 'given'.
- uxInitialCount:unsigned_portBASE_TYPE - The count value assigned to the semaphore when it is created.
-
xSemaphoreGiveFromISR
- Macro to release a semaphore. The semaphore must have previously been created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) must not be used with this macro.
This macro can be used from an ISR.
ANSIC prototype: bool xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore, signed_portBASE_TYPE *pxHigherPriorityTaskWoken)
- xSemaphore:xSemaphoreHandle - A handle to the semaphore being released. This is the handle returned when the semaphore was created.
- pxHigherPriorityTaskWoken: Pointer to signed_portBASE_TYPE - xSemaphoreGiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphoree caused a task to unblock, and the unblocked task has a priority higher than the currently running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then a context switch should be requested before the interrupt is exited.
- Return value:bool - Returns pdTRUE if the semaphore was given.
-
vTaskList
- 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.
NOTE: This function will disable interrupts for its duration. It is not intended for normal application runtime use but as a debug aid. Lists all the current tasks, along with their current state and stack usage high water mark. Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or suspended ('S').
ANSIC prototype: void vTaskList(signed portCHAR *pcWriteBuffer)
- pcWriteBuffer: Pointer to signed char - Pointer to buffer. A buffer into which the above mentioned details 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.
-
pvPortMalloc
- Allocates a memory block using the port pvPortMalloc() function
ANSIC prototype: pVoid pvPortMalloc(size_t xWantedSize)
- xWantedSize:byte - size of memory block requested
- Return value:pVoid - memory block or NULL if failed
-
vPortFree
- Frees a memory block previously allocated with pvPortMalloc()
ANSIC prototype: void vPortFree(void *pv)
- pv: Pointer to bool - Pointer to data
-
xTaskGetSchedulerState
- Returns the state of the scheduler
ANSIC prototype: portBASE_TYPE xTaskGetSchedulerState(void)
- Return value:portBASE_TYPE - One of the following constants (defined within task.h): taskSCHEDULER_NOT_STARTED, taskSCHEDULER_RUNNING, taskSCHEDULER_SUSPENDED.
-
uxTaskGetStackHighWaterMark
- The stack used by a task will grow and shrink as the task executes and interrupts are processed. uxTaskGetStackHighWaterMark() returns the minimum amount of remaining stack space that was available to the task since the task started executing - that is the amount of stack that remained unused when the task stack was at its greatest (deepest) value. This is what is referred to as the stack 'high water mark'.
ANSIC prototype: unsigned_portBASE_TYPE uxTaskGetStackHighWaterMark(xTaskHandle xTask)
- xTask:xTaskHandle - The handle of the task being queried. A task may query its own high water mark by passing NULL as the xTask parameter.
- Return value:unsigned_portBASE_TYPE - Error code
Note: Some methods can be implemented as macros.
|