]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - os/6.0.4_posix/port.c_documentation.txt
Update remaining files to the changed interface
[pes-rpp/rpp-lib.git] / os / 6.0.4_posix / port.c_documentation.txt
1 File: port.c.documentation.txt
2 Author: Corvus Corax
3 Desc: Description of port.c Functions and Directions about porting.
4 See FreeRTOS documentation ebook for details.
5
6
7 FreeRTOS is an architecture independent real time operating system.
8 Most architecture dependant code sits in a single file: port.c
9 Architecture dependant definitions sit in: portmacro.h
10
11 Other important files:
12
13 Source/portable/MemMang/head_3.c - memory management - very simple. Provides
14 functions like malloc and free - very easy to make a wrapper for on any system
15 that provides memory management.
16
17 FreeRTOS has internal scheduling. The real time scheduler sits in Source/task.c and calls low level functions of port.c for thread management.
18
19 For that port.c needs to provide functions to switch between threads on
20 request, as well as a tick handler that preempts threads on a periodic basis.
21
22 Only one FreeRTOS thread is active at any time!
23
24
25 port.c provides the API defined in portmacro.h.
26
27 Only a subset of the functions is explained here (with the naming from the
28 posix port. Their macros are sometimes named a bit different)
29
30
31 void vPortEnterCritical(void);
32
33 This function is called if a thread enters a "critical section".
34 In a critical sections the thread must not be preempted.
35
36 (To preempt a thread means to halt its execution when a timer interrupt comes
37 in, and give execution to another thread)
38 This function should increase a counter for that thread, since several
39 "Critical Sections" could be cascaded. Only if the outermost critical section
40 is exited, is preemtion allowed again.
41
42 void vPortExitCritical(void);
43 This function is called if a thread leaves a "critical section".
44 If a thread leaves the outermost critical section, the scheduler is allowed to
45 preempt it on timer interrupt (or other interrupts)
46
47
48 void vPortEnableInterrupts(void);
49 void vPortDisableInterrupts(void);
50
51 functions to enable and disable interrupts. On "real systems" this means all
52 interrupts including IO. When "simulating" this means the tick handler/ timer
53 / timer interrupt. The tick handler is supposed to not do anything if interrupts are disabled.
54
55
56 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack,
57 pdTASK_CODE pxCode, void *pvParameters );
58
59 Used to initialize a new thread. The stack memory area, command line
60 parameters for this task and the entry function (pxCode) are given
61
62 This function needs to initialize the new task/thread, but suspend it
63 immediately. It is only to be executed later if the scheduler says so.
64
65 returns pxTopOfStack if success and 0 on failure.
66
67 THIS WILL BE THE FIRST FUNCTION FreeRTOS CALLS.
68 The first thread to be created is likely the idle thread. At this time the
69 scheduler has not been started yet. Therefore it's important to start all
70 threads in suspended state!
71
72 void vPortEndScheduler(void);
73
74 Needs to end the scheduler (and as such all Tasks/threads) This means FreeRTOS
75 terminates - as in (simulated) system shutdown.
76
77
78 portBASE_TYPE xPortStartScheduler(void);
79
80 This function doesn't return until someone (another thread) calls
81 vPortEndScheduler(). You can set up your timer and tick handler here and start
82 the first thread. Then do what a scheduler does (manage threads)
83
84
85 vPortYield()
86
87 Sometimes threads go sleeping on purpose (for example during one of FreeRTOS
88 system calls - including sleep() )
89 This function should send the thread that calls it into suspended state and
90 not return until the scheduler gives back execution to this thread.
91
92
93 ===========
94 The scheduler.
95
96 What your scheduler needs to do:
97
98 Basically what your self written scheduler is allowed to do is the "dirty
99 work" for the high level scheduler logic provided by FreeRTOS task.c
100
101 The scheduler is supposed to run a timer interrupt/tick handler that gets
102 called every portTICK_RATE_MICROSECONDS microseconds.
103 That value is defined somewhere in OpenPilot and has to be exact as well as
104 the same on all architectures.
105
106 If you cannot set up a timer with that accuracy you are screwed!
107
108 Anyway. Every time the timer tick happens, you have to
109
110 - check whether you are allowed to execute the tick handler.
111   If interrupts are disabled and/or the thread is in a critical section, the
112   tick handler should do nothing
113
114 - Tell FreeRTOS that the tick has happened
115   Increment the Tick Count using the FreeRTOS function
116   vTaskIncrementTick();
117
118 - If preemption is enabled (and in OpenPilot it is!)
119   Tell the high level Scheduler of FreeRTOS to do its magic, using the
120   function
121   vTaskSwitchContext();
122
123 - You can find out which thread is SUPPOSED to be running with the function
124   xTaskGetCurrentTaskHandle();
125
126 - If this is for some reason not the currently running thread, SUSPEND that
127   thread with whatever method possible (signals, events, operating system
128   thread.suspend() - I don't know how to do that in Qt.
129
130 - Make the thread returned by xTaskGetCurrentTaskHandle() resume operation as
131   normal.
132
133 - Make sure that when you return from the tick handler, exactly one thread is
134   running and that is the one by xTaskGetCurrentTaskHandle() and all others
135   are suspended!
136
137
138
139 On top of that, threads can suspend themselves just like that. That happens
140 every time they call any blocking FreeRTOS function.
141
142 They do that with above mentioned function
143
144 vPortYield()
145
146 When vPortYield is called your scheduler must:
147
148 - Tell the high level Scheduler of FreeRTOS to do its magic, using the
149   function
150   vTaskSwitchContext();
151
152 - You can then find out which thread is SUPPOSED to be running with the function
153   xTaskGetCurrentTaskHandle();
154
155 - Make sure that the thread calling this function SUSPENDS and the thread
156   returned by xTaskGetCurrentTaskHandle() gets executed. Be aware that they
157   could be the same in which case vPortYield does exactly NOTHING!
158
159 - This function does not return (since the current thread is sent to sleep)
160   until the scheduler makes it wake up - either by the tick handler, or by
161   another thread calling vPortYield().
162
163 - So it must not ever return until xTaskGetCurrentTaskHandle() says the
164   calling thread is the current task handle.
165
166 - Then it returns to the caller.
167
168
169
170 =====
171
172 What method you use to send threads/tasks to sleep and wake them up again is
173 up to you.
174
175 The posix implementation uses signals and a signal handler in each thread that
176 sleeps until a resume signal is received
177
178 The native STM32 implementation manually switches contexts by and uses actual
179 system interrupts
180 (so does the native x86 implementation)
181
182 The native Win32 implementation uses win32 API calls to manipulate windows
183 threads (windows actually provides a call to remote-suspend and resume a
184 thread - posix doesn't)
185
186 I have no clue what measures for thread control and suspension/interruption Qt
187 offers. (I hope there are some)
188