source: rtems-docs/bsp_howto/bsp_howto_old_reference_only.rst @ f916fca

4.115
Last change on this file since f916fca was 548f844, checked in by Amar Takhar <amar@…>, on 01/17/16 at 05:48:04

Rename old document for reference only.

  • Property mode set to 100644
File size: 169.1 KB
Line 
1:orphan:
2
3
4
5.. COMMENT: %**end of header
6
7.. COMMENT: COPYRIGHT (c) 1989-2013.
8
9.. COMMENT: On-Line Applications Research Corporation (OAR).
10
11.. COMMENT: All rights reserved.
12
13.. COMMENT: Master file for the Getting Started (C) Guide
14
15.. COMMENT: COPYRIGHT (c) 1988-2002.
16
17.. COMMENT: On-Line Applications Research Corporation (OAR).
18
19.. COMMENT: All rights reserved.
20
21.. COMMENT: The following determines which set of the tables and figures we will use.
22
23.. COMMENT: We default to ASCII but if available TeX or HTML versions will
24
25.. COMMENT: be used instead.
26
27.. COMMENT: @clear use-html
28
29.. COMMENT: @clear use-tex
30
31.. COMMENT: The following variable says to use texinfo or html for the two column
32
33.. COMMENT: texinfo tables.  For somethings the format does not look good in html.
34
35.. COMMENT: With our adjustment to the left column in TeX, it nearly always looks
36
37.. COMMENT: good printed.
38
39.. COMMENT: Custom whitespace adjustments.  We could fiddle a bit more.
40
41.. COMMENT: Title Page Stuff
42
43.. COMMENT: I don't really like having a short title page.  -joel
44
45.. COMMENT: @shorttitlepage BSP and Device Driver Development Guide
46
47=======================================
48BSP and Device Driver Development Guide
49=======================================
50
51.. COMMENT: COPYRIGHT (c) 1988-2015.
52
53.. COMMENT: On-Line Applications Research Corporation (OAR).
54
55.. COMMENT: All rights reserved.
56
57.. COMMENT: The following puts a space somewhere on an otherwise empty page so we
58
59.. COMMENT: can force the copyright description onto a left hand page.
60
61COPYRIGHT © 1988 - 2015.
62
63On-Line Applications Research Corporation (OAR).
64
65The authors have used their best efforts in preparing
66this material.  These efforts include the development, research,
67and testing of the theories and programs to determine their
68effectiveness.  No warranty of any kind, expressed or implied,
69with regard to the software or the material contained in this
70document is provided.  No liability arising out of the
71application or use of any product described in this document is
72assumed.  The authors reserve the right to revise this material
73and to make changes from time to time in the content hereof
74without obligation to notify anyone of such revision or changes.
75
76The RTEMS Project is hosted at http://www.rtems.org.  Any
77inquiries concerning RTEMS, its related support components, or its
78documentation should be directed to the Community Project hosted athttp://www.rtems.org.
79
80Any inquiries for commercial services including training, support, custom
81development, application development assistance should be directed tohttp://www.rtems.com.
82
83.. COMMENT: This prevents a black box from being printed on "overflow" lines.
84
85.. COMMENT: The alternative is to rework a sentence to avoid this problem.
86
87RTEMS BSP and Device Driver Development Guide
88#############################################
89
90.. COMMENT: COPYRIGHT (c) 1988-2002.
91
92.. COMMENT: On-Line Applications Research Corporation (OAR).
93
94.. COMMENT: All rights reserved.
95
96Introduction
97############
98
99Before reading this documentation, it is strongly advised to read the
100RTEMS Development Environment Guide to get acquainted with the RTEMS
101directory structure.  This document describes how to do a RTEMS Board
102Support Package, i.e. how to port RTEMS on a new target board. Discussions
103are provided for the following topics:
104
105- RTEMS Board Support Package Organization
106
107- Makefiles and the Linker Command Script
108
109- Board Initialization Sequence
110
111- Device Drivers Including:
112  - Console Driver
113  - Clock Driver
114  - Timer Driver
115  - Real-Time Clock Driver
116  - Non-Volatile Memory Driver
117  - Networking Driver
118  - Shared Memory Support Driver
119  - Analog Driver
120  - Discrete Driver
121
122The original version of this manual was written by Geoffroy Montel
123<g_montel@yahoo.com>.  When he started development of the gen68340
124BSP, this manual did not exist.  He wrote the initial version of
125this manual as the result of his experiences.  At that time, this
126document was viewed internally as the most important "missing manual"
127in the RTEMS documentation set.
128
129The gen68340 BSP is a good example of the life of an RTEMS BSP.  It is
130based upon a part not recommended for new designs and none of the core RTEMS
131Project team members have one of these boards.  Thus we are unlikely to
132perform major updates on this BSP.  So as long as it compiles and links all
133tests, it will be available.
134
135The RTEMS Project team members are always trying to identify common
136code across BSPs and refactoring the code into shared routines.
137As part of this effort, the we will enhance the common BSP Framework.
138Not surprisingly, not every BSP takes advantage of every feature in
139the framework.  The gen68340 does not take advantage of as many features
140as the ERC32 BSP does.  So in many ways, the ERC32 is a better example
141BSP at this point.  But even the ERC32 BSP does not include examples
142of every driver template and framework available to the BSP author.
143So in this guide we will try to point out good examples from other BSPs.
144
145Our goal is for you to be able to reuse as much code as possible and
146write as little board specific code as possible.
147
148.. COMMENT: COPYRIGHT (c) 1988-2002.
149
150.. COMMENT: On-Line Applications Research Corporation (OAR).
151
152.. COMMENT: All rights reserved.
153
154Target Dependent Files
155######################
156
157RTEMS has a multi-layered approach to portability.  This is done to
158maximize the amount of software that can be reused.  Much of the
159RTEMS source code can be reused on all RTEMS platforms.  Other parts
160of the executive are specific to hardware in some sense.
161RTEMS classifies target dependent code based upon its dependencies
162into one of the following categories.
163
164- CPU dependent
165
166- Board dependent
167
168- Peripheral dependent
169
170CPU Dependent
171=============
172
173This class of code includes the foundation
174routines for the executive proper such as the context switch and
175the interrupt subroutine implementations.  Sources for the supported
176processor families can be found in ``cpukit/score/cpu``.
177A good starting point for a new family of processors is the``no_cpu`` directory, which holds both prototypes and
178descriptions of each needed CPU dependent function.
179
180CPU dependent code is further subcategorized if the implementation is
181dependent on a particular CPU model.  For example, the MC68000 and MC68020
182processors are both members of the m68k CPU family but there are significant
183differences between these CPU models which RTEMS must take into account.
184
185The source code found in the ``cpukit/score/cpu`` is required to
186only depend upon the CPU model variations that GCC distinguishes
187for the purposes of multilib’ing.  Multilib is the term the GNU
188community uses to refer to building a single library source multiple
189times with different compiler options so the binary code generated
190is compatible.  As an example, from GCC’s perspective, many PowerPC
191CPU models are just a PPC603e.  Remember that GCC only cares about
192the CPU code itself and need not be aware of any peripherals.  In
193the embedded community, we are exposed to thousands of CPU models
194which are all based upon only a relative small number of CPU cores.
195
196Similarly for the SPARC/ERC32 BSP, the ``RTEMS_CPU`` is specified as``erc32`` which is the name of the CPU model and BSP for this SPARC V7
197system on chip.  But the multilib variant used is actually ``v7``
198which indicates the ERC32 CPU core is a SPARC V7.
199
200Board Dependent
201===============
202
203This class of code provides the most specific glue between RTEMS and
204a particular board.  This code is represented by the Board Support Packages
205and associated Device Drivers.  Sources for the BSPs included in the
206RTEMS distribution are located in the directory ``c/src/lib/libbsp``.
207The BSP source directory is further subdivided based on the CPU family
208and BSP.
209
210Some BSPs may support multiple board models within a single board family.
211This is necessary when the board supports multiple variants on a
212single base board.  For example, the Motorola MVME162 board family has a
213fairly large number of variations based upon the particular CPU model
214and the peripherals actually placed on the board.
215
216Peripheral Dependent
217====================
218
219This class of code provides a reusable library of peripheral device
220drivers which can be tailored easily to a particular board.  The
221libchip library is a collection of reusable software objects that
222correspond to standard controllers.  Just as the hardware engineer
223chooses a standard controller when designing a board, the goal of
224this library is to let the software engineer do the same thing.
225
226The source code for the reusable peripheral driver library may be found
227in the directory ``c/src/lib/libchip``.  The source code is further
228divided based upon the class of hardware.  Example classes include serial
229communications controllers, real-time clocks, non-volatile memory, and
230network controllers.
231
232Questions to Ask
233================
234
235When evaluating what is required to support RTEMS applications on
236a particular target board, the following questions should be asked:
237
238- Does a BSP for this board exist?
239
240- Does a BSP for a similar board exists?
241
242- Is the board’s CPU supported?
243
244If there is already a BSP for the board, then things may already be ready
245to start developing application software.  All that remains is to verify
246that the existing BSP provides device drivers for all the peripherals
247on the board that the application will be using.  For example, the application
248in question may require that the board’s Ethernet controller be used and
249the existing BSP may not support this.
250
251If the BSP does not exist and the board’s CPU model is supported, then
252examine the reusable chip library and existing BSPs for a close match.
253Other BSPs and libchip provide starting points for the development
254of a new BSP.  It is often possible to copy existing components in
255the reusable chip library or device drivers from BSPs from different
256CPU families as the starting point for a new device driver.
257This will help reduce the development effort required.
258
259If the board’s CPU family is supported but the particular CPU model on
260that board is not, then the RTEMS port to that CPU family will have to
261be augmented.  After this is done, development of the new BSP can proceed.
262
263Otherwise both CPU dependent code and the BSP will have to be written.
264
265This type of development often requires specialized skills.  If
266you need help in making these modifications to RTEMS, please
267consider using one of the RTEMS Service Providers.  The current
268list of these is at http://www.rtems.org/support.html.
269
270CPU Dependent Executive Files
271=============================
272
273The CPU dependent files in the RTEMS executive source code are found
274in the following directory:
275.. code:: c
276
277    cpukit/score/cpu/*CPU*
278
279where *CPU* is replaced with the CPU family name.
280
281Within each CPU dependent directory inside the executive proper is a
282file named ``*CPU*.h`` which contains information about each of the
283supported CPU models within that family.
284
285CPU Dependent Support Files
286===========================
287
288The CPU dependent support files contain routines which aid in the development
289of applications using that CPU family.  For example, the support routines
290may contain standard trap handlers for alignment or floating point exceptions
291or device drivers for peripheral controllers found on the CPU itself.
292This class of code may be found in the following directory:
293
294.. code:: c
295
296    c/src/lib/libcpu/*CPU*
297
298CPU model dependent support code is found in the following directory:
299
300.. code:: c
301
302    c/src/lib/libcpu/*CPU*/*CPU_MODEL*
303
304*CPU_MODEL* may be a specific CPU model name or a name indicating a CPU
305core or a set of related CPU models.  The file ``configure.ac`` in each ``c/src/lib/libcpu/*CPU*`` directory contains the logic which enables
306the appropriate subdirectories for the specific CPU model your BSP has.
307
308Board Support Package Structure
309===============================
310
311The BSPs are all under the ``c/src/lib/libbsp`` directory.  Below this
312directory, there is a subdirectory for each CPU family.  Each BSP
313is found under the subdirectory for the appropriate processor
314family (m68k, powerpc, etc.).  In addition, there is source code
315available which may be shared across all BSPs regardless of
316the CPU family or just across BSPs within a single CPU family.  This
317results in a BSP using the following directories:
318.. code:: c
319
320    c/src/lib/libbsp/shared
321    c/src/lib/libbsp/*CPU*/shared
322    c/src/lib/libbsp/*CPU*/*BSP*
323
324Under each BSP specific directory, there is a collection of
325subdirectories.  For commonly provided functionality, the BSPs
326follow a convention on subdirectory naming.  The following list
327describes the commonly found subdirectories under each BSP.
328
329- *console*:
330  is technically the serial driver for the BSP rather
331  than just a console driver, it deals with the board
332  UARTs (i.e. serial devices).
333
334- *clock*:
335  support for the clock tick – a regular time basis to the kernel.
336
337- *timer*:
338  support of timer devices.
339
340- *rtc* or ``tod``:
341  support for the hardware real-time clock.
342
343- *nvmem*:
344  support for non-volatile memory such as EEPROM or Flash.
345
346- *network*:
347  the Ethernet driver.
348
349- *shmsupp*:
350  support of shared memory driver MPCI layer in a multiprocessor system,
351
352- *include*:
353  include files for this BSP.
354
355- *gnatsupp*:
356  BSP specific support for the GNU Ada run-time.  Each BSP that wishes
357  to have the possibility to map faults or exceptions into Ada language
358  exceptions or hardware interrupts into Ada interrupt tasks must provide
359  this support.
360
361There may be other directories in the BSP tree and the name should
362be indicative of the functionality of the code within that directory.
363
364The build order of the BSP is determined by the Makefile structure.
365This structure is discussed in more detail in the `Makefiles`_
366chapter.
367
368*NOTE:* This manual refers to the gen68340 BSP for numerous concrete
369examples.  You should have a copy of the gen68340 BSP available while
370reading this piece of documentation.   This BSP is located in the
371following directory:
372.. code:: c
373
374    c/src/lib/libbsp/m68k/gen68340
375
376Later in this document, the $BSP340_ROOT label will be used
377to refer to this directory.
378
379.. COMMENT: COPYRIGHT (c) 1988-2008.
380
381.. COMMENT: On-Line Applications Research Corporation (OAR).
382
383.. COMMENT: All rights reserved.
384
385
386Makefiles
387#########
388
389This chapter discusses the Makefiles associated with a BSP.  It does not
390describe the process of configuring, building, and installing RTEMS.
391This chapter will not provide detailed information about this process.
392Nonetheless, it is important to remember that the general process consists
393of four phases as shown here:
394
395- .. code:: c
396
397      bootstrap
398
399- .. code:: c
400
401      configure
402
403- .. code:: c
404
405      build
406
407- .. code:: c
408
409      install
410
411During the bootstrap phase, you are using the ``configure.ac`` and``Makefile.am`` files as input to GNU autoconf and automake to
412generate a variety of files.  This is done by running the ``bootstrap``
413script found at the top of the RTEMS source tree.
414
415During the configure phase, a number of files are generated.  These
416generated files are tailored for the specific host/target combination
417by the configure script.  This set of files includes the Makefiles used
418to actually compile and install RTEMS.
419
420During the build phase, the source files are compiled into object files
421and libraries are built.
422
423During the install phase, the libraries, header files, and other support
424files are copied to the BSP specific installation point.  After installation
425is successfully completed, the files generated by the configure and build
426phases may be removed.
427
428Makefiles Used During The BSP Building Process
429==============================================
430
431RTEMS uses the *GNU automake* and *GNU autoconf* automatic
432configuration package.  Consequently, there are a number of
433automatically generated files in each directory in the RTEMS
434source tree.  The ``bootstrap`` script found in the top level
435directory of the RTEMS source tree is executed to produce the
436automatically generated files.  That script must be run from
437a directory with a ``configure.ac`` file in it.  The ``bootstrap``
438command is usually invoked in one of the following manners:
439
440- ``bootstrap`` to regenerate all files that are generated by
441  autoconf and automake.
442
443- ``bootstrap -c`` to remove all files generated by autoconf and
444  automake.
445
446- ``bootstrap -p`` to regenerate ``preinstall.am`` files.
447
448There is a file named ``Makefile.am`` in each directory of
449a BSP.  This file is used by *automake* to produce the file named``Makefile.in`` which is also found in each directory of a BSP.
450When modifying a ``Makefile.am``, you can probably find examples of
451anything you need to do in one of the BSPs.
452
453The configure process specializes the ``Makefile.in`` files at the time that RTEMS
454is configured for a specific development host and target.  Makefiles
455are automatically generated from the ``Makefile.in`` files.  It is
456necessary for the BSP developer to provide the ``Makefile.am``
457files and generate the ``Makefile.in`` files.  Most of the
458time, it is possible to copy the ``Makefile.am`` from another
459similar directory and edit it.
460
461The ``Makefile`` files generated are processed when configuring
462and building RTEMS for a given BSP.
463
464The BSP developer is responsible for generating ``Makefile.am``
465files which properly build all the files associated with their BSP.
466Most BSPs will only have a single ``Makefile.am`` which details
467the set of source files to build to compose the BSP support library
468along with the set of include files that are to be installed.
469
470This single ``Makefile.am`` at the top of the BSP tree specifies
471the set of header files to install.  This fragment from the SPARC/ERC32
472BSP results in four header files being installed.
473.. code:: c
474
475    include_HEADERS = include/bsp.h
476    include_HEADERS += include/tm27.h
477    include_HEADERS += include/erc32.h
478    include_HEADERS += include/coverhd.h
479
480When adding new include files, you will be adding to the set of``include_HEADERS``.  When you finish editing the ``Makefile.am``
481file, do not forget to run ``bootstrap -p`` to regenerate the``preinstall.am``.
482
483The ``Makefile.am`` also specifies which source files to build.
484By convention, logical components within the BSP each assign their
485source files to a unique variable.  These variables which define
486the source files are collected into a single variable which instructs
487the GNU autotools that we are building ``libbsp.a``.  This fragment
488from the SPARC/ERC32 BSP shows how the startup related, miscellaneous
489support code, and the console device driver source is managed
490in the ``Makefile.am``.
491.. code:: c
492
493    startup_SOURCES = ../../sparc/shared/bspclean.c ../../shared/bsplibc.c \\
494    ../../shared/bsppredriverhook.c \\
495    ../../shared/bsppost.c ../../sparc/shared/bspstart.c \\
496    ../../shared/bootcard.c ../../shared/sbrk.c startup/setvec.c \\
497    startup/spurious.c startup/erc32mec.c startup/boardinit.S
498    clock_SOURCES = clock/ckinit.c
499    ...
500    noinst_LIBRARIES = libbsp.a
501    libbsp_a_SOURCES = $(startup_SOURCES) $(console_SOURCES) ...
502
503When adding new files to an existing directory, do not forget to add
504the new files to the list of files to be built in the corresponding``XXX_SOURCES`` variable in the ``Makefile.am`` and run``bootstrap``.
505
506Some BSPs use code that is built in ``libcpu``.  If you BSP does
507this, then you will need to make sure the objects are pulled into your
508BSP library.  The following from the SPARC/ERC32 BSP pulls in the cache,
509register window management and system call support code from the directory
510corresponding to its ``RTEMS_CPU`` model.
511.. code:: c
512
513    libbsp_a_LIBADD  = ../../../libcpu/@RTEMS_CPU@/cache.rel \\
514    ../../../libcpu/@RTEMS_CPU@/reg_win.rel \\
515    ../../../libcpu/@RTEMS_CPU@/syscall.rel
516
517*NOTE:* The ``Makefile.am`` files are ONLY processed by``bootstrap`` and the resulting ``Makefile.in`` files are only
518processed during the configure process of a RTEMS build. Therefore,
519when developing a BSP and adding a new file to a ``Makefile.am``,
520the already generated ``Makefile`` will not automatically
521include the new references unless you configured RTEMS with the``--enable-maintainer-mode`` option.  Otherwise, the new file not
522being be taken into account!
523
524Creating a New BSP Make Customization File
525==========================================
526
527When building a BSP or an application using that BSP, it is necessary
528to tailor the compilation arguments to account for compiler flags, use
529custom linker scripts, include the RTEMS libraries, etc..  The BSP
530must be built using this information.  Later, once the BSP is installed
531with the toolset, this same information must be used when building the
532application.  So a BSP must include a build configuration file.  The
533configuration file is ``make/custom/BSP.cfg``.
534
535The configuration file is taken into account when building one’s
536application using the RTEMS template Makefiles (``make/templates``).
537These application template Makefiles have been included with the
538RTEMS source distribution since the early 1990’s.  However there is
539a desire in the RTEMS user community to move all provided examples to
540GNU autoconf. They are included in the 4.9 release series and used for
541all examples provided with RTEMS. There is no definite time table for
542obsoleting them.  You are free to use these but be warned they have
543fallen out of favor with many in the RTEMS community and may disappear
544in the future.
545
546The following is a slightly shortened version of the make customization
547file for the gen68340 BSP.  The original source for this file can be
548found in the ``make/custom`` directory.
549.. code:: c
550
551    # The RTEMS CPU Family and Model
552    RTEMS_CPU=m68k
553    RTEMS_CPU_MODEL=m68340
554    include $(RTEMS_ROOT)/make/custom/default.cfg
555    # This is the actual bsp directory used during the build process.
556    RTEMS_BSP_FAMILY=gen68340
557    # This contains the compiler options necessary to select the CPU model
558    # and (hopefully) optimize for it.
559    CPU_CFLAGS = -mcpu=cpu32
560    # optimize flag: typically -O2
561    CFLAGS_OPTIMIZE_V = -O2 -g -fomit-frame-pointer
562
563The make customization files have generally grown simpler and simpler
564with each RTEMS release.  Beginning in the 4.9 release series, the rules
565for linking an RTEMS application are shared by all BSPs.  Only BSPs which
566need to perform a transformation from linked ELF file to a downloadable
567format have any additional actions for program link time. In 4.8 and
568older, every BSP specified the "make executable" or ``make-exe``
569rule and duplicated the same actions.
570
571It is generally easier to copy a ``make/custom`` file from a
572BSP similar to the one being developed.
573
574.. COMMENT: COPYRIGHT (c) 1988-2002.
575
576.. COMMENT: On-Line Applications Research Corporation (OAR).
577
578.. COMMENT: All rights reserved.
579
580Linker Script
581#############
582
583What is a "linkcmds" file?
584==========================
585
586The ``linkcmds`` file is a script which is passed to the linker at linking
587time.  This file describes the memory configuration of the board as needed
588to link the program.  Specifically it specifies where the code and data
589for the application will reside in memory.
590
591The format of the linker script is defined by the GNU Loader ``ld``
592which is included as a component of the GNU Binary Utilities.  If you
593are using GNU/Linux, then you probably have the documentation installed
594already and are using these same tools configured for *native* use.
595Please visit the Binutils project http://sourceware.org/binutils/
596if you need more information.
597
598Program Sections
599================
600
601An embedded systems programmer must be much more aware of the
602placement of their executable image in memory than the average
603applications programmer.  A program destined to be embedded as well
604as the target system have some specific properties that must be
605taken into account. Embedded machines often mean average performances
606and small memory usage.  It is the memory usage that concerns us
607when examining the linker command file.
608
609Two types of memories have to be distinguished:
610
611- RAM - volatile offering read and write access
612
613- ROM - non-volatile but read only
614
615Even though RAM and ROM can be found in every personal computer,
616one generally doesn’t care about them.  In a personal computer,
617a program is nearly always stored on disk and executed in RAM.  Things
618are a bit different for embedded targets: the target will execute the
619program each time it is rebooted or switched on.   The application
620program is stored in non-volatile memory such as ROM, PROM, EEPROM,
621or Flash. On the other hand, data processing occurs in RAM.
622
623This leads us to the structure of an embedded program.  In rough terms,
624an embedded program is made of sections.  It is the responsibility of
625the application programmer to place these sections in the appropriate
626place in target memory.  To make this clearer, if using the COFF
627object file format on the Motorola m68k family of microprocessors,
628the following sections will be present:
629
630- *code (``.text``) section*:
631  is the program’s code and it should not be modified.
632  This section may be placed in ROM.
633
634- *non-initialized data (``.bss``) section*:
635  holds uninitialized variables of the program. It can stay in RAM.
636
637- *initialized data (``.data``) section*:
638  holds the initialized program data which may be modified during the
639  program’s life.  This means they have to be in RAM.
640  On the other hand, these variables must be set to predefined values, and
641  those predefined values have to be stored in ROM.
642
643*NOTE:* Many programs and support libraries unknowingly assume that the``.bss`` section and, possibly, the application heap are initialized
644to zero at program start.  This is not required by the ISO/ANSI C Standard
645but is such a common requirement that most BSPs do this.
646
647That brings us up to the notion of the image of an executable: it consists
648of the set of the sections that together constitute the application.
649
650Image of an Executable
651======================
652
653As a program executable has many sections (note that the user can define
654their own, and that compilers define theirs without any notice), one has to
655specify the placement of each section as well as the type of memory
656(RAM or ROM) the sections will be placed into.
657For instance, a program compiled for a Personal Computer will see all the
658sections to go to RAM, while a program destined to be embedded will see
659some of his sections going into the ROM.
660
661The connection between a section and where that section is loaded into
662memory is made at link time.  One has to let the linker know where
663the different sections are to be placed once they are in memory.
664
665The following example shows a simple layout of program sections.  With
666some object formats, there are many more sections but the basic
667layout is conceptually similar.
668.. code:: c
669
670    +-----------------+-------------+
671    |     .text       |  RAM or ROM |
672    +-----------------+-------------+
673    |     .data       |  RAM        |
674    +-----------------+-------------+
675    |     .bss        |  RAM        |
676    +-----------------+-------------+
677
678Example Linker Command Script
679=============================
680
681The GNU linker has a command language to specify the image format.  This
682command language can be quite complicated but most of what is required
683can be learned by careful examination of a well-documented example.
684The following is a heavily commented version of the linker script
685used with the the ``gen68340`` BSP  This file can be found at
686$BSP340_ROOT/startup/linkcmds.
687.. code:: c
688
689    /*
690    *  Specify that the output is to be coff-m68k regardless of what the
691    *  native object format is.
692    \*/
693    OUTPUT_FORMAT(coff-m68k)
694    /*
695    *  Set the amount of RAM on the target board.
696    *
697    *  NOTE: The default may be overridden by passing an argument to ld.
698    \*/
699    RamSize = DEFINED(RamSize) ? RamSize : 4M;
700    /*
701    *  Set the amount of RAM to be used for the application heap.  Objects
702    *  allocated using malloc() come from this area.  Having a tight heap
703    *  size is somewhat difficult and multiple attempts to squeeze it may
704    *  be needed reducing memory usage is important.  If all objects are
705    *  allocated from the heap at system initialization time, this eases
706    *  the sizing of the application heap.
707    *
708    *  NOTE 1: The default may be overridden by passing an argument to ld.
709    *
710    *  NOTE 2: The TCP/IP stack requires additional memory in the Heap.
711    *
712    *  NOTE 3: The GNAT/RTEMS run-time requires additional memory in
713    *  the Heap.
714    \*/
715    HeapSize = DEFINED(HeapSize) ? HeapSize : 0x10000;
716    /*
717    *  Set the size of the starting stack used during BSP initialization
718    *  until first task switch.  After that point, task stacks allocated
719    *  by RTEMS are used.
720    *
721    *  NOTE: The default may be overridden by passing an argument to ld.
722    \*/
723    StackSize = DEFINED(StackSize) ? StackSize : 0x1000;
724    /*
725    *  Starting addresses and length of RAM and ROM.
726    *
727    *  The addresses must be valid addresses on the board.  The
728    *  Chip Selects should be initialized such that the code addresses
729    *  are valid.
730    \*/
731    MEMORY {
732    ram : ORIGIN = 0x10000000, LENGTH = 4M
733    rom : ORIGIN = 0x01000000, LENGTH = 4M
734    }
735    /*
736    *  This is for the network driver.  See the Networking documentation
737    *  for more details.
738    \*/
739    ETHERNET_ADDRESS =
740    DEFINED(ETHERNET_ADDRESS) ? ETHERNET_ADDRESS : 0xDEAD12;
741    /*
742    *  The following defines the order in which the sections should go.
743    *  It also defines a number of variables which can be used by the
744    *  application program.
745    *
746    *  NOTE: Each variable appears with 1 or 2 leading underscores to
747    *        ensure that the variable is accessible from C code with a
748    *        single underscore.  Some object formats automatically add
749    *        a leading underscore to all C global symbols.
750    \*/
751    SECTIONS {
752    /*
753    *  Make the RomBase variable available to the application.
754    \*/
755    _RamSize = RamSize;
756    __RamSize = RamSize;
757    /*
758    *  Boot PROM  - Set the RomBase variable to the start of the ROM.
759    \*/
760    rom : {
761    _RomBase = .;
762    __RomBase = .;
763    } >rom
764    /*
765    * Dynamic RAM - set the RamBase variable to the start of the RAM.
766    \*/
767    ram : {
768    _RamBase = .;
769    __RamBase = .;
770    } >ram
771    /*
772    *  Text (code) goes into ROM
773    \*/
774    .text : {
775    /*
776    *  Create a symbol for each object (.o).
777    \*/
778    CREATE_OBJECT_SYMBOLS
779    /*
780    *  Put all the object files code sections here.
781    \*/
782    \*(.text)
783    . = ALIGN (16);      /*  go to a 16-byte boundary \*/
784    /*
785    *  C++ constructors and destructors
786    *
787    *  NOTE:  See the CROSSGCC mailing-list FAQ for
788    *         more details about the "\[......]".
789    \*/
790    __CTOR_LIST__ = .;
791    \[......]
792    __DTOR_END__ = .;
793    /*
794    *  Declares where the .text section ends.
795    \*/
796    etext = .;
797    _etext = .;
798    } >rom
799    /*
800    *  Exception Handler Frame section
801    \*/
802    .eh_fram : {
803    . = ALIGN (16);
804    \*(.eh_fram)
805    } >ram
806    /*
807    *  GCC Exception section
808    \*/
809    .gcc_exc : {
810    . = ALIGN (16);
811    \*(.gcc_exc)
812    } >ram
813    /*
814    *  Special variable to let application get to the dual-ported
815    *  memory.
816    \*/
817    dpram : {
818    m340 = .;
819    _m340 = .;
820    . += (8 * 1024);
821    } >ram
822    /*
823    *  Initialized Data section goes in RAM
824    \*/
825    .data : {
826    copy_start = .;
827    \*(.data)
828    . = ALIGN (16);
829    _edata = .;
830    copy_end = .;
831    } >ram
832    /*
833    *  Uninitialized Data section goes in ROM
834    \*/
835    .bss : {
836    /*
837    *  M68K specific: Reserve some room for the Vector Table
838    *  (256 vectors of 4 bytes).
839    \*/
840    M68Kvec = .;
841    _M68Kvec = .;
842    . += (256 * 4);
843    /*
844    *  Start of memory to zero out at initialization time.
845    \*/
846    clear_start = .;
847    /*
848    *  Put all the object files uninitialized data sections
849    *  here.
850    \*/
851    \*(.bss)
852    \*(COMMON)
853    . = ALIGN (16);
854    _end = .;
855    /*
856    *  Start of the Application Heap
857    \*/
858    _HeapStart = .;
859    __HeapStart = .;
860    . += HeapSize;
861    /*
862    *  The Starting Stack goes after the Application Heap.
863    *  M68K stack grows down so start at high address.
864    \*/
865    . += StackSize;
866    . = ALIGN (16);
867    stack_init = .;
868    clear_end = .;
869    /*
870    *  The RTEMS Executive Workspace goes here.  RTEMS
871    *  allocates tasks, stacks, semaphores, etc. from this
872    *  memory.
873    \*/
874    _WorkspaceBase = .;
875    __WorkspaceBase = .;
876    } >ram
877    }
878
879Initialized Data
880================
881
882Now there’s a problem with the initialized data: the ``.data`` section
883has to be in RAM as this data may be modified during the program execution.
884But how will the values be initialized at boot time?
885
886One approach is to place the entire program image in RAM and reload
887the image in its entirety each time the program is run.  This is fine
888for use in a debug environment where a high-speed connection is available
889between the development host computer and the target.  But even in this
890environment, it is cumbersome.
891
892The solution is to place a copy of the initialized data in a separate
893area of memory and copy it into the proper location each time the
894program is started.  It is common practice to place a copy of the initialized ``.data`` section at the end of the code (``.text``) section
895in ROM when building a PROM image. The GNU tool ``objcopy``
896can be used for this purpose.
897
898The following figure illustrates the steps a linked program goes through
899to become a downloadable image.
900
901
902+--------------+-----+--------------------+--------------------------+
903| .data    RAM |     | .data          RAM |                          |
904+--------------+     +--------------------+                          |
905| .bss     RAM |     | .bss           RAM |                          |
906+--------------+     +--------------------+-----+--------------------+
907| .text    ROM |     | .text          ROM |     |     .text          |
908+--------------+-----+---------+----------+-----+--------------------+
909| copy of .data  ROM |         | copy of .data  |                    |
910+--------------------+---------+----------------+--------------------+
911|  Step 1            |Step 2                       Step 3            |
912+--------------------+--------------------------+--------------------+
913
914In Step 1, the program is linked together using the BSP linker script.
915
916In Step 2, a copy is made of the ``.data`` section and placed
917after the ``.text`` section so it can be placed in PROM.  This step
918is done after the linking time.  There is an example
919of doing this in the file $RTEMS_ROOT/make/custom/gen68340.cfg:
920.. code:: c
921
922    # make a PROM image using objcopy
923    m68k-rtems-objcopy \\
924    --adjust-section-vma .data= \\
925    \`m68k-rtems-objdump --section-headers \\
926    $(basename $@).exe \\
927    | awk '\[...]` \\
928    $(basename $@).exe
929
930NOTE: The address of the "copy of ``.data`` section" is
931created by extracting the last address in the ``.text``
932section with an ``awk`` script.  The details of how
933this is done are not relevant.
934
935Step 3 shows the final executable image as it logically appears in
936the target’s non-volatile program memory.  The board initialization
937code will copy the ""copy of ``.data`` section" (which are stored in
938ROM) to their reserved location in RAM.
939
940.. COMMENT: COPYRIGHT (c) 1988-2011.
941
942.. COMMENT: On-Line Applications Research Corporation (OAR).
943
944.. COMMENT: All rights reserved.
945
946Miscellaneous Support Files
947###########################
948
949GCC Compiler Specifications File
950================================
951
952The file ``bsp_specs`` defines the start files and libraries
953that are always used with this BSP.  The format of this file
954is admittedly cryptic and this document will make no attempt
955to explain it completely.  Below is the ``bsp_specs``
956file from the PowerPC psim BSP:
957.. code:: c
958
959    %rename endfile old_endfile
960    %rename startfile old_startfile
961    %rename link old_link
962    \*startfile:
963    %{!qrtems: %(old_startfile)} \\
964    %{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s start.o%s}}
965    \*link:
966    %{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -e _start -u __vectors}
967    \*endfile:
968    %{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
969
970The first section of this file renames the built-in definition of
971some specification variables so they can be augmented without
972embedded their original definition.  The subsequent sections
973specify what behavior is expected when the ``-qrtems`` option is specified.
974
975The ``*startfile`` section specifies that the BSP specific file``start.o`` will be used instead of ``crt0.o``.  In addition,
976various EABI support files (``ecrti.o`` etc.) will be linked in with
977the executable.
978
979The ``*link`` section adds some arguments to the linker when it is
980invoked by GCC to link an application for this BSP.
981
982The format of this file is specific to the GNU Compiler Suite.  The
983argument used to override and extend the compiler built-in specifications
984is available in all recent GCC versions.  The ``-specs`` option is
985present in all ``egcs`` distributions and ``gcc`` distributions
986starting with version 2.8.0.
987
988README Files
989============
990
991Most BSPs provide one or more ``README`` files.  Generally, there
992is a ``README`` file at the top of the BSP source.  This file
993describes the board and its hardware configuration, provides vendor
994information, local configuration information, information on downloading
995code to the board, debugging, etc..  The intent of this
996file is to help someone begin to use the BSP faster.
997
998A ``README`` file in a BSP subdirectory typically explains something
999about the contents of that subdirectory in greater detail.  For example,
1000it may list the documentation available for a particular peripheral
1001controller and how to obtain that documentation.  It may also explain some
1002particularly cryptic part of the software in that directory or provide
1003rationale on the implementation.
1004
1005times
1006=====
1007
1008This file contains the results of the RTEMS Timing Test Suite.  It is
1009in a standard format so that results from one BSP can be easily compared
1010with those of another target board.
1011
1012If a BSP supports multiple variants, then there may be multiple ``times``
1013files.  Usually these are named ``times.VARIANTn``.
1014
1015Tools Subdirectory
1016==================
1017
1018Some BSPs provide additional tools that aid in using the target board.
1019These tools run on the development host and are built as part of building
1020the BSP.  Most common is a script to automate running the RTEMS Test Suites
1021on the BSP.  Examples of this include:
1022
1023- ``powerpc/psim`` includes scripts to ease use of the simulator
1024
1025- ``m68k/mvme162`` includes a utility to download across the
1026  VMEbus into target memory if the host is a VMEbus board in the same
1027  chasis.
1028
1029bsp.h Include File
1030==================
1031
1032The file ``include/bsp.h`` contains prototypes and definitions
1033specific to this board.  Every BSP is required to provide a ``bsp.h``.
1034The best approach to writing a ``bsp.h`` is copying an existing one
1035as a starting point.
1036
1037Many ``bsp.h`` files provide prototypes of variables defined
1038in the linker script (``linkcmds``).
1039
1040tm27.h Include File
1041===================
1042
1043The ``tm27`` test from the RTEMS Timing Test Suite is designed to measure the length of time required to vector to and return from an interrupt handler. This test requires some help from the BSP to know how to cause and manipulate the interrupt source used for this measurement.  The following is a list of these:
1044
1045- ``MUST_WAIT_FOR_INTERRUPT`` - modifies behavior of ``tm27``.
1046
1047- ``Install_tm27_vector`` - installs the interrupt service
1048  routine for the Interrupt Benchmark Test (``tm27``).
1049
1050- ``Cause_tm27_intr`` - generates the interrupt source
1051  used in the Interrupt Benchmark Test (``tm27``).
1052
1053- ``Clear_tm27_intr`` - clears the interrupt source
1054  used in the Interrupt Benchmark Test (``tm27``).
1055
1056- ``Lower_tm27_intr`` - lowers the interrupt mask so the
1057  interrupt source used in the Interrupt Benchmark Test (``tm27``)
1058  can generate a nested interrupt.
1059
1060All members of the Timing Test Suite are designed to run *WITHOUT*
1061the Clock Device Driver installed.  This increases the predictability
1062of the tests’ execution as well as avoids occassionally including the
1063overhead of a clock tick interrupt in the time reported.  Because of
1064this it is sometimes possible to use the clock tick interrupt source
1065as the source of this test interrupt.  On other architectures, it is
1066possible to directly force an interrupt to occur.
1067
1068Calling Overhead File
1069=====================
1070
1071The file ``include/coverhd.h`` contains the overhead associated
1072with invoking each directive.  This overhead consists of the execution
1073time required to package the parameters as well as to execute the "jump to
1074subroutine" and "return from subroutine" sequence.  The intent of this
1075file is to help separate the calling overhead from the actual execution
1076time of a directive.  This file is only used by the tests in the
1077RTEMS Timing Test Suite.
1078
1079The numbers in this file are obtained by running the "Timer Overhead"``tmoverhd`` test.  The numbers in this file may be 0 and no
1080overhead is subtracted from the directive execution times reported by
1081the Timing Suite.
1082
1083There is a shared implementation of ``coverhd.h`` which sets all of
1084the overhead constants to 0.  On faster processors, this is usually the
1085best alternative for the BSP as the calling overhead is extremely small.
1086This file is located at:
1087.. code:: c
1088
1089    c/src/lib/libbsp/shared/include/coverhd.h
1090
1091sbrk() Implementation
1092=====================
1093
1094Although nearly all BSPs give all possible memory to the C Program Heap
1095at initialization, it is possible for a BSP to configure the initial
1096size of the heap small and let it grow on demand.  If the BSP wants
1097to dynamically extend the heap used by the C Library memory allocation
1098routines (i.e. ``malloc`` family), then the``sbrk`` routine must
1099be functional.  The following is the prototype for this routine:
1100.. code:: c
1101
1102    void * sbrk(size_t increment)
1103
1104The ``increment`` amount is based upon the ``sbrk_amount``
1105parameter passed to the ``bsp_libc_init`` during system initialization... index:: CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
1106
1107If your BSP does not want to support dynamic heap extension, then you do not have to do anything special.  However, if you want to support ``sbrk``, you must provide an implementation of this method and define ``CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK`` in ``bsp.h``.  This informs ``rtems/confdefs.h`` to configure the Malloc Family Extensions which support ``sbrk``.
1108
1109bsp_fatal_extension() - Cleanup the Hardware
1110============================================
1111
1112The ``bsp_fatal_extension()`` is an optional BSP specific initial extension
1113invoked once a fatal system state is reached.  Most of the BSPs use the same
1114shared version of ``bsp_fatal_extension()`` that does nothing or performs a
1115system reset.  This implementation is located in the following file:
1116.. code:: c
1117
1118    c/src/lib/libbsp/shared/bspclean.c
1119
1120The ``bsp_fatal_extension()`` routine can be used to return to a ROM
1121monitor, insure that interrupt sources are disabled, etc..  This routine is the
1122last place to ensure a clean shutdown of the hardware.  The fatal source,
1123internal error indicator, and the fatal code arguments are available to
1124evaluate the fatal condition.  All of the non-fatal shutdown sequences
1125ultimately pass their exit status to ``rtems_shutdown_executive`` and this
1126is what is passed to this routine in case the fatal source is
1127RTEMS_FATAL_SOURCE_EXIT.
1128
1129On some BSPs, it prints a message indicating that the application
1130completed execution and waits for the user to press a key before
1131resetting the board.  The PowerPC/gen83xx and PowerPC/gen5200 BSPs do
1132this when they are built to support the FreeScale evaluation boards.
1133This is convenient when using the boards in a development environment
1134and may be disabled for production use.
1135
1136Configuration Macros
1137====================
1138
1139Each BSP can define macros in bsp.h which alter some of the the default configuration parameters in ``rtems/confdefs.h``.  This section describes those macros:
1140
1141- .. index:: CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
1142
1143  ``CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK`` must be defined if the
1144  BSP has proper support for ``sbrk``.  This is discussed in more detail
1145  in the previous section.
1146
1147- .. index:: BSP_IDLE_TASK_BODY
1148
1149  ``BSP_IDLE_TASK_BODY`` may be defined to the entry point of a
1150  BSP specific IDLE thread implementation.  This may be overridden if the
1151  application provides its own IDLE task implementation.
1152
1153- .. index:: BSP_IDLE_TASK_STACK_SIZE
1154
1155  ``BSP_IDLE_TASK_STACK_SIZE`` may be defined to the desired
1156  default stack size for the IDLE task as recommended when using this BSP.
1157
1158- .. index:: BSP_INTERRUPT_STACK_SIZE
1159
1160  ``BSP_INTERRUPT_STACK_SIZE`` may be defined to the desired default interrupt stack size as recommended when using this BSP.  This is sometimes required when the BSP developer has knowledge of stack intensive interrupt handlers.
1161
1162- .. index:: BSP_ZERO_WORKSPACE_AUTOMATICALLY
1163
1164  ``BSP_ZERO_WORKSPACE_AUTOMATICALLY`` is defined when the BSP
1165  requires that RTEMS zero out the RTEMS C Program Heap at initialization.
1166  If the memory is already zeroed out by a test sequence or boot ROM,
1167  then the boot time can be reduced by not zeroing memory twice.
1168
1169- .. index:: BSP_DEFAULT_UNIFIED_WORK_AREAS
1170
1171  ``BSP_DEFAULT_UNIFIED_WORK_AREAS`` is defined when the BSP
1172  recommends that the unified work areas configuration should always
1173  be used.  This is desirable when the BSP is known to always have very
1174  little RAM and thus saving memory by any means is desirable.
1175
1176set_vector() - Install an Interrupt Vector
1177==========================================
1178
1179On targets with Simple Vectored Interrupts, the BSP must provide
1180an implementation of the ``set_vector`` routine.  This routine is
1181responsible for installing an interrupt vector.  It invokes the support
1182routines necessary to install an interrupt handler as either a "raw"
1183or an RTEMS interrupt handler.  Raw handlers bypass the RTEMS interrupt
1184structure and are responsible for saving and restoring all their own
1185registers.  Raw handlers are useful for handling traps, debug vectors,
1186etc..
1187
1188The ``set_vector`` routine is a central place to perform interrupt
1189controller manipulation and encapsulate that information.  It is usually
1190implemented as follows:
1191
1192.. code:: c
1193
1194    rtems_isr_entry set_vector(                     /* returns old vector \*/
1195    rtems_isr_entry     handler,                  /* isr routine        \*/
1196    rtems_vector_number vector,                   /* vector number      \*/
1197    int                 type                      /* RTEMS or RAW intr  \*/
1198    )
1199    {
1200    if the type is RAW
1201    install the raw vector
1202    else
1203    use rtems_interrupt_catch to install the vector
1204    perform any interrupt controller necessary to unmask
1205    the interrupt source
1206    return the previous handler
1207    }
1208
1209*NOTE:* The i386, PowerPC and ARM ports use a Programmable
1210Interrupt Controller model which does not require the BSP to implement``set_vector``.  BSPs for these architectures must provide a different
1211set of support routines.
1212
1213Interrupt Delay Profiling
1214=========================
1215
1216The RTEMS profiling needs support by the BSP for the interrupt delay times.  In
1217case profiling is enabled via the RTEMS build configuration option``--enable-profiling`` (in this case the pre-processor symbol``RTEMS_PROFILING`` is defined) a BSP may provide data for the interrupt
1218delay times.  The BSP can feed interrupt delay times with the``_Profiling_Update_max_interrupt_delay()`` function
1219(``#include <rtems/score/profiling.h>``).  For an example please have a look
1220at ``c/src/lib/libbsp/sparc/leon3/clock/ckinit.c``.
1221
1222Programmable Interrupt Controller API
1223=====================================
1224
1225A BSP can use the PIC API to install Interrupt Service Routines through
1226a set of generic methods. In order to do so, the header files
1227libbsp/shared/include/irq-generic.h and libbsp/shared/include/irq-info.h
1228must be included by the bsp specific irq.h file present in the include/
1229directory. The irq.h acts as a BSP interrupt support configuration file which
1230is used to define some important MACROS. It contains the declarations for
1231any required global functions like bsp_interrupt_dispatch(). Thus later on,
1232every call to the PIC interface requires including <bsp/irq.h>
1233
1234The generic interrupt handler table is intitalized by invoking the``bsp_interrupt_initialize()`` method from bsp_start() in the bspstart.c
1235file which sets up this table to store the ISR addresses, whose size is based
1236on the definition of macros, BSP_INTERRUPT_VECTOR_MIN & BSP_INTERRUPT_VECTOR_MAX
1237in include/bsp.h
1238
1239For the generic handler table to properly function, some bsp specific code is
1240required, that should be present in irq/irq.c . The bsp-specific functions required
1241to be writen by the BSP developer are :
1242
1243- .. index:: bsp_interrupt_facility_initialize()
1244
1245  ``bsp_interrupt_facility_initialize()`` contains bsp specific interrupt
1246  initialization code(Clear Pending interrupts by modifying registers, etc.).
1247  This method is called from bsp_interrupt_initialize() internally while setting up
1248  the table.
1249
1250- .. index:: bsp_interrupt_handler_default()
1251
1252  ``bsp_interrupt_handler_default()`` acts as a fallback handler when
1253  no ISR address has been provided corresponding to a vector in the table.
1254
1255- .. index:: bsp_interrupt_dispatch()
1256
1257  ``bsp_interrupt_dispatch()`` service the ISR by handling
1258  any bsp specific code & calling the generic method bsp_interrupt_handler_dispatch()
1259  which in turn services the interrupt by running the ISR after looking it up in
1260  the table. It acts as an entry to the interrupt switchboard, since the bsp
1261  branches to this function at the time of occurrence of an interrupt.
1262
1263- .. index:: bsp_interrupt_vector_enable()
1264
1265  ``bsp_interrupt_vector_enable()`` enables interrupts and is called in
1266  irq-generic.c while setting up the table.
1267
1268- .. index:: bsp_interrupt_vector_disable()
1269
1270  ``bsp_interrupt_vector_disable()`` disables interrupts and is called in
1271  irq-generic.c while setting up the table & during other important parts.
1272
1273An interrupt handler is installed or removed with the help of the following functions :
1274
1275.. code:: c
1276
1277    rtems_status_code rtems_interrupt_handler_install(   /* returns status code \*/
1278    rtems_vector_number vector,                        /* interrupt vector \*/
1279    const char \*info,                           /* custom identification text \*/
1280    rtems_option options,                              /* Type of Interrupt \*/
1281    rtems_interrupt_handler handler,                   /* interrupt handler \*/
1282    void \*arg  /* parameter to be passed to handler at the time of invocation \*/
1283    )
1284    rtems_status_code rtems_interrupt_handler_remove(   /* returns status code \*/
1285    rtems_vector_number vector,                       /* interrupt vector \*/
1286    rtems_interrupt_handler handler,                  /* interrupt handler \*/
1287    void \*arg                          /* parameter to be passed to handler \*/
1288    )
1289
1290.. COMMENT: COPYRIGHT (c) 1988-2002.
1291
1292.. COMMENT: On-Line Applications Research Corporation (OAR).
1293
1294.. COMMENT: All rights reserved.
1295
1296Ada95 Interrupt Support
1297#######################
1298
1299Introduction
1300============
1301
1302This chapter describes what is required to enable Ada interrupt
1303and error exception handling when using GNAT over RTEMS.
1304
1305The GNAT Ada95 interrupt support RTEMS was developed by
1306Jiri Gaisler <jgais@ws.estec.esa.nl> who also wrote this
1307chapter.
1308
1309Mapping Interrupts to POSIX Signals
1310===================================
1311
1312In Ada95, interrupts can be attached with the interrupt_attach pragma.
1313For most systems, the gnat run-time will use POSIX signal to implement
1314the interrupt handling, mapping one signal per interrupt. For interrupts
1315to be propagated to the attached Ada handler, the corresponding signal
1316must be raised when the interrupt occurs.
1317
1318The same mechanism is used to generate Ada error exceptions.
1319Three error exceptions are defined: program, constraint and storage
1320error. These are generated by raising the predefined signals: SIGILL,
1321SIGFPE and SIGSEGV. These signals should be raised when a spurious
1322or erroneous trap occurs.
1323
1324To enable gnat interrupt and error exception support for a particular
1325BSP, the following has to be done:
1326
1327# Write an interrupt/trap handler that will raise the corresponding
1328  signal depending on the interrupt/trap number.
1329
1330# Install the interrupt handler for all interrupts/traps that will be
1331  handled by gnat (including spurious).
1332
1333# At startup, gnat calls ``__gnat_install_handler()``. The BSP
1334  must provide this function which installs the interrupt/trap handlers.
1335
1336Which CPU-interrupt will generate which signal is implementation
1337defined. There are 32 POSIX signals (1 - 32), and all except the
1338three error signals (SIGILL, SIGFPE and SIGSEGV) can be used. I
1339would suggest to use the upper 16 (17 - 32) which do not
1340have an assigned POSIX name.
1341
1342Note that the pragma interrupt_attach will only bind a signal
1343to a particular Ada handler - it will not unmask the
1344interrupt or do any other things to enable it. This have to be
1345done separately, typically by writing various device register.
1346
1347Example Ada95 Interrupt Program
1348===============================
1349
1350An example program (``irq_test``) is included in the
1351Ada examples package to show how interrupts can be handled
1352in Ada95. Note that generation of the test interrupt
1353(``irqforce.c``) is BSP specific and must be edited.
1354
1355NOTE: The ``irq_test`` example was written for the SPARC/ERC32
1356BSP.
1357
1358Version Requirements
1359====================
1360
1361With RTEMS 4.0, a patch was required to psignal.c in RTEMS
1362sources (to correct a bug associated to the default action of
1363signals 15-32).   The SPARC/ERC32 RTEMS BSP includes the``gnatsupp`` subdirectory that can be used as an example
1364for other BSPs.
1365
1366With GNAT 3.11p, a patch is required for ``a-init.c`` to invoke
1367the BSP specific routine that installs the exception handlers.
1368
1369.. COMMENT: COPYRIGHT (c) 1988-2008.
1370
1371.. COMMENT: On-Line Applications Research Corporation (OAR).
1372
1373.. COMMENT: All rights reserved.
1374
1375Initialization Code
1376###################
1377
1378Introduction
1379============
1380
1381The initialization code is the first piece of code executed when there’s a
1382reset/reboot. Its purpose is to initialize the board for the application.
1383This chapter contains a narrative description of the initialization
1384process followed by a description of each of the files and routines
1385commonly found in the BSP related to initialization.  The remainder of
1386this chapter covers special issues which require attention such
1387as interrupt vector table and chip select initialization.
1388
1389Most of the examples in this chapter will be based on the SPARC/ERC32 and
1390m68k/gen68340 BSP initialization code.  Like most BSPs, the initialization
1391for these BSP is divided into two subdirectories under the BSP source
1392directory.  The BSP source code for these BSPs is in the following
1393directories:
1394.. code:: c
1395
1396    c/src/lib/libbsp/m68k/gen68340
1397    c/src/lib/libbsp/sparc/erc32
1398
1399Both BSPs contain startup code written in assembly language and C.
1400The gen68340 BSP has its early initialization start code in the``start340`` subdirectory and its C startup code in the ``startup``
1401directory.  In the ``start340`` directory are two source files.
1402The file ``startfor340only.s`` is the simpler of these files as it only
1403has initialization code for a MC68340 board.  The file ``start340.s``
1404contains initialization for a 68349 based board as well.
1405
1406Similarly, the ERC32 BSP has startup code written in assembly language
1407and C.  However, this BSP shares this code with other SPARC BSPs.
1408Thus the ``Makefile.am`` explicitly references the following files
1409for this functionality.
1410.. code:: c
1411
1412    ../../sparc/shared/start.S
1413
1414*NOTE:* In most BSPs, the directory named ``start340`` in the
1415gen68340 BSP would be simply named ``start`` or start followed by a
1416BSP designation.
1417
1418Required Global Variables
1419=========================
1420
1421Although not strictly part of initialization, there are a few global
1422variables assumed to exist by reusable device drivers.  These global
1423variables should only defined by the BSP when using one of these device
1424drivers.
1425
1426The BSP author probably should be aware of the ``Configuration``
1427Table structure generated by ``<rtems/confdefs.h>`` during debug but
1428should not explicitly reference it in the source code.  There are helper
1429routines provided by RTEMS to access individual fields.
1430
1431In older RTEMS versions, the BSP included a number of required global
1432variables.  We have made every attempt to eliminate these in the interest
1433of simplicity.
1434
1435Board Initialization
1436====================
1437
1438This section describes the steps an application goes through from the
1439time the first BSP code is executed until the first application task
1440executes.  The following figure illustrates the program flow during
1441this sequence:
1442
1443IMAGE NOT AVAILABLE IN ASCII VERSION
1444
1445The above figure illustrates the flow from assembly language start code
1446to the shared ``bootcard.c`` framework then through the C Library,
1447RTEMS, device driver initialization phases, and the context switch
1448to the first application task.  After this, the application executes
1449until it calls ``exit``, ``rtems_shutdown_executive``, or some
1450other normal termination initiating routine and a fatal system state is
1451reached.  The optional ``bsp_fatal_extension`` initial extension can perform
1452BSP specific system termination.
1453
1454The routines invoked during this will be discussed and their location
1455in the RTEMS source tree pointed out as we discuss each.
1456
1457Start Code - Assembly Language Initialization
1458---------------------------------------------
1459
1460The assembly language code in the directory ``start`` is the first part
1461of the application to execute.  It is responsible for initializing the
1462processor and board enough to execute the rest of the BSP.  This includes:
1463
1464- initializing the stack
1465
1466- zeroing out the uninitialized data section ``.bss``
1467
1468- disabling external interrupts
1469
1470- copy the initialized data from ROM to RAM
1471
1472The general rule of thumb is that the start code in assembly should
1473do the minimum necessary to allow C code to execute to complete the
1474initialization sequence.
1475
1476The initial assembly language start code completes its execution by
1477invoking the shared routine ``boot_card()``.
1478
1479The label (symbolic name) associated with the starting address of the
1480program is typically called ``start``.  The start object file is the
1481first object file linked into the program image so it is ensured that
1482the start code is at offset 0 in the ``.text`` section.  It is the
1483responsibility of the linker script in conjunction with the compiler
1484specifications file to put the start code in the correct location in
1485the application image.
1486
1487boot_card() - Boot the Card
1488---------------------------
1489
1490The ``boot_card()`` is the first C code invoked.  This file is the
1491core component in the RTEMS BSP Initialization Framework and provides
1492the proper sequencing of initialization steps for the BSP, RTEMS and
1493device drivers. All BSPs use the same shared version of ``boot_card()``
1494which is located in the following file:
1495.. code:: c
1496
1497    c/src/lib/libbsp/shared/bootcard.c
1498
1499The ``boot_card()`` routine performs the following functions:
1500
1501- It disables processor interrupts.
1502
1503- It sets the command line argument variables
1504  for later use by the application.
1505
1506- It invokes the BSP specific routine ``bsp_work_area_initialize()``
1507  which is supposed to initialize the RTEMS Workspace and the C Program Heap.
1508  Usually the default implementation in``c/src/lib/libbsp/shared/bspgetworkarea.c`` should be sufficient.  Custom
1509  implementations can use ``bsp_work_area_initialize_default()`` or``bsp_work_area_initialize_with_table()`` available as inline functions from``#include <bsp/bootcard.h>``.
1510
1511- It invokes the BSP specific routine ``bsp_start()`` which is
1512  written in C and thus able to perform more advanced initialization.
1513  Often MMU, bus and interrupt controller initialization occurs here.  Since the
1514  RTEMS Workspace and the C Program Heap was already initialized by``bsp_work_area_initialize()``, this routine may use ``malloc()``, etc.
1515
1516- It invokes the RTEMS directive``rtems_initialize_data_structures()`` to initialize the RTEMS
1517  executive to a state where objects can be created but tasking is not
1518  enabled.
1519
1520- It invokes the BSP specific routine ``bsp_libc_init()`` to initialize
1521  the C Library.  Usually the default implementation in``c/src/lib/libbsp/shared/bsplibc.c`` should be sufficient.
1522
1523- It invokes the RTEMS directive``rtems_initialize_before_drivers()`` to initialize the MPCI Server
1524  thread in a multiprocessor configuration and execute API specific
1525  extensions.
1526
1527- It invokes the BSP specific routine ``bsp_predriver_hook``. For
1528  most BSPs, the implementation of this routine does nothing.
1529
1530- It invokes the RTEMS directive``rtems_initialize_device_drivers()`` to initialize the statically
1531  configured set of device drivers in the order they were specified in
1532  the Configuration Table.
1533
1534- It invokes the BSP specific routine ``bsp_postdriver_hook``. For
1535  most BSPs, the implementation of this routine does nothing.  However, some
1536  BSPs use this hook and perform some initialization which must be done at
1537  this point in the initialization sequence.  This is the last opportunity
1538  for the BSP to insert BSP specific code into the initialization sequence.
1539
1540- It invokes the RTEMS directive``rtems_initialize_start_multitasking()``
1541  which initiates multitasking and performs a context switch to the
1542  first user application task and may enable interrupts as a side-effect of
1543  that context switch.  The context switch saves the executing context.  The
1544  application runs now.  The directive rtems_shutdown_executive() will return
1545  to the saved context.  The exit() function will use this directive.
1546  After a return to the saved context a fatal system state is reached.  The
1547  fatal source is RTEMS_FATAL_SOURCE_EXIT with a fatal code set to the value
1548  passed to rtems_shutdown_executive().
1549  The enabling of interrupts during the first context switch is often the source
1550  for fatal errors during BSP development because the BSP did not clear and/or
1551  disable all interrupt sources and a spurious interrupt will occur.
1552  When in the context of the first task but before its body has been
1553  entered, any C++ Global Constructors will be invoked.
1554
1555That’s it.  We just went through the entire sequence.
1556
1557bsp_work_area_initialize() - BSP Specific Work Area Initialization
1558------------------------------------------------------------------
1559
1560This is the first BSP specific C routine to execute during system
1561initialization.  It must initialize the support for allocating memory from the
1562C Program Heap and RTEMS Workspace commonly referred to as the work areas.
1563Many BSPs place the work areas at the end of RAM although this is certainly not
1564a requirement.  Usually the default implementation in:file:`c/src/lib/libbsp/shared/bspgetworkarea.c` should be sufficient.  Custom
1565implementations can use ``bsp_work_area_initialize_default()`` or``bsp_work_area_initialize_with_table()`` available as inline functions from``#include <bsp/bootcard.h>``.
1566
1567bsp_start() - BSP Specific Initialization
1568-----------------------------------------
1569
1570This is the second BSP specific C routine to execute during system
1571initialization.  It is called right after ``bsp_work_area_initialize()``.
1572The ``bsp_start()`` routine often performs required fundamental hardware
1573initialization such as setting bus controller registers that do not have a
1574direct impact on whether or not C code can execute.  The interrupt controllers
1575are usually initialized here.  The source code for this routine is usually
1576found in the file :file:`c/src/lib/libbsp/${CPU}/${BSP}/startup/bspstart.c`.
1577It is not allowed to create any operating system objects, e.g. RTEMS
1578semaphores.
1579
1580After completing execution, this routine returns to the ``boot_card()``
1581routine.  In case of errors, the initialization should be terminated via``bsp_fatal()``.
1582
1583bsp_predriver_hook() - BSP Specific Predriver Hook
1584--------------------------------------------------
1585
1586The ``bsp_predriver_hook()`` method is the BSP specific routine that is
1587invoked immediately before the the device drivers are initialized. RTEMS
1588initialization is complete but interrupts and tasking are disabled.
1589
1590The BSP may use the shared version of this routine which is empty.
1591Most BSPs do not provide a specific implementation of this callback.
1592
1593Device Driver Initialization
1594----------------------------
1595
1596At this point in the initialization sequence, the initialization
1597routines for all of the device drivers specified in the Device
1598Driver Table are invoked.  The initialization routines are invoked
1599in the order they appear in the Device Driver Table.
1600
1601The Driver Address Table is part of the RTEMS Configuration Table. It
1602defines device drivers entry points (initialization, open, close, read,
1603write, and control). For more information about this table, please
1604refer to the *Configuring a System* chapter in the*RTEMS Application C User’s Guide*.
1605
1606The RTEMS initialization procedure calls the initialization function for
1607every driver defined in the RTEMS Configuration Table (this allows
1608one to include only the drivers needed by the application).
1609
1610All these primitives have a major and a minor number as arguments:
1611
1612- the major number refers to the driver type,
1613
1614- the minor number is used to control two peripherals with the same
1615  driver (for instance, we define only one major number for the serial
1616  driver, but two minor numbers for channel A and B if there are two
1617  channels in the UART).
1618
1619RTEMS Postdriver Callback
1620-------------------------
1621
1622The ``bsp_postdriver_hook()`` BSP specific routine is invoked
1623immediately after the the device drivers and MPCI are initialized.
1624Interrupts and tasking are disabled.
1625
1626Most BSPs use the shared implementation of this routine which is responsible for opening the device ``/dev/console`` for standard input, output and error if the application has configured the Console Device Driver.  This file is located at:
1627.. code:: c
1628
1629    c/src/lib/libbsp/shared/bsppost.c
1630
1631The Interrupt Vector Table
1632==========================
1633
1634The Interrupt Vector Table is called different things on different
1635processor families but the basic functionality is the same.  Each
1636entry in the Table corresponds to the handler routine for a particular
1637interrupt source.  When an interrupt from that source occurs, the
1638specified handler routine is invoked.  Some context information is
1639saved by the processor automatically when this happens.  RTEMS saves
1640enough context information so that an interrupt service routine
1641can be implemented in a high level language.
1642
1643On some processors, the Interrupt Vector Table is at a fixed address.  If
1644this address is in RAM, then usually the BSP only has to initialize
1645it to contain pointers to default handlers.  If the table is in ROM,
1646then the application developer will have to take special steps to
1647fill in the table.
1648
1649If the base address of the Interrupt Vector Table can be dynamically
1650changed to an arbitrary address, then the RTEMS port to that processor
1651family will usually allocate its own table and install it.  For example,
1652on some members of the Motorola MC68xxx family, the Vector Base Register
1653(``vbr``) contains this base address.
1654
1655Interrupt Vector Table on the gen68340 BSP
1656------------------------------------------
1657
1658The gen68340 BSP provides a default Interrupt Vector Table in the
1659file ``$BSP_ROOT/start340/start340.s``.  After the ``entry``
1660label is the definition of space reserved for the table of
1661interrupts vectors.  This space is assigned the symbolic name
1662of ``__uhoh`` in the ``gen68340`` BSP.
1663
1664At ``__uhoh`` label is the default interrupt handler routine. This
1665routine is only called when an unexpected interrupts is raised.  One can
1666add their own routine there (in that case there’s a call to a routine -
1667$BSP_ROOT/startup/dumpanic.c - that prints which address caused the
1668interrupt and the contents of the registers, stack, etc.), but this should
1669not return.
1670
1671Chip Select Initialization
1672==========================
1673
1674When the microprocessor accesses a memory area, address decoding is
1675handled by an address decoder, so that the microprocessor knows which
1676memory chip(s) to access.   The following figure illustrates this:
1677
1678.. code:: c
1679
1680    +-------------------+
1681    ------------|                   |
1682    ------------|                   \|------------
1683    ------------|      Address      \|------------
1684    ------------|      Decoder      \|------------
1685    ------------|                   \|------------
1686    ------------|                   |
1687    +-------------------+
1688    CPU Bus                           Chip Select
1689
1690The Chip Select registers must be programmed such that they match
1691the ``linkcmds`` settings. In the gen68340 BSP, ROM and RAM
1692addresses can be found in both the ``linkcmds`` and initialization
1693code, but this is not a great way to do this.  It is better to
1694define addresses in the linker script.
1695
1696Integrated Processor Registers Initialization
1697=============================================
1698
1699The CPUs used in many embedded systems are highly complex devices
1700with multiple peripherals on the CPU itself.  For these devices,
1701there are always some specific integrated processor registers
1702that must be initialized.  Refer to the processors’ manuals for
1703details on these registers and be VERY careful programming them.
1704
1705Data Section Recopy
1706===================
1707
1708The next initialization part can be found in``$BSP340_ROOT/start340/init68340.c``. First the Interrupt
1709Vector Table is copied into RAM, then the data section recopy is initiated
1710(_CopyDataClearBSSAndStart in ``$BSP340_ROOT/start340/startfor340only.s``).
1711
1712This code performs the following actions:
1713
1714- copies the .data section from ROM to its location reserved in RAM
1715  (see `Initialized Data`_ for more details about this copy),
1716
1717- clear ``.bss`` section (all the non-initialized
1718  data will take value 0).
1719
1720The RTEMS Configuration Table
1721=============================
1722
1723The RTEMS configuration table contains the maximum number of objects RTEMS
1724can handle during the application (e.g. maximum number of tasks,
1725semaphores, etc.). It’s used to allocate the size for the RTEMS inner data
1726structures.
1727
1728The RTEMS configuration table is application dependent, which means that
1729one has to provide one per application. It is usually defined by defining
1730macros and including the header file ``<rtems/confdefs.h>``.  In simple
1731applications such as the tests provided with RTEMS, it is commonly found
1732in the main module of the application.  For more complex applications,
1733it may be in a file by itself.
1734
1735The header file ``<rtems/confdefs.h>`` defines a constant table
1736named ``Configuration``.  With RTEMS 4.8 and older, it was accepted
1737practice for the BSP to copy this table into a modifiable copy named``BSP_Configuration``.  This copy of the table was modified to define
1738the base address of the RTEMS Executive Workspace as well as to reflect
1739any BSP and device driver requirements not automatically handled by the
1740application.  In 4.9 and newer, we have eliminated the BSP copies of the
1741configuration tables and are making efforts to make the configuration
1742information generated by ``<rtems/confdefs.h>`` constant and read only.
1743
1744For more information on the RTEMS Configuration Table, refer to the*RTEMS Application C User’s Guide*.
1745
1746.. COMMENT: COPYRIGHT (c) 1988-2008.
1747
1748.. COMMENT: On-Line Applications Research Corporation (OAR).
1749
1750.. COMMENT: All rights reserved.
1751
1752Console Driver
1753##############
1754
1755Introduction
1756============
1757
1758This chapter describes the operation of a console driver using
1759the RTEMS POSIX Termios support.  Traditionally RTEMS has referred
1760to all serial device drivers as console device drivers.  A
1761console driver can be used to do raw data processing in addition
1762to the "normal" standard input and output device functions required
1763of a console.
1764
1765The serial driver may be called as the consequence of a C Library
1766call such as ``printf`` or ``scanf`` or directly via the``read`` or ``write`` system calls.
1767There are two main functioning modes:
1768
1769- console: formatted input/output, with special characters (end of
1770  line, tabulations, etc.) recognition and processing,
1771
1772- raw: permits raw data processing.
1773
1774One may think that two serial drivers are needed to handle these two types
1775of data, but Termios permits having only one driver.
1776
1777Termios
1778=======
1779
1780Termios is a standard for terminal management, included in the POSIX
17811003.1b standard.  As part of the POSIX and Open Group Single UNIX
1782Specification, is commonly provided on UNIX implementations.  The
1783Open Group has the termios portion of the POSIX standard online
1784at http://opengroup.org/onlinepubs/007908775/xbd/termios.html.
1785The requirements for the ``<termios.h>`` file are also provided
1786and are at http://opengroup.org/onlinepubs/007908775/xsh/termios.h.html.
1787
1788Having RTEMS support for Termios is beneficial because:
1789
1790- from the user’s side because it provides standard primitive operations
1791  to access the terminal and change configuration settings.  These operations
1792  are the same under UNIX and RTEMS.
1793
1794- from the BSP developer’s side because it frees the
1795  developer from dealing with buffer states and mutual exclusions on them.
1796  Early RTEMS console device drivers also did their own special
1797  character processing.
1798
1799- it is part of an internationally recognized standard.
1800
1801- it makes porting code from other environments easier.
1802
1803Termios support includes:
1804
1805- raw and console handling,
1806
1807- blocking or non-blocking characters receive, with or without
1808  Timeout.
1809
1810At this time, RTEMS documentation does not include a thorough discussion
1811of the Termios functionality.  For more information on Termios,
1812type ``man termios`` on a Unix box or point a web browser
1813athttp://www.freebsd.org/cgi/man.cgi.
1814
1815Driver Functioning Modes
1816========================
1817
1818There are generally three main functioning modes for an UART (Universal
1819Asynchronous Receiver-Transmitter, i.e. the serial chip):
1820
1821- polled mode
1822
1823- interrupt driven mode
1824
1825- task driven mode
1826
1827In polled mode, the processor blocks on sending/receiving characters.
1828This mode is not the most efficient way to utilize the UART. But
1829polled mode is usually necessary when one wants to print an
1830error message in the event of a fatal error such as a fatal error
1831in the BSP.  This is also the simplest mode to
1832program.  Polled mode is generally preferred if the serial port is
1833to be used primarily as a debug console.  In a simple polled driver,
1834the software will continuously check the status of the UART when
1835it is reading or writing to the UART.  Termios improves on this
1836by delaying the caller for 1 clock tick between successive checks
1837of the UART on a read operation.
1838
1839In interrupt driven mode, the processor does not block on sending/receiving
1840characters.  Data is buffered between the interrupt service routine
1841and application code.  Two buffers are used to insulate the application
1842from the relative slowness of the serial device.  One of the buffers is
1843used for incoming characters, while the other is used for outgoing characters.
1844
1845An interrupt is raised when a character is received by the UART.
1846The interrupt subroutine places the incoming character at the end
1847of the input buffer.  When an application asks for input,
1848the characters at the front of the buffer are returned.
1849
1850When the application prints to the serial device, the outgoing characters
1851are placed at the end of the output buffer.  The driver will place
1852one or more characters in the UART (the exact number depends on the UART)
1853An interrupt will be raised when all the characters have been transmitted.
1854The interrupt service routine has to send the characters
1855remaining in the output buffer the same way.   When the transmitting side
1856of the UART is idle, it is typically necessary to prime the transmitter
1857before the first interrupt will occur.
1858
1859The task driven mode is similar to interrupt driven mode, but the actual data
1860processing is done in dedicated tasks instead of interrupt routines.
1861
1862Serial Driver Functioning Overview
1863==================================
1864
1865The following Figure shows how a Termios driven serial driver works:
1866Figure not included in ASCII version
1867
1868The following list describes the basic flow.
1869
1870- the application programmer uses standard C library call (printf,
1871  scanf, read, write, etc.),
1872
1873- C library (ctx.g. RedHat (formerly Cygnus) Newlib) calls
1874  the RTEMS system call interface.  This code can be found in the:file:`cpukit/libcsupport/src` directory.
1875
1876- Glue code calls the serial driver entry routines.
1877
1878Basics
1879------
1880
1881The low-level driver API changed between RTEMS 4.10 and RTEMS 4.11.  The legacy
1882callback API is still supported, but its use is discouraged.  The following
1883functions are deprecated:
1884
1885- ``rtems_termios_open()`` - use ``rtems_termios_device_open()`` in
1886  combination with ``rtems_termios_device_install()`` instead.
1887
1888- ``rtems_termios_close()`` - use ``rtems_termios_device_close()``
1889  instead.
1890
1891This manual describes the new API.  A new console driver should consist of
1892three parts.
1893
1894# The basic console driver functions using the Termios support.  Add this
1895  the BSPs Makefile.am:
1896
1897  .. code:: c
1898
1899      [...]
1900      libbsp_a_SOURCES += ../../shared/console-termios.c
1901      \[...]
1902
1903# A general serial module specific low-level driver providing the handler
1904  table for the Termios ``rtems_termios_device_install()`` function.  This
1905  low-level driver could be used for more than one BSP.
1906
1907# A BSP specific initialization routine ``console_initialize()``, that
1908  calls ``rtems_termios_device_install()`` providing a low-level driver
1909  context for each installed device.
1910
1911You need to provide a device handler structure for the Termios device
1912interface.  The functions are described later in this chapter.  The first open
1913and set attributes handler return a boolean status to indicate success (true)
1914or failure (false).  The polled read function returns an unsigned character in
1915case one is available or minus one otherwise.
1916
1917If you want to use polled IO it should look like the following.  Termios must
1918be told the addresses of the handler that are to be used for simple character
1919IO, i.e. pointers to the ``my_driver_poll_read()`` and``my_driver_poll_write()`` functions described later in `Termios and Polled IO`_.
1920
1921.. code:: c
1922
1923    const rtems_termios_handler my_driver_handler_polled = {
1924    .first_open = my_driver_first_open,
1925    .last_close = my_driver_last_close,
1926    .poll_read = my_driver_poll_read,
1927    .write = my_driver_poll_write,
1928    .set_attributes = my_driver_set_attributes,
1929    .stop_remote_tx = NULL,
1930    .start_remote_tx = NULL,
1931    .mode = TERMIOS_POLLED
1932    }
1933
1934For an interrupt driven implementation you need the following.  The driver
1935functioning is quite different in this mode.  There is no device driver read
1936handler to be passed to Termios.  Indeed a ``console_read()`` call returns the
1937contents of Termios input buffer.  This buffer is filled in the driver
1938interrupt subroutine, see also `Termios and Interrupt Driven IO`_.  The driver
1939is responsible for providing a pointer to the``my_driver_interrupt_write()`` function.
1940
1941.. code:: c
1942
1943    const rtems_termios_handler my_driver_handler_interrupt = {
1944    .first_open = my_driver_first_open,
1945    .last_close = my_driver_last_close,
1946    .poll_read = NULL,
1947    .write = my_driver_interrupt_write,
1948    .set_attributes = my_driver_set_attributes,
1949    .stopRemoteTx = NULL,
1950    .stop_remote_tx = NULL,
1951    .start_remote_tx = NULL,
1952    .mode = TERMIOS_IRQ_DRIVEN
1953    };
1954
1955You can also provide hander for remote transmission control.  This
1956is not covered in this manual, so they are set to ``NULL`` in the above
1957examples.
1958
1959The low-level driver should provide a data structure for its device context.
1960The initialization routine must provide a context for each installed device via``rtems_termios_device_install()``.  For simplicity of the console
1961initialization example the device name is also present.  Her is an example header file.
1962.. code:: c
1963
1964    #ifndef MY_DRIVER_H
1965    #define MY_DRIVER_H
1966    #include <rtems/termiostypes.h>
1967    #include <some-chip-header.h>
1968    /* Low-level driver specific data structure \*/
1969    typedef struct {
1970    rtems_termios_device_context base;
1971    const char \*device_name;
1972    volatile module_register_block \*regs;
1973    /* More stuff \*/
1974    } my_driver_context;
1975    extern const rtems_termios_handler my_driver_handler_polled;
1976    extern const rtems_termios_handler my_driver_handler_interrupt;
1977    #endif /* MY_DRIVER_H \*/
1978
1979
1980Termios and Polled IO
1981---------------------
1982
1983The following handler are provided by the low-level driver and invoked by
1984Termios for simple character IO.
1985
1986The ``my_driver_poll_write()`` routine is responsible for writing ``n``
1987characters from ``buf`` to the serial device specified by ``tty``.
1988.. code:: c
1989
1990    static void my_driver_poll_write(
1991    rtems_termios_device_context \*base,
1992    const char                   \*buf,
1993    size_t                        n
1994    )
1995    {
1996    my_driver_context \*ctx = (my_driver_context \*) base;
1997    size_t i;
1998    /* Write \*/
1999    for (i = 0; i < n; ++i) {
2000    my_driver_write_char(ctx, buf[i]);
2001    }
2002    }
2003
2004The ``my_driver_poll_read`` routine is responsible for reading a single
2005character from the serial device specified by ``tty``.  If no character is
2006available, then the routine should return minus one.
2007.. code:: c
2008
2009    static int my_driver_poll_read(rtems_termios_device_context \*base)
2010    {
2011    my_driver_context \*ctx = (my_driver_context \*) base;
2012    /* Check if a character is available \*/
2013    if (my_driver_can_read_char(ctx)) {
2014    /* Return the character \*/
2015    return my_driver_read_char(ctx);
2016    } else {
2017    /* Return an error status \*/
2018    return -1;
2019    }
2020    }
2021
2022Termios and Interrupt Driven IO
2023-------------------------------
2024
2025The UART generally generates interrupts when it is ready to accept or to emit a
2026number of characters.  In this mode, the interrupt subroutine is the core of
2027the driver.
2028
2029The ``my_driver_interrupt_handler()`` is responsible for processing
2030asynchronous interrupts from the UART.  There may be multiple interrupt
2031handlers for a single UART.  Some UARTs can generate a unique interrupt vector
2032for each interrupt source such as a character has been received or the
2033transmitter is ready for another character.
2034
2035In the simplest case, the ``my_driver_interrupt_handler()`` will have to check
2036the status of the UART and determine what caused the interrupt.  The following
2037describes the operation of an ``my_driver_interrupt_handler`` which has to
2038do this:
2039.. code:: c
2040
2041    static void my_driver_interrupt_handler(
2042    rtems_vector_number  vector,
2043    void                \*arg
2044    )
2045    {
2046    rtems_termios_tty \*tty = arg;
2047    my_driver_context \*ctx = rtems_termios_get_device_context(tty);
2048    char buf[N];
2049    size_t n;
2050    /*
2051    * Check if we have received something.  The function reads the
2052    * received characters from the device and stores them in the
2053    * buffer.  It returns the number of read characters.
2054    \*/
2055    n = my_driver_read_received_chars(ctx, buf, N);
2056    if (n > 0) {
2057    /* Hand the data over to the Termios infrastructure \*/
2058    rtems_termios_enqueue_raw_characters(tty, buf, n);
2059    }
2060    /*
2061    * Check if we have something transmitted.  The functions returns
2062    * the number of transmitted characters since the last write to the
2063    * device.
2064    \*/
2065    n = my_driver_transmitted_chars(ctx);
2066    if (n > 0) {
2067    /*
2068    * Notify Termios that we have transmitted some characters.  It
2069    * will call now the interrupt write function if more characters
2070    * are ready for transmission.
2071    \*/
2072    rtems_termios_dequeue_characters(tty, n);
2073    }
2074    }
2075
2076The ``my_driver_interrupt_write()`` function is responsible for telling the
2077device that the ``n`` characters at ``buf`` are to be transmitted.  It
2078the value ``n`` is zero to indicate that no more characters are to send.
2079The driver can disable the transmit interrupts now.  This routine is invoked
2080either from task context with disabled interrupts to start a new transmission
2081process with exactly one character in case of an idle output state or from the
2082interrupt handler to refill the transmitter.  If the routine is invoked to
2083start the transmit process the output state will become busy and Termios starts
2084to fill the output buffer.  If the transmit interrupt arises before Termios was
2085able to fill the transmit buffer you will end up with one interrupt per
2086character.
2087.. code:: c
2088
2089    static void my_driver_interrupt_write(
2090    rtems_termios_device_context  \*base,
2091    const char                    \*buf,
2092    size_t                         n
2093    )
2094    {
2095    my_driver_context \*ctx = (my_driver_context \*) base;
2096    /*
2097    * Tell the device to transmit some characters from buf (less than
2098    * or equal to n).  When the device is finished it should raise an
2099    * interrupt.  The interrupt handler will notify Termios that these
2100    * characters have been transmitted and this may trigger this write
2101    * function again.  You may have to store the number of outstanding
2102    * characters in the device data structure.
2103    \*/
2104    /*
2105    * Termios will set n to zero to indicate that the transmitter is
2106    * now inactive.  The output buffer is empty in this case.  The
2107    * driver may disable the transmit interrupts now.
2108    \*/
2109    }
2110
2111Initialization
2112--------------
2113
2114The BSP specific driver initialization is called once during the RTEMS
2115initialization process.
2116
2117The ``console_initialize()`` function may look like this:
2118.. code:: c
2119
2120    #include <my-driver.h>
2121    #include <rtems/console.h>
2122    #include <bsp.h>
2123    #include <bsp/fatal.h>
2124    static my_driver_context driver_context_table[M] = { /* Some values \*/ };
2125    rtems_device_driver console_initialize(
2126    rtems_device_major_number  major,
2127    rtems_device_minor_number  minor,
2128    void                      \*arg
2129    )
2130    {
2131    rtems_status_code sc;
2132    #ifdef SOME_BSP_USE_INTERRUPTS
2133    const rtems_termios_handler \*handler = &my_driver_handler_interrupt;
2134    #else
2135    const rtems_termios_handler \*handler = &my_driver_handler_polled;
2136    #endif
2137    /*
2138    * Initialize the Termios infrastructure.  If Termios has already
2139    * been initialized by another device driver, then this call will
2140    * have no effect.
2141    \*/
2142    rtems_termios_initialize();
2143    /* Initialize each device \*/
2144    for (
2145    minor = 0;
2146    minor < RTEMS_ARRAY_SIZE(driver_context_table);
2147    ++minor
2148    ) {
2149    my_driver_context \*ctx = &driver_context_table[minor];
2150    /*
2151    * Install this device in the file system and Termios.  In order
2152    * to use the console (i.e. being able to do printf, scanf etc.
2153    * on stdin, stdout and stderr), one device must be registered as
2154    * "/dev/console" (CONSOLE_DEVICE_NAME).
2155    \*/
2156    sc = rtems_termios_device_install(
2157    ctx->device_name,
2158    major,
2159    minor,
2160    handler,
2161    NULL,
2162    ctx
2163    );
2164    if (sc != RTEMS_SUCCESSFUL) {
2165    bsp_fatal(SOME_BSP_FATAL_CONSOLE_DEVICE_INSTALL);
2166    }
2167    }
2168    return RTEMS_SUCCESSFUL;
2169    }
2170
2171Opening a serial device
2172-----------------------
2173
2174The ``console_open()`` function provided by :file:`console-termios.c` is
2175called whenever a serial device is opened.  The device registered as``"/dev/console"`` (``CONSOLE_DEVICE_NAME``) is opened automatically
2176during RTEMS initialization.  For instance, if UART channel 2 is registered as``"/dev/tty1"``, the ``console_open()`` entry point will be called as the
2177result of an ``fopen("/dev/tty1", mode)`` in the application.
2178
2179During the first open of the device Termios will call the``my_driver_first_open()`` handler.
2180.. code:: c
2181
2182    static bool my_driver_first_open(
2183    rtems_termios_tty             \*tty,
2184    rtems_termios_device_context  \*base,
2185    struct termios                \*term,
2186    rtems_libio_open_close_args_t \*args
2187    )
2188    {
2189    my_driver_context \*ctx = (my_driver_context \*) base;
2190    rtems_status_code sc;
2191    bool ok;
2192    /*
2193    * You may add some initialization code here.
2194    \*/
2195    /*
2196    * Sets the initial baud rate.  This should be set to the value of
2197    * the boot loader.  This function accepts only exact Termios baud
2198    * values.
2199    \*/
2200    sc = rtems_termios_set_initial_baud(tty, MY_DRIVER_BAUD_RATE);
2201    if (sc != RTEMS_SUCCESSFUL) {
2202    /* Not a valid Termios baud \*/
2203    }
2204    /*
2205    * Alternatively you can set the best baud.
2206    \*/
2207    rtems_termios_set_best_baud(term, MY_DRIVER_BAUD_RATE);
2208    /*
2209    * To propagate the initial Termios attributes to the device use
2210    * this.
2211    \*/
2212    ok = my_driver_set_attributes(base, term);
2213    if (!ok) {
2214    /* This is bad \*/
2215    }
2216    /*
2217    * Return true to indicate a successful set attributes, and false
2218    * otherwise.
2219    \*/
2220    return true;
2221    }
2222
2223Closing a Serial Device
2224-----------------------
2225
2226The ``console_close()`` provided by :file:`console-termios.c` is invoked when
2227the serial device is to be closed.  This entry point corresponds to the device
2228driver close entry point.
2229
2230Termios will call the ``my_driver_last_close()`` handler if the last close
2231happens on the device.
2232.. code:: c
2233
2234    static void my_driver_last_close(
2235    rtems_termios_tty             \*tty,
2236    rtems_termios_device_context  \*base,
2237    rtems_libio_open_close_args_t \*args
2238    )
2239    {
2240    my_driver_context \*ctx = (my_driver_context \*) base;
2241    /*
2242    * The driver may do some cleanup here.
2243    \*/
2244    }
2245
2246Reading Characters from a Serial Device
2247---------------------------------------
2248
2249The ``console_read()`` provided by :file:`console-termios.c` is invoked when
2250the serial device is to be read from.  This entry point corresponds to the
2251device driver read entry point.
2252
2253Writing Characters to a Serial Device
2254-------------------------------------
2255
2256The ``console_write()`` provided by :file:`console-termios.c` is invoked when
2257the serial device is to be written to.  This entry point corresponds to the
2258device driver write entry point.
2259
2260Changing Serial Line Parameters
2261-------------------------------
2262
2263The ``console_control()`` provided by :file:`console-termios.c` is invoked
2264when the line parameters for a particular serial device are to be changed.
2265This entry point corresponds to the device driver IO control entry point.
2266
2267The application writer is able to control the serial line configuration with
2268Termios calls (such as the ``ioctl()`` command, see the Termios
2269documentation for more details).  If the driver is to support dynamic
2270configuration, then it must have the ``console_control()`` piece of code.
2271Basically ``ioctl()`` commands call ``console_control()`` with the serial
2272line configuration in a Termios defined data structure.
2273
2274The driver is responsible for reinitializing the device with the correct
2275settings.  For this purpose Termios calls the ``my_driver_set_attributes()``
2276handler.
2277.. code:: c
2278
2279    static bool my_driver_set_attributes(
2280    rtems_termios_device_context \*base,
2281    const struct termios         \*term
2282    )
2283    {
2284    my_driver_context \*ctx = (my_driver_context \*) base;
2285    /*
2286    * Inspect the termios data structure and configure the device
2287    * appropriately.  The driver should only be concerned with the
2288    * parts of the structure that specify hardware setting for the
2289    * communications channel such as baud, character size, etc.
2290    \*/
2291    /*
2292    * Return true to indicate a successful set attributes, and false
2293    * otherwise.
2294    \*/
2295    return true;
2296    }
2297
2298.. COMMENT: COPYRIGHT (c) 1988-2002.
2299
2300.. COMMENT: On-Line Applications Research Corporation (OAR).
2301
2302.. COMMENT: All rights reserved.
2303
2304Clock Driver
2305############
2306
2307Introduction
2308============
2309
2310The purpose of the clock driver is to provide two services for the operating
2311system.
2312
2313- A steady time basis to the kernel, so that the RTEMS primitives that need
2314  a clock tick work properly.  See the *Clock Manager* chapter of the*RTEMS Application C User’s Guide* for more details.
2315
2316- An optional time counter to generate timestamps of the uptime and wall
2317  clock time.
2318
2319The clock driver is usually located in the :file:`clock` directory of the BSP.
2320Clock drivers should use the :dfn:`Clock Driver Shell` available via the:file:`clockdrv_shell.h` include file.
2321
2322Clock Driver Shell
2323==================
2324
2325The :dfn:`Clock Driver Shell` include file defines the clock driver functions
2326declared in ``#include <rtems/clockdrv.h>`` which are used by RTEMS
2327configuration file ``#include <rtems/confdefs.h>``.  In case the application
2328configuration defines ``#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER``,
2329then the clock driver is registered and should provide its services to the
2330operating system.  A hardware specific clock driver must provide some
2331functions, defines and macros for the :dfn:`Clock Driver Shell` which are
2332explained here step by step.  A clock driver file looks in general like this.
2333.. code:: c
2334
2335    /*
2336    * A section with functions, defines and macros to provide hardware specific
2337    * functions for the Clock Driver Shell.
2338    \*/
2339    #include "../../../shared/clockdrv_shell.h"
2340
2341Initialization
2342--------------
2343
2344Depending on the hardware capabilities one out of three clock driver variants
2345must be selected.
2346
2347- The most basic clock driver provides only a periodic interrupt service
2348  routine which calls ``rtems_clock_tick()``.  The interval is determined by
2349  the application configuration via ``#define
2350  CONFIGURE_MICROSECONDS_PER_TICK`` and can be obtained via``rtems_configuration_get_microseconds_per_tick()``.  The timestamp
2351  resolution is limited to the clock tick interval.
2352
2353- In case the hardware lacks support for a free running counter, then the
2354  module used for the clock tick may provide support for timestamps with a
2355  resolution below the clock tick interval.  For this so called simple
2356  timecounters can be used.
2357
2358- The desired variant uses a free running counter to provide accurate
2359  timestamps.  This variant is mandatory on SMP configurations.
2360
2361Clock Tick Only Variant
2362~~~~~~~~~~~~~~~~~~~~~~~
2363
2364.. code:: c
2365
2366    static void some_support_initialize_hardware( void )
2367    {
2368    /* Initialize hardware \*/
2369    }
2370    #define Clock_driver_support_initialize_hardware() \\
2371    some_support_initialize_hardware()
2372    /* Indicate that this clock driver lacks a proper timecounter in hardware \*/
2373    #define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
2374    #include "../../../shared/clockdrv_shell.h"
2375
2376Simple Timecounter Variant
2377~~~~~~~~~~~~~~~~~~~~~~~~~~
2378
2379.. code:: c
2380
2381    #include <rtems/timecounter.h>
2382    static rtems_timecounter_simple some_tc;
2383    static uint32_t some_tc_get( rtems_timecounter_simple \*tc )
2384    {
2385    return some.counter;
2386    }
2387    static bool some_tc_is_pending( rtems_timecounter_simple \*tc )
2388    {
2389    return some.is_pending;
2390    }
2391    static uint32_t some_tc_get_timecount( struct timecounter \*tc )
2392    {
2393    return rtems_timecounter_simple_downcounter_get(
2394    tc,
2395    some_tc_get,
2396    some_tc_is_pending
2397    );
2398    }
2399    static void some_tc_tick( void )
2400    {
2401    rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get );
2402    }
2403    static void some_support_initialize_hardware( void )
2404    {
2405    uint32_t frequency = 123456;
2406    uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
2407    uint32_t timecounter_ticks_per_clock_tick =
2408    ( frequency * us_per_tick ) / 1000000;
2409    /* Initialize hardware \*/
2410    rtems_timecounter_simple_install(
2411    &some_tc,
2412    frequency,
2413    timecounter_ticks_per_clock_tick,
2414    some_tc_get_timecount
2415    );
2416    }
2417    #define Clock_driver_support_initialize_hardware() \\
2418    some_support_initialize_hardware()
2419    #define Clock_driver_timecounter_tick() \\
2420    some_tc_tick()
2421    #include "../../../shared/clockdrv_shell.h"
2422
2423Timecounter Variant
2424~~~~~~~~~~~~~~~~~~~
2425
2426This variant is preferred since it is the most efficient and yields the most
2427accurate timestamps.  It is also mandatory on SMP configurations to obtain
2428valid timestamps.  The hardware must provide a periodic interrupt to service
2429the clock tick and a free running counter for the timecounter.  The free
2430running counter must have a power of two period.  The ``tc_counter_mask``
2431must be initialized to the free running counter period minus one, e.g. for a
243232-bit counter this is 0xffffffff.  The ``tc_get_timecount`` function must
2433return the current counter value (the counter values must increase, so if the
2434counter counts down, a conversion is necessary).  Use``RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER`` for the ``tc_quality``.  Set``tc_frequency`` to the frequency of the free running counter in Hz.  All
2435other fields of the ``struct timecounter`` must be zero initialized.
2436Install the initialized timecounter via ``rtems_timecounter_install()``.
2437.. code:: c
2438
2439    #include <rtems/timecounter.h>
2440    static struct timecounter some_tc;
2441    static uint32_t some_tc_get_timecount( struct timecounter \*tc )
2442    {
2443    some.free_running_counter;
2444    }
2445    static void some_support_initialize_hardware( void )
2446    {
2447    uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
2448    uint32_t frequency = 123456;
2449    /*
2450    * The multiplication must be done in 64-bit arithmetic to avoid an integer
2451    * overflow on targets with a high enough counter frequency.
2452    \*/
2453    uint32_t interval = (uint32_t) ( ( frequency * us_per_tick ) / 1000000 );
2454    /*
2455    * Initialize hardware and set up a periodic interrupt for the configuration
2456    * based interval.
2457    \*/
2458    some_tc.tc_get_timecount = some_tc_get_timecount;
2459    some_tc.tc_counter_mask = 0xffffffff;
2460    some_tc.tc_frequency = frequency;
2461    some_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
2462    rtems_timecounter_install( &some_tc );
2463    }
2464    #define Clock_driver_support_initialize_hardware() \\
2465    some_support_initialize_hardware()
2466    #include "../../../shared/clockdrv_shell.h"
2467
2468Install Clock Tick Interrupt Service Routine
2469--------------------------------------------
2470
2471The clock driver must provide a function to install the clock tick interrupt
2472service routine via ``Clock_driver_support_install_isr()``.
2473.. code:: c
2474
2475    #include <bsp/irq.h>
2476    #include <bsp/fatal.h>
2477    static void some_support_install_isr( rtems_interrupt_handler isr )
2478    {
2479    rtems_status_code sc;
2480    sc = rtems_interrupt_handler_install(
2481    SOME_IRQ,
2482    "Clock",
2483    RTEMS_INTERRUPT_UNIQUE,
2484    isr,
2485    NULL
2486    );
2487    if ( sc != RTEMS_SUCCESSFUL ) {
2488    bsp_fatal( SOME_FATAL_IRQ_INSTALL );
2489    }
2490    }
2491    #define Clock_driver_support_install_isr( isr, old ) \\
2492    some_support_install_isr( isr )
2493    #include "../../../shared/clockdrv_shell.h"
2494
2495Support At Tick
2496---------------
2497
2498The hardware specific support at tick is specified by``Clock_driver_support_at_tick()``.
2499.. code:: c
2500
2501    static void some_support_at_tick( void )
2502    {
2503    /* Clear interrupt \*/
2504    }
2505    #define Clock_driver_support_at_tick() \\
2506    some_support_at_tick()
2507    #include "../../../shared/clockdrv_shell.h"
2508
2509System Shutdown Support
2510-----------------------
2511
2512The :dfn:`Clock Driver Shell` provides the routine ``Clock_exit()`` that is
2513scheduled to be run during system shutdown via the ``atexit()`` routine.
2514The hardware specific shutdown support is specified by``Clock_driver_support_shutdown_hardware()`` which is used by``Clock_exit()``.  It should disable the clock tick source if it was
2515enabled.  This can be used to prevent clock ticks after the system is shutdown.
2516.. code:: c
2517
2518    static void some_support_shutdown_hardware( void )
2519    {
2520    /* Shutdown hardware \*/
2521    }
2522    #define Clock_driver_support_shutdown_hardware() \\
2523    some_support_shutdown_hardware()
2524    #include "../../../shared/clockdrv_shell.h"
2525
2526Multiple Clock Driver Ticks Per Clock Tick
2527------------------------------------------
2528
2529In case the hardware needs more than one clock driver tick per clock tick (e.g.
2530due to a limited range of the hardware timer), then this can be specified with
2531the optional ``#define CLOCK_DRIVER_ISRS_PER_TICK`` and ``#define
2532CLOCK_DRIVER_ISRS_PER_TICK_VALUE`` defines.  This is currently used only for x86
2533and it hopefully remains that way.
2534.. code:: c
2535
2536    /* Enable multiple clock driver ticks per clock tick \*/
2537    #define CLOCK_DRIVER_ISRS_PER_TICK 1
2538    /* Specifiy the clock driver ticks per clock tick value \*/
2539    #define CLOCK_DRIVER_ISRS_PER_TICK_VALUE 123
2540    #include "../../../shared/clockdrv_shell.h"
2541
2542Clock Driver Ticks Counter
2543--------------------------
2544
2545The :dfn:`Clock Driver Shell` provide a global variable that is simply a count
2546of the number of clock driver interrupt service routines that have occurred.
2547This information is valuable when debugging a system.  This variable is
2548declared as follows:
2549.. code:: c
2550
2551    volatile uint32_t Clock_driver_ticks;
2552
2553.. COMMENT: COPYRIGHT (c) 1988-2002.
2554
2555.. COMMENT: On-Line Applications Research Corporation (OAR).
2556
2557.. COMMENT: All rights reserved.
2558
2559Timer Driver
2560############
2561
2562The timer driver is primarily used by the RTEMS Timing Tests.
2563This driver provides as accurate a benchmark timer as possible.
2564It typically reports its time in microseconds, CPU cycles, or
2565bus cycles.  This information can be very useful for determining
2566precisely what pieces of code require optimization and to measure the
2567impact of specific minor changes.
2568
2569The gen68340 BSP also uses the Timer Driver to support a high performance
2570mode of the on-CPU UART.
2571
2572Benchmark Timer
2573===============
2574
2575The RTEMS Timing Test Suite requires a benchmark timer.  The
2576RTEMS Timing Test Suite is very helpful for determining
2577the performance of target hardware and comparing its performance
2578to that of other RTEMS targets.
2579
2580This section describes the routines which are assumed to exist by
2581the RTEMS Timing Test Suite.  The names used are *EXACTLY* what
2582is used in the RTEMS Timing Test Suite so follow the naming convention.
2583
2584benchmark_timer_initialize
2585--------------------------
2586
2587Initialize the timer source.
2588.. code:: c
2589
2590    void benchmark_timer_initialize(void)
2591    {
2592    initialize the benchmark timer
2593    }
2594
2595Read_timer
2596----------
2597
2598The ``benchmark_timer_read`` routine returns the number of benchmark
2599time units (typically microseconds) that have elapsed since the last
2600call to ``benchmark_timer_initialize``.
2601.. code:: c
2602
2603    benchmark_timer_t benchmark_timer_read(void)
2604    {
2605    stop time = read the hardware timer
2606    if the subtract overhead feature is enabled
2607    subtract overhead from stop time
2608    return the stop time
2609    }
2610
2611Many implementations of this routine subtract the overhead required
2612to initialize and read the benchmark timer.  This makes the times reported
2613more accurate.
2614
2615Some implementations report 0 if the harware timer value change is
2616sufficiently small.  This is intended to indicate that the execution time
2617is below the resolution of the timer.
2618
2619benchmark_timer_disable_subtracting_average_overhead
2620----------------------------------------------------
2621
2622This routine is invoked by the "Check Timer" (``tmck``) test in the
2623RTEMS Timing Test Suite.  It makes the ``benchmark_timer_read``
2624routine NOT subtract the overhead required
2625to initialize and read the benchmark timer.  This is used
2626by the ``tmoverhd`` test to determine the overhead
2627required to initialize and read the timer.
2628.. code:: c
2629
2630    void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
2631    {
2632    disable the subtract overhead feature
2633    }
2634
2635The ``benchmark_timer_find_average_overhead`` variable is used to
2636indicate the state of the "subtract overhead feature".
2637
2638gen68340 UART FIFO Full Mode
2639============================
2640
2641The gen68340 BSP is an example of the use of the timer to support the UART
2642input FIFO full mode (FIFO means First In First Out and roughly means
2643buffer). This mode consists in the UART raising an interrupt when n
2644characters have been received (*n* is the UART’s FIFO length). It results
2645in a lower interrupt processing time, but the problem is that a scanf
2646primitive will block on a receipt of less than *n* characters. The solution
2647is to set a timer that will check whether there are some characters
2648waiting in the UART’s input FIFO. The delay time has to be set carefully
2649otherwise high rates will be broken:
2650
2651- if no character was received last time the interrupt subroutine was
2652  entered, set a long delay,
2653
2654- otherwise set the delay to the delay needed for *n* characters
2655  receipt.
2656
2657.. COMMENT: COPYRIGHT (c) 1988-2002.
2658
2659.. COMMENT: On-Line Applications Research Corporation (OAR).
2660
2661.. COMMENT: All rights reserved.
2662
2663Real-Time Clock Driver
2664######################
2665
2666Introduction
2667============
2668
2669The Real-Time Clock (*RTC*) driver is responsible for providing an
2670interface to an *RTC* device.  \[NOTE: In this chapter, the abbreviation*TOD* is used for *Time of Day*.]  The capabilities provided by this
2671driver are:
2672
2673- Set the RTC TOD to RTEMS TOD
2674
2675- Set the RTEMS TOD to the RTC TOD
2676
2677- Get the RTC TOD
2678
2679- Set the RTC TOD to the Specified TOD
2680
2681- Get the Difference Between the RTEMS and RTC TOD
2682
2683The reference implementation for a real-time clock driver can
2684be found in ``c/src/lib/libbsp/shared/tod.c``.  This driver
2685is based on the libchip concept and can be easily configured
2686to work with any of the RTC chips supported by the RTC
2687chip drivers in the directory ``c/src/lib/lib/libchip/rtc``.
2688There is a README file in this directory for each supported
2689RTC chip.  Each of these README explains how to configure the
2690shared libchip implementation of the RTC driver for that particular
2691RTC chip.
2692
2693The DY-4 DMV177 BSP used the shared libchip implementation of the RTC
2694driver.  There were no DMV177 specific configuration routines.  A BSP
2695could use configuration routines to dynamically determine what type
2696of real-time clock is on a particular board.  This would be useful for
2697a BSP supporting multiple board models.  The relevant ports of
2698the DMV177’s ``RTC_Table`` configuration table is below:
2699.. code:: c
2700
2701    #include <bsp.h>
2702    #include <libchip/rtc.h>
2703    #include <libchip/icm7170.h>
2704    bool dmv177_icm7170_probe(int minor);
2705    rtc_tbl     RTC_Table[] = {
2706    { "/dev/rtc0",                /* sDeviceName \*/
2707    RTC_ICM7170,                /* deviceType \*/
2708    &icm7170_fns,               /* pDeviceFns \*/
2709    dmv177_icm7170_probe,       /* deviceProbe \*/
2710    (void \*) ICM7170_AT_1_MHZ,  /* pDeviceParams \*/
2711    DMV170_RTC_ADDRESS,         /* ulCtrlPort1 \*/
2712    0,                          /* ulDataPort \*/
2713    icm7170_get_register_8,     /* getRegister \*/
2714    icm7170_set_register_8,     /* setRegister \*/
2715    }
2716    };
2717    unsigned long  RTC_Count = (sizeof(RTC_Table)/sizeof(rtc_tbl));
2718    rtems_device_minor_number  RTC_Minor;
2719    bool dmv177_icm7170_probe(int minor)
2720    {
2721    volatile unsigned16 \*card_resource_reg;
2722    card_resource_reg = (volatile unsigned16 \*) DMV170_CARD_RESORCE_REG;
2723    if ( (\*card_resource_reg & DMV170_RTC_INST_MASK) == DMV170_RTC_INSTALLED )
2724    return TRUE;
2725    return FALSE;
2726    }
2727
2728Initialization
2729==============
2730
2731The ``rtc_initialize`` routine is responsible for initializing the
2732RTC chip so it can be used.  The shared libchip implementation of this
2733driver supports multiple RTCs and bases its initialization order on
2734the order the chips are defined in the ``RTC_Table``.  Each chip
2735defined in the table may or may not be present on this particular board.
2736It is the responsibility of the ``deviceProbe`` to indicate the
2737presence of a particular RTC chip.  The first RTC found to be present
2738is considered the preferred RTC.
2739
2740In the shared libchip based implementation
2741of the driver, the following actions are performed:
2742.. code:: c
2743
2744    rtems_device_driver rtc_initialize(
2745    rtems_device_major_number  major,
2746    rtems_device_minor_number  minor_arg,
2747    void                      \*arg
2748    )
2749    {
2750    for each RTC configured in RTC_Table
2751    if the deviceProbe for this RTC indicates it is present
2752    set RTC_Minor to this device
2753    set RTC_Present to TRUE
2754    break out of this loop
2755    if RTC_Present is not TRUE
2756    return RTEMS_INVALID_NUMBER to indicate that no RTC is present
2757    register this minor number as the "/dev/rtc"
2758    perform the deviceInitialize routine for the preferred RTC chip
2759    for RTCs past this one in the RTC_Table
2760    if the deviceProbe for this RTC indicates it is present
2761    perform the deviceInitialize routine for this RTC chip
2762    register the configured name for this RTC
2763    }
2764
2765The ``deviceProbe`` routine returns TRUE if the device
2766configured by this entry in the ``RTC_Table`` is present.
2767This configuration scheme allows one to support multiple versions
2768of the same board with a single BSP.  For example, if the first
2769generation of a board had Vendor A’s RTC chip and the second
2770generation had Vendor B’s RTC chip, RTC_Table could contain
2771information for both.  The ``deviceProbe`` configured
2772for Vendor A’s RTC chip would need to return TRUE if the
2773board was a first generation one.  The ``deviceProbe``
2774routines are very board dependent and must be provided by
2775the BSP.
2776
2777setRealTimeToRTEMS
2778==================
2779
2780The ``setRealTimeToRTEMS`` routine sets the current RTEMS TOD to that
2781of the preferred RTC.
2782.. code:: c
2783
2784    void setRealTimeToRTEMS(void)
2785    {
2786    if no RTCs are present
2787    return
2788    invoke the deviceGetTime routine for the preferred RTC
2789    set the RTEMS TOD using rtems_clock_set
2790    }
2791
2792setRealTimeFromRTEMS
2793====================
2794
2795The ``setRealTimeFromRTEMS`` routine sets the preferred RTC TOD to the
2796current RTEMS TOD.
2797.. code:: c
2798
2799    void setRealTimeFromRTEMS(void)
2800    {
2801    if no RTCs are present
2802    return
2803    obtain the RTEMS TOD using rtems_clock_get
2804    invoke the deviceSetTime routine for the preferred RTC
2805    }
2806
2807getRealTime
2808===========
2809
2810The ``getRealTime`` returns the preferred RTC TOD to the
2811caller.
2812.. code:: c
2813
2814    void getRealTime( rtems_time_of_day \*tod )
2815    {
2816    if no RTCs are present
2817    return
2818    invoke the deviceGetTime routine for the preferred RTC
2819    }
2820
2821setRealTime
2822===========
2823
2824The ``setRealTime`` routine sets the preferred RTC TOD to the
2825TOD specified by the caller.
2826.. code:: c
2827
2828    void setRealTime( rtems_time_of_day \*tod )
2829    {
2830    if no RTCs are present
2831    return
2832    invoke the deviceSetTime routine for the preferred RTC
2833    }
2834
2835checkRealTime
2836=============
2837
2838The ``checkRealTime`` routine returns the number of seconds
2839difference between the RTC TOD and the current RTEMS TOD.
2840.. code:: c
2841
2842    int checkRealTime( void )
2843    {
2844    if no RTCs are present
2845    return -1
2846    obtain the RTEMS TOD using rtems_clock_get
2847    get the TOD from the preferred RTC using the deviceGetTime routine
2848    convert the RTEMS TOD to seconds
2849    convert the RTC TOD to seconds
2850    return the RTEMS TOD in seconds - RTC TOD in seconds
2851    }
2852
2853.. COMMENT: COPYRIGHT (c) 1988-2002.
2854
2855.. COMMENT: On-Line Applications Research Corporation (OAR).
2856
2857.. COMMENT: All rights reserved.
2858
2859ATA Driver
2860##########
2861
2862Terms
2863=====
2864
2865ATA device - physical device attached to an IDE controller
2866
2867Introduction
2868============
2869
2870ATA driver provides generic interface to an ATA device. ATA driver is
2871hardware independent implementation of ATA standard defined in working draft
2872"AT Attachment Interface with Extensions (ATA-2)" X3T10/0948D revision 4c,
2873March 18, 1996. ATA Driver based on IDE Controller Driver and may be used for
2874computer systems with single IDE controller and with multiple as well. Although
2875current implementation has several restrictions detailed below ATA driver
2876architecture allows easily extend the driver. Current restrictions are:
2877
2878- Only mandatory (see draft p.29) and two optional (READ/WRITE MULTIPLE)
2879  commands are implemented
2880
2881- Only PIO mode is supported but both poll and interrupt driven
2882
2883The reference implementation for ATA driver can be found in``cpukit/libblock/src/ata.c``.
2884
2885Initialization
2886==============
2887
2888The ``ata_initialize`` routine is responsible for ATA driver
2889initialization. The main goal of the initialization is to detect and
2890register in the system all ATA devices attached to IDE controllers
2891successfully initialized by the IDE Controller driver.
2892
2893In the implementation of the driver, the following actions are performed:
2894.. code:: c
2895
2896    rtems_device_driver ata_initialize(
2897    rtems_device_major_number  major,
2898    rtems_device_minor_number  minor,
2899    void                      \*arg
2900    )
2901    {
2902    initialize internal ATA driver data structure
2903    for each IDE controller successfully initialized by the IDE Controller
2904    driver
2905    if the controller is interrupt driven
2906    set up interrupt handler
2907    obtain information about ATA devices attached to the controller
2908    with help of EXECUTE DEVICE DIAGNOSTIC command
2909    for each ATA device detected on the controller
2910    obtain device parameters with help of DEVICE IDENTIFY command
2911    register new ATA device as new block device in the system
2912    }
2913
2914Special processing of ATA commands is required because of absence of
2915multitasking environment during the driver initialization.
2916
2917Detected ATA devices are registered in the system as physical block devices
2918(see libblock library description). Device names are formed based on IDE
2919controller minor number device is attached to and device number on the
2920controller (0 - Master, 1 - Slave). In current implementation 64 minor
2921numbers are reserved for each ATA device which allows to support up to 63
2922logical partitions per device.
2923.. code:: c
2924
2925    controller minor    device number    device name    ata device minor
2926    0                  0             hda                0
2927    0                  1             hdb               64
2928    1                  0             hdc              128
2929    1                  1             hdd              172
2930    ...                ...            ...
2931
2932ATA Driver Architecture
2933=======================
2934
2935ATA Driver Main Internal Data Structures
2936----------------------------------------
2937
2938ATA driver works with ATA requests. ATA request is described by the
2939following structure:
2940.. code:: c
2941
2942    /* ATA request \*/
2943    typedef struct ata_req_s {
2944    Chain_Node        link;   /* link in requests chain \*/
2945    char              type;   /* request type \*/
2946    ata_registers_t   regs;   /* ATA command \*/
2947    uint32_t          cnt;    /* Number of sectors to be exchanged \*/
2948    uint32_t          cbuf;   /* number of current buffer from breq in use \*/
2949    uint32_t          pos;    /* current position in 'cbuf' \*/
2950    blkdev_request   \*breq;   /* blkdev_request which corresponds to the
2951    * ata request
2952    \*/
2953    rtems_id          sema;   /* semaphore which is used if synchronous
2954    * processing of the ata request is required
2955    \*/
2956    rtems_status_code status; /* status of ata request processing \*/
2957    int               error;  /* error code \*/
2958    } ata_req_t;
2959
2960ATA driver supports separate ATA requests queues for each IDE
2961controller (one queue per controller). The following structure contains
2962information about controller’s queue and devices attached to the controller:
2963.. code:: c
2964
2965    /*
2966    * This structure describes controller state, devices configuration on the
2967    * controller and chain of ATA requests to the controller.
2968    \*/
2969    typedef struct ata_ide_ctrl_s {
2970    bool          present;   /* controller state \*/
2971    ata_dev_t     device[2]; /* ata devices description \*/
2972    Chain_Control reqs;      /* requests chain \*/
2973    } ata_ide_ctrl_t;
2974
2975Driver uses array of the structures indexed by the controllers minor
2976number.
2977
2978The following structure allows to map an ATA device to the pair (IDE
2979controller minor number device is attached to, device number
2980on the controller):
2981.. code:: c
2982
2983    /*
2984    * Mapping of rtems ATA devices to the following pairs:
2985    * (IDE controller number served the device, device number on the controller)
2986    \*/
2987    typedef struct ata_ide_dev_s {
2988    int ctrl_minor;/* minor number of IDE controller serves rtems ATA device \*/
2989    int device;    /* device number on IDE controller (0 or 1) \*/
2990    } ata_ide_dev_t;
2991
2992Driver uses array of the structures indexed by the ATA devices minor
2993number.
2994
2995ATA driver defines the following internal events:
2996.. code:: c
2997
2998    /* ATA driver events \*/
2999    typedef enum ata_msg_type_s {
3000    ATA_MSG_GEN_EVT = 1,     /* general event \*/
3001    ATA_MSG_SUCCESS_EVT,     /* success event \*/
3002    ATA_MSG_ERROR_EVT,       /* error event \*/
3003    ATA_MSG_PROCESS_NEXT_EVT /* process next ata request event \*/
3004    } ata_msg_type_t;
3005
3006Brief ATA Driver Core Overview
3007------------------------------
3008
3009All ATA driver functionality is available via ATA driver ioctl. Current
3010implementation supports only two ioctls: BLKIO_REQUEST and
3011ATAIO_SET_MULTIPLE_MODE. Each ATA driver ioctl() call generates an
3012ATA request which is appended to the appropriate controller queue depending
3013on ATA device the request belongs to. If appended request is single request in
3014the controller’s queue then ATA driver event is generated.
3015
3016ATA driver task which manages queue of ATA driver events is core of ATA
3017driver. In current driver version queue of ATA driver events implemented
3018as RTEMS message queue. Each message contains event type, IDE controller
3019minor number on which event happened and error if an error occurred. Events
3020may be generated either by ATA driver ioctl call or by ATA driver task itself.
3021Each time ATA driver task receives an event it gets controller minor number
3022from event, takes first ATA request from controller queue and processes it
3023depending on request and event types. An ATA request processing may also
3024includes sending of several events. If ATA request processing is finished
3025the ATA request is removed from the controller queue. Note, that in current
3026implementation maximum one event per controller may be queued at any moment
3027of the time.
3028
3029(This part seems not very clear, hope I rewrite it soon)
3030
3031.. COMMENT: COPYRIGHT (c) 1988-2002.
3032
3033.. COMMENT: On-Line Applications Research Corporation (OAR).
3034
3035.. COMMENT: All rights reserved.
3036
3037IDE Controller Driver
3038#####################
3039
3040Introduction
3041============
3042
3043The IDE Controller driver is responsible for providing an
3044interface to an IDE Controller.  The capabilities provided by this
3045driver are:
3046
3047- Read IDE Controller register
3048
3049- Write IDE Controller register
3050
3051- Read data block through IDE Controller Data Register
3052
3053- Write data block through IDE Controller Data Register
3054
3055The reference implementation for an IDE Controller driver can
3056be found in ``$RTEMS_SRC_ROOT/c/src/libchip/ide``. This driver
3057is based on the libchip concept and allows to work with any of the IDE
3058Controller chips simply by appropriate configuration of BSP. Drivers for a
3059particular IDE Controller chips locate in the following directories: drivers
3060for well-known IDE Controller chips locate into``$RTEMS_SRC_ROOT/c/src/libchip/ide``, drivers for IDE Controller chips
3061integrated with CPU locate into``$RTEMS_SRC_ROOT/c/src/lib/libcpu/myCPU`` and
3062drivers for custom IDE Controller chips (for example, implemented on FPGA)
3063locate into ``$RTEMS_SRC_ROOT/c/src/lib/libbsp/myBSP``.
3064There is a README file in these directories for each supported
3065IDE Controller chip. Each of these README explains how to configure a BSP
3066for that particular IDE Controller chip.
3067
3068Initialization
3069==============
3070
3071IDE Controller chips used by a BSP are statically configured into``IDE_Controller_Table``. The ``ide_controller_initialize`` routine is
3072responsible for initialization of all configured IDE controller chips.
3073Initialization order of the chips based on the order the chips are defined in
3074the ``IDE_Controller_Table``.
3075
3076The following actions are performed by the IDE Controller driver
3077initialization routine:
3078.. code:: c
3079
3080    rtems_device_driver ide_controller_initialize(
3081    rtems_device_major_number  major,
3082    rtems_device_minor_number  minor_arg,
3083    void                      \*arg
3084    )
3085    {
3086    for each IDE Controller chip configured in IDE_Controller_Table
3087    if (BSP dependent probe(if exists) AND device probe for this IDE chip
3088    indicates it is present)
3089    perform initialization of the particular chip
3090    register device with configured name for this chip
3091    }
3092
3093Read IDE Controller Register
3094============================
3095
3096The ``ide_controller_read_register`` routine reads the content of the IDE
3097Controller chip register. IDE Controller chip is selected via the minor
3098number. This routine is not allowed to be called from an application.
3099.. code:: c
3100
3101    void ide_controller_read_register(rtems_device_minor_number minor,
3102    unsigned32 reg, unsigned32 \*value)
3103    {
3104    get IDE Controller chip configuration information from
3105    IDE_Controller_Table by minor number
3106    invoke read register routine for the chip
3107    }
3108
3109Write IDE Controller Register
3110=============================
3111
3112The ``ide_controller_write_register`` routine writes IDE Controller chip
3113register with specified value. IDE Controller chip is selected via the minor
3114number. This routine is not allowed to be called from an application.
3115.. code:: c
3116
3117    void ide_controller_write_register(rtems_device_minor_number minor,
3118    unsigned32 reg, unsigned32 value)
3119    {
3120    get IDE Controller chip configuration information from
3121    IDE_Controller_Table by minor number
3122    invoke write register routine for the chip
3123    }
3124
3125Read Data Block Through IDE Controller Data Register
3126====================================================
3127
3128The ``ide_controller_read_data_block`` provides multiple consequent read
3129of the IDE Controller Data Register. IDE Controller chip is selected via the
3130minor number. The same functionality may be achieved via separate multiple
3131calls of ``ide_controller_read_register`` routine but``ide_controller_read_data_block`` allows to escape functions call
3132overhead. This routine is not allowed to be called from an application.
3133.. code:: c
3134
3135    void ide_controller_read_data_block(
3136    rtems_device_minor_number  minor,
3137    unsigned16                 block_size,
3138    blkdev_sg_buffer          \*bufs,
3139    uint32_t                  \*cbuf,
3140    uint32_t                  \*pos
3141    )
3142    {
3143    get IDE Controller chip configuration information from
3144    IDE_Controller_Table by minor number
3145    invoke read data block routine for the chip
3146    }
3147
3148Write Data Block Through IDE Controller Data Register
3149=====================================================
3150
3151The ``ide_controller_write_data_block`` provides multiple consequent write
3152into the IDE Controller Data Register. IDE Controller chip is selected via the
3153minor number. The same functionality may be achieved via separate multiple
3154calls of ``ide_controller_write_register`` routine but``ide_controller_write_data_block`` allows to escape functions call
3155overhead. This routine is not allowed to be called from an application.
3156.. code:: c
3157
3158    void ide_controller_write_data_block(
3159    rtems_device_minor_number  minor,
3160    unsigned16                 block_size,
3161    blkdev_sg_buffer          \*bufs,
3162    uint32_t                  \*cbuf,
3163    uint32_t                  \*pos
3164    )
3165    {
3166    get IDE Controller chip configuration information from
3167    IDE_Controller_Table by minor number
3168    invoke write data block routine for the chip
3169    }
3170
3171.. COMMENT: COPYRIGHT (c) 1988-2002.
3172
3173.. COMMENT: On-Line Applications Research Corporation (OAR).
3174
3175.. COMMENT: All rights reserved.
3176
3177Non-Volatile Memory Driver
3178##########################
3179
3180The Non-Volatile driver is responsible for providing an
3181interface to various types of non-volatile memory.  These
3182types of memory include, but are not limited to, Flash, EEPROM,
3183and battery backed RAM.  The capabilities provided
3184by this class of device driver are:
3185
3186- Initialize the Non-Volatile Memory Driver
3187
3188- Optional Disable Read and Write Handlers
3189
3190- Open a Particular Memory Partition
3191
3192- Close a Particular Memory Partition
3193
3194- Read from a Particular Memory Partition
3195
3196- Write to a Particular Memory Partition
3197
3198- Erase the Non-Volatile Memory Area
3199
3200There is currently only one non-volatile device driver included in the
3201RTEMS source tree.  The information provided in this chapter
3202is based on drivers developed for applications using RTEMS.
3203It is hoped that this driver model information can form the
3204basis for a standard non-volatile memory driver model that
3205can be supported in future RTEMS distribution.
3206
3207Major and Minor Numbers
3208=======================
3209
3210The *major* number of a device driver is its index in the
3211RTEMS Device Address Table.
3212
3213A *minor* number is associated with each device instance
3214managed by a particular device driver.  An RTEMS minor number
3215is an ``unsigned32`` entity.  Convention calls
3216dividing the bits in the minor number down into categories
3217that specify an area of non-volatile memory and a partition
3218with that area.  This results in categories
3219like the following:
3220
3221- *area* - indicates a block of non-volatile memory
3222
3223- *partition* - indicates a particular address range with an area
3224
3225From the above, it should be clear that a single device driver
3226can support multiple types of non-volatile memory in a single system.
3227The minor number is used to distinguish the types of memory and
3228blocks of memory used for different purposes.
3229
3230Non-Volatile Memory Driver Configuration
3231========================================
3232
3233There is not a standard non-volatile driver configuration table but some
3234fields are common across different drivers.  The non-volatile memory driver
3235configuration table is typically an array of structures with each
3236structure containing the information for a particular area of
3237non-volatile memory.
3238The following is a list of the type of information normally required
3239to configure each area of non-volatile memory.
3240
3241*memory_type*
3242    is the type of memory device in this area.  Choices are battery backed RAM,
3243    EEPROM, Flash, or an optional user-supplied type.  If the user-supplied type
3244    is configured, then the user is responsible for providing a set of
3245    routines to program the memory.
3246
3247*memory*
3248    is the base address of this memory area.
3249
3250*attributes*
3251    is a pointer to a memory type specific attribute block.  Some of
3252    the fields commonly contained in this memory type specific attribute
3253    structure area:
3254
3255    *use_protection_algorithm*
3256
3257        is set to TRUE to indicate that the protection (i.e. locking) algorithm
3258        should be used for this area of non-volatile memory.  A particular
3259        type of non-volatile memory may not have a protection algorithm.
3260
3261    *access*
3262
3263        is an enumerated type to indicate the organization of the memory
3264        devices in this memory area.  The following is a list of the
3265        access types supported by the current driver implementation:
3266        - simple unsigned8
3267        - simple unsigned16
3268        - simple unsigned32
3269        - simple unsigned64
3270        - single unsigned8 at offset 0 in an unsigned16
3271        - single unsigned8 at offset 1 in an unsigned16
3272        - single unsigned8 at offset 0 in an unsigned32
3273        - single unsigned8 at offset 1 in an unsigned32
3274        - single unsigned8 at offset 2 in an unsigned32
3275        - single unsigned8 at offset 3 in an unsigned32
3276
3277    *depth*
3278
3279        is the depth of the progamming FIFO on this particular chip.  Some
3280        chips, particularly EEPROMs, have the same programming algorithm but
3281        vary in the depth of the amount of data that can be programmed in a single
3282        block.
3283
3284*number_of_partitions*
3285    is the number of logical partitions within this area.
3286
3287*Partitions*
3288    is the address of the table that contains an entry to describe each
3289    partition in this area.  Fields within each element of this
3290    table are defined as follows:
3291
3292    *offset*
3293
3294        is the offset of this partition from the base address of this area.
3295
3296    *length*
3297
3298        is the length of this partition.
3299
3300By dividing an area of memory into multiple partitions, it is possible
3301to easily divide the non-volatile memory for different purposes.
3302
3303Initialize the Non-Volatile Memory Driver
3304=========================================
3305
3306At system initialization, the non-volatile memory driver’s
3307initialization entry point will be invoked.  As part of
3308initialization, the driver will perform
3309whatever initializatin is required on each non-volatile memory area.
3310
3311The discrete I/O driver may register device names for memory
3312partitions of particular interest to the system.  Normally this
3313will be restricted to the device "/dev/nv_memory" to indicate
3314the entire device driver.
3315
3316Disable Read and Write Handlers
3317===============================
3318
3319Depending on the target’s non-volatile memory configuration, it may be
3320possible to write to a status register and make the memory area completely
3321inaccessible.  This is target dependent and beyond the standard capabilities
3322of any memory type.  The user has the optional capability to provide
3323handlers to disable and enable access to a partiticular memory area.
3324
3325Open a Particular Memory Partition
3326==================================
3327
3328This is the driver open call.  Usually this call does nothing other than
3329validate the minor number.
3330
3331With some drivers, it may be necessary to allocate memory when a particular
3332device is opened.  If that is the case, then this is often the place
3333to do this operation.
3334
3335Close a Particular Memory Partition
3336===================================
3337
3338This is the driver close call.  Usually this call does nothing.
3339
3340With some drivers, it may be necessary to allocate memory when a particular
3341device is opened.  If that is the case, then this is the place
3342where that memory should be deallocated.
3343
3344Read from a Particular Memory Partition
3345=======================================
3346
3347This corresponds to the driver read call.  After validating the minor
3348number and arguments, this call enables reads from the specified
3349memory area by invoking the user supplied "enable reads handler"
3350and then reads the indicated memory area.  When
3351invoked the ``argument_block`` is actually a pointer to the following
3352structure type:
3353.. code:: c
3354
3355    typedef struct {
3356    uint32_t  offset;
3357    void     \*buffer;
3358    uint32_t  length;
3359    uint32_t  status;
3360    }   Non_volatile_memory_Driver_arguments;
3361
3362The driver reads ``length`` bytes starting at ``offset`` into
3363the partition and places them at ``buffer``.  The result is returned
3364in ``status``.
3365
3366After the read operation is complete, the user supplied "disable reads handler"
3367is invoked to protect the memory area again.
3368
3369Write to a Particular Memory Partition
3370======================================
3371
3372This corresponds to the driver write call.   After validating the minor
3373number and arguments, this call enables writes to the specified
3374memory area by invoking the "enable writes handler", then unprotecting
3375the memory area, and finally actually writing to the indicated memory
3376area.  When invoked the ``argument_block`` is actually a pointer to
3377the following structure type:
3378.. code:: c
3379
3380    typedef struct {
3381    uint32_t   offset;
3382    void      \*buffer;
3383    uint32_t   length;
3384    uint32_t   status;
3385    }   Non_volatile_memory_Driver_arguments;
3386
3387The driver writes ``length`` bytes from ``buffer`` and
3388writes them to the non-volatile memory starting at ``offset`` into
3389the partition.  The result is returned in ``status``.
3390
3391After the write operation is complete, the "disable writes handler"
3392is invoked to protect the memory area again.
3393
3394Erase the Non-Volatile Memory Area
3395==================================
3396
3397This is one of the IOCTL functions supported by the I/O control
3398device driver entry point.  When this IOCTL function is invoked,
3399the specified area of non-volatile memory is erased.
3400
3401.. COMMENT: Written by Eric Norum
3402
3403.. COMMENT: COPYRIGHT (c) 1988-2002.
3404
3405.. COMMENT: On-Line Applications Research Corporation (OAR).
3406
3407.. COMMENT: All rights reserved.
3408
3409Networking Driver
3410#################
3411
3412Introduction
3413============
3414
3415This chapter is intended to provide an introduction to the
3416procedure for writing RTEMS network device drivers.
3417The example code is taken from the ‘Generic 68360’ network device
3418driver.  The source code for this driver is located in the``c/src/lib/libbsp/m68k/gen68360/network`` directory in the RTEMS
3419source code distribution.  Having a copy of this driver at
3420hand when reading the following notes will help significantly.
3421
3422Learn about the network device
3423==============================
3424
3425Before starting to write the network driver become completely
3426familiar with the programmer’s view of the device.
3427The following points list some of the details of the
3428device that must be understood before a driver can be written.
3429
3430- Does the device use DMA to transfer packets to and from
3431  memory or does the processor have to
3432  copy packets to and from memory on the device?
3433
3434- If the device uses DMA, is it capable of forming a single
3435  outgoing packet from multiple fragments scattered in separate
3436  memory buffers?
3437
3438- If the device uses DMA, is it capable of chaining multiple
3439  outgoing packets, or does each outgoing packet require
3440  intervention by the driver?
3441
3442- Does the device automatically pad short frames to the minimum
3443  64 bytes or does the driver have to supply the padding?
3444
3445- Does the device automatically retry a transmission on detection
3446  of a collision?
3447
3448- If the device uses DMA, is it capable of buffering multiple
3449  packets to memory, or does the receiver have to be restarted
3450  after the arrival of each packet?
3451
3452- How are packets that are too short, too long, or received with
3453  CRC errors handled?  Does the device automatically continue
3454  reception or does the driver have to intervene?
3455
3456- How is the device Ethernet address set?  How is the device
3457  programmed to accept or reject broadcast and multicast packets?
3458
3459- What interrupts does the device generate?  Does it generate an
3460  interrupt for each incoming packet, or only for packets received
3461  without error?  Does it generate an interrupt for each packet
3462  transmitted, or only when the transmit queue is empty?  What
3463  happens when a transmit error is detected?
3464
3465In addition, some controllers have specific questions regarding
3466board specific configuration.  For example, the SONIC Ethernet
3467controller has a very configurable data bus interface.  It can
3468even be configured for sixteen and thirty-two bit data buses.  This
3469type of information should be obtained from the board vendor.
3470
3471Understand the network scheduling conventions
3472=============================================
3473
3474When writing code for the driver transmit and receive tasks,
3475take care to follow the network scheduling conventions.  All tasks
3476which are associated with networking share various
3477data structures and resources.  To ensure the consistency
3478of these structures the tasks
3479execute only when they hold the network semaphore (``rtems_bsdnet_semaphore``).
3480The transmit and receive tasks must abide by this protocol.  Be very
3481careful to avoid ‘deadly embraces’ with the other network tasks.
3482A number of routines are provided to make it easier for the network
3483driver code to conform to the network task scheduling conventions.
3484
3485- ``void rtems_bsdnet_semaphore_release(void)``
3486  This function releases the network semaphore.
3487  The network driver tasks must call this function immediately before
3488  making any blocking RTEMS request.
3489
3490- ``void rtems_bsdnet_semaphore_obtain(void)``
3491  This function obtains the network semaphore.
3492  If a network driver task has released the network semaphore to allow other
3493  network-related tasks to run while the task blocks, then this function must
3494  be called to reobtain the semaphore immediately after the return from the
3495  blocking RTEMS request.
3496
3497- ``rtems_bsdnet_event_receive(rtems_event_set, rtems_option, rtems_interval, rtems_event_set \*)``
3498  The network driver task should call this function when it wishes to wait
3499  for an event.  This function releases the network semaphore,
3500  calls ``rtems_event_receive`` to wait for the specified event
3501  or events and reobtains the semaphore.
3502  The value returned is the value returned by the ``rtems_event_receive``.
3503
3504Network Driver Makefile
3505=======================
3506
3507Network drivers are considered part of the BSD network package and as such
3508are to be compiled with the appropriate flags.  This can be accomplished by
3509adding ``-D__INSIDE_RTEMS_BSD_TCPIP_STACK__`` to the ``command line``.
3510If the driver is inside the RTEMS source tree or is built using the
3511RTEMS application Makefiles, then adding the following line accomplishes
3512this:
3513
3514.. code:: c
3515
3516    DEFINES += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
3517
3518This is equivalent to the following list of definitions.  Early versions
3519of the RTEMS BSD network stack required that all of these be defined.
3520
3521.. code:: c
3522
3523    -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \\
3524    -DDIAGNOSTIC -DBOOTP_COMPAT
3525
3526Defining these macros tells the network header files that the driver
3527is to be compiled with extended visibility into the network stack.  This
3528is in sharp contrast to applications that simply use the network stack.
3529Applications do not require this level of visibility and should stick
3530to the portable application level API.
3531
3532As a direct result of being logically internal to the network stack,
3533network drivers use the BSD memory allocation routines   This means,
3534for example, that malloc takes three arguments.  See the SONIC
3535device driver (``c/src/lib/libchip/network/sonic.c``) for an example
3536of this.  Because of this, network drivers should not include``<stdlib.h>``.  Doing so will result in conflicting definitions
3537of ``malloc()``.
3538
3539*Application level* code including network servers such as the FTP
3540daemon are *not* part of the BSD kernel network code and should not be
3541compiled with the BSD network flags.  They should include``<stdlib.h>`` and not define the network stack visibility
3542macros.
3543
3544Write the Driver Attach Function
3545================================
3546
3547The driver attach function is responsible for configuring the driver
3548and making the connection between the network stack
3549and the driver.
3550
3551Driver attach functions take a pointer to an``rtems_bsdnet_ifconfig`` structure as their only argument.
3552and set the driver parameters based on the
3553values in this structure.  If an entry in the configuration
3554structure is zero the attach function chooses an
3555appropriate default value for that parameter.
3556
3557The driver should then set up several fields in the ifnet structure
3558in the device-dependent data structure supplied and maintained by the driver:
3559
3560``ifp->if_softc``
3561    Pointer to the device-dependent data.  The first entry
3562    in the device-dependent data structure must be an ``arpcom``
3563    structure.
3564
3565``ifp->if_name``
3566    The name of the device.  The network stack uses this string
3567    and the device number for device name lookups.  The device name should
3568    be obtained from the ``name`` entry in the configuration structure.
3569
3570``ifp->if_unit``
3571    The device number.  The network stack uses this number and the
3572    device name for device name lookups.  For example, if``ifp->if_name`` is ‘``scc``’ and ``ifp->if_unit`` is ‘``1``’,
3573    the full device name would be ‘``scc1``’.  The unit number should be
3574    obtained from the ‘name’ entry in the configuration structure.
3575
3576``ifp->if_mtu``
3577    The maximum transmission unit for the device.  For Ethernet
3578    devices this value should almost always be 1500.
3579
3580``ifp->if_flags``
3581    The device flags.  Ethernet devices should set the flags
3582    to ``IFF_BROADCAST|IFF_SIMPLEX``, indicating that the
3583    device can broadcast packets to multiple destinations
3584    and does not receive and transmit at the same time.
3585
3586``ifp->if_snd.ifq_maxlen``
3587    The maximum length of the queue of packets waiting to be
3588    sent to the driver.  This is normally set to ``ifqmaxlen``.
3589
3590``ifp->if_init``
3591    The address of the driver initialization function.
3592
3593``ifp->if_start``
3594    The address of the driver start function.
3595
3596``ifp->if_ioctl``
3597    The address of the driver ioctl function.
3598
3599``ifp->if_output``
3600    The address of the output function.  Ethernet devices
3601    should set this to ``ether_output``.
3602
3603RTEMS provides a function to parse the driver name in the
3604configuration structure into a device name and unit number.
3605.. code:: c
3606
3607    int rtems_bsdnet_parse_driver_name (
3608    const struct rtems_bsdnet_ifconfig \*config,
3609    char \**namep
3610    );
3611
3612The function takes two arguments; a pointer to the configuration
3613structure and a pointer to a pointer to a character.  The function
3614parses the configuration name entry, allocates memory for the driver
3615name, places the driver name in this memory, sets the second argument
3616to point to the name and returns the unit number.
3617On error, a message is printed and -1 is returned.
3618
3619Once the attach function  has set up the above entries it must link the
3620driver data structure onto the list of devices by
3621calling ``if_attach``.  Ethernet devices should then
3622call ``ether_ifattach``.  Both functions take a pointer to the
3623device’s ``ifnet`` structure as their only argument.
3624
3625The attach function should return a non-zero value to indicate that
3626the driver has been successfully configured and attached.
3627
3628Write the Driver Start Function.
3629================================
3630
3631This function is called each time the network stack wants to start the
3632transmitter.  This occures whenever the network stack adds a packet
3633to a device’s send queue and the ``IFF_OACTIVE`` bit in the
3634device’s ``if_flags`` is not set.
3635
3636For many devices this function need only set the ``IFF_OACTIVE`` bit in the``if_flags`` and send an event to the transmit task
3637indicating that a packet is in the driver transmit queue.
3638
3639Write the Driver Initialization Function.
3640=========================================
3641
3642This function should initialize the device, attach to interrupt handler,
3643and start the driver transmit and receive tasks.  The function
3644.. code:: c
3645
3646    rtems_id
3647    rtems_bsdnet_newproc (char \*name,
3648    int stacksize,
3649    void(\*entry)(void \*),
3650    void \*arg);
3651
3652should be used to start the driver tasks.
3653
3654Note that the network stack may call the driver initialization function more
3655than once.
3656Make sure multiple versions of the receive and transmit tasks are not accidentally
3657started.
3658
3659Write the Driver Transmit Task
3660==============================
3661
3662This task is reponsible for removing packets from the driver send queue and sending them to the device.  The task should block waiting for an event from the
3663driver start function indicating that packets are waiting to be transmitted.
3664When the transmit task has drained the driver send queue the task should clear
3665the ``IFF_OACTIVE`` bit in ``if_flags`` and block until another outgoing
3666packet is queued.
3667
3668Write the Driver Receive Task
3669=============================
3670
3671This task should block until a packet arrives from the device.  If the
3672device is an Ethernet interface the function ``ether_input`` should be called
3673to forward the packet to the network stack.   The arguments to ``ether_input``
3674are a pointer to the interface data structure, a pointer to the ethernet
3675header and a pointer to an mbuf containing the packet itself.
3676
3677Write the Driver Interrupt Handler
3678==================================
3679
3680A typical interrupt handler will do nothing more than the hardware
3681manipulation required to acknowledge the interrupt and send an RTEMS event
3682to wake up the driver receive or transmit task waiting for the event.
3683Network interface interrupt handlers must not make any calls to other
3684network routines.
3685
3686Write the Driver IOCTL Function
3687===============================
3688
3689This function handles ioctl requests directed at the device.  The ioctl
3690commands which must be handled are:
3691
3692``SIOCGIFADDR``
3693
3694``SIOCSIFADDR``
3695
3696    If the device is an Ethernet interface these
3697    commands should be passed on to ``ether_ioctl``.
3698
3699``SIOCSIFFLAGS``
3700
3701    This command should be used to start or stop the device,
3702    depending on the state of the interface ``IFF_UP`` and``IFF_RUNNING`` bits in ``if_flags``:
3703
3704    ``IFF_RUNNING``
3705
3706        Stop the device.
3707
3708    ``IFF_UP``
3709
3710        Start the device.
3711
3712    ``IFF_UP|IFF_RUNNING``
3713
3714        Stop then start the device.
3715
3716    ``0``
3717
3718        Do nothing.
3719
3720Write the Driver Statistic-Printing Function
3721============================================
3722
3723This function should print the values of any statistic/diagnostic
3724counters the network driver may use.  The driver ioctl function should call
3725the statistic-printing function when the ioctl command is``SIO_RTEMS_SHOW_STATS``.
3726
3727.. COMMENT: COPYRIGHT (c) 1988-2002.
3728
3729.. COMMENT: On-Line Applications Research Corporation (OAR).
3730
3731.. COMMENT: All rights reserved.
3732
3733Shared Memory Support Driver
3734############################
3735
3736The Shared Memory Support Driver is responsible for providing glue
3737routines and configuration information required by the Shared
3738Memory Multiprocessor Communications Interface (MPCI).  The
3739Shared Memory Support Driver tailors the portable Shared
3740Memory Driver to a particular target platform.
3741
3742This driver is only required in shared memory multiprocessing
3743systems that use the RTEMS mulitprocessing support.  For more
3744information on RTEMS multiprocessing capabilities and the
3745MPCI, refer to the *Multiprocessing Manager* chapter
3746of the *RTEMS Application C User’s Guide*.
3747
3748Shared Memory Configuration Table
3749=================================
3750
3751The Shared Memory Configuration Table is defined in the following
3752structure:
3753.. code:: c
3754
3755    typedef volatile uint32_t vol_u32;
3756    typedef struct {
3757    vol_u32 \*address;        /* write here for interrupt    \*/
3758    vol_u32  value;          /* this value causes interrupt \*/
3759    vol_u32  length;         /* for this length (0,1,2,4)   \*/
3760    } Shm_Interrupt_information;
3761    struct shm_config_info {
3762    vol_u32           \*base;       /* base address of SHM         \*/
3763    vol_u32            length;     /* length (in bytes) of SHM    \*/
3764    vol_u32            format;     /* SHM is big or little endian \*/
3765    vol_u32          (\*convert)(); /* neutral conversion routine  \*/
3766    vol_u32            poll_intr;  /* POLLED or INTR driven mode  \*/
3767    void             (\*cause_intr)( uint32_t );
3768    Shm_Interrupt_information   Intr; /* cause intr information   \*/
3769    };
3770    typedef struct shm_config_info shm_config_table;
3771
3772where the fields are defined as follows:
3773
3774*base*
3775    is the base address of the shared memory buffer used to pass
3776    messages between the nodes in the system.
3777
3778*length*
3779    is the length (in bytes) of the shared memory buffer used to pass
3780    messages between the nodes in the system.
3781
3782*format*
3783    is either SHM_BIG or SHM_LITTLE to indicate that the neutral format
3784    of the shared memory area is big or little endian.  The format
3785    of the memory should be chosen to match most of the inter-node traffic.
3786
3787*convert*
3788    is the address of a routine which converts from native format to
3789    neutral format.   Ideally, the neutral format is the same as the
3790    native format so this routine is quite simple.
3791
3792*poll_intr*
3793    is either INTR_MODE or POLLED_MODE to indicate how the node will be
3794    informed of incoming messages.
3795
3796*cause_intr*
3797
3798*Intr*
3799
3800    is the information required to cause an interrupt on a node.  This
3801    structure contains the following fields:
3802
3803    *address*
3804
3805        is the address to write at to cause an interrupt on that node.
3806        For a polled node, this should be NULL.
3807
3808    *value*
3809
3810        is the value to write to cause an interrupt.
3811
3812    *length*
3813
3814        is the length of the entity to write on the node to cause an interrupt.
3815        This can be 0 to indicate polled operation, 1 to write a byte, 2 to
3816        write a sixteen-bit entity, and 4 to write a thirty-two bit entity.
3817
3818Primitives
3819==========
3820
3821Convert Address
3822---------------
3823
3824The ``Shm_Convert_address`` is responsible for converting an address
3825of an entity in the shared memory area into the address that should be
3826used from this node.  Most targets will simply return the address
3827passed to this routine.  However, some target boards will have a special
3828window onto the shared memory.  For example, some VMEbus boards have
3829special address windows to access addresses that are normally reserved
3830in the CPU’s address space.
3831.. code:: c
3832
3833    void \*Shm_Convert_address( void \*address )
3834    {
3835    return the local address version of this bus address
3836    }
3837
3838Get Configuration
3839-----------------
3840
3841The ``Shm_Get_configuration`` routine is responsible for filling in the
3842Shared Memory Configuration Table passed to it.
3843.. code:: c
3844
3845    void Shm_Get_configuration(
3846    uint32_t           localnode,
3847    shm_config_table \**shmcfg
3848    )
3849    {
3850    fill in the Shared Memory Configuration Table
3851    }
3852
3853Locking Primitives
3854------------------
3855
3856This is a collection of routines that are invoked by the portable
3857part of the Shared Memory Driver to manage locks in the shared
3858memory buffer area.  Accesses to the shared memory must be
3859atomic.  Two nodes in a multiprocessor system must not be manipulating
3860the shared data structures simultaneously.  The locking primitives
3861are used to insure this.
3862
3863To avoid deadlock, local processor interrupts should be disabled the entire
3864time the locked queue is locked.
3865
3866The locking primitives operate on the lock``field`` of the ``Shm_Locked_queue_Control``
3867data structure.  This structure is defined as follows:
3868.. code:: c
3869
3870    typedef struct {
3871    vol_u32 lock;  /* lock field for this queue    \*/
3872    vol_u32 front; /* first envelope on queue      \*/
3873    vol_u32 rear;  /* last envelope on queue       \*/
3874    vol_u32 owner; /* receiving (i.e. owning) node \*/
3875    } Shm_Locked_queue_Control;
3876
3877where each field is defined as follows:
3878
3879*lock*
3880    is the lock field.  Every node in the system must agree on how this
3881    field will be used.  Many processor families provide an atomic
3882    "test and set" instruction that is used to manage this field.
3883
3884*front*
3885    is the index of the first message on this locked queue.
3886
3887*rear*
3888    is the index of the last message on this locked queue.
3889
3890*owner*
3891    is the node number of the node that currently has this structure locked.
3892
3893Initializing a Shared Lock
3894~~~~~~~~~~~~~~~~~~~~~~~~~~
3895
3896The ``Shm_Initialize_lock`` routine is responsible for
3897initializing the lock field.  This routines usually is implemented
3898as follows:
3899.. code:: c
3900
3901    void Shm_Initialize_lock(
3902    Shm_Locked_queue_Control \*lq_cb
3903    )
3904    {
3905    lq_cb->lock = LQ_UNLOCKED;
3906    }
3907
3908Acquiring a Shared Lock
3909~~~~~~~~~~~~~~~~~~~~~~~
3910
3911The ``Shm_Lock`` routine is responsible for
3912acquiring the lock field.  Interrupts should be
3913disabled while that lock is acquired.  If the lock
3914is currently unavailble, then the locking routine
3915should delay a few microseconds to allow the other
3916node to release the lock.  Doing this reduces bus contention
3917for the lock.  This routines usually is implemented as follows:
3918.. code:: c
3919
3920    void Shm_Lock(
3921    Shm_Locked_queue_Control \*lq_cb
3922    )
3923    {
3924    disable processor interrupts
3925    set Shm_isrstat to previous interrupt disable level
3926    while ( TRUE ) {
3927    atomically attempt to acquire the lock
3928    if the lock was acquired
3929    return
3930    delay some small period of time
3931    }
3932    }
3933
3934Releasing a Shared Lock
3935~~~~~~~~~~~~~~~~~~~~~~~
3936
3937The ``Shm_Unlock`` routine is responsible for
3938releasing the lock field and reenabling processor
3939interrupts.  This routines usually is implemented as follows:
3940.. code:: c
3941
3942    void Shm_Unlock(
3943    Shm_Locked_queue_Control \*lq_cb
3944    )
3945    {
3946    set the lock to the unlocked value
3947    reenable processor interrupts to their level prior
3948    to the lock being acquired.  This value was saved
3949    in the global variable Shm_isrstat
3950    }
3951
3952Installing the MPCI ISR
3953=======================
3954
3955The ``Shm_setvec`` is invoked by the portable portion
3956of the shared memory to install the interrupt service routine
3957that is invoked when an incoming message is announced.  Some
3958target boards support an interprocessor interrupt or mailbox
3959scheme and this is where the ISR for that interrupt would be
3960installed.
3961
3962On an interrupt driven node, this routine would be implemented
3963as follows:
3964.. code:: c
3965
3966    void Shm_setvec( void )
3967    {
3968    install the interprocessor communications ISR
3969    }
3970
3971On a polled node, this routine would be empty.
3972
3973.. COMMENT: COPYRIGHT (c) 1988-2009.
3974
3975.. COMMENT: On-Line Applications Research Corporation (OAR).
3976
3977.. COMMENT: All rights reserved.
3978
3979Frame Buffer Driver
3980###################
3981
3982In this chapter, we present the basic functionality implemented by a
3983frame buffer driver: ``frame_buffer_initialize()``, ``frame_buffer_open()``,``frame_buffer_close()``, ``frame_buffer_read()``, ``frame_buffer_write()``
3984and ``frame_buffer_control()``.
3985
3986Introduction
3987============
3988
3989The purpose of the frame buffer driver is to provide an abstraction for
3990graphics hardware.
3991By using the frame buffer interface, an application can display graphics
3992without knowing anything about the low-level details of interfacing to a
3993particular graphics adapter. The parameters governing the mapping of
3994memory to displayed pixels (planar or linear, bit depth, etc) is still
3995implementation-specific, but device-independent methods are provided to
3996determine and potentially modify these parameters.
3997
3998The frame buffer driver is commonly located in the ``console``
3999directory of the BSP and registered by the name */dev/fb0*.
4000Additional frame buffers (if available) are named */dev/fb1*,*/dev/fb2*, etc.
4001
4002To work with the frame buffer, the following operation sequence is used:``open()``, ``ioctls()`` to get the frame buffer info, ``read()`` and/or``write()``, and ``close()``.
4003
4004Driver Function Overview
4005========================
4006
4007Initialization
4008--------------
4009
4010The driver initialization is called once during the RTEMS initialization
4011process and returns RTEMS_SUCCESSFUL when the device driver is successfully
4012initialized. During the initialization, a name is assigned to the frame
4013buffer device.  If the graphics hardware supports console text output,
4014as is the case with the pc386 VGA hardware, initialization into graphics
4015mode may be deferred until the device is ``open()`` ed.
4016
4017The ``frame_buffer_initialize()`` function may look like this:
4018
4019.. code:: c
4020
4021    rtems_device_driver frame_buffer_initialize(
4022    rtems_device_major_number  major,
4023    rtems_device_minor_number  minor,
4024    void                      \*arg)
4025    {
4026    rtems_status_code status;
4027    printk( "frame buffer driver initializing..\\n" );
4028    /*
4029    * Register the device
4030    \*/
4031    status = rtems_io_register_name("/dev/fb0", major, 0);
4032    if (status != RTEMS_SUCCESSFUL)
4033    {
4034    printk("Error registering frame buffer device!\\n");
4035    rtems_fatal_error_occurred( status );
4036    }
4037    /*
4038    * graphics hardware initialization goes here for non-console
4039    * devices
4040    \*/
4041    return RTEMS_SUCCESSFUL;
4042    }
4043
4044Opening the Frame Buffer Device
4045-------------------------------
4046
4047The ``frame_buffer_open()`` function is called whenever a frame buffer device is opened.
4048If the frame buffer is registered as "/dev/fb0", the ``frame_buffer_open`` entry point
4049will be called as the result of an  ``open("/dev/fb0", mode)`` in the application.
4050
4051Thread safety of the frame buffer driver is implementation-dependent.
4052The VGA driver shown below uses a mutex to prevent multiple open()
4053operations of the frame buffer device.
4054
4055The ``frame_buffer_open()`` function returns RTEMS_SUCCESSFUL when the device driver
4056is successfully opened, and RTEMS_UNSATISFIED if the device is already open:
4057.. code:: c
4058
4059    rtems_device_driver frame_buffer_close(
4060    rtems_device_major_number  major,
4061    rtems_device_minor_number  minor,
4062    void                      \*arg
4063    )
4064    {
4065    if (pthread_mutex_unlock(&mutex) == 0){
4066    /* restore previous state.  for VGA this means return to text mode.
4067    * leave out if graphics hardware has been initialized in
4068    * frame_buffer_initialize() \*/
4069    ega_hwterm();
4070    printk( "FBVGA close called.\\n" );
4071    return RTEMS_SUCCESSFUL;
4072    }
4073    return RTEMS_UNSATISFIED;
4074    }
4075
4076In the previous example, the function ``ega_hwinit()`` takes care of
4077hardware-specific initialization.
4078
4079Closing the Frame Buffer Device
4080-------------------------------
4081
4082The ``frame_buffer_close()`` is invoked when the frame buffer device
4083is closed.  It frees up any resources allocated in``frame_buffer_open()``, and should restore previous hardware state.
4084The entry point corresponds to the device driver close entry point.
4085
4086Returns RTEMS_SUCCESSFUL when the device driver is successfully closed:
4087.. code:: c
4088
4089    rtems_device_driver frame_buffer_close(
4090    rtems_device_major_number  major,
4091    rtems_device_minor_number  minor,
4092    void                      \*arg)
4093    {
4094    pthread_mutex_unlock(&mutex);
4095    /* TODO check mutex return value, RTEMS_UNSATISFIED if it failed.  we
4096    * don't want to unconditionally call ega_hwterm()... \*/
4097    /* restore previous state.  for VGA this means return to text mode.
4098    * leave out if graphics hardware has been initialized in
4099    * frame_buffer_initialize() \*/
4100    ega_hwterm();
4101    printk( "frame buffer close called.\\n" );
4102    return RTEMS_SUCCESSFUL;
4103    }
4104
4105Reading from the Frame Buffer Device
4106------------------------------------
4107
4108The ``frame_buffer_read()`` is invoked from a ``read()`` operation
4109on the frame buffer device.
4110Read functions should allow normal and partial reading at the end of frame buffer memory.
4111This method returns RTEMS_SUCCESSFUL when the device is successfully read from:
4112.. code:: c
4113
4114    rtems_device_driver frame_buffer_read(
4115    rtems_device_major_number  major,
4116    rtems_device_minor_number  minor,
4117    void                      \*arg
4118    )
4119    {
4120    rtems_libio_rw_args_t \*rw_args = (rtems_libio_rw_args_t \*)arg;
4121    rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
4122    memcpy(rw_args->buffer, (const void \*) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
4123    return RTEMS_SUCCESSFUL;
4124    }
4125
4126Writing to the Frame Buffer Device
4127----------------------------------
4128
4129The ``frame_buffer_write()`` is invoked from a ``write()``
4130operation on the frame buffer device.
4131The frame buffer write function is similar to the read function, and
4132should handle similar cases involving partial writes.
4133
4134This method returns RTEMS_SUCCESSFUL when the device is successfully
4135written to:
4136.. code:: c
4137
4138    rtems_device_driver frame_buffer_write(
4139    rtems_device_major_number  major,
4140    rtems_device_minor_number  minor,
4141    void                      \*arg
4142    )
4143    {
4144    rtems_libio_rw_args_t \*rw_args = (rtems_libio_rw_args_t \*)arg;
4145    rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
4146    memcpy( (void \*) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
4147    return RTEMS_SUCCESSFUL;
4148    }
4149
4150Frame Buffer IO Control
4151-----------------------
4152
4153The frame buffer driver allows several ioctls, partially compatible with
4154the Linux kernel,
4155to obtain information about the hardware.
4156
4157All ``ioctl()`` operations on the frame buffer device invoke``frame_buffer_control()``.
4158
4159Ioctls supported:
4160
4161- ioctls to get the frame buffer screen info (fixed and variable).
4162
4163- ioctl to set and get palette.
4164
4165.. code:: c
4166
4167    rtems_device_driver frame_buffer_control(
4168    rtems_device_major_number  major,
4169    rtems_device_minor_number  minor,
4170    void                      \*arg
4171    )
4172    {
4173    rtems_libio_ioctl_args_t \*args = arg;
4174    printk( "FBVGA ioctl called, cmd=%x\\n", args->command  );
4175    switch( args->command ) {
4176    case FBIOGET_FSCREENINFO:
4177    args->ioctl_return =  get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
4178    break;
4179    case FBIOGET_VSCREENINFO:
4180    args->ioctl_return =  get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
4181    break;
4182    case FBIOPUT_VSCREENINFO:
4183    /* not implemented yet*/
4184    args->ioctl_return = -1;
4185    return RTEMS_UNSATISFIED;
4186    case FBIOGETCMAP:
4187    args->ioctl_return =  get_palette( ( struct fb_cmap * ) args->buffer );
4188    break;
4189    case FBIOPUTCMAP:
4190    args->ioctl_return =  set_palette( ( struct fb_cmap * ) args->buffer );
4191    break;
4192    default:
4193    args->ioctl_return = 0;
4194    break;
4195    }
4196    return RTEMS_SUCCESSFUL;
4197    }
4198
4199See ``rtems/fb.h`` for more information on the list of ioctls and
4200data structures they work with.
4201
4202.. COMMENT: COPYRIGHT (c) 1988-2002.
4203
4204.. COMMENT: On-Line Applications Research Corporation (OAR).
4205
4206.. COMMENT: All rights reserved.
4207
4208Analog Driver
4209#############
4210
4211The Analog driver is responsible for providing an
4212interface to Digital to Analog Converters (DACs) and
4213Analog to Digital Converters (ADCs).  The capabilities provided
4214by this class of device driver are:
4215
4216- Initialize an Analog Board
4217
4218- Open a Particular Analog
4219
4220- Close a Particular Analog
4221
4222- Read from a Particular Analog
4223
4224- Write to a Particular Analog
4225
4226- Reset DACs
4227
4228- Reinitialize DACS
4229
4230Most analog devices are found on I/O cards that support multiple
4231DACs or ADCs on a single card.
4232
4233There are currently no analog device drivers included in the
4234RTEMS source tree.  The information provided in this chapter
4235is based on drivers developed for applications using RTEMS.
4236It is hoped that this driver model information can form the
4237basis for a standard analog driver model that can be supported
4238in future RTEMS distribution.
4239
4240Major and Minor Numbers
4241=======================
4242
4243The *major* number of a device driver is its index in the
4244RTEMS Device Address Table.
4245
4246A *minor* number is associated with each device instance
4247managed by a particular device driver.  An RTEMS minor number
4248is an ``unsigned32`` entity.  Convention calls for
4249dividing the bits in the minor number down into categories
4250like the following:
4251
4252- *board* - indicates the board a particular device is located on
4253
4254- *port* - indicates the particular device on a board.
4255
4256From the above, it should be clear that a single device driver
4257can support multiple copies of the same board in a single system.
4258The minor number is used to distinguish the devices.
4259
4260Analog Driver Configuration
4261===========================
4262
4263There is not a standard analog driver configuration table but some
4264fields are common across different drivers.  The analog driver
4265configuration table is typically an array of structures with each
4266structure containing the information for a particular board.
4267The following is a list of the type of information normally required
4268to configure an analog board:
4269
4270*board_offset*
4271    is the base address of a board.
4272
4273*DAC_initial_values*
4274    is an array of the voltages that should be written to each DAC
4275    during initialization.  This allows the driver to start the board
4276    in a known state.
4277
4278Initialize an Analog Board
4279==========================
4280
4281At system initialization, the analog driver’s initialization entry point
4282will be invoked.  As part of initialization, the driver will perform
4283whatever board initialization is required and then set all
4284outputs to their configured initial state.
4285
4286The analog driver may register a device name for each DAC and ADC in
4287the system.
4288
4289Open a Particular Analog
4290========================
4291
4292This is the driver open call.  Usually this call does nothing other than
4293validate the minor number.
4294
4295With some drivers, it may be necessary to allocate memory when a particular
4296device is opened.  If that is the case, then this is often the place
4297to do this operation.
4298
4299Close a Particular Analog
4300=========================
4301
4302This is the driver close call.  Usually this call does nothing.
4303
4304With some drivers, it may be necessary to allocate memory when a particular
4305device is opened.  If that is the case, then this is the place
4306where that memory should be deallocated.
4307
4308Read from a Particular Analog
4309=============================
4310
4311This corresponds to the driver read call.  After validating the minor
4312number and arguments, this call reads the indicated device.  Most analog
4313devices store the last value written to a DAC.  Since DACs are output
4314only devices, saving the last written value gives the appearance that
4315DACs can be read from also.  If the device is an ADC, then it is sampled.
4316
4317*NOTE:* Many boards have multiple analog inputs but only one ADC.  On
4318these boards, it will be necessary to provide some type of mutual exclusion
4319during reads.  On these boards, there is a MUX which must be switched
4320before sampling the ADC.  After the MUX is switched, the driver must
4321delay some short period of time (usually microseconds) before the
4322signal is stable and can be sampled.  To make matters worse, some ADCs
4323cannot respond to wide voltage swings in a single sample.  On these
4324ADCs, one must do two samples when the voltage swing is too large.
4325On a practical basis, this means that the driver usually ends up
4326double sampling the ADC on these systems.
4327
4328The value returned is a single precision floating point number
4329representing the voltage read.  This value is stored in the``argument_block`` passed in to the call.  By returning the
4330voltage, the caller is freed from having to know the number of
4331bits in the analog and board dependent conversion algorithm.
4332
4333Write to a Particular Analog
4334============================
4335
4336This corresponds to the driver write call.  After validating the minor
4337number and arguments, this call writes the indicated device.  If the
4338specified device is an ADC, then an error is usually returned.
4339
4340The value written is a single precision floating point number
4341representing the voltage to be written to the specified DAC.
4342This value is stored in the ``argument_block`` passed in to the
4343call.  By passing the voltage to the device driver, the caller is
4344freed from having to know the number of bits in the analog
4345and board dependent conversion algorithm.
4346
4347Reset DACs
4348==========
4349
4350This is one of the IOCTL functions supported by the I/O control
4351device driver entry point.  When this IOCTL function is invoked,
4352all of the DACs are written to 0.0 volts.
4353
4354Reinitialize DACS
4355=================
4356
4357This is one of the IOCTL functions supported by the I/O control
4358device driver entry point.  When this IOCTL function is invoked,
4359all of the DACs are written with the initial value configured
4360for this device.
4361
4362Get Last Written Values
4363=======================
4364
4365This is one of the IOCTL functions supported by the I/O control
4366device driver entry point.  When this IOCTL function is invoked,
4367the following information is returned to the caller:
4368
4369- last value written to the specified DAC
4370
4371- timestamp of when the last write was performed
4372
4373.. COMMENT: COPYRIGHT (c) 1988-2002.
4374
4375.. COMMENT: On-Line Applications Research Corporation (OAR).
4376
4377.. COMMENT: All rights reserved.
4378
4379Discrete Driver
4380###############
4381
4382The Discrete driver is responsible for providing an
4383interface to Discrete Input/Outputs.  The capabilities provided
4384by this class of device driver are:
4385
4386- Initialize a Discrete I/O Board
4387
4388- Open a Particular Discrete Bitfield
4389
4390- Close a Particular Discrete Bitfield
4391
4392- Read from a Particular Discrete Bitfield
4393
4394- Write to a Particular Discrete Bitfield
4395
4396- Reset DACs
4397
4398- Reinitialize DACS
4399
4400Most discrete I/O devices are found on I/O cards that support many
4401bits of discrete I/O on a single card.  This driver model is centered
4402on the notion of reading bitfields from the card.
4403
4404There are currently no discrete I/O device drivers included in the
4405RTEMS source tree.  The information provided in this chapter
4406is based on drivers developed for applications using RTEMS.
4407It is hoped that this driver model information can form the
4408discrete I/O driver model that can be supported in future RTEMS
4409distribution.
4410
4411Major and Minor Numbers
4412=======================
4413
4414The *major* number of a device driver is its index in the
4415RTEMS Device Address Table.
4416
4417A *minor* number is associated with each device instance
4418managed by a particular device driver.  An RTEMS minor number
4419is an ``unsigned32`` entity.  Convention calls for
4420dividing the bits in the minor number down into categories
4421that specify a particular bitfield.  This results in categories
4422like the following:
4423
4424- *board* - indicates the board a particular bitfield is located on
4425
4426- *word* - indicates the particular word of discrete bits the
4427  bitfield is located within
4428
4429- *start* - indicates the starting bit of the bitfield
4430
4431- *width* - indicates the width of the bitfield
4432
4433From the above, it should be clear that a single device driver
4434can support multiple copies of the same board in a single system.
4435The minor number is used to distinguish the devices.
4436
4437By providing a way to easily access a particular bitfield from
4438the device driver, the application is insulated with knowing how
4439to mask fields in and out of a discrete I/O.
4440
4441Discrete I/O Driver Configuration
4442=================================
4443
4444There is not a standard discrete I/O driver configuration table but some
4445fields are common across different drivers.  The discrete I/O driver
4446configuration table is typically an array of structures with each
4447structure containing the information for a particular board.
4448The following is a list of the type of information normally required
4449to configure an discrete I/O board:
4450
4451*board_offset*
4452    is the base address of a board.
4453
4454*relay_initial_values*
4455    is an array of the values that should be written to each output
4456    word on the board during initialization.  This allows the driver
4457    to start with the board’s output  in a known state.
4458
4459Initialize a Discrete I/O Board
4460===============================
4461
4462At system initialization, the discrete I/O driver’s initialization entry point
4463will be invoked.  As part of initialization, the driver will perform
4464whatever board initializatin is required and then set all
4465outputs to their configured initial state.
4466
4467The discrete I/O driver may register a device name for bitfields of
4468particular interest to the system.  Normally this will be restricted
4469to the names of each word and, if the driver supports it, an "all words".
4470
4471Open a Particular Discrete Bitfield
4472===================================
4473
4474This is the driver open call.  Usually this call does nothing other than
4475validate the minor number.
4476
4477With some drivers, it may be necessary to allocate memory when a particular
4478device is opened.  If that is the case, then this is often the place
4479to do this operation.
4480
4481Close a Particular Discrete Bitfield
4482====================================
4483
4484This is the driver close call.  Usually this call does nothing.
4485
4486With some drivers, it may be necessary to allocate memory when a particular
4487device is opened.  If that is the case, then this is the place
4488where that memory should be deallocated.
4489
4490Read from a Particular Discrete Bitfield
4491========================================
4492
4493This corresponds to the driver read call.  After validating the minor
4494number and arguments, this call reads the indicated bitfield.  A
4495discrete I/O devices may have to store the last value written to
4496a discrete output.  If the bitfield is output only, saving the last
4497written value gives the appearance that it can be read from also.
4498If the bitfield is input, then it is sampled.
4499
4500*NOTE:* Many discrete inputs have a tendency to bounce.  The application
4501may have to take account for bounces.
4502
4503The value returned is an ``unsigned32`` number
4504representing the bitfield read.  This value is stored in the``argument_block`` passed in to the call.
4505
4506*NOTE:* Some discrete I/O drivers have a special minor number
4507used to access all discrete I/O bits on the board.  If this special
4508minor is used, then the area pointed to by ``argument_block`` must
4509be the correct size.
4510
4511Write to a Particular Discrete Bitfield
4512=======================================
4513
4514This corresponds to the driver write call.  After validating the minor
4515number and arguments, this call writes the indicated device.  If the
4516specified device is an ADC, then an error is usually returned.
4517
4518The value written is an ``unsigned32`` number
4519representing the value to be written to the specified
4520bitfield.  This value is stored in the``argument_block`` passed in to the call.
4521
4522*NOTE:* Some discrete I/O drivers have a special minor number
4523used to access all discrete I/O bits on the board.  If this special
4524minor is used, then the area pointed to by ``argument_block`` must
4525be the correct size.
4526
4527Disable Discrete Outputs
4528========================
4529
4530This is one of the IOCTL functions supported by the I/O control
4531device driver entry point.  When this IOCTL function is invoked,
4532the discrete outputs are disabled.
4533
4534*NOTE:* It may not be possible to disable/enable discrete output on all
4535discrete I/O boards.
4536
4537Enable Discrete Outputs
4538=======================
4539
4540This is one of the IOCTL functions supported by the I/O control
4541device driver entry point.  When this IOCTL function is invoked,
4542the discrete outputs are enabled.
4543
4544*NOTE:* It may not be possible to disable/enable discrete output on all
4545discrete I/O boards.
4546
4547Reinitialize Outputs
4548====================
4549
4550This is one of the IOCTL functions supported by the I/O control
4551device driver entry point.  When this IOCTL function is invoked,
4552the discrete outputs are rewritten with the configured initial
4553output values.
4554
4555Get Last Written Values
4556=======================
4557
4558This is one of the IOCTL functions supported by the I/O control
4559device driver entry point.  When this IOCTL function is invoked,
4560the following information is returned to the caller:
4561
4562- last value written to the specified output word
4563
4564- timestamp of when the last write was performed
4565
4566Command and Variable Index
4567##########################
4568
4569There are currently no Command and Variable Index entries.
4570
4571.. COMMENT: @printindex fn
4572
4573Concept Index
4574#############
4575
4576There are currently no Concept Index entries.
4577
4578.. COMMENT: @printindex cp
Note: See TracBrowser for help on using the repository browser.