source: rtems-docs/bsp_howto/bsp_howto_old_reference_only.rst @ 9aafb39

4.115
Last change on this file since 9aafb39 was a1c7180, checked in by Joel Sherrill <joel@…>, on 10/28/16 at 00:19:00

Misc: Capitalize RTEMS.

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