1 | Using the RTEMS Scheduler Simulator |
---|
2 | =================================== |
---|
3 | :doctype: book |
---|
4 | :toc3: |
---|
5 | :toclevels: 3 |
---|
6 | :icons: |
---|
7 | :numbered: |
---|
8 | |
---|
9 | Joel Sherrill <joel.sherrill@oarcorp.com> |
---|
10 | |
---|
11 | 1.0, 5 May 2013 |
---|
12 | |
---|
13 | Introduction |
---|
14 | ------------ |
---|
15 | The Scheduler Simulator is designed allow one to debug and validate an |
---|
16 | algorithm before attempting to execute it in the more complex environment |
---|
17 | of the actual RTEMS run-time on real hardware or a CPU simulator. |
---|
18 | The Scheduler Simulator script language is designed to produce very |
---|
19 | reproducible event sequences which may not be easy to do with the |
---|
20 | scheduler and a real set of tasks. |
---|
21 | |
---|
22 | The Scheduler Simulator consists of a subset of the RTEMS SuperCore, |
---|
23 | Classic API, Shell, and a set of custom commands to access particular |
---|
24 | services. These are provided in the form of a library which can be |
---|
25 | utilized to instance scheduler simulator variants for custom algorithms. |
---|
26 | |
---|
27 | Checking out from Source Code Repository |
---|
28 | ---------------------------------------- |
---|
29 | |
---|
30 | The RTEMS Scheduler Simulator is in its own CVS module named |
---|
31 | rtems-schedsim in the RTEMS git Repository. It can be cloned as follows: |
---|
32 | |
---|
33 | ------------------------------------------------------------- |
---|
34 | git://git.rtems.org/rtems-schedsim.git |
---|
35 | ------------------------------------------------------------- |
---|
36 | |
---|
37 | The source code must then be bootstrapped using the bootstrap script from |
---|
38 | the RTEMS source tree. After this is complete, it can be configured |
---|
39 | and built outside the source tree like RTEMS itself. The following is |
---|
40 | an example bootstrap and configure command invocation: |
---|
41 | |
---|
42 | ------------------------------------------------------------- |
---|
43 | # â$râ is an environment variable which points to top of RTEMS source tree |
---|
44 | $ cd rtems-schedsim/ |
---|
45 | $ $r/bootstrap |
---|
46 | . |
---|
47 | configure.ac:18: installing `./config.guess' |
---|
48 | configure.ac:18: installing `./config.sub' |
---|
49 | configure.ac:19: installing `./install-sh' |
---|
50 | configure.ac:19: installing `./missing' |
---|
51 | ./schedsim |
---|
52 | rtems/Makefile.am: installing `../depcomp' |
---|
53 | $ cd .. |
---|
54 | $ mkdir b-schedsim |
---|
55 | $ cd b-schedsim |
---|
56 | $ ../rtems-schedsim/configure --enable-maintainer-mode --prefix=/tmp/schedsim \ |
---|
57 | --enable-rtemsdir=/home/joel/rtems-4.11-work/build/rtems |
---|
58 | ------------------------------------------------------------- |
---|
59 | |
---|
60 | Unless the 'âenable-smp' option is specified, it will not build the |
---|
61 | scheduler simulator instance for the Simple SMP Scheduler which is |
---|
62 | located in the schedsim/shell/schedsim_smpsimple subdirectory. |
---|
63 | |
---|
64 | After the tree is configured, it is a normal 'make' and 'make install' to |
---|
65 | build and install the RTEMS Scheduler Simulator. |
---|
66 | |
---|
67 | There are currently two scheduler simulator instances in this source |
---|
68 | tree. They are located in: |
---|
69 | |
---|
70 | * schedsim/shell/schedsim_smpsimple â Simple SMP Scheduler |
---|
71 | * schedsim/shell/schedsim_priority â Deterministic Priority Schedulers |
---|
72 | |
---|
73 | Under each is a directory named 'scenarios' with .scen files and |
---|
74 | .expected files. To run a single scenario, something like this works |
---|
75 | when in 'schedsim_priority'. |
---|
76 | |
---|
77 | The scenarios are in the source tree and the binary is in the build tree. |
---|
78 | This results in the simulator name often requiring a full path to execute. |
---|
79 | |
---|
80 | ------------------------------------------------------------- |
---|
81 | $ cd |
---|
82 | /home/joel/rtems-4.11-work/build/rtems-schedsim/schedsim/shell/schedsim_priority |
---|
83 | $ ../../../../b-schedsim/schedsim/shell/schedsim_priority/schedsim \ |
---|
84 | scenarios/script06.scen |
---|
85 | ------------------------------------------------------------- |
---|
86 | |
---|
87 | There is a script in the directory 'rtems-schedsim/schedsim/shell' named |
---|
88 | 'run_scenarios' which can run all or a subset of scenarios and tell you |
---|
89 | if they pass or fail. It must be provided with the name of the Scheduler |
---|
90 | Simulator instance to invoke. |
---|
91 | |
---|
92 | ------------------------------------------------------------- |
---|
93 | $ pwd |
---|
94 | /home/joel/rtems-4.11-work/build/rtems-schedsim/schedsim/shell/schedsim_priority |
---|
95 | $ ../run_scenarios -A \ |
---|
96 | -s ../../../../b-schedsim/schedsim/shell/schedsim_priority/schedsim_priority/schedsim_priority |
---|
97 | PASS - scenarios/script01.scen |
---|
98 | PASS - scenarios/script02.scen |
---|
99 | PASS - scenarios/script03.scen |
---|
100 | PASS - scenarios/script04.scen |
---|
101 | PASS - scenarios/script05.scen |
---|
102 | PASS â scenarios/script06.scen |
---|
103 | ------------------------------------------------------------- |
---|
104 | |
---|
105 | The first time you run a scenario, there is no output to check against |
---|
106 | and the script will echo the cp command line required to turn the actual |
---|
107 | output into the expected output file. |
---|
108 | |
---|
109 | Scripting Language |
---|
110 | ------------------ |
---|
111 | The Scheduler Simulator has a small command set which is designed to |
---|
112 | allow the scheduler implementer to write simple script files to exercise |
---|
113 | a scheduling algorithm. |
---|
114 | |
---|
115 | This chapter describes each of these commands and their common |
---|
116 | characteristics. Examples were executed using the Scheduler Simulator |
---|
117 | found in examples-v2/schedsim/schedsim_priority. Any lines of output |
---|
118 | from this simulator instance which start with 'Thread Heir' and |
---|
119 | 'Thread Executing' are printed by the '_Thread_Dispatch' wrapper |
---|
120 | |
---|
121 | Common Characteristics |
---|
122 | ~~~~~~~~~~~~~~~~~~~~~~ |
---|
123 | The commands use arguments of similar types. This section describes |
---|
124 | the command characteristics of the commands. |
---|
125 | |
---|
126 | Task Names |
---|
127 | ^^^^^^^^^^ |
---|
128 | Multiple commands take task names. The task names are of Classic API |
---|
129 | form. They can be up to four characters. They should not start with "0" |
---|
130 | since that is the test used to determine if it is a hexadecimal task id. |
---|
131 | |
---|
132 | Commands |
---|
133 | ~~~~~~~~ |
---|
134 | The commands supported by the RTEMS Scheduler Simulator are described |
---|
135 | in this section. |
---|
136 | |
---|
137 | echo Command |
---|
138 | ^^^^^^^^^^^^ |
---|
139 | *Usage*: echo [ARGS] |
---|
140 | |
---|
141 | This methods prints all of the arguments on its command line to standard |
---|
142 | output followed by a new line. |
---|
143 | |
---|
144 | help Command |
---|
145 | ^^^^^^^^^^^^^ |
---|
146 | *Usage*: help [topic|command] |
---|
147 | |
---|
148 | This command is used to obtain information on commands within a category |
---|
149 | (e.g. misc, rtems, etc.) or on a specific command. |
---|
150 | |
---|
151 | exit Command |
---|
152 | ^^^^^^^^^^^^ |
---|
153 | *Usage*: exit |
---|
154 | |
---|
155 | This command is used to exit the Scheduler Simulator. |
---|
156 | |
---|
157 | rtems_init Command |
---|
158 | ^^^^^^^^^^^^^^^^^^ |
---|
159 | *Usage*: rtems_init |
---|
160 | |
---|
161 | This command initializes RTEMS using the configuration provided. |
---|
162 | |
---|
163 | task_create Command |
---|
164 | ^^^^^^^^^^^^^^^^^^^ |
---|
165 | *Usage*: task_create name priority |
---|
166 | |
---|
167 | This command creates and starts a Classic API task with the specified name |
---|
168 | and initial priority. It also starts the task. This is the equivalent |
---|
169 | of the rtems_task_create and rtems_task_start Classic API directives. |
---|
170 | The following is the output from the invocation 'task_create joel 5': |
---|
171 | |
---|
172 | ------------------------------------------------------------- |
---|
173 | Task (joel) created: id=0x0a010001, priority=5 |
---|
174 | Task (joel) starting: id=0x0a010001, priority=5 |
---|
175 | Thread Heir: 0x0a010001 priority=5 |
---|
176 | Thread Executing: 0x0a010001 priority=5 |
---|
177 | ------------------------------------------------------------- |
---|
178 | |
---|
179 | task_delete Command |
---|
180 | ^^^^^^^^^^^^^^^^^^^ |
---|
181 | *Usage*: task_delete name|id |
---|
182 | |
---|
183 | This command deletes the specified task. It is the equivalent of the |
---|
184 | rtems_task_delete directive in the Classic API. |
---|
185 | |
---|
186 | The following is the output from the invocation task_delete joel : |
---|
187 | |
---|
188 | ------------------------------------------------------------- |
---|
189 | Thread Heir: 0x09010001 priority=255 |
---|
190 | Thread Executing: 0x09010001 priority=255 |
---|
191 | Task (0x0a010001) deleted |
---|
192 | ------------------------------------------------------------- |
---|
193 | |
---|
194 | task_mode Command |
---|
195 | ^^^^^^^^^^^^^^^^^ |
---|
196 | *Usage*: task_mode [-tTpP] |
---|
197 | |
---|
198 | This command is used to modified the current mode of the currently |
---|
199 | executing task. It is the equivalent of the rtems_task_mode directive |
---|
200 | in the Classic API. |
---|
201 | |
---|
202 | The command line arguments are processed as follows: |
---|
203 | |
---|
204 | * -t - disable timeslicing |
---|
205 | * -T - enable timeslicing |
---|
206 | * -p - disable preemption |
---|
207 | * -p - enable preemption |
---|
208 | |
---|
209 | task_priority Command |
---|
210 | ^^^^^^^^^^^^^^^^^^^^^ |
---|
211 | *Usage*: task_set_priority name|id priority |
---|
212 | |
---|
213 | This command is used to modified the current priority of the currently |
---|
214 | executing task. It is the equivalent of the rtems_task_priority directive |
---|
215 | in the Classic API. When priority is 0, then the current priority of |
---|
216 | the specified task is returned. |
---|
217 | |
---|
218 | The following is the output from the invocation task_priority joel 0: |
---|
219 | |
---|
220 | ------------------------------------------------------------- |
---|
221 | Task (0x0a010001) Current Priority is 0 |
---|
222 | ------------------------------------------------------------- |
---|
223 | |
---|
224 | The following is the output from the invocation task_priority joel 5: |
---|
225 | |
---|
226 | ------------------------------------------------------------- |
---|
227 | Task (0x0a010001) Change Priority from 1 to 5 |
---|
228 | ------------------------------------------------------------- |
---|
229 | |
---|
230 | task_resume Command |
---|
231 | ^^^^^^^^^^^^^^^^^^^ |
---|
232 | *Usage*: task_resume name|id |
---|
233 | |
---|
234 | This command is used to suspend the specified task. It is the equivalent |
---|
235 | of the rtems_task_suspend directive in the Classic API. |
---|
236 | |
---|
237 | task_suspend Command |
---|
238 | ^^^^^^^^^^^^^^^^^^^^ |
---|
239 | *Usage*: task_suspend name|id |
---|
240 | |
---|
241 | This command is used to resume the specified task. It is the equivalent |
---|
242 | of the rtems_task_resume directive in the Classic API. |
---|
243 | |
---|
244 | task_wake_after Command |
---|
245 | ^^^^^^^^^^^^^^^^^^^^^^^ |
---|
246 | *Usage*: task_wake_after ticks |
---|
247 | |
---|
248 | This command is used to cause the currently executing task to sleep |
---|
249 | for the specified number of ticks. It is the equivalent of the |
---|
250 | rtems_task_wake_after directive in the Classic API. |
---|
251 | |
---|
252 | clock_tick Command |
---|
253 | ^^^^^^^^^^^^^^^^^^ |
---|
254 | *Usage*: clock_tick ticks |
---|
255 | This command is used to cause the specified number of ticks to pass. |
---|
256 | |
---|
257 | It is the equivalent of calling the rtems_clock_tick directive tick |
---|
258 | times in the Classic API. |
---|
259 | |
---|
260 | semaphore_create Command |
---|
261 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
---|
262 | *Usage*: semaphore_create [-bcsfpiC:V:] name |
---|
263 | |
---|
264 | This method creates a semaphore named name with the specified attributes. It is the equivalent of the rtems_semaphore_create directive in the Classic API. |
---|
265 | |
---|
266 | The command line arguments are processed as follows: |
---|
267 | |
---|
268 | * -b - binary mutex |
---|
269 | * -c - counting semaphore |
---|
270 | * -s - simple binary semaphore |
---|
271 | * -f - FIFO Blockin* |
---|
272 | * -p - Priority Blocking |
---|
273 | * -i - Priority Inheritance |
---|
274 | * -C priority - Priority Ceiling and priority |
---|
275 | * -V initial - Initial value (default=0) |
---|
276 | |
---|
277 | semaphore_delete Command |
---|
278 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
---|
279 | *Usage*: semaphore_delete name|id |
---|
280 | |
---|
281 | This method deletes the specified semaphore. It is the equivalent of |
---|
282 | the rtems_semaphore_delete directive in the Classic API. |
---|
283 | |
---|
284 | semaphore_obtain Command |
---|
285 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
---|
286 | *Usage*: semaphore_obtain name|id ticks |
---|
287 | |
---|
288 | This method causes the currently executing thread to attempt to obtain the |
---|
289 | specified semaphore. It is the equivalent of the rtems_semaphore_obtain |
---|
290 | directive in the Classic API. |
---|
291 | |
---|
292 | *NOTE*: no polling supported yet |
---|
293 | |
---|
294 | semaphore_release Command |
---|
295 | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
---|
296 | *Usage*: semaphore_release name|id |
---|
297 | |
---|
298 | This method causes the currently executing thread to release the specified |
---|
299 | semaphore. It is the equivalent of the rtems_semaphore_release directive |
---|
300 | in the Classic API. |
---|
301 | |
---|
302 | semaphore_flush Command |
---|
303 | ^^^^^^^^^^^^^^^^^^^^^^^ |
---|
304 | *Usage*: semaphore_flush name|id |
---|
305 | |
---|
306 | This method causes the currently executing thread to flush the specified |
---|
307 | semaphore. It is the equivalent of the rtems_semaphore_flush directive |
---|
308 | in the Classic API. |
---|
309 | |
---|
310 | |
---|
311 | executing Command |
---|
312 | ^^^^^^^^^^^^^^^^^ |
---|
313 | *Usage*: executing |
---|
314 | |
---|
315 | This method prints information on the currently executing task. |
---|
316 | |
---|
317 | heir Command |
---|
318 | ^^^^^^^^^^^^ |
---|
319 | *Usage*: heir |
---|
320 | |
---|
321 | This method prints information on the current heir task(s). |
---|
322 | |
---|
323 | Constructing Your Own Scheduler Simulator |
---|
324 | ----------------------------------------- |
---|
325 | The Scheduler Simulator Framework is provided in the form of a library |
---|
326 | which can be utilized to instance scheduler simulator variants for |
---|
327 | custom algorithms. |
---|
328 | |
---|
329 | If developing a scheduler for possible inclusion in the main RTEMS source |
---|
330 | code, then you will want to construct the simulator in the 'rtems-schedsim' |
---|
331 | tree following the examples that are already present. |
---|
332 | |
---|
333 | However, it it also possible to construct a Scheduler Simulator instance |
---|
334 | outside the rtems-schedsim source tree. The directory schedsim in |
---|
335 | the git module 'examples-v2' is a minimal example of doing this. It is |
---|
336 | based on an installed copy of the RTEMS Scheduler Simulator and uses |
---|
337 | the default Deterministic Priority Scheduler in RTEMS. It provides the |
---|
338 | following files: |
---|
339 | |
---|
340 | * config.c - RTEMS Configuration Instance |
---|
341 | * Makefile - instructions on building |
---|
342 | * printheir_executing.c - custom versions of PRINT_EXECUTING() and |
---|
343 | PRINT_HEIR() |
---|
344 | * README - overview of directory contents |
---|
345 | * schedsim.cc - main() for custom Scheduler Simulator instance |
---|
346 | * wrap_thread_dispatch.c - wrap method for _Thread_Dispatch so script |
---|
347 | output can include information on when context switches occur. |
---|
348 | |
---|
349 | When compiled, it produces an executable schedsim which has the following usage: |
---|
350 | |
---|
351 | ------------------------------------------------------------- |
---|
352 | Usage: ./schedsim [-v] script |
---|
353 | -v - enable verbose output |
---|
354 | ------------------------------------------------------------- |
---|
355 | |
---|
356 | When invoked with '/dev/stdin' as the script, one can enter commands |
---|
357 | interactively. The primary use case expected however is to use predefined |
---|
358 | scripts to exercise specific schedulers. For example, this is the |
---|
359 | contents of the script 'rtems/tools/schedsim/shell/scripts/script01' from |
---|
360 | the RTEMS Scheduler Simulator source: |
---|
361 | |
---|
362 | ------------------------------------------------------------- |
---|
363 | echo "*** TEST 01 ***" |
---|
364 | rtems_init |
---|
365 | echo "=== Create and delete 0x0a010001 ===" |
---|
366 | task_create TA1 3 |
---|
367 | task_delete TA1 |
---|
368 | echo "=== Create and delete 0x0a010002 ===" |
---|
369 | task_create TA1 3 |
---|
370 | task_delete 0x0a010002 |
---|
371 | echo "*** END OF TEST 01 ***" |
---|
372 | exit |
---|
373 | # We will not get here |
---|
374 | ------------------------------------------------------------- |
---|
375 | |
---|
376 | This test initializes the RTEMS simulator, creates and deletes two tasks, |
---|
377 | and then exits. When executed, the following output is generated: |
---|
378 | |
---|
379 | ------------------------------------------------------------- |
---|
380 | *** TEST 01 *** |
---|
381 | Thread Heir: 0x09010001 priority=255 |
---|
382 | Thread Executing: 0x09010001 priority=255 |
---|
383 | === Create and delete 0x0a010001 === |
---|
384 | Task (TA1) created: id=0x0a010001, priority=3 |
---|
385 | Task (TA1) starting: id=0x0a010001, priority=3 |
---|
386 | Thread Heir: 0x0a010001 priority=3 |
---|
387 | Thread Executing: 0x0a010001 priority=3 |
---|
388 | Thread Heir: 0x09010001 priority=255 |
---|
389 | Thread Executing: 0x09010001 priority=255 |
---|
390 | Task (0x0a010001) deleted |
---|
391 | === Create and delete 0x0a010002 === |
---|
392 | Task (TA1) created: id=0x0a010002, priority=3 |
---|
393 | Task (TA1) starting: id=0x0a010002, priority=3 |
---|
394 | Thread Heir: 0x0a010002 priority=3 |
---|
395 | Thread Executing: 0x0a010002 priority=3 |
---|
396 | Thread Heir: 0x09010001 priority=255 |
---|
397 | Thread Executing: 0x09010001 priority=255 |
---|
398 | Task (0x0a010002) deleted |
---|
399 | *** END OF TEST 01 *** |
---|
400 | ------------------------------------------------------------- |
---|
401 | |
---|
402 | This example uses a scheduler provided with RTEMS. If you are developing |
---|
403 | your own scheduler, then you will have to include the scheduler in |
---|
404 | your build and configure it just as if doing so as part of a regular |
---|
405 | RTEMS application. The following configuration directives will need to |
---|
406 | be specified: |
---|
407 | |
---|
408 | The pluggable scheduler interface was added after the 4.10 release series |
---|
409 | so there are not a lot of options at this point. We anticipate a lower |
---|
410 | memory, non-deterministic priority scheduler suitable for use in small |
---|
411 | systems and an Earliest Deadline First Scheduler (EDF) to arrive in |
---|
412 | the future. |
---|
413 | |
---|
414 | The pluggable scheduler interface enables the user to provide their own |
---|
415 | scheduling algorithm. If you choose to do this, you must define multiple |
---|
416 | configuration macros. The following information on specifying a user |
---|
417 | provided scheduler is from the 'Configuring a System' chapter of |
---|
418 | the RTEMS User's Guide. |
---|
419 | |
---|
420 | First, you must define CONFIGURE_SCHEDULER_USER to indicate |
---|
421 | the application provides its own scheduling algorithm. If |
---|
422 | +CONFIGURE_SCHEDULER_USER+ is defined then the following additional macros |
---|
423 | must be defined: |
---|
424 | |
---|
425 | * +CONFIGURE_SCHEDULER_USER_ENTRY_POINTS+ must be defined with the set of |
---|
426 | methods which implement this scheduler. |
---|
427 | * +CONFIGURE_MEMORY_FOR_SCHEDULER+ must be defined with the amount of |
---|
428 | memory required as a base amount for the scheduler. |
---|
429 | * +CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER(_tasks)+ must be defined as |
---|
430 | a formula which computes the amount of memory required based upon the |
---|
431 | number of tasks configured. |
---|
432 | |
---|