FreeRTOS Reference Manual rv3
FreeRTOS Reference Manual rv3
MANUAL
All text, source code and diagrams are the exclusive property of Richard Barry. Distribution or
publication in any form is strictly prohibited without prior written authority from Real Time Engineers
Ltd. FreeRTOS™, FreeRTOS.org™ and the FreeRTOS logo are trade marks of Real Time
Engineers Ltd.
Version 1.0.1
This document was supplied to [email protected]
http://www.FreeRTOS.org This document was supplied to [email protected]
CONTENTS
CONTENTS I
FreeRTOS 1
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
FreeRTOS 2
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
LIST OF FIGURES
FreeRTOS 3
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
FreeRTOS 4
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
FreeRTOS 5
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
LIST OF NOTATION
FreeRTOS 6
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
CHAPTER 1
FreeRTOS 1
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
1.1 S COPE
This document provides a technical reference to the primary FreeRTOS API1 and configuration
options. It is assumed the reader is already familiar with the concepts of writing multi tasking
applications and the primitives provided by real time kernels. Readers that are not familiar with these
fundamental concepts are recommended to read “Using the FreeRTOS Real Time Kernel – A
Practical Guide” for a much more descriptive, hands on, and explanatory text.
The API reference has been split into three sections – task functions, queue functions and semaphore
functions. Each section is presented alphabetically – with the exception that the function name prefix
that specifies the functions return type is not considered in the alphabetical ordering. For example the
function vTaskDelay() is a void function so is prefixed with a ‘v’, but for the purpose of alphabetical
sorting the ‘v’ is ignored.
1. API functions that do not end in “FromISR” must not be used from within an interrupt service
routine (ISR).
2. API functions that could potentially cause a context switch must not be called while the
scheduler is suspended.
3. API functions that could potentially cause a context switch must not be called from within a
critical section.
1
The ‘alternative’ API is not included as its use is no longer recommended. The co-routine API is also omitted
as co-routines are only useful to a small subset of applications.
FreeRTOS 2
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
CHAPTER 2
TASK API
FreeRTOS 3
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Each created task can optionally have a ‘tag’ value assigned to it. The meaning of the tag value is
defined by the application writer as the kernel itself will not normally access it directly.
As a special case the tag value can be used to associate a ‘task hook’ (or callback) function with a
task. The hook function can then be invoked using xTaskCallApplicationTaskHook().
Task hook functions can be used for any purpose. The example shown demonstrates a task hook
being used to output debug trace information.
Listing 2 The prototype to which all task hook functions must conform
FreeRTOS 4
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Parameters
xTask The handle of the task whose hook function is being called. See the pxCreatedTask
parameter of the xTaskCreate() API function for information on obtaining handles to
tasks.
A task can call its own hook function by passing NULL in place of a valid task handle.
pvParameters The value used as the parameter to the task hook function itself.
Using a pointer to void allows the task hook parameter to effectively have any type.
Integral types can be passed in by simply casting the parameter to the actual type
within the hook function itself. Likewise the void pointer can be used to point to any
standard or compound type.
FreeRTOS 5
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* This example does not make use of the hook return value so just returns
0 in every case. */
return 0;
}
/******************************************************************************/
for( ;; )
{
/* The rest of the task code goes here. */
}
}
/******************************************************************************/
FreeRTOS 6
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Newly created tasks are initially placed in the Ready state but will immediately become the Running
state task if there are no higher priority tasks that are able to run.
Tasks can be created both before and after the scheduler has been started.
Parameters
pvTaskCode Pointer to the function that implements the task. This is just the task name.
pcName A descriptive name for the task. This is not used by FreeRTOS in any way. It is
included purely as a debugging aid. Identifying a task by a human readable name is
much simpler than attempting to do the same from its handle.
usStackDepth Each task has its own unique state that is allocated by the kernel to the task when
the task is created. The usStackDepth value tells the kernel how big to make the
stack.
The value specifies the number of words the stack can hold, not the number of
bytes. For example, if the stack is 32 bits wide and usStackDepth is passed in as
100, then 400 bytes of stack space will be allocated (100 * 4bytes). 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.
FreeRTOS 7
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
The size of the stack used by the idle task is defined by the application defined
constant configMINIMAL_STACK_SIZE . The value assigned to this constant in the
FreeRTOS demo application for the microcontroller architecture being used is the
minimum recommended for any task. If your task uses a lot of stack space then you
will need to assign a larger value.
pvParameters Task functions accept a parameter of type pointer to void ( void* ). The value
assigned to pvParameters when the task is created is the value passed into the task.
uxPriority Defines the priority at which the task will execute. Priorities can be assigned from 0,
which is the lowest priority, to (configMAX_PRIORITIES – 1), which is the highest
priority.
pxCreatedTask pvCreatedTask can be used to pass out a handle to the task being created. This
handle can then be used to reference the task within API calls that, for example,
change the task priority or delete the task.
If your application has no use for the task handle then pvCreatedTask can be set to
NULL.
Return Values
FreeRTOS 8
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Define a structure called xStruct and a variable of type xStruct. These are just used to
demonstrate a parameter being passed into a task function. */
typdef struct A_STRUCT
{
char cStructMember1;
char cStructMember2;
} xStruct;
/* Define the task that will be created. Note the name of the function that implements
the task is used as the first parameter in the call to xTaskCreate() below. */
void vTaskCode( void * pvParameters )
{
xStruct *pxParameters;
/* Define a function that creates a task. This could be called either before of after
the scheduler has been started. */
void vAnotherFunction( void )
{
xTaskHandle xHandle;
/* The handle can now be used in other API functions, for example to change the priority
of the task. */
vTaskPrioritySet( xHandle, 2 );
}
FreeRTOS 9
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Places the calling task into the Blocked state for a fixed number of tick interrupts.
If vTaskDelay() is called a fraction of a tick period prior to the next tick interrupt occurring then the
fraction will count as one tick interrupt.
Specifying a delay period of 0 ticks will not result in the calling task being placed into the Blocked state
but will cause the calling task to yield. Calling vTaskDelay( 0 ) is equivalent to calling taskYIELD().
Parameters
xTicksToDelay The number of tick interrupts that the calling task should remain in the Blocked state
before being transitioned back into the Ready state.
For example, if a task called vTaskDelay( 100 ) while the tick count was 10,000, then
it would immediately enter the Blocked state and remain there until the tick count
reached 10,100.
Return Values
None.
FreeRTOS 10
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Enter the Blocked state for 20 tick interrupts – the actual time spent in the
Blocked state is dependent on the tick frequency. */
vTaskDelay( 20 );
/* 20 ticks will have passed since the first call to vTaskDelay() was executed. */
FreeRTOS 11
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Places the calling task into the Blocked state until an absolute time is reached.
vTaskDelay() will cause the calling task to enter the Blocked state for the specified number of ticks
from the time vTaskDelay() was called – the time at which the calling task exits the Blocked state is
therefore relative to when vTaskDelay() was called. vTaskDelayUntil() instead specifies the absolute
(exact) time at which it will exit the Blocked state.
FreeRTOS 12
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Parameters
Return Values
None.
FreeRTOS 13
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
FreeRTOS 14
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Deletes a task.
Deleted tasks no longer exist and cannot enter the Running state. A handle used to reference a task
will not be valid and must not be used after the referenced task has been deleted.
It is the responsibility of the idle task to free memory that was allocated to tasks that have since been
deleted. It is therefore important that applications that make use of the vTaskDelete() API function do
not completely starve the idle task of all processing time.
Note also that only memory that is allocated to a task by the kernel itself will be automatically freed
when the task is deleted. Any memory or other resource that the implementation of the task allocates
must be freed explicitly.
Parameters
pxTask The handle of the task that is to be deleted (the subject task) – see the pxCreatedTask
parameter of the xTaskCreate() API function for information on obtaining handles to tasks.
A task can delete itself by passing NULL in place of a valid task handle.
Return Values
None.
FreeRTOS 15
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Delete the task calling this function by calling vTaskDelete() with a NULL parameter.
The calling task could also be deleted by passing its handle instead of NULL. */
vTaskDelete( NULL );
}
FreeRTOS 16
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Sets the microcontroller status flags so that all or a subset of interrupts are disabled – depending on
the port being used.
If the FreeRTOS port for the microcontroller being used permits interrupts to nest then only interrupts
up to and including the interrupt priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY will be
disabled. Interrupts that have a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY
remain enabled.
If the FreeRTOS port for the microcontroller being used does not permit interrupts to nest then all
interrupts are disabled.
Some FreeRTOS API functions use critical sections that will re-enable interrupts if the critical section
nesting count is zero – even if interrupts were disabled by a call to taskDISABLE_INTERRUPTS()
before the API function was called.
Parameters
None.
Return Values
None.
FreeRTOS 17
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Some FreeRTOS API functions use critical sections that will re-enable interrupts if the critical section
nesting count is zero – even if interrupts were disabled by a call to taskDISABLE_INTERRUPTS()
before the API function was called.
Parameters
None.
Return Values
None.
FreeRTOS 18
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
vTaskEndScheduler() has only been implemented for the real mode x86 port that is launched from
DOS. It stops the kernel tick interrupt, deletes all the tasks, then resumes from the point where
vTaskStartScheduler() was called.
vTaskEndScheduler() requires an exit function to be defined within the portable layer (see
vPortEndScheduler() in port. c for the PC port) to perform the hardware specific operations such as
stopping the tick interrupt.
vTaskEndScheduler() will cause all of the resources allocated by the kernel to be freed - but will not
free resources allocated by tasks themselves.
Parameters
None.
Return Values
None.
FreeRTOS 19
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
ulTaskEndTrace() relates to a deprecated trace feature that has been replaced by the more flexible
trace macros.
FreeRTOS contains a simple execution trace facility that writes the number of the selected task and a
timestamp to a RAM buffer during each context switch. With the help of a data conversion utility the
RAM buffer can be converted to a plain text file for offline viewing within a spread sheet program.
Parameters
None.
Return Values
ulTaskEndTrace() returns the number of bytes that were written into the RAM buffer while the trace
was running.
FreeRTOS 20
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
This is the most basic way of creating a critical section. It works by simply disabling interrupts either
completely, or up to the interrupt priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY –
depending on the FreeRTOS port being used.
Preemptive context switches can only occur from within an interrupt, so as long as interrupts remain
disabled the task that called taskENTER_CRITICAL() is guaranteed to remain in the Running state
until the critical section is exited.
It is safe for critical sections to become nested because the kernel keeps a count of the nesting depth.
The critical section will only be exited when the nesting depth returns to zero – which is when one call
to taskEXIT_CRITICAL() has been executed for every preceding call to taskENTER_CRITICAL().
Critical sections must be kept very short otherwise they will adversely affect interrupt response times.
Every call to taskENTER_CRITICAL() must be closely paired with a call to taskEXIT_CRITICAL().
FreeRTOS API functions should not be called from within a critical section.
Parameters
None.
Return Values
None.
FreeRTOS 21
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Perform the action that is being protected by the critical section here. */
/* Exit the critical section – in this example the function is itself called from
a critical section so this call to taskEXIT_CRITICAL() will decrement the nesting
by one, but not result in interrupts becoming enabled. */
taskEXIT_CRITICAL();
}
/* The operation that required the critical section is complete so exit the critical
section. After this call to taskEXIT_CRITICAL() the nesting depth will be zero so
interrupts will have been enabled. */
taskEXIT_CRITICAL();
}
}
FreeRTOS 22
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
This is the most basic way of creating a critical section. It works by simply disabling interrupts either
completely, or up to the interrupt priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY –
depending on the FreeRTOS port being used.
Preemptive context switches can only occur from within an interrupt, so as long as interrupts remain
disabled the task that called taskENTER_CRITICAL() is guaranteed to remain in the Running state
until the critical section is exited.
It is safe for critical sections to become nested because the kernel keeps a count of the nesting depth.
The critical section will only be exited when the nesting depth returns to zero – which is when one call
to taskEXIT_CRITICAL() has been executed for every preceding call to taskENTER_CRITICAL().
Critical sections must be kept very short otherwise they will adversely affect interrupt response times.
Every call to taskENTER_CRITICAL() must be closely paired with a call to taskEXIT_CRITICAL().
FreeRTOS API functions should not be called from within a critical section.
Parameters
None.
Return Values
None.
Example
FreeRTOS 23
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns the handle of the task that is currently in the Running state – which will be the task that called
xTaskGetCurrentTaskHandle().
Parameters
None.
Return Values
FreeRTOS 24
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
None.
Return Values
The value returned is the total number of tasks - suspended tasks, plus blocked tasks, plus ready
tasks, plus the idle task, plus the running task.
FreeRTOS 25
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Returns a value that indicates which state the scheduler is currently in.
Parameters
None.
Return Values
FreeRTOS 26
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task maintains its own stack, the total size of which is specified when the task is created.
uxTaskGetStackHighWaterMark() is used to query how near a task has come to overflowing the stack
space allocated to it. This value is called the stack 'high water mark'.
Parameters
A task may query its own high water mark by passing NULL as the xTask parameter.
Return Values
The value returned is the high water mark in words (one word being 4 bytes on a 32bit architecture).
The closer the returned value is to zero the closer the task has come to overflowing its stack. A return
value of zero indicates that the task has actually overflowed its stack already.
Notes
FreeRTOS 27
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
for( ;; )
{
/* Call any function. */
vTaskDelay( 1000 );
/* Calling a function will have used some stack space, we would therefore now expect
uxTaskGetStackHighWaterMark() to return a value lower than when it was called on
entering the task. */
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
}
}
FreeRTOS 28
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
FreeRTOS can optionally collect data on the amount of processing time that has been used by each
task. vTaskGetRunTimeStats() creates a table in a character buffer to present the collected data in an
easily readable form. An example is shown in Figure 1.
• Task – This is the name given to the task when the task was created.
• Abs Time (Absolute Time) – This is the total 'time' that the task has actually been executing
(the total time that the task has been in the Running state). The time base used is set by the
application.
• % Time – This shows essentially the same information but as a percentage of the total
processing time rather than as an absolute time.
FreeRTOS 29
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Parameters
pcWriteBuffer The buffer into which the table text will be written. This must be large enough to hold
the entire table as no boundary checking is performed.
Return Values
None.
Notes
1. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
The time base used by the run time stats must have a higher resolution than the tick interrupt –
otherwise the gathered statistics may be too inaccurate to be truly useful. It is recommended to
make the time base between 10 and 20 times faster than the tick interrupt. The faster the time
base the more accurate the statistics will be – but also the sooner the timer value will overflow.
2. portGET_RUN_TIME_COUNTER_VALUE()
FreeRTOS 30
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* The LM3Sxxxx Eclipse demo application already includes a 20KHz timer interrupt. The interrupt
handler was updated to simply increment a variable called ulHighFrequencyTimerTicks each time it
executed. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() simply sets this variable to 0 and
portGET_RUN_TIME_COUNTER_VALUE() returns its value. To implement this the following few lines were
added to FreeRTOSConfig.h. */
Listing 24 Example macro definitions, taken from the LM3Sxxx Eclipse Demo
/* The LPC17xx demo application does not include the high frequency interrupt test, so
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() was used to configure the timer 0 peripheral to generate the
time base. portGET_RUN_TIME_COUNTER_VALUE() simply returns the current timer 0 counter value. This was
implemented using the following functions and macros. */
/* Defined in main.c. */
void vConfigureTimerForRunTimeStats( void )
{
const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
/* Reset Timer 0 */
T0TCR = TCR_COUNT_RESET;
/* Defined in FreeRTOSConfig.h. */
extern void vConfigureTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() T0TC
Listing 25 Example macro definitions, taken from the LPC17xx Eclipse Demo
FreeRTOS 31
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
FreeRTOS 32
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Time is measured in ‘ticks’ – which is the total number of tick interrupts that have occurred since the
scheduler was started. xTaskGetTickCount() returns the current tick count value.
Parameters
None.
Return Values
Notes
The actual time one tick period represents depends on the value assigned to configTICK_RATE_HZ
within FreeRTOSConifg.h. The constant portTICK_RATE_MS can be used to convert a time in
milliseconds to a time in ‘ticks’.
The tick count will eventually overflow and return to zero. This will not effect the internal operation of
the kernel - for example tasks will always block for the specified period even if the tick count overflows
while the task is in the Blocked state. Overflows must however be considered by host applications if
the application makes direct use of the tick count value.
The frequency at which the tick count overflows depends on both the tick frequency and the data type
used to hold the count value. If configUSE_16_BIT_TICKS is set to 1 then the tick count will be held
in a 16bit variable. If configUSE_16_BIT_TICKS is set to 0 then the tick count will be held in a 32bit
variable.
FreeRTOS 33
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
FreeRTOS 34
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Creates a table in a character buffer that describes the state of each task. An example is shown in
Figure 2.
• Name – This is the name given to the task when the task was created.
o 'B'locked,
o 'R'eady,
o 'S'uspended or
FreeRTOS 35
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
• Stack – Shows the ‘high water mark’ of the task stack. This is the minimum amount of free
stack that has been available during the lifetime of the task. The closer this value is to zero the
closer the task has come to overflowing its stack.
• Num – This is just a unique number that is assigned to each task. It has no purpose other than
to help identify tasks when more than one task has been assigned the same name.
Parameters
pcWriteBuffer The buffer into which the table text will be written. This must be large enough to hold
the entire table as no boundary checking is performed.
Return Values
None.
Notes
vTaskList() will disable interrupts for the duration of its execution. This might not acceptable for
applications that include hard real time functionality.
By default vTaskList() makes use of the standard library sprintf() function which can result in a marked
increase in the compiled image size. The FreeRTOS download includes an open source cut down
version of sprintf() within a file called printf-stdarg.c. This can be used in place of the standard library
sprintf()to help minimise the code size impact. Note that printf-stdarg.c is licensed separately to
FreeRTOS.
Tasks that are in the Blocked state but without specifying a time out (they have blocked indefinately to
wait for an event) will be shown as being in the Suspended state.
FreeRTOS 36
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
FreeRTOS 37
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
The handle to a task is obtained using the pxCreatedTask parameter to the xTaskCreate()
API function when the task is created.
A task may query its own priority by setting pxTask to NULL instead of a valid task handle.
Return Values
The value returned is the current priority of the task being queried.
FreeRTOS 38
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Is our priority higher than the priority of the task just created? */
if( uxOurPriority > uxCreatedPriority )
{
/* Yes. */
}
}
}
FreeRTOS 39
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
A task may change its own priority by passing NULL in pxTask instead of a valid task
handle.
uxNewPriority The new priority for the task. Priorities can be assigned from 0, which is the lowest
priority, to (configMAX_PRIORITIES – 1), which is the highest priority.
Return Values
None.
Notes
vTaskPrioritySet() must only be called from an executing task and therefore must not be called while
the scheduler is in the Initialization state (prior to the scheduler being started).
It is possible to have a set of tasks that are all blocked waiting for the same queue or semaphore
event. Under normal circumstances tasks are unblocked in priority order – the first event will unblock
the highest priority task, the second event the second highest priority task, etc. However, using
FreeRTOS 40
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
vTaskPrioritySet() to change the priority of such a blocked task will not cause the order in which tasks
are unblocked to be re-evaluated.
Example
FreeRTOS 41
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Transition a task from the Suspended state to the Ready state. The task must have previously been
suspended using a call to vTaskSuspend().
Parameters
pxTaskToResume The handle of the task being resumed (transitioned out of the Suspended state).
Return Values
None.
Notes
A task can be blocked to wait for a queue event, specifying a timeout period. It is legitimate to move
such a Blocked task into the Suspended state using a call to vTaskSuspend(), then out of the
Suspended state and into the Ready state using a call to vTaskResume(). Following this scenario, the
next time the task enters the Running state it will check whether or not its timeout period has (in the
mean time) expired. If the timeout period has not expired the task will once again enter the Blocked
state to wait for the queue event for the remainder of the originally specified timeout period.
A task can also be blocked to wait for a temporal event using the vTaskDelay() or vTaskDelayUntil()
API functions. It is legitimate to move such a Blocked task into the Suspended state using a call to
vTaskSuspend(), then out of the Suspended state and into the Ready state using a call to
vTaskResume(). Following this scenario, the next time the task enters the Running state it shall exit
the vTaskDelay() or vTaskDelayUntil() function as if the specified delay period had expired, even if this
is not actually the case.
vTaskResume() must only be called from an executing task and therefore must not be called while the
scheduler is in the Initialization state (prior to the scheduler being started).
FreeRTOS 42
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* The suspended task will not run during this period, unless another task calls
vTaskResume( xHandle ). */
FreeRTOS 43
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Resumes scheduler activity by transitioning the scheduler out of the Suspended state into the Active
state.
Parameters
None.
Return Values
pdTRUE The scheduler was transitioned into the Active state. The transition caused a pending
context switch to occur.
pdFALSE Either the scheduler was transitioned into the Active state and the transition did not cause
a context switch to occur, or the scheduler was left in the Suspended state due to nested
calls to vTaskSuspendAll().
Notes
The scheduler can be suspended by calling vTaskSuspendAll(). When the scheduler is suspended
interrupts remain enabled, but a context switch cannot occur. If a context switch is requested while
the scheduler is suspended the request will be held pending and only performed when the scheduler
is resumed (un-suspended). Calls to xTaskResumeAll() transition the scheduler out of the Suspended
state following a previous call to vTaskSuspendAll().
Calls to vTaskSuspendAll() can be nested. The same number of calls must be made to
xTaskResumeAll() as have previously been made to vTaskSuspendAll() before the scheduler will
leave the Suspended state and re-enter the Active state.
xTaskResumeAll() must only be called from an executing task and therefore must not be called while
the scheduler is in the Initialization state (prior to the scheduler being started).
Other API functions should not be called while the scheduler is suspended.
FreeRTOS 44
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* The operation is complete. Set the scheduler back into the Active
state. */
if( xTaskResumeAll() == pdTRUE )
{
/* A context switch occurred within xTaskResumeAll(). */
}
else
{
/* A context switch did not occur within xTaskResumeAll(). */
}
}
}
FreeRTOS 45
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Parameters
pxTaskToResume The handle of the task being resumed (transitioned out of the Suspended state).
Return Values
The return value indicates whether or not a context switch should be requested prior to exiting the
interrupt. pdTRUE is returned if the task being resumed (unblocked) has a priority equal to or higher
than the currently executing task – meaning a context switch should be performed. pdFALSE is
returned if the task being resumed has a priority lower that the currently executing task – meaning a
context switch should not be performed.
Notes
A task can be suspended by calling vTaskSuspend(). While in the Suspended state the task will not
be selected to enter the Running state. vTaskResume() and xTaskResumeFromISR() can be used to
resume (un-suspend) a task. xTaskResumeFromISR() can be called from an interrupt whereas
vTaskResume() cannot.
Calls to vTaskSuspend() do not maintain a nesting count. A task that has been suspended by one of
more calls to vTaskSuspend() will always be un-suspended by a single call to vTaskResume() or
xTaskResumeFromISR().
xTaskResumeFromISR() should not be used to synchronize a task with an interrupt as doing so runs
the risk of interrupt events being missed if they occur faster than the ISR can handle. Task and
interrupt synchronization can instead safely be achieved through the use of a binary or counting
semaphore as the semaphore effectively latches the event to ensure it is not missed.
FreeRTOS 46
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
xTaskHandle xHandle;
/* The task is now suspended, so will not reach here until the ISR resumes it. */
}
}
FreeRTOS 47
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Each task can be assigned a 'tag' value. The value is purely for use by host applications (the
application that uses FreeRTOS) and the kernel itself does not reference or otherwise make any use
of it.
Parameters
xTask The handle of the task to which a tag value is being assigned. A task can assign a tag
value to itself by either using its own handle or alternatively by using NULL in place of a
valid task handle.
pxTagValue The value being assigned to the task tag. This is of type pdTASK_HOOK_CODE to
permit a function pointer to be assigned as the tag, although any type can actually be
assigned – not just function pointers.
Return Values
None.
Notes
The tag value can be used to hold a function pointer that can then be called using the
xTaskCallApplicationTaskHook() API function – effectively assigning a callback function to the task. It
is common for this callback to be used in combination with the traceTASK_SWITCHED_IN macro to
implement an execution trace feature.
FreeRTOS 48
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
for( ;; )
{
/* Rest of task code goes here. */
}
}
/***********************************************/
return 0;
}
/* Now define the task that sets prvExampleTaskHook as its hook/tag value.
This is in effect registering the task callback. */
void vAnotherTask( void *pvParameters )
{
/* Register a callback function for the currently running task. */
vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook );
for( ;; )
{
/* Rest of task code goes here. */
}
}
FreeRTOS 49
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Transitions the scheduler from the Initialization state into the Running state. Typically before the
scheduler has been started main() (or a function called by main()) will be executing. After the
scheduler has been started only tasks and interrupts will ever execute.
Starting the scheduler causes the highest priority task that was created while the scheduler was in the
Initialization state to enter the Running state.
Parameters
None.
Return Values
The Idle task is automatically created when the scheduler is started. vTaskStartScheduler() will only
return if there is not enough heap memory available for the Idle task to be created successfully.
Notes
Ports that execute on ARM7 and ARM9 processors require the processor to be in Supervisor mode
prior to vTaskStartScheduler() being called.
FreeRTOS 50
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
xTaskHandle xHandle;
/* This code will only be reached if the Idle task could not be created within
vTaskStartScheduler(). An infinite loop is used to assist debugging by preventing
the execution attempting to return from main(). */
for( ;; );
}
FreeRTOS 51
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Places a task into the Suspended state. A task that is in the Suspended state will never be selected to
enter the Running state.
Parameters
A task may suspend itself by either setting pxTaskToSuspend to its own task
handle or simply by setting pxTaskToSuspend to NULL.
Return Values
None.
Notes
vTaskSuspend() must only be called from an executing task and therefore must not be called while the
scheduler is in the Initialization state (prior to the scheduler being started).
FreeRTOS 52
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* The created task will not run during this period, unless another task calls
vTaskResume( xHandle ). */
/* Suspend ourselves. */
vTaskSuspend( NULL );
/* This task can only execute past the call to vTaskSuspend( NULL ) if another
task has resumed (un-suspended) it using a call to vTaskResume(). */
}
}
FreeRTOS 53
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Suspends all scheduler activity by transitioning the scheduler from the Active state into the Suspended
state.
Parameters
None.
Return Values
None.
Notes
The scheduler can be suspended by calling vTaskSuspendAll(). When the scheduler is suspended
interrupts remain enabled, but a context switch cannot occur. If a context switch is requested while
the scheduler is suspended the request will be held pending and only performed when the scheduler
is resumed (un-suspended). Calls to xTaskResumeAll() transition the scheduler out of the Suspended
state following a previous call to vTaskSuspendAll().
Calls to vTaskSuspendAll() can be nested. The same number of calls must be made to
xTaskResumeAll() as have previously been made to vTaskSuspendAll() before the scheduler will
leave the Suspended state and re-enter the Active state.
xTaskResumeAll() must only be called from an executing task and therefore must not be called while
the scheduler is in the Initialization state (prior to the scheduler being started).
Other API functions should not be called while the scheduler is suspended.
FreeRTOS 54
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* The operation is complete. Set the scheduler back into the Active
state. */
if( xTaskResumeAll() == pdTRUE )
{
/* A context switch occurred within xTaskResumeAll(). */
}
else
{
/* A context switch did not occur within xTaskResumeAll(). */
}
}
}
FreeRTOS 55
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “task.h”
Summary
Yielding is where a task volunteers to leave the Running state without being pre-empted and before its
time slice has been fully utilized.
Parameters
None.
Return Values
None.
Notes
taskYIELD() must only be called from an executing task and therefore must not be called while the
scheduler is in the Initialization state (prior to the scheduler being started).
When a task calls taskYIELD() the scheduler will select another Ready state task of equal priority to
enter the Running state in its place. If there are no other Ready state tasks of equal priority then the
task that called taskYIELD() will itself be transitioned straight back into the Running state.
FreeRTOS 56
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* If there are any tasks of equal priority to this task that are in the Ready
state then let them execute now - even though this task has not used all of its
time slice. */
taskYIELD();
/* If there were any tasks of equal priority to this task in the Ready state
then they will have executed before and code following taskYIELD() is executed. */
}
}
FreeRTOS 57
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
CHAPTER 3
QUEUE API
FreeRTOS 58
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
Associates a queue or semaphore handle with a text name and adds the association into the queue
registry.
Parameters
xQueue The handle of the queue that is being added to the registry. Semaphore handles can
also be used.
pcQueueName The name being assigned to the queue or semaphore. This is just a text string to
assist debugging.
Return Values
None.
Notes
The queue registry has two purposes, both of which are associated with kernel aware debugging:
1. It allows a textual name to be associated with a queue for easy queue identification within a
debugging user interface.
2. It contains the information required by a debugger to locate each registered queue and
semaphore.
configQUEUE_REGISTRY_SIZE defines the maximum number of queues and semaphores that can
be registered. Only the queues and semaphores that need to be viewed within a kernel aware
debugging interface need to be registered.
The queue registry is only required when a kernel aware debugger is being used. At all other times it
has no purpose and can be omitted by setting configQUEUE_REGISTRY_SIZE to 0 or by omitting the
definition altogether.
FreeRTOS 59
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
FreeRTOS 60
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
Creates a queue.
Parameters
uxQueueLength The maximum number of items the queue can hold at any time.
uxItemSize The size in bytes of each item the queue will hold.
Return Values
A handle to the created queue is returned provided the queue was created successfully. NULL is
returned if the queue cannot be created because there is too little heap RAM available.
Notes
Queues are used to pass data between tasks and between tasks and interrupts.
Queues can be created prior to the scheduler being started and from within a task after the scheduler
has been started.
FreeRTOS 61
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
FreeRTOS 62
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
Deletes a queue that was previously created using a call to xQueueCreate(). vQueueDelete() can
also be used to delete a semaphore.
Parameters
pxQueueToDelete The handle of the queue being deleted. Semaphore handles can also be used.
Return Values
None
Notes
Queues are used to pass data between tasks and between tasks and interrupts.
A queue/semaphore must not be deleted if there are any tasks that are blocked on the
queue/semaphore waiting for events (sends or receives).
FreeRTOS 63
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
FreeRTOS 64
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
Queries the number of items that are currently held within a queue.
Parameters
Return Values
The number of items that are held within the queue being queried.
Example
FreeRTOS 65
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
A version of uxQueueMessagesWaiting() that can be used from inside an interrupt service routine.
Parameters
Return Values
The number of items that are contained within the queue being queried.
Example
/* Check the status of the queue, if it contains more than 10 items then wake the task that
will drain the queue. */
FreeRTOS 66
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
Reads an item from a queue, but does not remove the item from the queue. Therefore the same item
would be returned the next time xQueueReceive() or xQueuePeek() was called on the same queue.
FreeRTOS 67
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Parameters
xQueue The handle of the queue from which the data is to be read.
pvBuffer A pointer to the memory into which the data read from the queue will be copied.
The length of the buffer must be at least equal to the queue item size (set when the
queue was created).
xTicksToWait The number of ticks for which the calling task should be held in the Blocked state to
wait for data to become available from the queue should the queue already be empty.
A value of zero will prevent the calling task from entering the Blocked state.
Return Values
pdPASS Data was successfully read from the queue. If a block time was specified then
the calling task may have been temporarily placed into the Blocked state to wait
for data to become available and data did become available before the block
time expired.
errQUEUE_EMPTY The queue was empty so no date could be read form the queue. If a block time
was specified then the calling task may have been temporarily placed into the
Blocked state to wait for data to become available, but no data became
available before the block time expired.
Notes
None.
FreeRTOS 68
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
struct AMessage
{
portCHAR ucMessageID;
portCHAR ucData[ 20 ];
} xMessage;
xQueueHandle xQueue;
if( xQueue != 0 )
{
/* Peek a message on the created queue. Block for 10 ticks if a message is not
immediately available. */
if( xQueuePeek( xQueue, &( pxRxedMessage ), 10 ) )
{
/* pxRxedMessage now points to the struct AMessage variable posted by vATask, but
the item still remains on the queue. */
}
}
FreeRTOS 69
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
FreeRTOS 70
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Parameters
xQueue The handle of the queue from which the data is to be received.
pvBuffer A pointer to the memory into which the data received from the queue will be copied.
The length of the buffer must be at least equal to the queue item size (set when the
queue was created).
xTicksToWait The number of ticks for which the calling task should be held in the Blocked state to
wait for data to become available from the queue should the queue already be empty.
A value of zero will prevent the calling task from entering the Blocked state.
Return Values
pdPASS Data was successfully read from the queue. If a block time was specified then
the calling task may have been temporarily placed into the Blocked state to wait
for data to become available and data did become available before the block
time expired.
errQUEUE_EMPTY The queue was empty so no date could be read form the queue. If a block time
was specified then the calling task may have been temporarily placed into the
Blocked state to wait for data to become available, but no data became
available before the block time expired.
Notes
None.
FreeRTOS 71
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Create a task here, passing in the queue handle as the task parameter. */
xTaskCreate( vAnotherTask, “Task”, STACK_SIZE, ( void * ) xQueue, TASK_PRIORITY, NULL );
/* Will only reach here if the idle task could not be created. */
for( ;; );
}
/* The queue handle is passed into this task as the task parameter. */
xQueue = ( xQueueHandle ) pvParameters;
for( ;; )
{
/* Wait for the maximum period for data to become available on the queue. */
if( xQueueReceive( xQueue, &xMessage, portMAX_DELAY ) != pdPASS )
{
/* We could not receive from the queue, even after blocking. */
}
else
{
/* xMessage now contains the received data. */
}
}
}
FreeRTOS 72
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
pvBuffer A pointer to the buffer into which the data received from the queue will
be copied.
The length of the buffer must be at least equal to the queue item size
(set when the queue was created).
pxHigherPriorityTaskWoken A task may be blocked waiting for space to become available on the
queue. If xQueueReceiveFromISR() causes such a task to unblock then
*pxHigherPriorityTaskWoken will get set to pdTRUE, otherwise
*pxHigherPriorityTaskWoken will remain unchanged.
Return Values
pdFAIL Data was not received from the queue because the queue was already empty.
Notes
Calling xQueueReceiveFromISR() within an interrupt service routine can potentially cause a task that
was blocked on a queue to leave the Blocked state. A context switch should be performed if such an
unblocked task has a priority higher than the currently executing task. The context switch will ensure
that the interrupt returns directly to the highest priority Ready state task.
FreeRTOS 73
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Unlike the xQueueReceive() API function, xQueueReceiveFromISR() will not itself perform a context
switch. It will instead just indicate whether or not a context switch is required.
xQueueReceiveFromISR() must not be called prior to the scheduler being started. Therefore an
interrupt that calls xQueueReceiveFromISR() must not be allowed to execute prior to the scheduler
being started.
Example
For clarity of demonstration the example makes multiple calls to xQueueReceiveFromISR() to receive
multiple small data items. This is inefficient and therefore not recommended for most applications. A
preferable approach would be to send the multiple data items in a structure to the queue in a single
post, allowing xQueueReceiveFromISR() to be called only once. Alternatively processing can be
deferred to the task level.
/* vISR is an interrupt service routine that empties a queue of values, sending each to a
peripheral. It might be that there are multiple tasks blocked on the queue waiting for space to
write more data to the queue. */
void vISR( void )
{
portCHAR cByte;
portBASE_TYPE xHigherPriorityTaskWoken;
/* Now the queue is empty and we have cleared the interrupt we can perform a context switch
if one is required. NOTE: The syntax required to perform a context switch from an ISR
varies from port to port, and from compiler to compiler. Check the documentation and
examples for the port being used to find the actual syntax required. */
taskYIELD_FROM_ISR(xHigherPriorityTaskWoken );
}
FreeRTOS 74
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “queue.h”
Summary
xQueueSend() and xQueueSendToBack() both send data to the back of a queue. xQueueSend() was
the original version and it is now recommended to use xQueueSendToBack() in it place.
Parameters
pvItemToQueue A pointer to the data to be sent to the queue. The size of the data that can be sent
to a queue was defined when the queue was created.
xTicksToWait The number of ticks for which the calling task should be held in the Blocked state to
wait for space to become available on the queue should the queue already be full.
A value of zero will prevent the calling task from entering the Blocked state.
FreeRTOS 75
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Return Values
pdPASS Data was successfully sent to the queue. If a block time was specified then the
calling task may have been temporarily placed into the Blocked state to wait for
space to become available and space did become available before the block time
expired.
errQUEUE_FULL The queue is already full so no data could be sent to the queue. If a block time
was specified then the calling task may have been temporarily placed into the
Blocked state to wait for space to become available, but no space became
available before the block time expired.
Notes
None.
FreeRTOS 76
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Create a task here, passing in the queue handle as the task parameter. */
xTaskCreate( vAnotherTask, “Task”, STACK_SIZE, ( void * ) xQueue, TASK_PRIORITY, NULL );
/* Will only reach here if the idle task could not be created. */
for( ;; );
}
/* The queue handle is passed into this task as the task parameter. */
xQueue = ( xQueueHandle ) pvParameters;
for( ;; )
{
/* Create a message to send on the queue. */
xMessage.ucMessageID = SEND_EXAMPLE;
/* Send the message to the queue, waiting for 10 ticks for space become available
should the queue already be full. */
if( xQueueSendToBack( xQueue, &xMessage, 10 ) != pdPASS )
{
/* Data could not be sent to the queue even after waiting 10 ticks. */
}
}
}
FreeRTOS 77
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
3.10 X Q UEUE S END FROM ISR(), X QUEUE S END TO B ACK FROM ISR(),
X Q UEUE S END T O F RONT F ROM ISR()
#include “FreeRTOS.h”
#include “queue.h”
Summary
Parameters
FreeRTOS 78
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Return Values
errQUEUE_FULL Data could not be sent to the queue because the queue was already full.
Notes
FreeRTOS 79
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Write the byte to the queue. xHigherPriorityTaskWoken will get set to pdTRUE if
writing to the queue unblocks a task, and the unblocked task has a priority higher
than the currently executing task. */
xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
} while(INPUT_BYTE( BUFFER_COUNT ) );
/* Now the buffer is empty and we have cleared the interrupt we can perform a context switch
if one is required. NOTE: The syntax required to perform a context switch from an ISR
varies from port to port, and from compiler to compiler. Check the documentation and
examples for the port being used to find the actual syntax required. */
taskYIELD_FROM_ISR(xHigherPriorityTaskWoken );
}
FreeRTOS 80
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
CHAPTER 4
SEMAPHORE API
FreeRTOS 81
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Parameters
xSemaphore Variable of type xSemaphoreHandle into which the handle of the created semaphore
will be stored.
Return Values
None.
Creating a semaphore requires the kernel to allocate RAM from the heap. If there is insufficient heap
memory available for this purpose the semaphore will not be created and xSemaphore will be set to
NULL.
Notes
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 synchronization (between tasks or between tasks and an interrupt), and
mutexes the better choice for implementing simple mutual exclusion.
Binary Semaphores – A binary semaphore need not be ‘given’ back once ‘taken’ (obtained), so task
synchronization can be implemented by one task/interrupt continuously 'giving' the semaphore while
another continuously 'takes' the semaphore (see the xSemaphoreGiveFromISR() documentation).
Mutexes – The priority of a task that holds a mutex will 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. A task that obtains a mutex must always give the mutex 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
FreeRTOS 82
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
provided on the xSemaphoreTake() documentation page. A fast and simple priority inheritance
mechanism is implemented that assumes a task will only ever hold a single mutex at any one time.
Both mutexes 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.
Both mutexes and binary semaphores are initialized such that the first call to xSemaphoreTake() on
the semaphore/mutex will pass.
Example
xSemaphoreHandle xSemaphore;
FreeRTOS 83
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Parameters
uxMaxCount The maximum count value that can be reached. When the semaphore reaches this
value it can no longer be 'given'.
Return Values
Creating a semaphore requires the kernel to allocate RAM from the heap. If there is insufficient heap
memory available for this purpose then xSemaphoreCreateCounting() will return NULL, otherwise
xSemaphoreCreateCounting() will return a handle to the newly created semaphore.
Notes
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.
FreeRTOS 84
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
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.
Example
/* The semaphore cannot be used before a call to xSemaphoreCreateCounting(). The max value to
which the semaphore can count shall be 10, and the initial value assigned to the count shall
be 0. */
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
FreeRTOS 85
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Parameters
None
Return Values
Creating a mutex requires the kernel to allocate RAM from the heap. If there is insufficient heap
memory available for this purpose then xSemaphoreCreateMutex() will return NULL, otherwise
xSemaphoreCreateMutex() will return a handle to the newly created mutex.
Notes
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 synchronization (between tasks or between tasks and an interrupt), and
mutexes the better choice for implementing simple mutual exclusion.
Binary Semaphores – A binary semaphore need not be ‘given’ back once ‘taken’ (obtained), so task
synchronization can be implemented by one task/interrupt continuously 'giving' the semaphore while
another continuously 'takes' the semaphore (see the xSemaphoreGiveFromISR() documentation).
Mutexes – The priority of a task that holds a mutex will 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. A task that obtains a mutex must always give the mutex 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 fast and simple priority inheritance
mechanism is implemented that assumes a task will only ever hold a single mutex at any one time.
FreeRTOS 86
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Both mutexes 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.
Both mutexes and binary semaphores are initialized such that the first call to xSemaphoreTake() on
the semaphore/mutex will pass.
Mutex type semaphores cannot be used from within interrupt service routines.
Example
xSemaphoreHandle xSemaphore;
FreeRTOS 87
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Parameters
None
Return Values
Creating a mutex requires the kernel to allocate RAM from the heap. If there is insufficient heap
memory available for this purpose then xSemaphoreCreateRecursiveMutex() will return NULL,
otherwise xSemaphoreCreateRecursiveMutex() will return a handle to the newly created mutex.
Notes
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.
FreeRTOS 88
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
FreeRTOS 89
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Macro to ‘give’ (or release) a semaphore. The semaphore must have first been successfully created
and successfully ‘taken’.
Parameters
Return Values
pdFAIL The task could not give the semaphore because it was not the semaphore holder. A task
must successfully ‘take’ a semaphore before it can successfully ‘give’ it back.
Notes
None.
FreeRTOS 90
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
for( ;; )
{
if( xSemaphore != NULL )
{
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{
/* We would expect this call to fail because we cannot give
a semaphore without first "taking" it. */
}
/* ... */
FreeRTOS 91
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Macro to ‘give’ (or release) a semaphore. This macro is a version of xSemaphoreGive() that is safe to
use from within an ISR.
Parameters
Return Values
errQUEUE_FULL The semaphore could not be given, probably because it was already available.
Notes
Calling xSemaphoreGiveFromISR() within an interrupt service routine can potentially cause a task that
was blocked waiting to take the semaphore to leave the Blocked state. A context switch should be
performed if such an unblocked task has a priority higher than the currently executing task. The
context switch will ensure that the interrupt returns directly to the highest priority Ready state task.
Unlike the xSemaphoreGive() API function, xSemaphoreGiveFromISR() will not itself perform a
context switch. It will instead just indicate whether or not a context switch is required.
xSemaphoreGiveFromISR() must not be called prior to the scheduler being started. Therefore an
interrupt that calls xSemaphoreGiveFromISR() must not be allowed to execute prior to the scheduler
being started.
FreeRTOS 92
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* Define a task that performs an action each time an interrupt occurs. The interrupt
processing is deferred to this task. The task is synchronized with the interrupt using
a semaphore. */
void vATask( void * pvParameters )
{
/* It is assumed the semaphore has already been created outside of this task. */
for( ;; )
{
/* Wait for the next event. */
if( xSemaphoreTake( xSemaphore, portMAX_DELAY ) == pdTRUE )
{
/* The event has occurred, process it here. */
...
/* The event has occurred, use the semaphore to unblock the task so the task
can process the event. */
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
/* Now the task has been unblocked a context switch should be performed if the priority
of the unblocked task is higher than the currently executing task. If this is the case
then xHigherPriorityTaskWoken will have been set to pdTRUE. NOTE: The syntax required
to perform a context switch from an ISR varies from port to port, and from compiler
to compiler. Check the documentation and examples for the port being used to find the
actual syntax required. */
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
FreeRTOS 93
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Macro to recursively ‘give’ (or release) a mutex type semaphore that has previously been created
using the xSemaphoreCreateRecursiveMutex() API function.
Parameters
Return Values
pdFAIL The mutex could not be ‘given’ because the calling task was not the mutex holder.
Notes
A mutex used recursively can be 'taken' repeatedly by the owner. The mutex does not 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.
xSemaphoreGiveRecursive() must only be called from an executing task and therefore must not be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
xSemaphoreGiveRecursive() must also not be called from within a critical section or while the
scheduler is suspended.
FreeRTOS 94
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
...
For some reason due to the nature of the code further calls to
xSemaphoreTakeRecursive() are made on the same mutex. In real code these would not
be just sequential calls as this would make no sense. Instead the calls are likely
to be buried inside a more complex call structure, for example in a TCP/IP stack.*/
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
/* The mutex has now been 'taken' three times, so will not be available to another
task until it has also been given back three times. Again it is unlikely that real
code would have these calls sequentially, but instead buried in a more complex call
structure. This is just for illustrative purposes. */
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
FreeRTOS 95
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Macro to ‘take’ (or obtain) a semaphore that has previously been created using
vSemaphoreCreateBinary(), xSemaphoreCreateCounting() or xSemaphoreCreateMutex().
Parameters
xBlockTime The time in ticks to wait for the semaphore to become available if it is not available
immediately. A block time of zero can be used to poll the semaphore without ever
blocking.
Return Values
pdPASS The semaphore was successfully ‘taken’ (obtained). The calling task may have been
temporarily held in the Blocked state to wait for the semaphore to become available, and
the semaphore did become available before the block time expired.
Notes
xSemaphoreTake() must only be called from an executing task and therefore must not be called while
the scheduler is in the Initialization state (prior to the scheduler being started).
xSemaphoreTake() must also not be called from within a critical section or while the scheduler is
suspended.
FreeRTOS 96
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
/* ... */
FreeRTOS 97
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
#include “FreeRTOS.h”
#include “semphr.h”
Summary
Macro to recursively ‘take’ (or obtain) a mutex type semaphore that has previously been created using
the xSemaphoreCreateRecursiveMutex() API function.
Parameters
xBlockTime The time in ticks to wait for the mutex to become available if it is not available
immediately. A block time of zero can be used to poll the mutex without ever blocking.
Return Values
Notes
A mutex used recursively can be 'taken' repeatedly by the owner. The mutex does not 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.
xSemaphoreTakeRecursive() must only be called from an executing task and therefore must not be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
xSemaphoreTakeRecursive() must also not be called from within a critical section or while the
scheduler is suspended.
FreeRTOS 98
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Example
...
For some reason due to the nature of the code further calls to
xSemaphoreTakeRecursive() are made on the same mutex. In real code these would not
be just sequential calls as this would make no sense. Instead the calls are likely
to be buried inside a more complex call structure, for example in a TCP/IP stack.*/
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
/* The mutex has now been 'taken' three times, so will not be available to another
task until it has also been given back three times. Again it is unlikely that real
code would have these calls sequentially, but instead buried in a more complex call
structure. This is just for illustrative purposes. */
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
FreeRTOS 99
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
CHAPTER 5
KERNEL CONFIGURATION
FreeRTOS 100
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Each application that uses FreeRTOS must define a header file called FreeRTOSConfig.h in which
some or all of the configuration constants described in this chapter should be defined. Each demo
application included in the FreeRTOS download contains a pre-defined FreeRTOSConfig.h that can
be used as a reference or simply copied.
These constants permit API functions to be either included or excluded from the buiild. For
example, defining INCLUDE_vTaskPrioritySet as 0 will prevent the vTaskPrioritySet() API function
being included in the build, while setting the constant to 1 will ensure vTaskPrioritySet() is included
in the build.
The “INCLUDE_” constants are provided to permit the code size to be reduced when a linker that
does not automatically remove functions that are never called is being used. If your linker does
removed unused functions then every “INCLUDE_” constant can be set to 1 with no impact on the
generated code size.
INCLUDE_vTaskPrioritySet
INCLUDE_uxTaskPriorityGet
INCLUDE_vTaskDelete
INCLUDE_vTaskCleanUpResources
INCLUDE_vTaskSuspend
INCLUDE_vTaskDelayUntil
INCLUDE_vTaskDelay
INCLUDE_uxTaskGetStackHighWaterMark
These constants define various attributes of the kernel – as described in the next section.
FreeRTOS 101
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
configCHECK_FOR_STACK_OVERFLOW
Each task has a unique stack that is automatically allocated from the heap when the task is created.
The size of the stack is set by the usStackDepth parameter of the xTaskCreate() call used to create
the task.
Stack overflow is a very common cause of application instability. FreeRTOS provides two optional
mechanisms that can be used to assist in overflow detection and debugging. The option used is
configured by the configCHECK_FOR_STACK_OVERFLOW configuration constant.
The pxTask and pcTaskName parameters pass the handle and name of the offending task into the
hook function. Note however that the parameter values could themselves have been corrupted if the
stack overflow was severe.
Stack overflow checking can only be used on architectures that have a linear (rather than segmented)
memory map. Also, some processors could potentially generate a fault or exception in response to a
stack corruption before the overflow checking can be performed by the kernel.
Stack overflow checking increases the time taken to perform a context switch.
It is likely that a task stack will reach its greatest (deepest) value after the kernel has swapped the
task out of the Running state as this is when the stack will contain the entire task context. When
method 1 is used the kernel will check that the stack pointer remains within the valid stack space
following each context save. The stack overflow hook function is called if the stack pointer
contains a value that is outside of the valid region.
Method one is quick but will not necessarily catch all stack overflow occurrences.
FreeRTOS 102
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
When a task is created the stack allocated to the task is filled with a known pattern. When method
2 is used the kernel will check the last n bytes within the valid stack range to ensure the pattern
remains in tact and has not been overwritten. The stack overflow hook function is called if any of
these n bytes have changed from their expected value.
Method two is less efficient than method one, but still fairly fast. It is very likely to catch all stack
overflow occurrences but this cannot be guaranteed.
configCPU_CLOCK_HZ
The configCPU_CLOCK_HZ value is used to setup a timer peripheral to generate the tick interrupt. It
must be set to the frequency of the clock that feeds the timer. In most cases this is equal to the
microcontroller frequency.
configIDLE_SHOULD_YIELD
configIDLE_SHOULD_YIELD controls the behavior of tasks that run at the same priority as the idle
task. It only has an effect if the preemptive scheduler is being used.
Tasks that share a priority time slice with each other. If none of the tasks get preempted or interrupted
(an over simplification) then it might be assumed that when averaged over time each idle priority task
will be allocated an equal amount of processing time. However, when configIDLE_SHOULD_YIELD is
set to 1 the idle task will yield immediately should any other task at the idle priority be ready to run.
This ensures the minimum amount of time is spent in the idle task when application tasks are available
for scheduling. A side effect of this behavior is shown in Figure 3.
Figure 3 shows the execution pattern of four tasks that execute at the idle priority. Tasks A, B and C
are application tasks. Task I is the idle task itself. A context switch occurs with regular period at times
T0, T1, ..., T6. When the idle task yields task A starts to execute – but the idle task had already used
up part of a time slice leaving only the remainder of the time slice for task A. Tasks I and A effectively
share a single time slice resulting in tasks B and C getting more execution time than task A.
FreeRTOS 103
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Setting configIDLE_SHOULD_YIELD to 0 prevents this behavior by allowing the idle task to run for its
entire time slice. When this is the case, averaged over time, the other tasks that share the idle priority
will get an equal share of the processing time – but more time will also be spent executing the idle
task. The Idle task can however be used productively if an idle task hook is defined to implement the
functionality of one of the other idle priority tasks.
configKERNEL_INTERRUPT_PRIORITY, configMAX_SYSCALL_INTERRUPT_PRIORITY
As an example – imagine a hypothetical microcontroller that has 8 interrupt priority levels. In this
hypothetical case 0 is the lowest interrupt priority and 7 is the highest interrupt priority2. Figure 4
describes what can and cannot be done at each priority level should
configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY be set
to 0 and 4 respectively.
2
Note care must be taken when assigning values to configKERNEL_INTERRUPT_PRIORITY and
configMAX_SYCALL_INTERRUPT_PRIORITY as some microcontrollers use 0 to mean the lowest priority, while
others use 0 to mean the highest priority.
FreeRTOS 104
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
ISR's running above the configMAX_SYSCALL_INTERRUPT_PRIORITY are never masked out by the
kernel itself, so their responsiveness is not effected by the kernel functionality. This is ideal for
interrupts that require very high temporal accuracy – for example interrupts that perform motor
commutation. However interrupts that have a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY cannot call any FreeRTOS API functions, even those
that end in “FromISR” cannot be used.
configMAX_CO_ROUTINE_PRIORITIES
Sets the maximum priority that can be assigned to a co-routine. Co-routines can be assigned a
priority from 0 to (configMAX_CO_ROUTINE_PRIORITIES – 1).
configMAX_PRIORITIES
Sets the maximum priority that can be assigned to a task. Tasks can be assigned a priority from 0 to
(configMAX_PRIORITIES – 1). 0 is the lowest priority.
configMAX_TASK_NAME_LEN
Sets the maximum number of characters (including the NULL terminator) that can be used when
assigning a name to a task. Attempting to use a name that has more than
configMAX_TASK_NAME_LEN characters will result in the name being truncated.
FreeRTOS 105
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
configMINIMAL_STACK_SIZE
Sets the size of the stack allocated to the Idle task. The value is specified in words, not bytes.
The kernel itself does not use configMINIMAL_STACK_SIZE for any other purpose, however many of
the standard demo tasks also make use of configMINIMAL_STACK_SIZE. The value used by the
demo tasks on any particular architecture is the minimum recommended stack size for any task.
configQUEUE_REGISTRY_SIZE
Sets the maximum number of queues and semaphores that can be referenced from the queue registry
at any one time.
configTICK_RATE_HZ
configTOTAL_HEAP_SIZE
The kernel allocates memory from the heap each time a task, queue or semaphore is created.
configTOTAL_HEAP_SIZE sets the heap size in bytes when either heap_1.c or heap_2.c is included
in the application. configTOTAL_HEAP_SIZE has no effect if any other memory allocation scheme is
used (including heap_3.c).
configUSE_16_BIT_TICKS
The tick count is held in a variable of type portTickType. When configUSE_16_BIT_TICKS is set to 1
portTickType will be defined to be an unsigned 16bit type. When configUSE_16_BIT_TICKS is set to
0 portTickType will be defined to be an unsigned 32bit type.
Using a 16bit type can greatly improve efficiency on 8 and 16bit processors but only at the cost of
limiting the maximum block time that can be specified to 0xffff.
configUSE_ALTERNATIVE_API
Two sets of API functions are provided to send to and receive from queues – the standard API and the
‘alternative’ API. Only the standard API is documented in this manual. Use of the alternative API is
no longer recommended.
Setting confgiUSE_ALTERNATIVE_API to 1 will include the alternative API functions in the build.
Setting configUSE_ALTERNATIVE_API to 0 will omit the alternative API functions from the build.
FreeRTOS 106
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
configUSE_APPLICATION_TASK_TAG
configUSE_CO_ROUTINES
Co-routines are light weight tasks that save RAM by sharing a stack, but have limited functionality.
Their use is omitted from this manual.
configUSE_COUNTING_SEMAPHORES
configUSE_IDLE_HOOK
When configUSE_IDLE_HOOK is set to 1 the Idle task will call the idle hook function on each iteration
of its loop, and the application must provide the idle hook implementation.
When configUSE_IDLE_HOOK is set to 0 the idle hook will never be called and does not have to be
defined.
configUSE_MUTEXES
Set configUSE_MUTEXES to 1 to include the mutex API in the build. Set configUSE_MUTEXES to 0
to omit the mutex API from the build.
configUSE_PREEMPTION
The tick interrupt will never cause a context switch when configUSE_PREEMPTION is set to 0.
configUSE_RECURSIVE_MUTEXES
Set configUSE_RECURSIVE_MUTEXES to 1 to include the recursive mutex API in the build. Set
configUSE_RECURSIVE_MUTEXES to 0 to omit the recursive mutex API from the build.
FreeRTOS 107
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
configUSE_TICK_HOOK
When configUSE_TICK_HOOK is set to 1 the tick interrupt will call the tick hook function each time it
executes and the application must provide the tick hook implementation.
When configUSE_TICK_HOOK is set to 0 the tick hook function will never be called and does not
need to be defined.
configUSE_TRACE_FACILITY
Set configUSE_TRACE_FACILITY to 1 to include the legacy trace facility in the build. Set
configUSE_TRACE_FACILITY to 0 to exclude the legacy trace facility from the build.
Setting configUSE_TRACE_FACILITY to 1 will slightly increase the time required to perform a context
switch.
It is recommended that the trace macros are used in place of the legacy trace mechanism.
FreeRTOS 108
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Data Types
Each port of FreeRTOS has a unique portable.h header file in which is defined a set of macros that
detail the data types that are used. All the FreeRTOS source code and demo applications use these
macro definitions rather than directly using base C data types – but there is absolutely no reason why
applications that use FreeRTOS need to do the same. Application writers can substitute the real data
types for each of the macros defined within Table 1.
portCHAR char
portSHORT short
portLONG long
portTickType This is used to store the tick count and specify block times.
Using a 16bit type can greatly improve efficiency on 8 and 16bit architectures but
severely limits the range of block times that can specified. It would not make
sense to use a 16bit type on a 32bit architecture.
portBASE_TYPE This will be defined to be the most efficient type for the architecture. Typically
this would be a 32bit type on a 32bit architecture, a 16bit type on a 16bit
architecture, and an 8 bit type on an 8bit architectures.
portBASE_TYPE is generally used for return types that can only take a very
limited range of values and for Booleans.
Some compilers make all unqualified char variables unsigned, while others make them signed. For
this reason the FreeRTOS source code explicitly qualifies every use of portCHAR with either signed or
unsigned.
FreeRTOS 109
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Variable Names
Variables are pre-fixed with their type. ‘c’ for char, ‘s’ for short, ‘l’ for long and ‘x’ for portBASE_TYPE
and any other type (structures, task handles, queue handles, etc.).
If a variable is unsigned it is also prefixed with a ‘u’. If a variable is a pointer it is also prefixed with a
‘p’. Therefore a variable of type unsigned char will be prefixed with ‘uc’, and a variable of type pointer
to char will be prefixed ‘pc’.
Function Names
Functions are prefixed with both the type they return and the file they are defined within. For example:
Formatting
Macro Names
Most macros are written in capitals and prefixed with lower case letters that indicate where the macro
is defined. Table 2 provides a list of prefixes.
FreeRTOS 110
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
Note that the semaphore API is written almost entirely as a set of macros but follows the function
naming convention rather than the macro naming convention.
The macros defined in Table 3 are used throughout the FreeRTOS source.
Macro Value
pdTRUE 1
pdFALSE 0
pdPASS 1
pdFAIL 0
The FreeRTOS source code can be compiled with a lot of different compilers, all of which have
different quirks as to how and when they generate warnings. In particular different compilers want
casting to be used in different ways. As a result the FreeRTOS source code contains more type
casting than would normally be warranted.
FreeRTOS 111
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
FreeRTOS is licensed under a modified version of the GNU General Public License (GPL) and can be
used in commercial applications under that license. An alternative and optional commercial license is
also available if:
• You cannot fulfill the requirements stated in the "Open Source Modified GPL license" column
of Table 4.
Is it free? Yes No
Do I have to offer to provide the FreeRTOS source code Yes (a WEB link to the No
to users of my application? FreeRTOS.org site is
normally sufficient)
FreeRTOS 112
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.
http://www.FreeRTOS.org This document was supplied to [email protected]
The FreeRTOS source code is licensed under version 2 of the GNU General Public License (GPL)
with an exception. The full text of the GPL is available at http://www.freertos.org/license.txt. The text
of the exception is provided below.
The exception permits the source code of applications that use FreeRTOS solely through the API
published on the FreeRTOS.org WEB site to remain closed source, thus permitting the use of
FreeRTOS in commercial applications without necessitating that the entire application be open
sourced. The exception can only be used if you wish to combine FreeRTOS with a proprietary product
and you comply with the terms stated in the exception itself.
Note the exception text is subject to change. Consult the FreeRTOS.org WEB site for the most up to
date version.
Clause 1
Linking FreeRTOS statically or dynamically with other modules is making a combined work based on FreeRTOS. Thus, the
terms and conditions of the GNU General Public License cover the whole combination.
As a special exception, the copyright holder of FreeRTOS gives you permission to link FreeRTOS with independent modules
that communicate with FreeRTOS solely through the FreeRTOS API interface, regardless of the license terms of these
independent modules, and to copy and distribute the resulting combined work under terms of your choice, provided that:
1. Every copy of the combined work is accompanied by a written statement that details to the recipient the version of
FreeRTOS used and an offer by yourself to provide the FreeRTOS source code should the recipient request it.
2. The combined work is not itself an RTOS, scheduler, kernel or related product.
3. The combined work is not itself a library intended for linking into other software applications.
Any FreeRTOS source code, whether modified or in it's original release form, or whether in whole or in part, can only be
distributed by you under the terms of the GNU General Public License plus this exception. An independent module is a
module which is not derived from or based on FreeRTOS.
Clause 2
FreeRTOS.org may not be used for any competitive or comparative purpose, including the publication of any form of run time
or compile time metric, without the express permission of Richard Barry (this is the norm within the industry and is intended
to ensure information accuracy).
FreeRTOS 113
Designed For Microcontrollers;
© 2009 Real Time Engineers Ltd. Distribution or publication in any form is strictly prohibited.