1 |
1026 |
ivang |
@c
|
2 |
|
|
@c COPYRIGHT (c) 1988-2002.
|
3 |
|
|
@c On-Line Applications Research Corporation (OAR).
|
4 |
|
|
@c All rights reserved.
|
5 |
|
|
@c
|
6 |
|
|
@c clock.t,v 1.9 2002/01/17 21:47:44 joel Exp
|
7 |
|
|
@c
|
8 |
|
|
|
9 |
|
|
@chapter Clock Driver
|
10 |
|
|
|
11 |
|
|
@section Introduction
|
12 |
|
|
|
13 |
|
|
The purpose of the clock driver is to provide a steady time
|
14 |
|
|
basis to the kernel, so that the RTEMS primitives that need
|
15 |
|
|
a clock tick work properly. See the @code{Clock Manager} chapter
|
16 |
|
|
of the @b{RTEMS Application C User's Guide} for more details.
|
17 |
|
|
|
18 |
|
|
The clock driver is located in the @code{clock} directory of the BSP.
|
19 |
|
|
|
20 |
|
|
@section Clock Driver Global Variables
|
21 |
|
|
|
22 |
|
|
This section describes the global variables expected to be provided by
|
23 |
|
|
this driver.
|
24 |
|
|
|
25 |
|
|
@subsection Major and Minor Number
|
26 |
|
|
|
27 |
|
|
The major and minor numbers of the clock driver are made available via
|
28 |
|
|
the following variables.
|
29 |
|
|
|
30 |
|
|
@itemize @bullet
|
31 |
|
|
@item rtems_device_major_number rtems_clock_major;
|
32 |
|
|
@item rtems_device_minor_number rtems_clock_minor;
|
33 |
|
|
@end itemize
|
34 |
|
|
|
35 |
|
|
The clock device driver is responsible for declaring and
|
36 |
|
|
initializing these variables. These variables are used
|
37 |
|
|
by other RTEMS components -- notably the Shared Memory Driver.
|
38 |
|
|
|
39 |
|
|
@b{NOTE:} In a future RTEMS version, these variables may be replaced
|
40 |
|
|
with the clock device driver registering @b{/dev/clock}.
|
41 |
|
|
|
42 |
|
|
@subsection Ticks Counter
|
43 |
|
|
|
44 |
|
|
Most of the clock device drivers provide a global variable
|
45 |
|
|
that is simply a count of the number of clock driver interrupt service
|
46 |
|
|
routines that have occured. This information is valuable when debugging
|
47 |
|
|
a system. This variable is declared as follows:
|
48 |
|
|
|
49 |
|
|
@example
|
50 |
|
|
volatile rtems_unsigned32 Clock_driver_ticks;
|
51 |
|
|
@end example
|
52 |
|
|
|
53 |
|
|
@section Initialization
|
54 |
|
|
|
55 |
|
|
The initialization routine is responsible for
|
56 |
|
|
programming the hardware that will periodically
|
57 |
|
|
generate an interrupt. A programmable interval timer is commonly
|
58 |
|
|
used as the source of the clock tick.
|
59 |
|
|
|
60 |
|
|
The device should be programmed such that an interrupt is generated
|
61 |
|
|
every @i{m} microseconds, where @i{m} is equal to
|
62 |
|
|
@code{BSP_Configuration.microseconds_per_tick}. Sometimes the periodic interval
|
63 |
|
|
timer can use a prescaler so you have to look carefully at your user's
|
64 |
|
|
manual to determine the correct value.
|
65 |
|
|
|
66 |
|
|
You must use the RTEMS primitive @code{rtems_interrupt_catch} to install
|
67 |
|
|
your clock interrupt service routine:
|
68 |
|
|
|
69 |
|
|
@example
|
70 |
|
|
rtems_interrupt_catch (Clock_ISR, CLOCK_VECTOR, &old_handler);
|
71 |
|
|
@end example
|
72 |
|
|
|
73 |
|
|
Since there is currently not a driver entry point invoked at system
|
74 |
|
|
shutdown, many clock device drivers use the @code{atexit} routine
|
75 |
|
|
to schedule their @code{Clock_exit} routine to execute when the
|
76 |
|
|
system is shutdown.
|
77 |
|
|
|
78 |
|
|
By convention, many of the clock drivers do not install the clock
|
79 |
|
|
tick if the @code{ticks_per_timeslice} field of the Configuration
|
80 |
|
|
Table is 0.
|
81 |
|
|
|
82 |
|
|
@section System shutdown
|
83 |
|
|
|
84 |
|
|
Many drivers provide the routine @code{Clock_exit} that is scheduled
|
85 |
|
|
to be run during system shutdown via the @code{atexit} routine.
|
86 |
|
|
The @code{Clock_exit} routine will disable the clock tick source
|
87 |
|
|
if it was enabled. This can be used to prevent clock ticks after the
|
88 |
|
|
system is shutdown.
|
89 |
|
|
|
90 |
|
|
@section Clock Interrupt Subroutine
|
91 |
|
|
|
92 |
|
|
It only has to inform the kernel that a ticker has elapsed, so call :
|
93 |
|
|
|
94 |
|
|
@example
|
95 |
|
|
@group
|
96 |
|
|
rtems_isr Clock_isr( rtems_vector_number vector )
|
97 |
|
|
@{
|
98 |
|
|
invoke the rtems_clock_tick() directive to announce the tick
|
99 |
|
|
if necessary for this hardware
|
100 |
|
|
reload the programmable timer
|
101 |
|
|
@}
|
102 |
|
|
@end group
|
103 |
|
|
@end example
|
104 |
|
|
|
105 |
|
|
@section IO Control
|
106 |
|
|
|
107 |
|
|
The clock driver must supply a handler for the IO control device driver
|
108 |
|
|
entry point. This functionality is used by other components -- notably
|
109 |
|
|
the Shared Memory Driver to install a wrapper for the clock interrupt
|
110 |
|
|
service routine. The following shows the functionality required:
|
111 |
|
|
|
112 |
|
|
@example
|
113 |
|
|
@group
|
114 |
|
|
rtems_device_driver Clock_control(
|
115 |
|
|
rtems_device_major_number major,
|
116 |
|
|
rtems_device_minor_number minor,
|
117 |
|
|
void *pargp
|
118 |
|
|
)
|
119 |
|
|
@{
|
120 |
|
|
error check the argument pointer parameter
|
121 |
|
|
|
122 |
|
|
if the command is "ISR"
|
123 |
|
|
invoke the clock interrupt service routine
|
124 |
|
|
else if the command is "NEW"
|
125 |
|
|
install the requested handler
|
126 |
|
|
@}
|
127 |
|
|
@end group
|
128 |
|
|
@end example
|
129 |
|
|
|
130 |
|
|
|
131 |
|
|
|
132 |
|
|
|