Creating a New FreeRTOS PortYou do not need to read or understand this page if using one of the many existing ports and demo applications!
Porting FreeRTOS to a completely different and as yet unsupported microcontroller is not a trivial task. The aim of this page is to describe the house keeping preliminaries required to get a new port started.
Each port is moderately unique and very dependent on the processor and tools being used, so this page cannot provide specifics on the porting detail. There are however plenty of other FreeRTOS ports already in existence and it is suggested that these are used as a reference.
Porting within the same processor family is a much more straight forward task – for example, from one ARM7 based device to another. The documentation page detailing how to modify an existing demo application would be a good point to start reading if this is your aim.
Setting up the Directory StructureThe FreeRTOS kernel source code is generally contained within 3 source files (4 if co-routines are used) that are common to all ports, and one or two ‘port’ files that tailor the RTOS kernel to a particular architecture.
- Download the latest version of the FreeRTOS source code.
- Unzip the files into a convenient location, taking care to maintain the directory structure.
- Familiarise yourself with the source code organisation and directory structure.
- Create a directory that will contain the ‘port’ files for the [architecture] port. Following the convention outlined in the link, the directory should be of the form: FreeRTOS/Source/portable/[compiler name]/[processor name]. For example, if you are using the GCC compiler you can create a [architecture] directory off the existing FreeRTOS/Source/portable/GCC directory.
- Copy empty port.c and portmacro.h files into the directory you have just created. These files should just contain the stubs of the functions and macro’s that require implementing. See existing port.c and portmacro.h files for a list of such functions and macros. You can create a stub file from one of these existing files by simply deleting the function and macro bodies.
- If the stack on the microcontroller being ported to grows downward from high memory to low memory then set portSTACK_GROWTH in portmacro.h to -1, otherwise set portSTACK_GROWTH to 1.
- Create a directory that will contain the demo application files for the [architecture] port. Following the convention again this should be of the form FreeRTOS/Demo/[architecture_compiler], or something similar.
- Copy existing FreeRTOSConfig.h and main.c files into the directory just created. Again these should be edited to be just stub files.
- Take a look at the FreeRTOSConfig.h file. It contains some macro’s that will need setting for your chosen hardware.
- Create a directory off the directory just created and call it ParTest (probably FreeRTOS/Demo/[architecture_compiler]/ParTest). Copy into this directory a ParTest.c stub file.
- ParTest.c contains three simple functions to:
- Setup some GPIO that can flash a few LEDs,
- Set or clear a specific LED, and
- Toggle the state of an LED.
These three functions need implementing for your development board. Having LED outputs working will facilitate the rest of the required work. Take a look at the many existing ParTest.c files included in the other demo projects for examples (the ParTest name is a historical anomaly for PARallel port TEST), and the page describing how to modify an existing demo application for information on writing and testing the ParTest.c functions.
Creating a ProjectNow all the required files are in place you need to create a project (or makefile) that will successfully build them. Obviously they just contain stubs so will not yet do anything, but once they are building the stubs can incrementally be replaced with working functions.
The project will need to contain the following files:
- Source/portable/[compiler name]/[processor name]/port.c
- Source/portable/MemMang/heap_1.c (or heap_2.c or heap_3.c or heap_4.c)
- Demo/[processor name]/main.c
- Demo/[Processor name]/ParTest/ParTest.c
The following directories need to be in the include path – please use relative paths from the Demo/[Process name] directory – NOT absolute paths:
- Demo/Common (i.e. ../Common)
- Demo/[Processor Name]
- Source/portable/[Compiler name]/[Processor name]
Implementing the StubsNow the difficult bit. Once the project is compiling the portable layer stubs require implementation. It is suggested that pxPortInitialiseStack() is the first function to be implemented. To implement pxPortInitialiseStack() you must first decide upon your task context stack frame structure, which is very architecture dependent.