]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - doc/sgml/user-guide/programming.sgml
Initial revision
[karo-tx-redboot.git] / doc / sgml / user-guide / programming.sgml
1 <!-- {{{ Banner                         -->
2
3 <!-- =============================================================== -->
4 <!--                                                                 -->
5 <!--     programming.sgml                                            -->
6 <!--                                                                 -->
7 <!--     eCos User Guide                                             -->
8 <!--                                                                 -->
9 <!-- =============================================================== -->
10 <!-- ####COPYRIGHTBEGIN####                                          -->
11 <!--                                                                 -->
12 <!-- =============================================================== -->
13 <!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.  -->
14 <!-- Copyright (C) 2003 Nick Garnett                                 -->
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 <!-- ####DESCRIPTIONEND####                                          -->
29 <!-- =============================================================== -->
30
31 <!-- }}} -->
32
33 <part ID="user-guide-programming">
34 <TITLE>Programming With <productname>eCos</productname></TITLE>
35
36 <CHAPTER ID="PROGRAMMING-WITH-ECOS">
37 <TITLE>Programming With <productname>eCos</productname></TITLE>
38
39 <PARA>The following chapters of this manual comprise a simple tutorial
40 for configuring and building <productname>eCos</productname>, building and running <productname>eCos</productname> tests,
41 and finally building three stand-alone example programs which use
42 the  <productname>eCos</productname> API to perform some simple tasks.</PARA>
43
44 <PARA>You will need a properly installed <productname>eCos</productname> system, with the correct
45 versions of the GNU toolchain.<!-- <conditionaltext> --> On Windows
46 you will be using the bash command line interpreter that comes with
47 Cygwin, with the environment variables set as described in the
48 toolchain documentation.</PARA>
49
50 <SECT1 id="development-process">
51 <TITLE>The Development Process</TITLE>
52
53 <PARA>Most development projects using <productname>eCos</productname> would contain some (or
54 most) of  the following:</PARA>
55
56 <SECT2>
57 <TITLE><productname>eCos</productname> Configuration</TITLE>
58
59 <PARA><productname>eCos</productname> is configured to provide the desired API (the inclusion
60 of libc, uitron, and the disabling of certain undesired funtions,
61 etc.), and semantics (selecting scheduler, mutex behavior, etc.).
62 See <XREF LINKEND="CONFIGURING-AND-BUILDING-ECOS-FROM-SOURCE">.</PARA>
63
64 <PARA>It would normally make sense to enable <productname>eCos</productname> assertion checking
65 at this time as well, to catch as many programming errors during
66 the development phase as possible.</PARA>
67
68 <PARA>Note that it should not be necessary to spend much time on
69 <productname>eCos</productname> configuration initially. It may be important to perform fine
70 tuning to reduce the memory footprint and to improve performance
71 later when the product reaches a testable state.</PARA>
72 </SECT2>
73
74 <SECT2>
75 <TITLE>    Integrity check of the <productname>eCos</productname> configuration</TITLE>
76
77 <PARA>While we strive to thoroughly test <productname>eCos</productname>, the vast number
78 of configuration permutations mean that the particular configuration
79 parameters used for your project may not have been tested. Therefore,
80 we advise running the <productname>eCos</productname> tests after the project's
81 <productname>eCos</productname> configuration has been determined. See <XREF LINKEND="RUNNING-AN-ECOS-TEST-CASE">.</PARA>
82
83 <PARA>Obviously, this should be repeated if the configuration changes
84 later on in the development process.</PARA>
85 </SECT2>
86
87 <SECT2>
88 <TITLE>    Application Development - Target Neutral Part</TITLE>
89
90 <PARA>While your project is probably targeting a specific architecture
91 and platform, possibly custom hardware, it may be possible to perform
92 part of the application development using simulated or synthetic
93 targets.</PARA>
94
95 <PARA>There are three good reasons for doing this:</PARA>
96
97 <ITEMIZEDLIST>
98
99 <LISTITEM>
100 <PARA>It may be possible by this means to perform application
101 development in parallel with the design/implementation
102 of the target hardware, thus providing more time for developing
103 and testing functionality, and reducing time-to-market.</PARA>
104 </LISTITEM>
105
106 <LISTITEM>
107 <PARA>The build-run-debug-cycle may be faster when the application
108 does not have to be downloaded to a target via a serial interface.
109 Debugging is also likely to be more responsive when you do not have to
110 to communicate with the remote GDB stubs in RedBoot via serial. It
111 also removes the need for manually or automatically resetting the
112 target hardware.</PARA>
113 </LISTITEM>
114
115 <listitem>
116 <para>
117 New hardware can often be buggy. Comparing the behaviour of the
118 program on the hardware and in the simulator or synthetic target may
119 allow you to identify where the problems lie.
120 </para>
121 </listitem>
122
123 </ITEMIZEDLIST>
124
125 <PARA>This approach is possible because all targets (including
126 simulators and synthetic ones) provide the same basic API: that
127 is, kernel, libc, libm, uitron, infra, and to some extent, HAL and
128 IO.</PARA>
129
130 <PARA>Synthetic targets are especially suitable as they allow you
131 to construct simulations of elaborate devices by interaction with
132 the host system, where an IO device API can hide the details from
133 the application. When switching to hardware later in the development
134 cycle, the IO driver is properly implemented.
135 </para>
136
137 <para>
138 Simulators can also do this, but it all depends on the
139 design and capabilities of the simulator you use. Some, like
140 <ULINK URL="http://sources.redhat.com/sid">SID</ULINK> or
141 <ULINK URL="http://bochs.sourceforge.net/">Bochs</ULINK> provide
142 complete hardware emulation, while others just support enough of the
143 instruction set to run compiled code.
144 </PARA>
145
146 <PARA>Therefore, select a simulator or synthetic target and use
147 it for as long as possible for application development. That is,
148 configure for the selected target, build <productname>eCos</productname>, build the application
149 and link with <productname>eCos</productname>, run and debug. Repeat the latter two steps until
150 you are happy with it.</PARA>
151
152 <PARA>Obviously, at some time you will have to switch to the intended
153 target hardware, for example when adding target specific feature
154 support, for memory footprint/performance characterization,
155 and for final tuning of <productname>eCos</productname> and the application.</PARA>
156
157 </SECT2>
158
159 <SECT2>
160 <TITLE>    Application Development - Target Specific Part</TITLE>
161
162 <PARA>Repeat the build-run-debug-cycle while performing final tuning
163 and debugging of application. Remember to disable <productname>eCos</productname> assertion
164 checking if you are testing any performance-related aspects, it can
165 make a big difference.</PARA>
166
167 <PARA>It may be useful to switch between this and the previous step
168 repeatedly through the development process; use the simulator/synthetic
169 target for actual development, and use the target hardware to continually
170 check memory footprint and performance. There should be little cost
171 in switching between the two targets when using two separate build
172 trees. </PARA>
173 </SECT2>
174
175 </SECT1>
176
177 </CHAPTER>
178
179 <!-- ==================================================== -->
180
181 <CHAPTER ID="CONFIGURING-AND-BUILDING-ECOS-FROM-SOURCE"><!-- <conditionaltext> -->
182 <TITLE><!-- <xref> --><!-- <index></index> -->Configuring and Building <productname>eCos</productname> from Source</TITLE>
183
184 <PARA>This chapter documents the configuration of <productname>eCos</productname>. The process is
185 the same for any of the supported targets: you may select a
186 hardware target (if you have a board available), any one of the
187 simulators, or a synthetic target (if your host platform has synthetic
188 target support).</PARA>
189
190 <!-- ==================================================== -->
191
192 <SECT1 id="ecos-startup-configs">
193 <TITLE><!-- <xref> --><productname>eCos</productname> Start-up Configurations</TITLE>
194
195 <PARA>There are various ways to download an executable image to a
196 target board, and these involve different ways of preparing the
197 executable image. In the <productname>eCos</productname> Hardware Abstraction Layer (HAL package)
198 there are configuration options to support the different download
199 methods. <XREF LINKEND="user-guide-download-methods"> summarizes the
200 ways in which an <productname>eCos</productname> image can be prepared for different types of
201 download. This is not an exhaustive list, some targets define
202 additional start-up types of their own. Where a ROM Monitor is
203 mentioned, this will usually be RedBoot, although on some older, or
204 low resource, targets you may need to use CygMon or the GDB stubs ROM,
205 see the target documentation for details.</PARA>
206
207
208 <TABLE id="user-guide-download-methods">
209 <TITLE>Configuration for various download methods</TITLE>
210 <TGROUP COLS="2">
211 <THEAD>
212 <ROW>
213 <ENTRY>Download method</ENTRY>
214 <ENTRY>HAL configuration</ENTRY>
215 </ROW>
216 </THEAD>
217 <TBODY>
218 <ROW>
219 <ENTRY>Burn hardware ROM</ENTRY>
220 <ENTRY>&nbsp;ROM or ROMRAM start-up</ENTRY>
221 </ROW>
222 <ROW>
223 <ENTRY>Download to ROM emulator</ENTRY>
224 <ENTRY>&nbsp;ROM or ROMRAM start-up</ENTRY>
225 </ROW>
226 <ROW>
227 <ENTRY>Download to board with ROM Monitor</ENTRY>
228 <ENTRY>&nbsp;RAM start-up</ENTRY>
229 </ROW>
230 <ROW>
231 <ENTRY>Download to simulator without ROM Monitor</ENTRY>
232 <ENTRY>&nbsp;ROM start-up</ENTRY>
233 </ROW>
234 <ROW>
235 <ENTRY>Download to simulator with ROM Monitor</ENTRY>
236 <ENTRY>&nbsp;RAM start-up</ENTRY>
237 </ROW>
238 <ROW>
239 <ENTRY>Download to simulator ignoring devices</ENTRY>
240 <ENTRY>&nbsp;SIM configuration</ENTRY>
241 </ROW>
242 <ROW>
243 <ENTRY>Run synthetic target</ENTRY>
244 <ENTRY>&nbsp;RAM start-up</ENTRY>
245 </ROW>
246 </TBODY>
247 </TGROUP>
248 </TABLE>
249
250 <CAUTION>
251
252 <PARA>You cannot run an application configured for RAM start-up
253 on the simulator directly: it will fail during start-up. You can
254 only download it to the simulator if
255 you are already running RedBoot in the simulator,
256 as described in the toolchain documentation
257 or you load through the 
258 <EMPHASIS>SID </EMPHASIS>
259 GDB debugging component.  This is not the same as the simulated
260 stub, since it does not require a target program to be running to
261 get GDB to talk to it.  It can be done before letting the simulator
262 run
263 or you use the ELF loader component to get a program into memory.</PARA>
264
265 </CAUTION><!-- <label> --><!-- <conditionaltext> --><!-- NOTE</label> -->
266
267 <NOTE>
268 <PARA>Configuring <productname>eCos</productname>' HAL package for simulation should
269 rarely be needed for real development; binaries built with such
270 a kernel will not run on target boards at all,<!-- <conditionaltext> -->
271 and the MN10300 and
272 TX39 simulators can run binaries built for stdeval1 and jmr3904
273 target boards.
274 The main use for a ``simulation'' configuration
275 is if you are trying to work around problems with the device drivers
276 or with the simulator.  Also note that when using a TX39 system configured
277 for simulator start-up you should then invoke the simulator with 
278 the <OPTION>--board=jmr3904pal</OPTION>
279 option instead of 
280 <OPTION>--board=jmr3904</OPTION><!-- <conditionaltext> --></PARA>
281 </NOTE>
282
283 <NOTE>
284 <PARA>If your chosen architecture does not have simulator support,
285 then the combinations above that refer to the simulator do not apply.
286 Similarly, if your chosen platform does not have RedBoot
287 ROM support, the combinations listed above that use 
288 RedBoot do not apply.</PARA>
289 </NOTE>
290
291 <PARA>The debugging environment for most developers will be either
292 a hardware board or the simulator, in which case they will be able
293 to select a single HAL configuration.</PARA>
294
295 </SECT1>
296
297 <!-- ==================================================== -->
298
299 <SECT1 id="using-configtool-windows-linux">
300 <TITLE><!-- <index></index> -->
301 Configuration Tool on Windows and Linux Quick Start</TITLE>
302
303 <PARA><!-- <conditionaltext> --> 
304
305 This section described the GUI based configuration tool. This
306 tool is probably more suited to users who prefer GUI's. The next
307 section describes a CLI based tool which Unix users may
308 prefer. </PARA>
309
310 <PARA>Note that the use of the <application>Configuration Tool</application>
311 is described in detail in <XREF
312 LINKEND="THE-ECOS-CONFIGURATION-TOOL">.</PARA>
313
314 <PARA>The <application>Configuration Tool</application> (see <XREF LINKEND="PROGRAMMING-FIGURE-CONFIGURATION-TOOL">)
315 has five main elements: the <EMPHASIS>configuration window</EMPHASIS>,
316 the <emphasis>conflicts window</emphasis>,
317 the <EMPHASIS>properties window</EMPHASIS>, the <!-- <xref> --><EMPHASIS>short
318 description window</EMPHASIS>,
319 and the <EMPHASIS>output window</EMPHASIS>.</PARA>
320
321 <FIGURE ID="PROGRAMMING-FIGURE-CONFIGURATION-TOOL">
322 <TITLE>Configuration Tool</TITLE><!-- <xref> -->
323 <GRAPHIC ENTITYREF="programming-graphic1"></GRAPHIC>
324 </FIGURE>
325
326 <PARA>Start by opening the templates window via <GUIMENUITEM>Build-&#62;Templates</GUIMENUITEM>.
327 Select the desired target (see <XREF LINKEND="FIGURE-TEMPLATE-SELECTION">).</PARA>
328
329 <FIGURE ID="FIGURE-TEMPLATE-SELECTION">
330 <TITLE>Template selection</TITLE><!-- <xref> -->
331 <GRAPHIC ENTITYREF="programming-graphic2"></GRAPHIC>
332 </FIGURE>
333
334 <PARA>Make sure that the configuration is correct for the target
335 in terms of endianness, CPU model, Startup type, etc. (see <XREF LINKEND="CONFIGURING-FOR-THE-TARGET">).</PARA>
336
337 <FIGURE ID="CONFIGURING-FOR-THE-TARGET">
338 <TITLE><!-- <conditionaltext> --><!-- <xref> -->Configuring
339 for the target</TITLE>
340 <GRAPHIC ENTITYREF="programming-graphic3"></GRAPHIC>
341 </FIGURE>
342
343 <PARA>Next, select the <EMPHASIS>Build-&#62;Library</EMPHASIS> menu
344 item to start building <productname>eCos</productname> (see <XREF
345 LINKEND="FIGURE-SELECTING-THE-BUILD-LIBRARY-MENU-ITEM">).  The
346 application will configure the sources, prepare a build tree, and
347 build the <FILENAME>libtarget.a</FILENAME> library, which contains the
348 <productname>eCos</productname> kernel and other packages.</PARA>
349
350 <FIGURE ID="FIGURE-SELECTING-THE-BUILD-LIBRARY-MENU-ITEM"><!-- <xref> -->
351 <TITLE>Selecting the Build Library menu item</TITLE>
352 <GRAPHIC ENTITYREF="programming-graphic4"></GRAPHIC>
353 </FIGURE>
354
355
356 <PARA>The <EMPHASIS>Save As</EMPHASIS> dialog box will appear, asking
357 you to specify a directory in which to place your save file. You
358 can use the default, but it is a good idea to make a subdirectory,
359 called <filename>ecos-work</filename> for example. </PARA>
360
361 <FIGURE>
362 <TITLE>Save file dialog</TITLE>
363 <GRAPHIC ENTITYREF="programming-graphic5"></GRAPHIC>
364 </FIGURE>
365
366 <PARA>The first time you build an <productname>eCos</productname> library for a specific
367 architecture, the <application>Configuration Tool</application> may prompt
368 you for the location of the appropriate build tools (including
369 <command>make</command> and
370 <command><replaceable>TARGET-</replaceable>gcc</command>) using a
371 <EMPHASIS>Build Tools</EMPHASIS> dialog box (as shown in <XREF
372 LINKEND="FIGURE-BUILD-TOOLS-DIALOG">). You can select a location from
373 the drop down list, browse to the directory using the
374 <EMPHASIS>Browse</EMPHASIS> button, or type in the location of the
375 build tools manually.</PARA>
376
377 <FIGURE ID="FIGURE-BUILD-TOOLS-DIALOG"><!-- <xref> -->
378 <TITLE>Build tools dialog</TITLE>
379 <GRAPHIC ENTITYREF="programming-graphic6"></GRAPHIC>
380 </FIGURE>
381
382 <PARA>The <application>Configuration Tool</application> may also prompt you
383 for the location of the user tools (such as <command>cat</command> and
384 <command>ls</command>) using a <emphasis>User Tools</emphasis> dialog
385 box (as shown in <XREF LINKEND="FIGURE-USER-TOOLS-DIALOG">). As with
386 the <EMPHASIS>Build Tools</EMPHASIS> dialog, you can select a location
387 from the drop down list, browse to the directory using the
388 <EMPHASIS>Browse</EMPHASIS> button, or type in the location of the
389 user tools manually. Note that on Linux, this will often be
390 unnecessary as the tools will already be on your PATH.</PARA>
391
392 <FIGURE ID="FIGURE-USER-TOOLS-DIALOG"><!-- <xref> -->
393 <TITLE>User tools dialog</TITLE>
394 <GRAPHIC ENTITYREF="programming-graphic7"></GRAPHIC>
395 </FIGURE>
396
397 <PARA>When the tool locations have been entered, the <application>Configuration
398 Tool</application> will configure the sources, prepare a build tree,
399 and build the <filename>libtarget.a</filename> library, which contains
400 the <productname>eCos</productname> kernel and other packages.</PARA>
401
402 <PARA>The output from the configuration process and the building
403 of <filename>libtarget.a</filename> will be shown in the output
404 window.</PARA>
405
406 <PARA>Once the build process has finished you will have a kernel
407 with other packages in <FILENAME>libtarget.a</FILENAME>. You should
408 now build the <productname>eCos</productname> tests for your particular configuration. </PARA>
409
410 <PARA>You can do this by selecting <EMPHASIS>Build</EMPHASIS> -&#62; <EMPHASIS>Tests</EMPHASIS>.
411 Notice that you could have selected <EMPHASIS>Tests</EMPHASIS> instead
412 of <EMPHASIS>Library</EMPHASIS> in the earlier step and it would
413 have built <EMPHASIS>both</EMPHASIS> the library and the tests,
414 but this would increase the build time substantially, and if you
415 do not need to build the tests it is unnecessary.</PARA>
416
417 <FIGURE>
418 <TITLE>Selecting the Build Tests menu item</TITLE>
419 <GRAPHIC ENTITYREF="programming-graphic8"></GRAPHIC>
420 </FIGURE>
421
422 <PARA><XREF LINKEND="RUNNING-AN-ECOS-TEST-CASE"> will guide you through running one
423             of the test cases you just built on the selected target,
424             using GDB. </PARA>
425 </SECT1>
426
427 <!-- ==================================================== -->
428
429 <SECT1 ID="USING-ECOSCONFIG-ON-LINUX">
430 <TITLE><!-- <index></index> -->
431 Ecosconfig on Windows and Linux Quick Start</TITLE>
432
433 <PARA>As an alternative to using the graphical
434 <application>Configuration Tool</application>, it is possible to
435 configure and build a kernel by editing a configuration file manually
436 and using the <command>ecosconfig</command> command. Users with a Unix
437 background may find this tool more suitable than the GUI tool
438 described in the previous section.</PARA>
439
440 <para>
441 Manual configuration and the <command>ecosconfig</command> command are
442 described in detail in <XREF LINKEND="manual-configuration">.
443 </para>
444
445 <para>
446 To use the <command>ecosconfig</command> command you need to start a
447 shell. In Windows you need to start a
448 <productname>CygWin</productname> <command>bash</command> shell, not a
449 DOS command line.
450 </para>
451
452 <!--
453 <para>
454 XXXXX Need to know whether there will be a packaged shell entry in the
455 start menu, and where XXXXX
456 </para>
457 -->
458
459 <PARA>The following instructions assume that the
460 <literal>PATH</literal> and <literal>ECOS_REPOSITORY</literal>
461 environment variables have been setup correctly as described in <XREF
462 LINKEND="user-guide-installation-linux">.  They also assume Linux
463 usage but equally well apply to Windows running Cygwin.</PARA>
464
465 <PARA>Before invoking <command>ecosconfig</command> you need to
466 choose a directory in which to work. For the purposes of this tutorial,
467 the default path will be <FILENAME><replaceable>BASE_DIR</replaceable>/ecos-work</FILENAME>.
468 Create this directory and change to it by typing: </PARA>
469
470 <PROGRAMLISTING>
471 $ mkdir <replaceable>BASE_DIR</replaceable>/ecos-work
472 $ cd <replaceable>BASE_DIR</replaceable>/ecos-work
473 </PROGRAMLISTING>
474
475 <PARA>To see what options can be used with <command>ecosconfig</command>,
476 type: </PARA>
477
478 <PROGRAMLISTING>$ ecosconfig --help</PROGRAMLISTING>
479
480 <PARA>The available packages, targets and templates may be listed
481 as follows:</PARA>
482
483 <PROGRAMLISTING>
484 $ ecosconfig list
485 </PROGRAMLISTING>
486
487 <PARA>Here is sample output from <command>ecosconfig</command> showing
488 the usage message.</PARA>
489
490 <EXAMPLE>
491 <TITLE>Getting <!-- <index></index> --> help from ecosconfig</TITLE>
492
493 <PROGRAMLISTING>
494 $ ecosconfig --help
495 Usage: ecosconfig [ qualifier ... ] [ command ]
496   commands are:
497     list                                       : list repository contents
498     new TARGET [ TEMPLATE [ VERSION ] ]        : create a configuration
499     target TARGET                              : change the target hardware
500     template TEMPLATE [ VERSION ]              : change the template
501     add PACKAGE [ PACKAGE ... ]                : add package(s)
502     remove PACKAGE [ PACKAGE ... ]             : remove package(s)
503     version VERSION PACKAGE [ PACKAGE ... ]    : change version of package(s)
504     export FILE                                : export minimal config info
505     import FILE                                : import additional config info
506     check                                      : check the configuration
507     resolve                                    : resolve conflicts
508     tree                                       : create a build tree
509   qualifiers are:
510     --config=FILE                              : the configuration file
511     --prefix=DIRECTORY                         : the install prefix
512     --srcdir=DIRECTORY                         : the source repository
513     --no-resolve                               : disable conflict
514 resolution
515     --version                                  : show version and copyright
516 $
517 </PROGRAMLISTING>
518 </EXAMPLE>
519
520 <EXAMPLE>
521
522 <TITLE>ecosconfig output &mdash; <!-- <index></index> -->
523 list of available packages, targets and templates</TITLE>
524
525 <PROGRAMLISTING>
526 $ ecosconfig list
527 Package CYGPKG_CYGMON (CygMon support via eCos): 
528 aliases: cygmon 
529 versions: &Version; 
530 Package CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1742 (Wallclock driver for Dallas 1742): 
531 aliases: devices_wallclock_ds1742 device_wallclock_ds1742 
532 versions: &Version; 
533 Package CYGPKG_DEVICES_WALLCLOCK_SH3 (Wallclock driver for SH3 RTC module): 
534 aliases: devices_wallclock_sh3 device_wallclock_sh3 
535 versions: &Version; 
536 Package CYGPKG_DEVICES_WATCHDOG_ARM_AEB (Watchdog driver for ARM/AEB board): 
537 aliases: devices_watchdog_aeb device_watchdog_aeb 
538 versions: &Version; 
539 Package CYGPKG_DEVICES_WATCHDOG_ARM_EBSA285 (Watchdog driver for ARM/EBSA285 board): 
540 aliases: devices_watchdog_ebsa285 device_watchdog_ebsa285 
541 versions: &Version; 
542 &hellip;
543 </PROGRAMLISTING>
544 </EXAMPLE>
545
546
547 <SECT2>
548 <TITLE>Selecting a <!-- <index></index> --> Target</TITLE>
549
550 <PARA>To configure for a listed target, type: </PARA>
551
552 <PROGRAMLISTING>
553 $ ecosconfig new &lt;target&#62;
554 </PROGRAMLISTING>
555
556 <PARA>For example, to configure for the ARM PID development board,
557 type: </PARA>
558
559 <PROGRAMLISTING>
560 $ ecosconfig new pid
561 </PROGRAMLISTING>
562
563 <PARA>You can then edit the generated file,
564 <FILENAME>ecos.ecc</FILENAME>, setting the options as required for the
565 target (endianess, CPU model, Startup type, etc.).  For detailed
566 information about how to edit the <filename>ecos.ecc</filename> file,
567 see the <citetitle>CDL Writer's Guide</citetitle> and <XREF
568 LINKEND="editing-an-ecos-savefile">.
569 </PARA>
570
571 <PARA>Create a build tree for the configured target by typing:</PARA>
572
573 <PROGRAMLISTING>
574 $ ecosconfig tree
575 </PROGRAMLISTING>
576
577 <para>
578 If there are any problem with the configuration,
579 <command>ecosconfig</command> will tell you. The most likely cause of
580 this is mistakes when editing the <filename>ecos.ecc</filename> file.
581 You can check whether the configuration you have made is correct,
582 without building the tree with the following command:
583 </para>
584
585 <PROGRAMLISTING>
586 $ ecosconfig check
587 </PROGRAMLISTING>
588
589 <para>
590 If this reports any conflicts you can get
591 <command>ecosconfig</command> to try and resolve them itself by typing:
592 </para>
593
594 <PROGRAMLISTING>
595 $ ecosconfig resolve
596 </PROGRAMLISTING>
597
598 <para>
599 See <XREF LINKEND="conflicts-and-constraints"> for more details.
600 </para>
601
602 <PARA>You can now run the command <command>make</command> or <command>make
603 tests</command>, after which you will be at the same point you
604 would be after running the <application>Configuration Tool</application>
605 &mdash; you can start developing your own applications,
606 following the steps in <XREF LINKEND="BUILDING-AND-RUNNING-SAMPLE-APPLIATIONS">. </PARA>
607
608 <PARA>The procedure shown above allows you to do very coarse-grained
609 configuration of the <productname>eCos</productname> kernel: you can select which packages
610 to include in your kernel, and give target and start-up options.
611 But you cannot select components within a package, or set the very
612 fine-grained options. </PARA>
613
614 <PARA>To select fine-grained configuration options you will need to
615 edit the configuration file <filename>ecos.ecc</filename> in the
616 current directory and regenerate the build tree.</PARA>
617
618 <CAUTION>
619 <PARA>You should follow the manual configuration process described
620 above very carefully, and you should read the comments in each file
621 to see when one option depends on other options or packages being
622 enabled or disabled. If you do not, you might end up with an inconsistently
623 configured kernel which could fail to build or might execute
624 incorrectly.</PARA>
625 </CAUTION>
626
627 </SECT2>
628 </SECT1>
629
630 </CHAPTER>
631
632 <!-- ==================================================== -->
633
634 <CHAPTER ID="RUNNING-AN-ECOS-TEST-CASE">
635 <TITLE>Running an <productname>eCos</productname> Test Case</TITLE>
636
637 <PARA>In <XREF LINKEND="using-configtool-windows-linux"> or <XREF
638 LINKEND="using-ecosconfig-on-linux"> you created the <productname>eCos</productname> test cases
639 as part of the build process. Now it is time to try and run one.
640 </para>
641
642 <!-- ==================================================== -->
643
644 <SECT1 id="using-configtool-testcase">
645 <TITLE>Using the <application>Configuration Tool</application></TITLE>
646
647 <PARA>Test executables that have been linked using the
648 <emphasis>Build-&gt;Tests</emphasis> operation against the current
649 configuration can be executed by selecting <EMPHASIS>Tools-&#62;Run
650 Tests</EMPHASIS>.</PARA>
651
652 <PARA>When a test run is invoked, a property sheet is displayed, see
653 <xref linkend="programming-run-tests">. Press the <emphasis>Uncheck
654 All</emphasis> button and then find and check just one test,
655 <filename>bin_sem0</filename> for example.
656 </para>
657
658 <FIGURE id="programming-run-tests">
659 <TITLE>Run tests</TITLE>
660 <GRAPHIC ENTITYREF="graphic27"></GRAPHIC>
661 </FIGURE>
662
663 <para>
664 Now press the <emphasis>Properties</emphasis> button to set up
665 communications with the target. This will bring up a properties dialog
666 shown in <xref linkend="programming-run-properties">. If you have
667 connected the target board via a serial cable, check the
668 <emphasis>Serial</emphasis> radio button, and select the serial port
669 and baud rate for the board. If the target is connected via the
670 network select the <emphasis>TCP/IP</emphasis> button and enter the IP
671 address that the board has been given, and the port number (usually
672 9000).
673 </para>
674
675 <FIGURE id="programming-run-properties">
676 <TITLE>Properties dialog box</TITLE>
677 <GRAPHIC ENTITYREF="graphic25"></GRAPHIC>
678 </FIGURE>
679
680 <para>
681 Click OK on this dialog and go back to the <emphasis>Run
682 Tests</emphasis> dialog. Press the <emphasis>Run</emphasis> button and
683 the selected test will be downloaded and run. The
684 <emphasis>Output</emphasis> tab will show you how this is
685 progressing. If it seems to stop for a long time, check that the
686 target board is correctly connected, and that <productname>eCos</productname> has been correctly
687 configured -- especially the start-up type.
688 </para>
689
690 <para>
691 When the program runs you should see a couple of line similar to this appear:
692 </para>
693
694 <PROGRAMLISTING>
695 PASS:&lt;Binary Semaphore 0 OK&gt;
696 EXIT:&lt;done&gt;
697 </PROGRAMLISTING>
698
699 <para>
700 This indicates that the test has run successfully.
701 </para>
702
703 <PARA>See <xref linkend="config-tool-test-execution"> for
704 further details.</PARA>
705
706 </SECT1>
707
708 <!-- ==================================================== -->
709
710 <SECT1 id="using-commandline-testcase">
711 <TITLE>Using the command line</TITLE>
712
713 <PARA>Start a command shell (such as a Cygwin shell window in Windows)
714 with the environment variables set as described in the toolchain
715 documentation.  Change to the directory in which you set up your build
716 tree, and invoke <!-- <index></index> --> GDB on the test
717 program.</PARA>
718
719 <PARA>To run the <!-- <index></index> -->bin_sem0 test (which will
720 test the kernel for the correct creation and destruction of binary
721 semaphores) type: </PARA>
722
723 <PROGRAMLISTING>
724 $ <replaceable>TARGET-</replaceable>gdb -nw install/tests/kernel/<replaceable>&Version;</replaceable>/tests/bin_sem0
725 </PROGRAMLISTING>
726
727 <PARA>You should see output similar to the following in the command
728 window:</PARA>
729
730 <PROGRAMLISTING>
731 GNU gdb THIS-GDB-VERSION
732 Copyright 2001 Free Software Foundation, Inc.
733 GDB is free software, covered by the GNU General Public License, and you are
734 welcome to change it and/or distribute copies of it under certain conditions.
735 Type "show copying" to see the conditions.
736 There is absolutely no warranty for GDB.  Type "show warranty" for details.
737 This GDB was configured as "--host=THIS-HOST --target=THIS-TARGET".
738 (gdb)
739 </PROGRAMLISTING>
740
741 <PARA>If you are trying to run a synthetic target test on <!--
742 <index></index> -->Linux, skip the following connection and download
743 steps. Otherwise, connect to the target by typing: </PARA>
744
745 <PROGRAMLISTING>
746 (gdb) set remotebaud 38400
747 (gdb) target remote /dev/ttyS0
748 </PROGRAMLISTING>
749 <PARA>on Linux or</PARA>
750 <PROGRAMLISTING>
751 (gdb) set remotebaud 38400
752 (gdb) target remote com1
753 </PROGRAMLISTING>
754 <PARA>on Windows or</PARA>
755 <PROGRAMLISTING>
756 (gdb) target sim
757 </PROGRAMLISTING>
758 <para>to use a simulator in either host O/S.</para>
759
760 <para>
761 Check the documentation for the target board for the actual baud rate
762 to use when connecting to real targets.
763 </para>
764
765 <PARA>
766 You will see output similar to the following: </PARA>
767
768 <programlisting width=72>
769 Remote debugging using /dev/ttyS1
770 0x0000d50c in ?? ()
771     at <replaceable>BASE_DIR</replaceable>/kernel/<replaceable>&Version;</replaceable>/src/common/kapi.cxx:345
772
773 Current language:  auto; currently c++
774 (gdb) 
775 </programlisting>
776
777 <para>
778 Or if you are using the simulator:
779 </para>
780
781 <PROGRAMLISTING>
782 Connected to the simulator.
783 (gdb)
784 </PROGRAMLISTING>
785
786 <PARA>Now download the program to the target with</PARA>
787
788 <PROGRAMLISTING>
789 (gdb) load
790 </PROGRAMLISTING>
791
792 <PARA>You should see output similar to the following on your screen: </PARA>
793
794 <PROGRAMLISTING>
795 Loading section .text, size 0x4b04 lma 0x108000
796 Loading section .rodata, size 0x738 lma 0x10cb08
797 Loading section .data, size 0x1c0 lma 0x10d240
798 Start address 0x108000, load size 21500
799 Transfer rate: 24571 bits/sec, 311 bytes/write.
800 (gdb)
801 </PROGRAMLISTING>
802
803 <PARA>You are now ready to run your program. If you type: </PARA>
804
805 <PROGRAMLISTING>
806 (gdb) continue
807 </PROGRAMLISTING>
808
809 <PARA>you will see output similar to the following: </PARA>
810
811 <PROGRAMLISTING>
812 Continuing.
813 PASS:&lt;Binary Semaphore 0 OK&gt;
814 EXIT:&lt;done&gt;
815 </PROGRAMLISTING>
816
817 <NOTE>
818 <PARA> If you are using a simulator or the synthetic target rather
819             than real hardware, you must use the GDB command
820             &ldquo;run&rdquo; rather than &ldquo;continue&rdquo; to
821             start your program.</PARA>
822 </NOTE>
823
824 <PARA>You can terminate your GDB session with
825 <EMPHASIS>Control+C</EMPHASIS>, otherwise it will sit in the
826 &ldquo;idle&rdquo; thread and use up CPU time. This is not a problem
827 with real targets, but may have undesirable effects in simulated or
828 synthetic targets. Type <command>quit</command> and you are
829 done. </PARA>
830
831 </SECT1>
832
833 <!-- ==================================================== -->
834
835 <SECT1 id="testing-filters">
836 <TITLE>Testing Filters</TITLE>
837
838 <PARA>While most test cases today run solely in the target environment,
839 some packages may require external testing infrastructure and/or
840 feedback from the external environment to do complete testing.</PARA>
841
842 <PARA>The serial package is an example of this. The network package
843 also contains some tests that require programs to be run on a
844 host. See the network <citetitle>Tests and Demonstrations</citetitle>
845 section in the network documentation in the <citetitle><productname>eCos</productname> Reference
846 Guide</citetitle>. Here we will concentrate on the serial tests since
847 these are applicable to more targets.
848 </para>
849
850 <PARA>Since the serial line is also used for communication with
851 GDB, a  filter is inserted in the communication pathway between
852 GDB and the serial device which is connected to the hardware target.
853 The filter forwards all communication between the two, but also
854 listens for special commands embedded in the data stream from the
855 target.</PARA>
856
857 <PARA>When such a command is seen, the filter stops forwarding data
858 to GDB from the target and enters a special mode. In this mode
859 the test case running on the target is able to control the filter,
860 commanding it to run various tests. While these tests run, GDB is
861 isolated from the target.</PARA>
862
863 <PARA>As the test completes (or if the filter detects a target crash)
864 the communication path between GDB and the hardware target is re-established,
865 allowing GDB to resume control.</PARA>
866
867 <PARA>In theory, it is possible to extend the filter to provide
868 a generic framework for other target-external testing components,
869 thus decoupling the testing infrastructure from the (possibly limited)
870 communication means provided by the target (serial, JTAG, Ethernet,
871 etc). </PARA>
872
873 <PARA>Another advantage is that the host tools do not need to
874 know about the various testing environments required by the <productname>eCos</productname>
875 packages, since all contact with the target continues to happen
876 via GDB.</PARA>
877
878 </sect1>
879
880 </CHAPTER>
881
882
883 <!-- ==================================================== -->
884
885 <CHAPTER ID="BUILDING-AND-RUNNING-SAMPLE-APPLIATIONS"><!-- <conditionaltext> -->
886 <TITLE><!-- <xref> -->Building and <!-- <index></index> -->Running Sample Applications</TITLE>
887
888 <PARA>The example programs in this tutorial are included, along
889 with a <filename>Makefile</filename>, in the <filename>examples</filename> directory
890 of the <productname>eCos</productname> distribution. The first program you will run is a <EMPHASIS>hello
891 world</EMPHASIS>-style application, then you will run a more complex
892 application that demonstrates the creation of threads and the use
893 of cyg_thread_delay(), and finally you will run
894 one that uses clocks and alarm handlers.</PARA>
895
896 <PARA>The <filename>Makefile</filename> depends on an externally
897 defined variable to find the <productname>eCos</productname> library and header files. This
898 variable is <literal>INSTALL_DIR</literal> and must be set to the
899 pathname of the install directory created in <xref
900 linkend="using-configtool-windows-linux">.
901 </PARA>
902
903 <para>
904 <literal>INSTALL_DIR</literal> may be either be set in the shell
905 environment or may be supplied on the command line. To set it in the
906 shell do the following in a <command>bash</command> shell:
907 </para>
908
909 <programlisting width=72>
910 $ export INSTALL_DIR=BASE_DIR/ecos-work/arm_install
911 </programlisting>
912
913 <para>
914 You can then run <command>make</command> without any extra parameters
915 to build the examples.
916 </para>
917
918 <para>
919 Alternatively, if you can do the following:
920 </para>
921
922 <programlisting width=72>
923 $ make INSTALL_DIR=BASE_DIR/ecos-work/arm_install
924 </programlisting>
925
926 <!-- ==================================================== -->
927
928 <SECT1 id="ecos-hello-world">
929 <TITLE><productname>eCos</productname> Hello World</TITLE>
930
931 <PARA>The following code is found in the file <FILENAME><!-- <index></index> -->hello.c</FILENAME>
932 in the <FILENAME>examples</FILENAME> directory: </PARA>
933
934 <SECT2>
935 <TITLE><productname>eCos</productname><!-- <index></index> --> hello world program listing</TITLE>
936
937 <PROGRAMLISTING>
938 /* this is a simple hello world program */
939 #include &lt;stdio.h&#62;
940 int main(void)
941 {
942  printf("Hello, eCos world!\n");
943  return 0;
944 }
945 </PROGRAMLISTING>
946
947 <PARA>To compile this or any other program that is not part of the
948 <productname>eCos</productname> distribution, you can follow the procedures described below. Type
949 this explicit compilation command (assuming your current working
950 directory is also where you built the <productname>eCos</productname> kernel):</PARA>
951
952 <PROGRAMLISTING>
953 $ <replaceable>TARGET-</replaceable>gcc -g -I<replaceable>BASE_DIR</replaceable>/ecos-work/install/include hello.c -L<replaceable>BASE_DIR</replaceable>/ecos-work/install/lib -Ttarget.ld -nostdlib
954 </PROGRAMLISTING>
955
956 <PARA>The compilation command above contains some standard GCC
957 options (for example, <OPTION>-g</OPTION> enables debugging), as well
958 as some mention of paths
959 (<OPTION>-I<replaceable>BASE_DIR</replaceable>/ecos-work/install/include</OPTION> allows files
960 like <FILENAME>cyg/kernel/kapi.h</FILENAME> to be found, and
961 <OPTION>-L<replaceable>BASE_DIR</replaceable>/ecos-work/install/lib</OPTION> allows the linker to
962 find <OPTION>-Ttarget.ld</OPTION>). </PARA>
963
964 <PARA>The executable program will be called <FILENAME>a.out</FILENAME>. </PARA>
965
966 <NOTE>
967 <PARA>Some target systems require special options to be passed to
968 gcc to compile correctly for that system. Please examine the Makefile
969 in the examples directory to see if this applies to your target.</PARA>
970 </NOTE>
971
972 <PARA>You can now run the resulting program using GDB in exactly the
973 same the way you ran the test case before. The procedure will be the
974 same, but this time run
975 <command><replaceable>TARGET-</replaceable>gdb</command> specifying
976 <option>-nw a.out</option> on the command line:</PARA>
977
978 <PROGRAMLISTING>
979 $ <replaceable>TARGET-</replaceable>gdb -nw a.out
980 </PROGRAMLISTING>
981
982 <PARA>For targets other than the synthetic linux target, you should
983 now run the usual GDB commands described earlier. Once this is done,
984 typing the command "continue" at the (gdb) prompt ("run" for
985 simulators) will allow the program to execute and print the string
986 "Hello, eCos world!" on your screen.</PARA>
987
988 <PARA>On the synthetic linux target, you may use the "run" command
989 immediately - you do not need to connect to the target, nor use the
990 "load" command.<!-- <conditionaltext> --></PARA>
991
992 </SECT2>
993 </SECT1>
994
995 <!-- ==================================================== -->
996
997 <SECT1 id="sample-twothreads">
998 <TITLE>A Sample Program with Two Threads</TITLE>
999
1000 <PARA>Below is a program that uses some of <productname>eCos</productname>' system calls. It
1001 creates two threads, each of which goes into an infinite loop in which
1002 it sleeps for a while (using cyg_thread_delay()).  This code is found
1003 in the file <filename><!-- <index></index> -->twothreads.c</filename>
1004 in the examples directory.</PARA>
1005
1006 <SECT2>
1007 <TITLE><productname>eCos</productname> <!-- <index></index> -->two-threaded program listing</TITLE>
1008
1009 <PROGRAMLISTING>
1010 #include &lt;cyg/kernel/kapi.h&#62;
1011 #include &lt;stdio.h&#62;
1012 #include &lt;math.h&#62;
1013 #include &lt;stdlib.h&#62;
1014
1015 /* now declare (and allocate space for) some kernel objects,
1016   like the two threads we will use */
1017 cyg_thread thread_s[2]; /* space for two thread objects */
1018
1019 char stack[2][4096];    /* space for two 4K stacks */
1020
1021 /* now the handles for the threads */
1022 cyg_handle_t simple_threadA, simple_threadB;
1023
1024 /* and now variables for the procedure which is the thread */
1025 cyg_thread_entry_t simple_program;
1026
1027 /* and now a mutex to protect calls to the C library */
1028 cyg_mutex_t cliblock;
1029
1030 /* we install our own startup routine which sets up threads */
1031 void cyg_user_start(void)
1032 {
1033  printf("Entering twothreads' cyg_user_start() function\n");
1034
1035  cyg_mutex_init(&amp;cliblock);
1036
1037  cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
1038         "Thread A", (void *) stack[0], 4096,
1039         &amp;simple_threadA, &amp;thread_s[0]);
1040  cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
1041         "Thread B", (void *) stack[1], 4096,
1042         &amp;simple_threadB, &amp;thread_s[1]);
1043
1044  cyg_thread_resume(simple_threadA);
1045  cyg_thread_resume(simple_threadB);
1046 }
1047
1048 /* this is a simple program which runs in a thread */
1049 void simple_program(cyg_addrword_t data)
1050 {
1051  int message = (int) data;
1052  int delay;
1053
1054  printf("Beginning execution; thread data is %d\n", message);
1055
1056  cyg_thread_delay(200);
1057
1058  for (;;) {
1059  delay = 200 + (rand() % 50);
1060
1061  /* note: printf() must be protected by a
1062  call to cyg_mutex_lock() */
1063  cyg_mutex_lock(&amp;cliblock); {
1064  printf("Thread %d: and now a delay of %d clock ticks\n",
1065         message, delay);
1066  }
1067  cyg_mutex_unlock(&amp;cliblock);
1068  cyg_thread_delay(delay);
1069  }
1070 }
1071 </PROGRAMLISTING>
1072
1073 <PARA>
1074 When you run the program (by typing <command>continue</command> at
1075 the (<EMPHASIS>gdb</EMPHASIS>) prompt) the output should look like
1076 this:</PARA>
1077
1078 <PROGRAMLISTING>
1079 Starting program: <replaceable>BASE_DIR</replaceable>/examples/twothreads.exe
1080 Entering twothreads' cyg_user_start()
1081 function
1082 Beginning execution; thread data is 0
1083 Beginning execution; thread data is 1
1084 Thread 0: and now a delay of 240 clock ticks
1085 Thread 1: and now a delay of 225 clock ticks
1086 Thread 1: and now a delay of 234 clock ticks
1087 Thread 0: and now a delay of 231 clock ticks
1088 Thread 1: and now a delay of 224 clock ticks
1089 Thread 0: and now a delay of 249 clock ticks
1090 Thread 1: and now a delay of 202 clock ticks
1091 Thread 0: and now a delay of 235 clock ticks
1092 </PROGRAMLISTING>
1093
1094 <NOTE>
1095 <PARA>When running in a simulator the <!-- <index></index> -->
1096 delays might be quite long. On a hardware board (where the clock
1097 speed is 100 ticks/second) the delays should average to
1098 about 2.25 seconds. In simulation, the delay will depend on the
1099 speed of the host processor and will almost always be much slower than
1100 the actual board. You might want to reduce the delay parameter when running
1101 in simulation.
1102 </PARA>
1103 </NOTE>
1104
1105 <PARA>
1106 <XREF LINKEND="FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"> shows how this
1107 multitasking program executes.  Note that apart from the thread
1108 creation system calls, this program also creates and uses a
1109 <EMPHASIS><!-- <index></index> -->mutex</EMPHASIS> for synchronization
1110 between the <function>printf()</function> calls in the two
1111 threads. This is because the C library standard I/O (by default) is
1112 configured not to be thread-safe, which means that if more than one
1113 thread is using standard I/O they might corrupt each other. This is
1114 fixed by a mutual exclusion (or <EMPHASIS>mutex</EMPHASIS>) lockout
1115 mechanism: the threads do not call <function>printf()</function> until
1116 <function>cyg_mutex_lock()</function> has returned, which only happens
1117 when the other thread calls
1118 <function>cyg_mutex_unlock()</function>.</PARA>
1119
1120 <PARA>You could avoid using the mutex by configuring the C library to
1121 be thread-safe (by selecting the component
1122 <LITERAL>CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS</LITERAL>).</PARA>
1123
1124 <FIGURE
1125 ID="FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"><!-- <xref> --> <TITLE>Two
1126 threads with simple print statements after random delays</TITLE>
1127 <GRAPHIC ENTITYREF="programming-graphic9"></GRAPHIC>
1128 </FIGURE>
1129
1130 </SECT2>
1131
1132 </SECT1>
1133
1134 </CHAPTER>
1135
1136 <!-- ==================================================== -->
1137
1138 <CHAPTER ID="CLOCKS-AND-ALARM-HANDLERS">
1139 <TITLE>More Features &mdash; <!-- <index></index> -->Clocks and Alarm
1140 Handlers</TITLE>
1141
1142 <PARA>If a program wanted to execute a task at a given time, or
1143 periodically, it could do it in an inefficient way by sitting in a
1144 loop and checking the real-time clock to see if the proper amount of
1145 time has elapsed. But operating systems usually provide system calls
1146 which allow the program to be informed at the desired time.</PARA>
1147
1148 <PARA><productname>eCos</productname> provides a rich timekeeping formalism, involving
1149 <EMPHASIS>counters</EMPHASIS>, <EMPHASIS>clocks</EMPHASIS>,
1150 <EMPHASIS>alarms</EMPHASIS>, and <EMPHASIS>timers</EMPHASIS>.  The
1151 precise definition, relationship, and motivation of these features is
1152 beyond the scope of this tutorial, but these examples illustrate how
1153 to set up basic periodic tasks.</PARA>
1154
1155 <PARA><!-- <index></index> -->Alarms are events that happen at
1156 a given time, either once or periodically. A thread associates an
1157 alarm handling function with the alarm, so that the function will
1158 be invoked every time the alarm &ldquo;goes off&rdquo;.</PARA>
1159
1160 <!-- ==================================================== -->
1161
1162 <SECT1 id="sample-alarms">
1163 <TITLE>A Sample Program with Alarms</TITLE>
1164
1165 <PARA><!-- <index></index> --><FILENAME>simple-alarm.c</FILENAME> (in
1166 the examples directory) is a short program that creates a thread that
1167 creates an alarm. The alarm is handled by the function
1168 <FUNCTION>test_alarm_func()</FUNCTION>, which sets a global
1169 variable. When the main thread of execution sees that the variable has
1170 changed, it prints a message.</PARA>
1171
1172 <EXAMPLE>
1173 <TITLE>A sample <!-- <index></index> -->program that creates an alarm</TITLE>
1174
1175 <PROGRAMLISTING>
1176 /* this is a very simple program meant to demonstrate
1177  a basic use of time, alarms and alarm-handling functions  in eCos */
1178
1179 #include &lt;cyg/kernel/kapi.h&#62;
1180
1181 #include &lt;stdio.h&#62;
1182
1183 #define NTHREADS 1
1184 #define STACKSIZE 4096
1185
1186 static cyg_handle_t thread[NTHREADS];
1187
1188 static cyg_thread thread_obj[NTHREADS];
1189 static char stack[NTHREADS][STACKSIZE];
1190
1191 static void alarm_prog( cyg_addrword_t data );
1192
1193 /* we install our own startup routine which sets up
1194   threads and starts the scheduler */
1195 void cyg_user_start(void)
1196 {
1197  cyg_thread_create(4, alarm_prog, (cyg_addrword_t) 0,
1198         "alarm_thread", (void *) stack[0],
1199         STACKSIZE, &amp;thread[0], &amp;thread_obj[0]);
1200  cyg_thread_resume(thread[0]);
1201 }
1202
1203 /* we need to declare the alarm handling function (which is
1204  defined below), so that we can pass it to  cyg_alarm_initialize() */
1205 cyg_alarm_t test_alarm_func;
1206
1207 /* alarm_prog() is a thread which sets up an alarm which is then
1208  handled by test_alarm_func() */
1209 static void alarm_prog(cyg_addrword_t data)
1210 {
1211  cyg_handle_t test_counterH, system_clockH, test_alarmH;
1212  cyg_tick_count_t ticks;
1213  cyg_alarm test_alarm;
1214  unsigned how_many_alarms = 0, prev_alarms = 0, tmp_how_many;
1215
1216  system_clockH = cyg_real_time_clock();
1217  cyg_clock_to_counter(system_clockH, &amp;test_counterH);
1218  cyg_alarm_create(test_counterH, test_alarm_func,
1219         (cyg_addrword_t) &amp;how_many_alarms,
1220         &amp;test_alarmH, &amp;test_alarm);
1221  cyg_alarm_initialize(test_alarmH, cyg_current_time()+200, 200);
1222
1223  /* get in a loop in which we read the current time and
1224     print it out, just to have something scrolling by */
1225  for (;;) {
1226    ticks = cyg_current_time();
1227    printf("Time is %llu\n", ticks);
1228    /* note that we must lock access to how_many_alarms, since the
1229    alarm handler might change it. this involves using the
1230    annoying temporary variable tmp_how_many so that I can keep the
1231    critical region short */
1232    cyg_scheduler_lock();
1233    tmp_how_many = how_many_alarms;
1234    cyg_scheduler_unlock();
1235    if (prev_alarms != tmp_how_many) {
1236      printf(" --- alarm calls so far: %u\n", tmp_how_many);
1237      prev_alarms = tmp_how_many;
1238    }
1239    cyg_thread_delay(30);
1240  }
1241 }
1242
1243 /* test_alarm_func() is invoked as an alarm handler, so
1244    it should be quick and simple. in this case it increments
1245    the data that is passed to it. */
1246 void test_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
1247 {
1248  ++*((unsigned *) data);
1249 }
1250 </PROGRAMLISTING>
1251 </EXAMPLE>
1252
1253 <PARA>When you run this program (by typing <COMMAND>continue</COMMAND> at
1254 the (<EMPHASIS>gdb</EMPHASIS>) prompt) the output should look like
1255 this:</PARA>
1256 <SCREEN>
1257 Starting program: <replaceable>BASE_DIR</replaceable>/examples/simple-alarm.exe
1258 Time is 0
1259 Time is 30
1260 Time is 60
1261 Time is 90
1262 Time is 120
1263 Time is 150
1264 Time is 180
1265 Time is 210
1266   --- alarm calls so far: 1
1267 Time is 240
1268 Time is 270
1269 Time is 300
1270 Time is 330
1271 Time is 360
1272 Time is 390
1273 Time is 420
1274   --- alarm calls so far: 2
1275 Time is 450
1276 Time is 480
1277 </SCREEN>
1278
1279 <NOTE>
1280 <PARA>When running in a simulator the <!-- <index></index> --> delays
1281 might be quite long. On a hardware board (where the clock speed is 100
1282 ticks/second) the delays should average to about 0.3 seconds (and 2
1283 seconds between alarms). In simulation, the delay will depend on the
1284 speed of the host processor and will almost always be much slower than
1285 the actual board. You might want to reduce the delay parameter when
1286 running in simulation.</PARA>
1287 </NOTE>
1288
1289 <PARA>Here are a few things you might notice about this program:</PARA>
1290
1291 <ITEMIZEDLIST>
1292 <LISTITEM>
1293 <PARA>It used the <function>cyg_real_time_clock()</function> function;
1294 this always returns a handle to the default system real-time <!--
1295 <index></index> --> clock. </PARA>
1296 </LISTITEM>
1297
1298 <LISTITEM>
1299 <PARA><!-- <index></index> -->Clocks are based on <!-- <index></index>
1300 --> counters, so the function <function>cyg_alarm_create()</function>
1301 uses a counter handle. The program used the function
1302 <function>cyg_clock_to_counter()</function> to strip the clock handle
1303 to the underlying counter handle. </PARA>
1304 </LISTITEM>
1305
1306 <LISTITEM>
1307 <PARA>Once the alarm is created it is <!-- <index></index> -->
1308 initialized with <function>cyg_alarm_initialize()</function>, which
1309 sets the time at which the alarm should go off, as well as the period
1310 for repeating alarms. It is set to go off at the current time and
1311 then to repeat every 200 ticks. </PARA>
1312 </LISTITEM>
1313
1314 <LISTITEM>
1315 <PARA>The alarm handler function
1316 <function>test_alarm_func()</function> conforms to the guidelines for
1317 writing alarm handlers and other <!-- <index></index> --><!--
1318 <index></index> --> delayed service routines: it does not invoke any
1319 functions which might lock the scheduler.  This is discussed in detail
1320 in the <CITETITLE><productname>eCos</productname> Reference Manual</CITETITLE>, in the chapter
1321 <citetitle>The <productname>eCos</productname> Kernel</citetitle>.</PARA>
1322 </LISTITEM>
1323
1324 <LISTITEM>
1325 <PARA>There is a <EMPHASIS>critical region</EMPHASIS> in this program:
1326 the variable <LITERAL>how_many_alarms</LITERAL> is accessed in the
1327 main thread of control and is also modified in the alarm handler. To
1328 prevent a possible (though unlikely) race condition on this variable,
1329 access to <LITERAL>how_many_alarms</LITERAL> in the principal thread
1330 is protected by calls to <FUNCTION>cyg_scheduler_lock()</FUNCTION> and
1331 <FUNCTION>cyg_scheduler_unlock()</FUNCTION>. When the scheduler is
1332 locked, the alarm handler will not be invoked, so the problem is
1333 averted. </PARA>
1334 </LISTITEM>
1335 </ITEMIZEDLIST>
1336 </SECT1>
1337 </CHAPTER>
1338
1339 </part>
1340