📄 concepts.sgml
字号:
kill routine to be able to function correctly. For example if a threadis blocked while waiting on a mutex and is killed off by anotherthread then the kill operation may have to do two things: remove thethread from the mutex's queue of waiting threads; and undo theeffects, if any, of priority inheritance. The implementation requiresextra fields in the thread data structure so that the kill routineknows about the thread's current state, and extra code in the mutexroutines to fill in and clear these extra fields correctly.</para><para>Most embedded applications do not require the ability to kill off athread asynchronously, and hence the kill routine will not get linkedinto the final application image. Without compile-time configurabilitythis would still mean that the mutex code and similar parts of thesystem contain code and data that serve no useful purpose in thisapplication. The &eCos; approach allows the user to select that thethread kill functionality is not required, and all the components canadapt to this at compile-time. For example the code in the mutex lockroutine contains statements to support the killing of threads, butthese statements will only get compiled in if that functionality isrequired. The overall result is that the final application imagecontains only the code and data that is really needed for theapplication to work, and nothing else.</para><para>Of course there are complications. To return to the button example,the application code might only use text buttons directly, but itmight also use some higher-level widget such as a file selector andthis file selector might require buttons with pictures. Therefore thebutton code must still be compiled to support pictures as well astext. The configuration tools must be aware of the dependenciesbetween components and ensure that the internal constraints are met,as well as the external requirements of the application code. An areaof particular concern is conflicting requirements: a button componentmight be written in such a way that it can only support either textbuttons or picture buttons, but not both in one application; thiswould represent a weakness in the component itself rather than in thecomponent framework as a whole.</para><para>Compile-time configurability is not intended to replace the otherapproaches but rather to complement them. There will be times whenrun-time selection of behavior is desirable: for example anapplication may need to be able to change the baud rate of a serialline, and the system must then provide a way of doing this atrun-time. There will also be times when link-time selection isdesirable: for example a C library might provide two different randomnumber routines <function>rand</function> and<function>lrand48</function>; these do not affect other code so thereis no good reason for the C library component not to provide both ofthese, and allow the application code to use none, one, or both ofthem as appropriate; any unused functions will just get eliminated atlink-time. Compile-time selection of behavior is another option, andit can be the most powerful one of the three and the best suited toembedded systems development.</para></sect1><!-- }}} --><!-- {{{ Degrees --><sect1 id="overview.degress"><title>Degrees of Configurability</title><para>Components can support configurability in varying degrees. It is notnecessary to have any configuration options at all, and the only userchoice is whether or not to load a particular package. Alternativelyit is possible to implement highly-configurable code. As an exampleconsider a typical facility that is provided by many real-timekernels, mutex locks. The possible configuration options include:</para><orderedlist><listitem><para>If no part of the application and no other component requires mutexesthen there is no point in having the mutex code compiled into alibrary at all. This saves having to compile the code. In additionthere will never be any need for the user to configure the detailedbehavior of mutexes. Therefore the presence of mutexes is aconfiguration option in itself.</para></listitem><listitem><para>Even if the application does make use of mutexes directly orindirectly, this does not mean that all mutex functions have to beincluded. The minimum functionality consists of lock and unlockfunctions. However there are variants of the locking primitive such astry-lock and try-with-timeout which may or may not be needed.</para><para>Generally it will be harmless to compile the try-lock function even ifit is not actually required, because the function will get eliminatedat link-time. Some users might take the view that the try-lockfunction should never get compiled in unless it is actually needed, toreduce compile-time and disk usage. Other users might argue that thereare very few valid uses for a try-lock function and it should not becompiled by default to discourage incorrect uses. The presence of atry-lock function is a possible configuration option, although it maybe sensible to default it to true.</para><para>The try-with-timeout variant is more complicated because it adds adependency: the mutex code will now rely on some other component toprovide a timer facility. To make things worse the presence of thistimer might impact other components, for example it may now benecessary to guard against timer interrupts, and thus have aninsidious effect on code size. The presence of a lock-with-timeoutfunction is clearly a sensible configuration option, but the defaultvalue is less obvious. If the option is enabled by default then thefinal application image may end up with code that is not actuallyessential. If the option is disabled by default then users will haveto enable the option somehow in order to use the function, implyingmore effort on the part of the user. One possible approach is tocalculate the default value based on whether or not a timer componentis present anyway.</para></listitem><listitem><para>The application may or may not require the ability to create anddestroy mutexes dynamically. For most embedded systems it is both lesserror-prone and more efficient to create objects like mutexesstatically. Dynamic creation of mutexes can be implemented using apre-allocated pool of mutex objects, involving some extra code tomanipulate the pool and an additional configuration option to definethe size of the pool. Alternatively it can be implemented using ageneral-purpose memory allocator, involving quite a lot of extra codeand configuration options. However this general-purpose memoryallocator may be present anyway to support the application itself orsome other component. The ability to create and destroy mutexesdynamically is a configuration option, and there may not be a sensibledefault that is appropriate for all applications.</para></listitem><listitem><para>An important issue for mutex locks is the handling of priorityinversion, where a high priority thread is prevented from runningbecause it needs a lock owned by a lower priority thread. This is onlyan issue if there is a scheduler with multiple priorities: somesystems may need multi-threading and hence synchronization primitives,but a single priority level may suffice. If priority inversion is atheoretical possibility then the application developer may still wantto ignore it because the application has been designed such that theproblem cannot arise in practice. Alternatively the developer may wantsome sort of exception raised if priority inversion does occur,because it should not happen but there may still be bugs in the code.If priority inversion can occur legally then there are three main waysof handling it: priority ceilings, priority inheritance, and ignoringthe problem. Priority ceilings require little code but extra effort onthe part of the application developer. Priority inheritance requiresmore code but is automatic. Ignoring priority inversion may or may notbe acceptable, depending on the application and exactly when priorityinversion can occur. Some of these choices involve additionalconfiguration options, for example there are different ways of raisingan exception, and priority inheritance may or may not be appliedrecursively.</para></listitem><listitem><para>As a further complication some mutexes may be hidden inside acomponent rather than being an explicit part of the application. Forexample, if the C library is configured to provide a<function>malloc</function> call then there may be an associated mutexto make the function automatically thread-safe, with no need forexternal locking. In such cases the memory allocation component of theC library can impose a constraint on the kernel, requiring thatmutexes be provided. If the user attempts to disable mutexes anywaythen the configuration tools will report a conflict.</para></listitem><listitem><para>The mutex code should contain some general debugging code such asassertions and tracing. Usually such debug support will be enabled ordisabled at a coarse level such as the entire system or everythinginside the kernel, but sometimes it will be desirable to enable thesupport more selectively. One reason would be memory requirements: thetarget may not have enough memory to hold the system if all debuggingis enabled. Another reason is if most of the system is working butthere are a few problems still to resolved; enabling debugging in theentire system might change the system's timing behavior too much, butenabling some debug options selectively can still be useful. Thereshould be configuration options to allow specific types of debuggingto be enabled at a fine-grain, but with default settings inheritedfrom an enclosing component or from global settings.</para></listitem><listitem><para>The mutex code may contain specialized code to interactwith a debugging tool running on the host. It should bepossible to enable or disable this debugging code, and there maybe additional configuration options controlling the detailedbehavior.</para></listitem></orderedlist><para>Altogether there may be something like ten to twenty configurationoptions that are specific to the mutex code. There may be a similarnumber of additional options related to assertions and other debugfacilities. All of the options should have sensible default values,possibly fixed, possibly calculated depending on what is happeningelsewhere in the configuration. For example the default setting foran assertion option should generally inherit from a kernel-wideassertion control option, which in turn inherits from a global option.This allows users to enable or disable assertions globally or ata more fine-grained level, as desired.</para><para>Different components may be configurable to different degrees, rangingfrom no options at all to the fine-grained configurability of theabove mutex example (or possibly even further). It is up to componentwriters to decide what options should be provided and how best toserve the needs of application developers who want to use thatcomponent.</para></sect1><!-- }}} --><!-- {{{ Warning --><sect1 id="overview.warning"><title>Warnings</title><para>Large parts of &eCos; were developed concurrently with the developmentof the configuration technology, or in some cases before design workon that technology was complete. As a consequence the various &eCos;packages often make only limited use of the available functionality.This situation is expected to change over time. It does mean that manyof the descriptions in this guide will not correspond exactly to howthe &eCos; packages work right now, but rather to how they could work.Some of the more extreme discrepancies such as the location of on-linedocumentation in the component repository will be mentioned in theappropriate places in the guide.</para><para>A consequence of this is that developers of new components can look atexisting &CDL; scripts for examples, and discover discrepanciesbetween what is recommended in this guide and what actually happens atpresent. In such cases this guide should be treated as authoritative.</para><para>It is also worth noting that the current component framework is notfinished. Various parts of this guide will refer to possible changesand enhancements in future versions. Examining the source code of theconfiguration tools may reveal hints about other likely developments,and there are many more possible enhancements which only exist at aconceptual level right now.</para></sect1><!-- }}} --></chapter>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -