FreeRTOS
From OR1K
This page provides information about ports of FreeRTOS to OpenRISC
Contents |
Introduction
FreeRTOS
FreeRTOS is an open source, royalty free, real-time kernel for embedded systems. It is written in ANSI C and assembly code. It is distributed under the GPL with an optional exception. The exception permits users' proprietary code to remain closed source while maintaining the kernel itself as open source.
- FreeRTOS is open soruce and free RTOS kernel for embedded systems.
- it supports both preemptive and non-preemptive scheduiling policy.
- it supports task and coruotines (simple and lightweight task that has very limited stack).
FreeRTOS port for OpenRISC
Overall structure
FreeRTOS port for OpenRISC is consist of four parts.
- User application: User program code
- FreeRTOS kernel: Architecture and board independent kernel code
- FreeRTOS OpenRISC port: Architecture dependent kernel code
- BSP: Board dependent code
Directory structure
FreeRTOS kernel code resides in 'FreeRTOSVx.y.z/Source'. All header files related kernel reside in 'FreeRTOSVx.y.z/Source/include'. 'portable.h' ,which is provide portable layer resides in this directory. Architecure dependent files reside in 'FreeRTOSVx.y.z/Source/portable/GCC/OpenRISC'.
portable.h
This file contains portable layer for each architecture. It contains only definition, actual function body implemented in architecture specific directory. In many cases, implementation filename is 'port.c'.
- portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) : Setups the initial stack of a new task.
- portBASE_TYPE xPortStartScheduler( void ) : Setups the hardware to ready for scheduler, and then sheduler taks control. Generally it set tick timer to correct period and enable interrupt controller. In normal case. this function will never return.
- void vPortEndScheduler( void ) : function for end scheduler. disable tick timer interrupt.
- Other malloc related functions : Those functions are for dynamic memory allocation. You can found actual implementation in 'FreeRTOSVx.y.z/Source/portable/MemMang'. Three diffrent implementation are given by default.
portmacro.h
This file contains settings for architecture specific definitions. This section describes Hardware Abstraction Layer of OpenRISC port.
Type definitions
#define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE unsigned portLONG #define portBASE_TYPE long #define portTickType unsigned portLONG #define portMAX_DELAY (portTickType)0xffffffff
'portBASE_TYPE' should be most efficient type for architecture. In case of OpenRISC, it is 'long'. 'portTickType' is type for hold the number of tick timer interrupt expired.
Architecure specific definitions
#define portSTACK_GROWTH -1
#define portTICK_RATE_MS ( (portTickType) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portCRITICAL_NESTING_IN_TCB 1
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
#define portYIELD_FROM_ISR() vTaskSwitchContext()
#define portYIELD() { \
__asm__ __volatile__ ( "l.sw -4(r1), r11" ); \
__asm__ __volatile__ ( "l.addi r11, r0, 0x0FCC" ); \
__asm__ __volatile__ ( "l.sys 0x0FCC" ); \
__asm__ __volatile__ ( "l.nop " ); \
}
#define portNOP() __asm__ __volatile__ ( "l.nop" )
#define portDISABLE_INTERRUPTS() vPortDisableInterrupts()
#define portENABLE_INTERRUPTS() vPortEnableInterrupts()
'portSTACK_GROWTH' is specify direction of stack growth. Upwards is 1. Downwards is -1. In case of OpenRISC, stack grows downwards. 'portTICK_RATE_MS' si specify period of tick timer in 1 millisecond. 'port YIELD' will be requested to scheduler for switch to other task after end of this time slice. It is implemented by system call 0x0FCC.
#define portENTER_CRITICAL() { \
__asm__ __volatile__ ( "l.sw -4(r1), r11" ); \
__asm__ __volatile__ ( "l.addi r11, r0, 0x0FCE" ); \
__asm__ __volatile__ ( "l.sys 0x0FCE" ); \
__asm__ __volatile__ ( "l.nop " ); \
}
#define portEXIT_CRITICAL() { \
__asm__ __volatile__ ( "l.sw -4(r1), r11" ); \
__asm__ __volatile__ ( "l.addi r11, r0, 0x0FCF" ); \
__asm__ __volatile__ ( "l.sys 0x0FCF" ); \
__asm__ __volatile__ ( "l.nop " ); \
}
These macros are used for manage critical section. These are implemented by system call.
Context management
Context save
OpenRISC port be saved context by following steps.
1. make stack rooms at the stack of current task (EPCR, ESR, R1 ~ R31) 2. save R3 ~ R5, these are clobber register 3. save ESR, EPCR, R3~R5 are corrupted in this step. 4. save R9, R2, R6 ~ R31(except R9) 5. save R1(stack pointer register) 6. restore R3 ~ R5 by original value
Context restore
OpenRISC port be restored context by following steps.
1. restore R1(stack pointer of next running task) 2. restore R9, R2, R6 ~ R31(except R9) 3. restore ESR, EPCR, R3 ~ R5 are corrupted in this step 4. restore R3 ~ R5 5. resume next task by l.rfi
Download source code
At present the FreeRTOS port is maintained by Kim Sung Su aka filepang. The source code may be found in SVN here:
http://opencores.org/ocsvn/openrisc/openrisc/trunk/rtos/freertos-6.1.1
Checkout source code via SVN client like below.
svn co http://opencores.org/ocsvn/openrisc/openrisc/trunk/rtos/freertos-6.1.1 FreeRTOSV6.1.1 --username ****
Compile and running demo project
Note that you will need the latest OpenRISC GNU toolchain port and or1ksim on your linux box.
Compile
Currently, a demo project was prepared on Or1ksim only. it will be placed in FreeRTOSVx.y.z/Demo/OpenRISC_SIM_GCC. Move to this directory, setup your or32-elf-gcc path in Makefile. Edit CCPATH variable like below.
CCPATH = /opt/or32-new
And then, run make script.
make
Running
Running FreeRTOS on Or1ksim by following command:
make sim
Debugging
For debugging FreeRTOS port, invoke Or1ksim and or32-elf-gdb by following command:
make debug
After or32-elf-gdb invoke successfully, connect Or1ksim by following gdb command:
target remote :9999 load set $pc=0x100 break main continue
Bug reporting
Please report any bugs via bugzilla.
Future work
- Porting standard demo task [done]
- Testing under FPGA board
Past FreeRTOS ports
Several past attempts of porting FreeRTOS have been made. Here are a few starting points
