RTOS Implementation on STM32. (1)
RTOS Implementation on STM32. (1)
User manual
Developing applications on STM32Cube with
RTOS
Introduction
The STM32Cube is an STMicroelectronics original initiative to significantly
improve developer productivity by reducing development effort, time and cost.
STM32Cube covers the whole STM32 portfolio.
STM32Cube includes
STM32CubeMX, a graphical software configuration tool that allows the
generation of C initialization code using graphical wizards.
A comprehensive embedded software platform, delivered per
Series (such as STM32CubeF4 for STM32F4 Series)
– The STM32Cube HAL, STM32 abstraction layer embedded software
ensuring maximized portability across the STM32 portfolio,
– Low-layer APIs (LL) offering a fast light-weight expert-oriented
layer, which is closer to the hardware than the HAL. LL APIs are
available only for a set of peripherals.
– A consistent set of middleware components such as RTOS, USB,
TCP/IP, Graphics,
– All embedded software utilities, delivered with a full set of examples.
A real-time operating system is an operating system optimized for use in
embedded/real- time applications. Their primary objective is to ensure a timely
and deterministic response to events. Using a real-time operating system allows
applications to be written as a set of independent threads that inter-
communicate using message queues and semaphores.
This user manual is intended for developers who use STM32Cube firmware on
STM32 microcontrollers and microprocessors. It provides a full description of
how to use the STM32Cube firmware components with a real-time operating
system (RTOS); this user manual comes also with description of a set of
examples based on FreeRTOS™ using the common APIs provided by the CMSIS-
OS wrapping layer. In the STM32Cube firmware FreeRTOS™ is used as real-time
operating system through the generic CMSIS-OS
wrapping layer provided by Arm®. Examples and applications using the
FreeRTOS™ can
be directly ported on any other RTOS without modifying the high level APIs,
only the CMSIS-OS wrapper has to be changed in this case. Refer to the release
notes of the package to know the version of FreeRTOS™ and CMSIS-RTOS
firmware components used with the STM32Cube.
This document is applicable to all STM32 devices; however for simplicity
reason, the STM32F4xx devices and STM32CubeF4 are used as reference
platform. To know more about the examples implementation on your STM32
device, please refer to the readme file provided within the associated
STM32Cube firmware package.
Contents
1 FreeRTOS™................................................................................................. 5
1.1 Overview........................................................................................ 5
1.2 License........................................................................................... 6
1.3 FreeRTOS™ source organization....................................................7
1.4 Porting FreeRTOS™ on STM32........................................................8
1.5 FreeRTOS™ API...............................................................................9
1.6 FreeRTOS™ memory management...............................................10
1.7 FreeRTOS™ low power management...........................................12
1.8 FreeRTOS™ configuration.............................................................12
2 CMSIS-RTOS module................................................................................14
2.1 Overview...................................................................................... 14
2.2 CMSIS-RTOS API............................................................................ 15
3 FreeRTOS™ applications.........................................................................18
3.1 Thread creation example..............................................................18
3.2 Semaphores examples.................................................................19
3.2.1 Semaphore between threads....................................................19
3.2.2 Semaphore from ISR.................................................................20
3.3 Mutexes example.........................................................................21
3.4 Queues example...........................................................................21
3.5 Timer example.............................................................................. 22
3.6 Low-power example.....................................................................23
4 Conclusion.................................................................................................25
5 FAQs...........................................................................................................26
6 Revision history........................................................................................ 27
2/ UM1722 Rev
34 3
UM1722 List of tables
List of tables
UM1722 Rev 3/
3 34
List of figures UM1722
List of figures
4/ UM1722 Rev
34 3
UM1722 FreeRTOS™
1 FreeRTOS™
1.1 Overview
FreeRTOS™ is a class of RTOS that is designed to be small enough to run on a
microcontroller or microprocessor, although its use is not limited to
microcontroller and microprocessor applications.
A microcontroller or a microprocessor is a small and resource real-time
constrained processor that incorporates, on a single chip, the processor itself,
read only memory (ROM or Flash) to hold the program to be executed, and the
random access memory (RAM) needed by the programs it executes. Typically
the program is executed directly from the read only memory.
Microcontrollers and microprocessor are used in deeply embedded applications
(those applications where you never actually see the processors themselves or
the software they are running) that normally have a very specific and
dedicated job to do. The size constraints, and dedicated end application nature,
rarely warrant the use of a full RTOS implementation - or indeed make the use
of a full RTOS implementation possible.
FreeRTOS™ therefore provides the core real-time scheduling functionality, inter-
task communication, timing and synchronization primitives only. This means it is
more accurately described as a real-time kernel, or real-time executive.
Additional functionality, such as a command console interface, or networking
stacks, can be then be included with add-on components.
FreeRTOS™ is a scalable real-time demonstration builder core designed
specifically for small embedded systems. Highlights include
FreeRTOS™ demonstration builder core-preemptive, cooperative
and hybrid configuration options.
Official support for 27 architectures (counting ARM7 and Arm® Cortex®-
M3 as one architecture each).
FreeRTOS-MPU supports the Arm® Cortex®-M3 Memory Protection Unit
(MPU).
Designed to be small, simple and easy to use. Typically a demonstration
builder core binary image will be in the region of 4K to 9K bytes.
Very portable code structure predominantly written in C.
Supports both tasks and co-routines.
Queues, binary semaphores, counting semaphores, recursive semaphores
and mutexes for communication and synchronization between tasks, or
between tasks and interrupts.
Mutexes with priority inheritance.
Supports efficient software timers.
Powerful execution traces functionality.
Stack overflows detection options.
Pre-configured demo applications for selected single board computers
allowing out of the box operation and fast learning curve.
Free forum support, or optional commercial support and licensing.
No software restriction on the number of tasks that can be created.
No software restriction on the number of priorities that can be used.
1.2 License
The FreeRTOS™ source code is licensed by a modified GNU General Public License.
The modification takes the form of an exception. The full text of the GNU
General Public License is shown here:
The FreeRTOS.org source code is licensed by the modified GNU General Public
License (GPL) text provided below. The FreeRTOS download also includes
demo application source code, some of which is provided by third parties
AND IS LICENSED SEPARATELY FROM FREERTOS.ORG.
For the avoidance of any doubt refer to the comment included at the top
of each source and header file for license and copyright information.
This is a list of files for which Real Time Engineers Ltd are not the
copyright owner and are NOT COVERED BY THE GPL.
2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels.
Users must ensure the open source license conditions stated at the top
of each uIP source file is understood and adhered to.
3) The lwIP TCP/IP stack the copyright of which is held by the Swedish
Institute of Computer Science. Users must ensure the open source license
conditions stated at the top of each lwIP source file is understood and
adhered to.
Errors and omissions should be reported to Richard Barry, contact details for
whom can be obtained from http://www.FreeRTOS.org.
UM1722 Rev 7/
3 34
FreeRTOS™ UM1722
Demo Source
Task.c Portable
Queue.c
Compiler
List.c
Platform
Abstraction Layer
Hardware
(HAL)
Port.c
The core RTOS code is contained in three files, called tasks.c, queue.c and
list.c., in the FreeRTOS/Source directory. The same directory contains two
optional files called timers.c and croutine.c which implement software timer
and co-routine functionality. Each supported processor architecture requires a
small amount of architecture specific RTOS code. This is the RTOS portable
layer, located in the FreeRTOS/Source/Portable/[compiler]/[architecture] sub
directories, where [compiler] and [architecture] are the compiler used to create
the port, and the architecture on which the port runs, respectively.
The sample heap allocation schemes are also located in the portable layer. The
various sample heap_x.c files are located in the
FreeRTOS/Source/portable/MemMang directory.
UM1722 Rev 9/
3 34
FreeRTOS™ UM1722
– xTaskCreate
Task creation
– vTaskDelete
– vTaskDelay
– vTaskDelayUntil
– uxTaskPriorityGet
– vTaskPrioritySet
Task control – vTaskSuspend
– vTaskResume
– xTaskResumeFromISR
– vTaskSetApplicationTag
– xTaskCallApplicationTaskHook
– xTaskGetCurrentTaskHandle
– xTaskGetSchedulerState
– uxTaskGetNumberOfTasks
Task utilities – vTaskList
– vTaskStartTrace
– ulTaskEndTrace
– vTaskGetRunTimeStats
– vTaskStartScheduler
– vTaskEndScheduler
Kernel control
– vTaskSuspendAll
– xTaskResumeAll
– xQueueCreate
– xQueueSend
– xQueueReceive
– xQueuePeek
– xQueueSendFromISR
Queue management
– xQueueSendToBackFromISR
– xQueueSendToFrontFromISR
– xQueueReceiveFromISR
– vQueueAddToRegistry
– vQueueUnregisterQueue
– vSemaphoreCreateBinary
– vSemaphoreCreateCounting
– xSemaphoreCreateMutex
Semaphores
– xSemaphoreTake
– xSemaphoreGive
– xSemaphoreGiveFromISR
Scheme 1 - heap_1.c
This is the simplest scheme of all. It does not permit memory to be freed once
it has been allocated, but despite this is suitable for a surprisingly large number
of applications.
The algorithm simply subdivides a single array into smaller blocks as requests
for RAM are made. The total size of the array is set by the definition
configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h. This scheme:
can be used if your application never deletes a task or queue (no calls to
vTaskDelete () or vQueueDelete () are ever made).
is always deterministic (always takes the same amount of time to return a
block).
is used by the PIC, AVR and 8051 demo applications - as these do not
dynamically create or delete tasks after vTaskStartScheduler() has been
called.
heap_1.c is suitable for a lot of small real-time systems provided that all
tasks and queues are created before the kernel is started.
Scheme 2 - heap_2.c
This scheme uses a best fit algorithm and, unlike scheme 1, allows
previously allocated blocks to be freed. It does not however combine
adjacent free blocks into a single large block.
Again the total amount of available RAM is set by the definition
configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h.
This scheme:
can be used even when the application repeatedly calls vTaskCreate
()/vTaskDelete () or vQueueCreate ()/vQueueDelete () (causing multiple
calls to pvPortMalloc() and vPortFree()).
should not be used if the memory being allocated and freed is of a
random size - this would only be the case if tasks being deleted each had
a different stack depth, or queues being deleted were of different lengths.
could possibly result in memory fragmentation problems should your
application create blocks of queues and tasks in an unpredictable order.
This would be unlikely for nearly all applications but
should be kept in mind.
is not deterministic - but is also not particularly inefficient.
heap_2.c is suitable for most small real-time systems that have to dynamically
create tasks.
Scheme 3 - heap_3.c
This is just a wrapper for the standard malloc() and free() functions. It makes
them thread safe. This scheme:
Requires the linker to setup a heap, and the compiler library to provide
malloc() and free() implementations.
Is not deterministic.
Will probably considerably increase the kernel code size.
Is used by the PC (x86 single board computer) demo application.
Scheme 4 - heap_4.c
This scheme uses a first fit algorithm and, unlike scheme 2, does combine
adjacent free memory blocks into a single large block (it does include a
coalescence algorithm).
The total amount of available heap space is set by configTOTAL_HEAP_SIZE -
which is defined in FreeRTOSConfig.h.
The xPortGetFreeHeapSize() API function returns the total amount of heap space
that remains unallocated (allowing the configTOTAL_HEAP_SIZE setting to be
optimized), but does not provide information on how the unallocated memory is
fragmented into smaller blocks.
This implementation:
can be used even when the application repeatedly deletes tasks, queues,
semaphores and mutexes.
is much less likely than the heap_2 implementation to result in a heap
space that is badly fragmented into multiple small blocks - even when the
memory being allocated and freed is of random size.
end if
/ * T he low est in ter ru pt pri ori ty tha t can be us ed in a c a l l t o a "s et
pri or ity " f unc tio n. */
# def ine co nfi gLI BRA RY _LO WES T_I NTE RRU PT _PR IOR ITY 0xf
/ * I nte rru pt pri ori ti es use d b y t he ke rne l p ort la yer it se lf. T hes
e a re ge ner ic t o a ll Cor tex - M po rts , a nd do not re ly on an y p art icu la
r l ibr ary fu nct ion s. */ # def ine co nfi gKE RNE L_ INT ERR UPT _PR IOR IT Y (
c onf igL IBR ARY _LO WES T_ INT ERR UPT _PR IOR IT Y < < ( 8 - co nfi gPR IO _BI TS) )
# def ine co nfi gMA X_S YS CAL L_I NTE RRU PT_ PR IOR ITY (
c onf igL IBR ARY _MA X_S YS CAL L_I NTE RRU PT_ PR IOR ITY << (8 - con fi gPR IO_ BIT S)
)
/ * D efi nit ion s t hat m ap the Fr eeR TOS p ort in ter rup t h and le rs to
the ir CMS IS s tan dar d n ame s. */
# def ine vP ort SVC Han dl er SVC _Ha ndl er
# def ine xP ort Pen dSV Ha ndl er Pen dSV _Ha nd ler
/ * I MPO RTA NT: Th is de fin e M UST be co mm ent ed whe n u sed wi th ST M32 Cub e f
irm wa re,
to p rev ent ov erw rit ing S ysT ick _Ha ndl er de fin ed wit hin ST M32
Cu be HAL
*/
/ * # def ine xP ort Sys Ti ckH and ler Sy sTi ck _Ha ndl er */
Note: SVC_Handler and PendSV_Handler must be removed from stm32f4xx_it.c/.h files when
working with FreeRTOS™ to avoid a duplicate definition
2 CMSIS-RTOS module
2.1 Overview
The CMSIS-RTOS is a common API for Real-Time operating systems. It provides a
standardized programming interface that is portable to many RTOS and enables
therefore software templates, middleware, libraries, and other components that
can work across supported the RTOS systems.
This module is represented by cmsis_os.c/h files located under the following
repository “Middlewares\Third_Party\FreeRTOS\CMSIS_RTOS”.
– The osDelay function puts a thread into the state WAITING for a
specified period of time.
– The generic osWait function waits for events that are assigned to a
thread.
– The osThreadYield provides co-operative thread switching and passes
execution to another thread of the same priority.
The CMSIS-RTOS API is designed to optionally incorporate multi-processor systems
and/or access protection via the Arm® Cortex®-M memory protection unit (MPU).
In some RTOS implementation threads may execute on different processors and Mail
and Message queues can therefore reside in shared memory resources.
The CMSIS-RTOS API encourages the software industry to evolve existing RTOS
implementations. Kernel objects are defined and accessed using macros. This
allows differentiation. RTOS implementations can be different and optimized in
various aspects towards the Arm® Cortex®-M processors. Optional features may
be for example:
Generic Wait function; i.e. with support of time intervals.
Support of the Arm® Cortex®-M Memory Protection Unit (MPU).
Zero-copy mail queue.
Support of multi-processor systems.
Support of a DMA controller.
Deterministic context switching.
Round-robin context switching.
Deadlock avoidance, for example with priority inversion.
Zero interrupt latency by using the Arm® Cortex®-M3/M4 instructions LDEX
and STEX.
3 FreeRTOS™ applications
/* Start thread 1 */
LEDThread1Handle = osThreadCreate (osThread(LED1), NULL);
Thread 2: this thread toggles the LED2 each 500 ms for 10 seconds then it
suspend itself. Thread 1 will resume the execution of thread 2 after 5 seconds.
5s 15 s
0s 10 s
5s 10 s
0s
Thread 1 release the semaphore and suspends itself Thread 2 release the semaphore
Thread 2 (low priority) obtains the semaphore, End of cycle
resume Thread 1 and toggles LED2
Thread (bllocked)
osSemaphoreWaii
t()
osSemaphoreRelleas osSemaphoreWaii
e() t()
The consumer is a higher priority than the producer and is set to block on
queue reads. The queue only has space for one item, as soon as the producer
posts a message on the queue the consumer will unblock, preempt the
producer, and remove the item.
Queu
e
Thread Thread
(Producer) (Consumer)
osMessagePut() osMessageGet()
Messag
e
0 10 20 30 40 Time
(ms)
0 0 0 0
4 Conclusion
5 FAQs
How to use a clock other than SysTick to generate the tick interrupt?
User can optionally provide its own tick interrupt source by generating an
interrupt from a timer other than SysTick:
Provide an implementation of vPortSetupTimerInterrupt() that generates
an interrupt at the frequency specified by the configTICK_RATE_HZ
FreeRTOSConfig.h constant.
Install xPortSysTickHandler() as the handler for the timer interrupt, and
ensure xPortSysTickHandler() is not mapped to SysTick_Handler() in
FreeRTOSConfig.h, or renamed as SysTick_Handler() in port.c.
6 Revision history
STMicroelectronics NV and its subsidiaries (“ST”) reserve the right to make changes, corrections, enhancements,
modifications, and improvements to ST products and/or to this document at any time without notice. Purchasers should
obtain the latest relevant information on ST products before placing orders. ST products are sold pursuant to ST’s terms
and conditions of sale in place at the time of order acknowledgement.
Purchasers are solely responsible for the choice, selection, and use of ST products and ST assumes no liability for
application assistance or the design of Purchasers’ products.
Resale of ST products with provisions different from the information set forth herein shall void any warranty granted by ST
for such product.
ST and the ST logo are trademarks of ST. For additional information about ST trademarks, please refer to
www.st.com/trademarks. All other product or service names are the property of their respective owners.
Information in this document supersedes and replaces information previously supplied in any prior versions of this
document.