]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/libcdl/doc/concepts.sgml
Initial revision
[karo-tx-redboot.git] / tools / src / libcdl / doc / concepts.sgml
1 <!-- {{{ Banner                 -->
2
3 <!-- =============================================================== -->
4 <!--                                                                 -->
5 <!--     concepts.sgml                                               -->
6 <!--                                                                 -->
7 <!--     Introductory chapter.                                       -->
8 <!--                                                                 -->
9 <!-- =============================================================== -->
10 <!-- ####COPYRIGHTBEGIN####                                          -->
11 <!--                                                                 -->
12 <!-- =============================================================== -->
13 <!-- Copyright (C) 2000, 2001, 2002 Red Hat, Inc.                    -->
14 <!--                                                                 -->
15 <!-- This material may be distributed only subject to the terms      -->
16 <!-- and conditions set forth in the Open Publication License, v1.0  -->
17 <!-- or later (the latest version is presently available at          -->
18 <!-- http://www.opencontent.org/openpub/)                            -->
19 <!-- Distribution of the work or derivative of the work in any       -->
20 <!-- standard (paper) book form is prohibited unless prior           -->
21 <!-- permission obtained from the copyright holder                   -->
22 <!-- =============================================================== -->
23 <!--                                                                 -->      
24 <!-- ####COPYRIGHTEND####                                            -->
25 <!-- =============================================================== -->
26 <!-- #####DESCRIPTIONBEGIN####                                       -->
27 <!--                                                                 -->
28 <!-- Author(s):   bartv                                              -->
29 <!-- Contact(s):  bartv                                              -->
30 <!-- Date:        2000/02/06                                         -->
31 <!-- Version:     0.01                                               -->
32 <!--                                                                 -->
33 <!-- ####DESCRIPTIONEND####                                          -->
34 <!-- =============================================================== -->
35
36 <!-- }}} -->
37
38 <chapter id="overview">
39 <title>Overview</title>
40
41 <!-- {{{ Introit                --> 
42
43 <para>
44 &eCos; was designed from the very beginning as a configurable
45 component architecture. The core &eCos; system consists of a number of
46 different components such as the kernel, the C library, an
47 infrastructure package. Each of these provides a large number of
48 configuration options, allowing application developers to build a
49 system that matches the requirements of their particular application.
50 To manage the potential complexity of multiple components and lots of
51 configuration options, &eCos; comes with a component framework: a
52 collection of tools specifically designed to support configuring
53 multiple components. Furthermore this component framework is
54 extensible, allowing additional components to be added to the system
55 at any time.
56 </para>
57
58 <!-- }}} -->
59 <!-- {{{ Terminology            --> 
60
61 <sect1 id="overview.terminology">
62 <title>Terminology</title>
63 <para>
64 The &eCos; component architecture involves a number of key concepts.
65 </para>
66
67 <!-- {{{ Component Framework    -->
68
69 <sect2 id="concepts.terminology.framework">
70 <title>Component Framework</title>
71
72 <para>
73 The phrase <phrase>component framework</phrase> is used to describe
74 the collection of tools that allow users to configure a system and
75 administer a component repository. This includes the <application
76 class="software">ecosconfig</application> command line tool, the
77 graphical configuration tool, and the package administration tool.
78 Both the command line and graphical tools are based on a single
79 underlying library, the &CDL; library.
80 </para>
81
82 </sect2>
83
84 <!-- }}} -->
85 <!-- {{{ Option                 -->
86
87 <sect2 id="concepts.terminology.option">
88 <title>Configuration Option</title>
89 <para>
90 The option is the basic unit of configurability. Typically each option
91 corresponds to a single choice that a user can make. For example there
92 is an option to control whether or not assertions are enabled, and the
93 kernel provides an option corresponding to the number of scheduling
94 priority levels in the system. Options can control very small amounts
95 of code such as whether or not the C library's
96 <function>strtok</function> gets inlined. They can also control quite
97 large amounts of code, for example whether or not the
98 <function>printf</function> supports floating point conversions.
99 </para>
100 <para>
101 Many options are straightforward, and the user only gets to choose
102 whether the option is enabled or disabled. Some options are more
103 complicated, for example the number of scheduling priority levels is a
104 number that should be within a certain range. Options should always
105 start off with a sensible default setting, so that it is not necessary
106 for users to make hundreds of decisions before any work can start on
107 developing the application. Once the application is running the
108 various configuration options can be used to tune the system for the
109 specific needs of the application.
110 </para>
111 <para>
112 The component framework allows for options that are not directly
113 user-modifiable. Consider the case of processor endianness: some
114 processors are always big-endian or always little-endian, while with
115 other processors there is a choice. Depending on the user's choice of
116 target hardware, endianness may or may not be user-modifiable.
117 </para>
118 </sect2>
119
120 <!-- }}} -->
121 <!-- {{{ Component              -->
122
123 <sect2 id="concepts.terminology.component">
124 <title>Component</title>
125 <para>
126 A component is a unit of functionality such as a particular kernel
127 scheduler or a device driver for a specific device. A component is
128 also a configuration option in that users may want to enable
129 or disable all the functionality in a component. For example, if a
130 particular device on the target hardware is not going to be used by
131 the application, directly or indirectly, then there is no point in
132 having a device driver for it. Furthermore disabling the device driver
133 should reduce the memory requirements for both code and data.
134 </para>
135 <para>
136 Components may contain further configuration options. In the case of a
137 device driver, there may be options to control the exact behavior of
138 that driver. These will of course be irrelevant if the driver as a
139 whole is disabled. More generally options and components live in a
140 hierarchy, where any component can contain options specific to that
141 component and further sub-components. It is possible to view the
142 entire &eCos; kernel as one big component, containing sub-components
143 for scheduling, exception handling, synchronization primitives, and so
144 on. The synchronization primitives component can contain further
145 sub-components for mutexes, semaphores, condition variables, event
146 flags, and so on. The mutex component can contain configuration
147 options for issues like priority inversion support.
148 </para>
149 </sect2>
150
151 <!-- }}} -->
152 <!-- {{{ Package                -->
153
154 <sect2 id="concepts.terminology.package">
155 <title>Package</title>
156 <para>
157 A package is a special type of component. Specifically, a package is
158 the unit of distribution of components. It is possible to create a
159 distribution file for a package containing all of the source code,
160 header files, documentation, and other relevant files. This
161 distribution file can then be installed using the appropriate tool.
162 Afterwards it is possible to uninstall that package, or to install a
163 later version. The core &eCos; distribution comes with a number of
164 packages such as the kernel and the infrastructure. Other packages
165 such as network stacks can come from various different sources and can
166 be installed alongside the core distribution.
167 </para>
168 <para>
169 Packages can be enabled or disabled, but the user experience is a
170 little bit different. Generally it makes no sense for the tools to
171 load the details of every single package that has been installed. For
172 example, if the target hardware uses an ARM processor then there is no
173 point in loading the HAL packages for other architectures and
174 displaying choices to the user which are not relevant. Therefore
175 enabling a package means loading its configuration data into the
176 appropriate tool, and disabling a package is an unload operation. In
177 addition, packages are not just enabled or disabled: it is also
178 possible to select the particular version of a package that should be
179 used.
180 </para>
181 </sect2>
182
183 <!-- }}} -->
184 <!-- {{{ Configuration          -->
185
186 <sect2 id="concepts.terminology.configuration">
187 <title>Configuration</title>
188 <para>
189 A configuration is a collection of user choices. The various
190 tools that make up the component framework deal with entire
191 configurations. Users can create a new configuration, output a
192 savefile (by default <filename>ecos.ecc</filename>), manipulate a
193 configuration, and use a configuration to generate a build tree prior
194 to building &eCos; and any other packages that have been selected.
195 A configuration includes details such as which packages have been
196 selected, in addition to finer-grained information such as which
197 options in those packages have been enabled or disabled by the user. 
198 </para>
199 </sect2>
200
201 <!-- }}} -->
202 <!-- {{{ Target                 -->
203
204 <sect2 id="concepts.terminology.target">
205 <title>Target</title>
206 <para>
207 The target is the specific piece of hardware on which the application
208 is expected to run. This may be an off-the-shelf evaluation board, a
209 piece of custom hardware intended for a specific application, or it
210 could be something like a simulator. One of the steps when creating a
211 new configuration is need to specify the target. The component
212 framework will map this on to a set of packages that are used to
213 populate the configuration, typically HAL and device driver packages,
214 and in addition it may cause certain options to be changed from their
215 default settings to something more appropriate for the
216 specified target.
217 </para>
218 </sect2>
219
220 <!-- }}} -->
221 <!-- {{{ Template               -->
222
223 <sect2 id="concepts.terminology.template">
224 <title>Template</title>
225 <para>
226 A template is a partial configuration, aimed at providing users with
227 an appropriate starting point. &eCos; is shipped with a small number
228 of templates, which correspond closely to common ways of using the
229 system. There is a minimal template which provides very little
230 functionality, just enough to bootstrap the hardware and then jump
231 directly to application code. The default template adds additional
232 functionality, for example it causes the kernel and C library packages
233 to be loaded as well. The uitron template adds further functionality
234 in the form of a &uITRON; compatibility layer. Creating a new
235 configuration typically involves specifying a template as well as a
236 target, resulting in a configuration that can be built and linked with
237 the application code and that will run on the actual hardware. It is
238 then possible to fine-tune configuration options to produce something
239 that better matches the specific requirements of the application.
240 </para>
241 </sect2>
242
243 <!-- }}} -->
244 <!-- {{{ Properties             -->
245
246 <sect2 id="concepts.terminology.properties">
247 <title>Properties</title>
248 <para>
249 The component framework needs a certain amount of information about
250 each option. For example it needs to know what the legal values are,
251 what the default should be, where to find the on-line documentation if
252 the user needs to consult that in order to make a decision, and so on.
253 These are all properties of the option. Every option (including
254 components and packages) consists of a name and a set of properties.
255 </para>
256 </sect2>
257
258 <!-- }}} -->
259 <!-- {{{ Consequences           -->
260
261 <sect2 id="concepts.terminology.consequences">
262 <title>Consequences</title>
263 <para>
264 Choices must have consequences. For an &eCos; configuration the main
265 end product is a library that can be linked with application code, so
266 the consequences of a user choice must affect the build process. This
267 happens in two main ways. First, options can affect which files get
268 built and end up in the library. Second, details of the current option
269 settings get written into various configuration header files using C
270 preprocessor <literal>#define</literal> directives, and package source
271 code can <literal>#include</literal> these configuration headers and
272 adapt accordingly. This allows options to affect a package at a very
273 fine grain, at the level of individual lines in a source file if
274 desired. There may be other consequences as well, for example there
275 are options to control the compiler flags that get used during the
276 build process.
277 </para>
278 </sect2>
279
280 <!-- }}} -->
281 <!-- {{{ Constraints            -->
282
283 <sect2 id="concepts.terminology.constraints">
284 <title>Constraints</title>
285 <para>
286 Configuration choices are not independent. The C library can provide
287 thread-safe implementations of functions like
288 <function>rand</function>, but only if the kernel provides support for
289 per-thread data. This is a constraint: the C library option has a
290 requirement on the kernel. A typical configuration involves a
291 considerable number of constraints, of varying complexity: many
292 constraints are straightforward, option <literal>A</literal> requires
293 option <literal>B</literal>, or option <literal>C</literal> precludes
294 option <literal>D</literal>. Other constraints can be more
295 complicated, for example option <literal>E</literal> may require the
296 presence of a kernel scheduler but does not care whether it is the
297 bitmap scheduler, the mlqueue scheduler, or something else.
298 </para>
299 <para>
300 Another type of constraint involves the values that can be used for
301 certain options. For example there is a kernel option related to the
302 number of scheduling levels, and there is a legal values constraint on
303 this option: specifying zero or a negative number for the number of
304 scheduling levels makes no sense.
305 </para>
306 </sect2>
307
308 <!-- }}} -->
309 <!-- {{{ Conflicts              -->
310
311 <sect2 id="concepts.terminology.conflicts">
312 <title>Conflicts</title>
313 <para>
314 As the user manipulates options it is possible to end up with an
315 invalid configuration, where one or more constraints are not
316 satisfied. For example if kernel per-thread data is disabled but the C
317 library's thread-safety options are left enabled then there are
318 unsatisfied constraints, also known as conflicts. Such conflicts will
319 be reported by the configuration tools. The presence of conflicts does
320 not prevent users from attempting to build &eCos;, but the
321 consequences are undefined: there may be compile-time failures, there
322 may be link-time failures, the application may completely fail to run,
323 or the application may run most of the time but once in a while there
324 will be a strange failure&hellip; Typically users will want to resolve
325 all conflicts before continuing.
326 </para>
327 <para>
328 To make things easier for the user, the configuration tools contain an
329 inference engine. This can examine a conflict in a particular
330 configuration and try to figure out some way of resolving the
331 conflict. Depending on the particular tool being used, the inference
332 engine may get invoked automatically at certain times or the user may
333 need to invoke it explicitly. Also depending on the tool, the
334 inference engine may apply any solutions it finds automatically or it
335 may request user confirmation.
336 </para>
337 </sect2>
338
339 <!-- }}} -->
340 <!-- {{{ CDL                    -->
341
342 <sect2 id="concepts.terminology.cdl">
343 <title>CDL</title>
344 <para>
345 The configuration tools require information about the various options
346 provided by each package, their consequences and constraints, and
347 other properties such as the location of on-line documentation. This
348 information has to be provided in the form of &CDL; scripts. CDL
349 is short for Component Definition Language, and is specifically
350 designed as a way of describing configuration options.
351 </para>
352 <para>
353 A typical package contains the following:
354 </para>
355 <orderedlist>
356 <listitem><para>
357 Some number of source files which will end up in a library. The
358 application code will be linked with this library to produce an
359 executable. Some source files may serve other purposes, for example to
360 provide a linker script.
361 </para></listitem>
362 <listitem><para>
363 Exported header files which define the interface provided by the
364 package. 
365 </para></listitem>
366 <listitem><para>
367 On-line documentation, for example reference pages for each exported
368 function. 
369 </para></listitem>
370 <listitem><para>
371 Some number of test cases, shipped in source format, allowing users to
372 check that the package is working as expected on their particular
373 hardware and in their specific configuration.
374 </para></listitem>
375 <listitem><para>
376 One or more &CDL; scripts describing the package to the configuration
377 system.
378 </para></listitem>
379 </orderedlist>
380 <para>
381 Not all packages need to contain all of these. For example some
382 packages such as device drivers may not provide a new interface,
383 instead they just provide another implementation of an existing
384 interface. However all packages must contain a &CDL; script that
385 describes the package to the configuration tools.
386 </para>
387 </sect2>
388
389 <!-- }}} -->
390 <!-- {{{ Component Repository   -->
391
392 <sect2 id="concepts.terminology.repo">
393 <title>Component Repository</title>
394 <para>
395 All &eCos; installations include a component repository. This is a
396 directory structure where all the packages get installed. The
397 component framework comes with an administration tool that allows new
398 packages or new versions of a package to be installed, old packages to
399 be removed, and so on. The component repository includes a simple
400 database, maintained by the administration tool, which contains
401 details of the various packages.
402 </para>
403 <para>
404 Generally application developers do not need to modify anything inside
405 the component repository, except by means of the administration tool.
406 Instead their work involves separate build and install trees. This
407 allows the component repository to be treated as a read-only resource
408 that can be shared by multiple projects and multiple users. Component
409 writers modifying one of the packages do need to manipulate files in
410 the component repository.
411 </para>
412 </sect2>
413
414 <!-- }}} -->
415
416 </sect1>
417
418 <!-- }}} -->
419 <!-- {{{ Why configurability ?  --> 
420
421 <sect1 id="overview.configurability">
422 <title>Why Configurability?</title>
423 <para>
424 The &eCos; component framework places a great deal of emphasis on
425 configurability. The fundamental goal is to allow large parts of
426 embedded applications to be constructed from re-usable software
427 components, which does not a priori require that those components be
428 highly configurable. However embedded application development often
429 involves some serious constraints.
430 </para>
431 <para>
432 Many embedded applications have to work with very little memory, to
433 keep down manufacturing costs. The final application image that will
434 get blown into EPROM's or used to manufacture ROMs should contain only
435 the code that is absolutely necessary for the application to work, and
436 nothing else. If a few tens of kilobytes are added unnecessarily to a
437 typical desktop application then this is regrettable, but is quite
438 likely to go unnoticed. If an embedded application does not fit on the
439 target hardware then the problem is much more serious. The component
440 framework must allow users to configure the components so that any
441 unnecessary functionality gets removed.
442 </para>
443 <para>
444 Many embedded applications need deterministic behavior so that they
445 can meet real-time requirements. Such deterministic behavior can
446 often be provided, but at a cost in terms of code size, slower
447 algorithms, and so on. Other applications have no such real-time
448 requirements, or only for a small part of the overall system, and the
449 bulk of the system should not suffer any penalties. Again the
450 component framework must allow the users control over the timing
451 behavior of components.
452 </para>
453 <para>
454 Embedded systems tend to be difficult to debug. Even when it is
455 possible to get information out of the target hardware by means other
456 than flashing an LED, the more interesting debugging problems are
457 likely to be timing-related and hence very hard to reproduce and track
458 down. The re-usable components can provide debugging assistance in
459 various ways. They can provide functionality that can be exploited by
460 source level debuggers such as gdb, for example per-thread debugging
461 information. They can also contain various assertions so that problems
462 can be detected early on, tracing mechanisms to figure out what
463 happened before the assertion failure, and so on. Of course all of
464 these involve overheads, especially code size, and affect the timing.
465 Allowing users to control which debugging features are enabled for any
466 given application build is very desirable.
467 </para>
468 <para>
469 However, although it is desirable for re-usable components to provide
470 appropriate configuration options this is not required. It is possible
471 to produce a package which does not provide a single configuration
472 option&nbsp;&mdash;&nbsp;although the user still gets to choose
473 whether or not to use the package. In such cases it is still necessary
474 to provide a minimal CDL script, but its main purpose would be to
475 integrate the package with the component framework's build system.
476 </para>
477 </sect1>
478
479 <!-- }}} -->
480 <!-- {{{ Approaches             --> 
481
482 <sect1 id="overview.approaches">
483 <title>Approaches to Configurability</title>
484
485 <para>
486 The purpose of configurability is to control the behavior of
487 components. A scheduler component may or may not support time slicing;
488 it may or may not support multiple priorities; it may or may not
489 perform error checking on arguments passed to the scheduler routines.
490 In the context of a desktop application a button widget may contain
491 some text or it may contain a picture; the text may be displayed in a
492 variety of fonts; the foreground and background color may vary. When
493 an application uses a component there must be some way of specifying
494 the desired behavior. The component writer has no way of knowing in
495 advance exactly how a particular component will end up being used.
496 </para>
497 <para>
498 One way to control the behavior is at run time. The application
499 creates an instance of a button object, and then instructs this object
500 to display either text or a picture. No special effort by the
501 application developer is required, since a button can always support
502 all desired behavior. There is of course a major disadvantage in
503 terms of the size of the final application image: the code that gets
504 linked with the application has to provide support for all possible
505 behavior, even if the application does not require it.
506 </para>
507 <para>
508 Another approach is to control the behavior at link-time, typically
509 by using inheritance in an object-oriented language. The button
510 library provides an abstract base class <classname>Button</classname>
511 and derived classes <classname>TextButton</classname> and
512 <classname>PictureButton</classname>. If an application only uses text
513 buttons then it will only create objects of type
514 <classname>TextButton</classname>, and the code for the
515 <classname>PictureButton</classname> class does not get used. In
516 many cases this approach works rather well and reduces the final image
517 size, but there are limitations. The main one is that you can only
518 have so many derived classes before the system gets unmanageable: a
519 derived class
520 <classname>TextButtonUsingABorderWidthOfOnePlusAWhiteBackgroundAndBlackForegroundAndATwelvePointTimesFontAndNoErrorCheckingOrAssertions</classname>
521 is not particularly sensible as far as most application developers are
522 concerned.
523 </para>
524 <para>
525 The &eCos; component framework allows the behavior of components to
526 be controlled at an even earlier time: when the component source code
527 gets compiled and turned into a library. The button component could
528 provide options, for example an option that only text buttons need to
529 be supported. The component gets built and becomes part of a library
530 intended specifically for the application, and the library will
531 contain only the code that is required by this application and nothing
532 else. A different application with different requirements would need
533 its own version of the library, configured separately.
534 </para>
535 <para>
536 In theory compile-time configurability should give the best possible
537 results in terms of code size, because it allows code to be controlled
538 at the individual statement level rather than at the function or
539 object level. Consider an example more closely related to embedded
540 systems, a package to support multi-threading. A standard routine
541 within such a package allows applications to kill threads
542 asynchronously: the POSIX routine for this is
543 <function>pthread_cancel</function>; the equivalent routine in &uITRON;
544 is <function>ter_tsk</function>. These routines themselves tend to
545 involve a significant amount of code, but that is not the real
546 problem: other parts of the system require extra code and data for the
547 kill routine to be able to function correctly. For example if a thread
548 is blocked while waiting on a mutex and is killed off by another
549 thread then the kill operation may have to do two things: remove the
550 thread from the mutex's queue of waiting threads; and undo the
551 effects, if any, of priority inheritance. The implementation requires
552 extra fields in the thread data structure so that the kill routine
553 knows about the thread's current state, and extra code in the mutex
554 routines to fill in and clear these extra fields correctly.
555 </para>
556 <para>
557 Most embedded applications do not require the ability to kill off a
558 thread asynchronously, and hence the kill routine will not get linked
559 into the final application image. Without compile-time configurability
560 this would still mean that the mutex code and similar parts of the
561 system contain code and data that serve no useful purpose in this
562 application. The &eCos; approach allows the user to select that the
563 thread kill functionality is not required, and all the components can
564 adapt to this at compile-time. For example the code in the mutex lock
565 routine contains statements to support the killing of threads, but
566 these statements will only get compiled in if that functionality is
567 required. The overall result is that the final application image
568 contains only the code and data that is really needed for the
569 application to work, and nothing else.
570 </para>
571 <para>
572 Of course there are complications. To return to the button example,
573 the application code might only use text buttons directly, but it
574 might also use some higher-level widget such as a file selector and
575 this file selector might require buttons with pictures. Therefore the
576 button code must still be compiled to support pictures as well as
577 text. The configuration tools must be aware of the dependencies
578 between components and ensure that the internal constraints are met,
579 as well as the external requirements of the application code. An area
580 of particular concern is conflicting requirements: a button component
581 might be written in such a way that it can only support either text
582 buttons or picture buttons, but not both in one application; this
583 would represent a weakness in the component itself rather than in the
584 component framework as a whole.
585 </para>
586 <para>
587 Compile-time configurability is not intended to replace the other
588 approaches but rather to complement them. There will be times when
589 run-time selection of behavior is desirable: for example an
590 application may need to be able to change the baud rate of a serial
591 line, and the system must then provide a way of doing this at
592 run-time. There will also be times when link-time selection is
593 desirable: for example a C library might provide two different random
594 number routines <function>rand</function> and
595 <function>lrand48</function>; these do not affect other code so there
596 is no good reason for the C library component not to provide both of
597 these, and allow the application code to use none, one, or both of
598 them as appropriate; any unused functions will just get eliminated at
599 link-time. Compile-time selection of behavior is another option, and
600 it can be the most powerful one of the three and the best suited to
601 embedded systems development.
602 </para>
603
604 </sect1>
605
606 <!-- }}} -->
607 <!-- {{{ Degrees                -->
608
609 <sect1 id="overview.degress">
610 <title>Degrees of Configurability</title>
611
612 <para>
613 Components can support configurability in varying degrees. It is not
614 necessary to have any configuration options at all, and the only user
615 choice is whether or not to load a particular package. Alternatively
616 it is possible to implement highly-configurable code. As an example
617 consider a typical facility that is provided by many real-time
618 kernels, mutex locks. The possible configuration options include:
619 </para>
620
621 <orderedlist>
622
623 <listitem>
624 <para>
625 If no part of the application and no other component requires mutexes
626 then there is no point in having the mutex code compiled into a
627 library at all. This saves having to compile the code. In addition
628 there will never be any need for the user to configure the detailed
629 behavior of mutexes. Therefore the presence of mutexes is a
630 configuration option in itself.
631 </para>
632 </listitem>
633
634 <listitem>
635 <para>
636 Even if the application does make use of mutexes directly or
637 indirectly, this does not mean that all mutex functions have to be
638 included. The minimum functionality consists of lock and unlock
639 functions. However there are variants of the locking primitive such as
640 try-lock and try-with-timeout which may or may not be needed.
641 </para>
642 <para>
643 Generally it will be harmless to compile the try-lock function even if
644 it is not actually required, because the function will get eliminated
645 at link-time. Some users might take the view that the try-lock
646 function should never get compiled in unless it is actually needed, to
647 reduce compile-time and disk usage. Other users might argue that there
648 are very few valid uses for a try-lock function and it should not be
649 compiled by default to discourage incorrect uses. The presence of a
650 try-lock function is a possible configuration option, although it may
651 be sensible to default it to true.
652 </para>
653 <para>
654 The try-with-timeout variant is more complicated because it adds a
655 dependency: the mutex code will now rely on some other component to
656 provide a timer facility. To make things worse the presence of this
657 timer might impact other components, for example it may now be
658 necessary to guard against timer interrupts, and thus have an
659 insidious effect on code size. The presence of a lock-with-timeout
660 function is clearly a sensible configuration option, but the default
661 value is less obvious. If the option is enabled by default then the
662 final application image may end up with code that is not actually
663 essential. If the option is disabled by default then users will have
664 to enable the option somehow in order to use the function, implying
665 more effort on the part of the user. One possible approach is to
666 calculate the default value based on whether or not a timer component
667 is present anyway.
668 </para>
669 </listitem>
670
671 <listitem>
672 <para>
673 The application may or may not require the ability to create and
674 destroy mutexes dynamically. For most embedded systems it is both less
675 error-prone and more efficient to create objects like mutexes
676 statically. Dynamic creation of mutexes can be implemented using a
677 pre-allocated pool of mutex objects, involving some extra code to
678 manipulate the pool and an additional configuration option to define
679 the size of the pool. Alternatively it can be implemented using a
680 general-purpose memory allocator, involving quite a lot of extra code
681 and configuration options. However this general-purpose memory
682 allocator may be present anyway to support the application itself or
683 some other component. The ability to create and destroy mutexes
684 dynamically is a configuration option, and there may not be a sensible
685 default that is appropriate for all applications.
686 </para>
687 </listitem>
688
689 <listitem>
690 <para>
691 An important issue for mutex locks is the handling of priority
692 inversion, where a high priority thread is prevented from running
693 because it needs a lock owned by a lower priority thread. This is only
694 an issue if there is a scheduler with multiple priorities: some
695 systems may need multi-threading and hence synchronization primitives,
696 but a single priority level may suffice. If priority inversion is a
697 theoretical possibility then the application developer may still want
698 to ignore it because the application has been designed such that the
699 problem cannot arise in practice. Alternatively the developer may want
700 some sort of exception raised if priority inversion does occur,
701 because it should not happen but there may still be bugs in the code.
702 If priority inversion can occur legally then there are three main ways
703 of handling it: priority ceilings, priority inheritance, and ignoring
704 the problem. Priority ceilings require little code but extra effort on
705 the part of the application developer. Priority inheritance requires
706 more code but is automatic. Ignoring priority inversion may or may not
707 be acceptable, depending on the application and exactly when priority
708 inversion can occur. Some of these choices involve additional
709 configuration options, for example there are different ways of raising
710 an exception, and priority inheritance may or may not be applied
711 recursively.
712 </para>
713 </listitem>
714
715 <listitem>
716 <para>
717 As a further complication some mutexes may be hidden inside a
718 component rather than being an explicit part of the application. For
719 example, if the C library is configured to provide a
720 <function>malloc</function> call then there may be an associated mutex
721 to make the function automatically thread-safe, with no need for
722 external locking. In such cases the memory allocation component of the
723 C library can impose a constraint on the kernel, requiring that
724 mutexes be provided. If the user attempts to disable mutexes anyway
725 then the configuration tools will report a conflict.
726 </para>
727 </listitem>
728
729 <listitem>
730 <para>
731 The mutex code should contain some general debugging code such as
732 assertions and tracing. Usually such debug support will be enabled or
733 disabled at a coarse level such as the entire system or everything
734 inside the kernel, but sometimes it will be desirable to enable the
735 support more selectively. One reason would be memory requirements: the
736 target may not have enough memory to hold the system if all debugging
737 is enabled. Another reason is if most of the system is working but
738 there are a few problems still to resolved; enabling debugging in the
739 entire system might change the system's timing behavior too much, but
740 enabling some debug options selectively can still be useful. There
741 should be configuration options to allow specific types of debugging
742 to be enabled at a fine-grain, but with default settings inherited
743 from an enclosing component or from global settings.
744 </para>
745 </listitem>
746
747 <listitem>
748 <para>
749 The mutex code may contain specialized code to interact
750 with a debugging tool running on the host. It should be
751 possible to enable or disable this debugging code, and there may
752 be additional configuration options controlling the detailed
753 behavior.
754 </para>
755 </listitem>
756
757 </orderedlist>
758
759 <para>
760 Altogether there may be something like ten to twenty configuration
761 options that are specific to the mutex code. There may be a similar
762 number of additional options related to assertions and other debug
763 facilities. All of the options should have sensible default values,
764 possibly fixed, possibly calculated depending on what is happening
765 elsewhere in the configuration. For example the default setting for
766 an assertion option should generally inherit from a kernel-wide
767 assertion control option, which in turn inherits from a global option.
768 This allows users to enable or disable assertions globally or at
769 a more fine-grained level, as desired.
770 </para>
771 <para>
772 Different components may be configurable to different degrees, ranging
773 from no options at all to the fine-grained configurability of the
774 above mutex example (or possibly even further). It is up to component
775 writers to decide what options should be provided and how best to
776 serve the needs of application developers who want to use that
777 component.
778 </para>
779 </sect1>
780
781 <!-- }}} -->
782 <!-- {{{ Warning                -->
783
784 <sect1 id="overview.warning">
785 <title>Warnings</title>
786 <para>
787 Large parts of &eCos; were developed concurrently with the development
788 of the configuration technology, or in some cases before design work
789 on that technology was complete. As a consequence the various &eCos;
790 packages often make only limited use of the available functionality.
791 This situation is expected to change over time. It does mean that many
792 of the descriptions in this guide will not correspond exactly to how
793 the &eCos; packages work right now, but rather to how they could work.
794 Some of the more extreme discrepancies such as the location of on-line
795 documentation in the component repository will be mentioned in the
796 appropriate places in the guide.
797 </para>
798 <para>
799 A consequence of this is that developers of new components can look at
800 existing &CDL; scripts for examples, and discover discrepancies
801 between what is recommended in this guide and what actually happens at
802 present. In such cases this guide should be treated as authoritative.
803 </para>
804 <para>
805 It is also worth noting that the current component framework is not
806 finished. Various parts of this guide will refer to possible changes
807 and enhancements in future versions. Examining the source code of the
808 configuration tools may reveal hints about other likely developments,
809 and there are many more possible enhancements which only exist at a
810 conceptual level right now.
811 </para>
812
813 </sect1>
814
815 <!-- }}} -->
816
817 </chapter>