-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathFreeRTOS.mw
170 lines (117 loc) · 6.87 KB
/
FreeRTOS.mw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
This page provides information about ports of FreeRTOS to OpenRISC
== 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 specifies direction of stack growth. Upwards is 1. Downwards is -1. In case of OpenRISC, stack grows downwards.
'portTICK_RATE_MS' specifies period of tick timer in milliseconds.
'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 [[user:filepang|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 [http://bugzilla.opencores.org 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
* http://mattzz.dyndns.org/wiki/bin/view/Projects/PortingFreeRTOStoOpenRISC
* http://opencores.org/forum,OpenRISC,0,4153