FreeRTOS Demo for the TI MSP430F5438 (MSP430X) Microcontroller
Using the IAR Embedded Workbench
This page documents the FreeRTOS demo application for the MSP430X / MSP430F5438 microcontroller from
Texas Instruments. The demo uses the IAR Embedded Workbench for MSP430
from IAR Systems, and targets the official MSP-EXP430F5438
experimenter board from TI (instructions
are provided should you wish to use an alternative development board).
It is recommended not to attempt to open the demo project in an IAR Embedded Workbench
version that is earlier than V5.20 as to do so can silently corrupt the project file.
The port and demo project were developed and tested using both the 'Large' and 'Small' data models. The build configurations table below contains important information
on using the small data model.
Features of FreeRTOS that are demonstrated by this demo project
The project demonstrates the following FreeRTOS features and techniques:
The 'gatekeeper' task design pattern
The demo LCD task is the only task that is permitted to access the LCD,
so is the LCD 'gatekeeper'. Other tasks and interrupts that want
to write strings to the LCD do not access the LCD directly, but instead
send the string they wish to display to the LCD task using a FreeRTOS
The 'controller' task design pattern
The LCD task also demonstrates the 'controller' task design pattern.
Messages that are sent to the LCD are structures that contain both a
message type and a message value parameter. The LCD task knows what to
do with the message value (which can be an integer, character pointer,
or anything else) by first inspecting the message type.
Controlled (not free running) polling of an input
A button polling task uses the vTaskDelay() FreeRTOS API function
to control the rate at which it reads a button input. This
removes the need for complex button debouncing, as well as preventing
the task from utilising all of the available processing time.
(Effectively and indirectly) Writing to the LCD from an interrupt service routine
Slow output devices such as LCDs cannot normally be accessed efficiently from an
interrupt service routine. In this demo the joystick select button is
used to generate an external interrupt, and the interrupt service routine
sends a string to the LCD indirectly by sending it to the LCD task on
a message queue. This is using the LCD task as a 'gatekeeper' task as
Gathering and displaying run time statistics
Run time statistics provide information on the amount of processing time
allocated to each task since the embedded target was booted. Times are
provided both as an absolute value and as a percentage of the total run
An Idle task hook function
The demo makes use of the idle task hook to place the processor into a
low power state. Note however that the demo is implemented using standard
task implementations that are used by many different demos, and is
therefore not optimised for low power operation. Lower power consumption
would be achieved by converting polling tasks into event driven tasks,
and slowing the tick interrupt frequency.
A tick interrupt hook function
The demo makes use of the tick interrupt hook to implement 'watchdog'
type functionality. It monitors all the other tasks in the system to
look for any unexpected behaviour. It then sends either a PASS or an
error code status message to the LCD/Controller task. The LCD/Controller
demo task uses the message type member of the message it receives to
interpret the message as a status message, then uses the message value
member of the same message to determine which status string it should
write to the LCD.
A malloc() failed hook function
The malloc() failed hook will be called when a call to pvPortMalloc()
fails because there is not enough FreeRTOS heap memory available
for the allocation to complete.
pvPortMalloc() can be called from application tasks, but is also called
from FreeRTOS API functions that create tasks, queues and semaphores.
Querying the amount of FreeRTOS heap memory that remains unallocated
xPortGetFreeHeapSize() is called from a task after the RTOS scheduler has been
started and outputs the amount of FreeRTOS heap memory that remains
unallocated (the amount of heap memory that is still available) to the
terminal IO window of the IAR Embedded Workbench IDE.
Note: If this project fails to build then it is likely the version of IAR
Embedded Workbench being used is too old. If this is the case, then it is also
likely that the project file has been (silently) corrupted and will need to be
restored to its original state before it can be built even with an updated IAR version.
IMPORTANT! Notes on using the MSP430X IAR Demo
Please read all the following points before using this RTOS port.
See also the FAQ My application does
not run, what could be wrong?
- Source Code Organisation
- The Demo Application
- RTOS Configuration and Usage Details
Source Code Organisation
The FreeRTOS download contains the source code for all the FreeRTOS ports so
includes many more files than are required for this demo.
See the Source Code Organization
section for a description of the downloaded files and information on creating a
The IAR workspace file for the MSP430F5438 demo is called RTOSDemo.eww
and is located in the FreeRTOS/Demo/MSP430X_MSP430F5438_IAR directory.
The Demo Application
Demo application hardware setup
The demo application includes an interrupt driven UART test. This creates two
tasks, a transmit task and a receive task. The transmit task transmits characters
on UCA1, and the receive task receives characters on the same UCA1 peripheral. The receive task
expects to receive the characters transmitted by the transmit task, but as there
is no external 9 way connector, the hardware is internally configured to use a
loopback mode. Therefore, unlike other FreeRTOS demos, it is not necessary to
fit an external loopback connector to the UART for the COM port test to work.
Note that the implementation of the UART interrupt service routine is provided to demonstrate the use
of queues from inside an interrupt service routine. It is not intended to
be an example of an efficient interrupt implementation. A real application should make use
of the DMA. Or, as a minimum, transmission and reception could use a simple
RAM ring buffer, and synchronise with a task using a semaphore when a complete
message has been received or transmitted.
The port was developed and tested using a Texas Instruments MSP-FET430UIF USB
Building and running the demo application
The IAR project contains three build configurations. All the build configurations
demonstrate the same functionality, but with different run time models and optimisation
settings as described in the table below.
Configured to use the large data model with zero optimisation
Configured to use the large data model with maximum optimisation.
Configured to use the small data model with zero optimisation.
Note: The small data model is selected using the usual IAR
project target configuration options. In addition to this,
FreeRTOS is configured to use the small data model by defining
the assembler preprocessor symbol "__DATA_MODEL_SMALL__". This is
an assembler preprocessor symbol, not a compiler preprocessor
- Open the FreeRTOS/Demo/MSP430X_MSP430F5438_IAR/RTOSDemo.eww workspace from within the Embedded Workbench IDE.
- Select 'Rebuild All' from the IDE 'Project' menu. The project should build with no errors or warnings.
- Select 'Debug' from the IDE 'Project' menu. The MSP430X flash memory will be programmed with the newly built binary. The debugger will then start and run to the main() function.
The top of this web page lists the FreeRTOS features that are demonstrated
by the MSP430X5438 demo project. The comments contained in the main.c
source file provide more information on how this functionality is implemented
The following behaviour will be observed when the demo is executing correctly:
The image below is a screen shot taken during a debugging session. The FreeRTOS
state viewer Tasks and Queues windows can be seen at the bottom of the
screen shot. Run time statistics information can be see in in the terminal IO
Screen shot taken during a FreeRTOS debugging session.
state viewer plug in windows can be seen at the bottom of the screen shot.
Run time statistics information can be seen in the terminal IO window.
Configuring the RTOS tick interrupt
FreeRTOS requires exclusive use of a timer that is capable of generating a fast
periodic interrupt called the RTOS 'tick' interrupt. The timer is configured in
a user definable hook (or callback) function, so giving the application writer
the flexibility to decide which timer peripheral is actually used. The name and
prototype of the hook function is shown below:
void vApplicationSetupTimerInterrupt( void );
The constant configTICK_VECTOR must be set to the interrupt vector number of the
chosen peripheral. configTICK_VECTOR is defined in the FreeRTOSConfig.h header
file. This demo project includes an implementation of
vApplicationSetupTimerInterrupt() that configures time TA0 to generate the tick
interrupt and therefore sets configTICK_VECTOR to TIMER0_A0_VECTOR. The provided
code will have to be modified only if the application being developed needs TA0
to be free for some other purpose.
RTOS port specific configuration
Configuration items specific to these demos are contained in FreeRTOS/Demo/MSP430X_MSP430F5438_IAR/FreeRTOSConfig.h. The
constants defined in this file can be edited to meet the needs of your application. In particular -
Each port #defines 'BaseType_t' to equal the most efficient data type for that
processor. This port defines BaseType_t to be of type short.
Note that vPortEndScheduler() has not been implemented.
Interrupt service routines
Unlike most ports, interrupt service routines that cause a context switch have
no special requirements and can be written as per the compiler documentation.
The macro portYIELD_FROM_ISR() can be used to request a context switch from within an ISR.
Note that portYIELD_FROM_ISR() must be the last statement in the ISR.
This demo project provides examples of FreeRTOS interrupt service routines -
namely prvSelectButtonInterrupt() defined in main.c and prvUSCI_A0_ISR() defined in
serial.c. Note that prvUSCI_A0_ISR() is implemented to stress the port and
demonstrate queues being used from interrupts - it is not intended to be a demonstration
of an efficient or a generic interrupt service routine!
Switching between the pre-emptive and co-operative RTOS kernels
Set the definition configUSE_PREEMPTION within FreeRTOS/Demo/MSP430X_MSP430F5438_IAR/FreeRTOSConfig.h to 1 to use pre-emption or 0
to use co-operative.
As with all the ports, it is essential that the correct compiler options are used. The best way to ensure this is to base your
application on the provided demo application files.
Source/Portable/MemMang/heap_1.c is included in the demo application project to provide the memory
allocation required by the RTOS kernel.
Please refer to the Memory Management section of the API documentation for
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.