summaryrefslogtreecommitdiffstats
path: root/doc/bsp_howto/clock.t
blob: e6bd4f3cb0b22a28303f75d361d4ade679c0741c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
@c
@c  COPYRIGHT (c) 1988-1998.
@c  On-Line Applications Research Corporation (OAR).
@c  All rights reserved.
@c
@c  $Id$
@c

@chapter Clock Driver

@section Introduction

The purpose of the clock driver is to provide a steady time
basis to the kernel, so that the RTEMS primitives that need
a clock tick work properly.  See the @code{Clock Manager} chapter
of the @b{RTEMS Application C User's Guide} for more details.

The clock driver is located in the @code{clock} directory of the BSP. 

@section Clock Driver Global Variables

@subsection Major and Minor Number

The major and minor numbers of the clock driver are made available via 
the following variables.  

@itemize @bullet
@item rtems_device_major_number rtems_clock_major;
@item rtems_device_minor_number rtems_clock_minor;
@end itemize

The clock device driver is responsible for declaring and
initializing these variables.  These variables are used
by other RTEMS components -- notably the Shared Memory Driver. 

@b{NOTE:} In a future RTEMS version, these variables may be replaced
with the clock device driver registering @b{/dev/clock}.

@subsection Ticks Counter

Most of the clock device drivers provide a global variable
that is simply a count of the number of clock driver interrupt service
routines that have occured.  This information is valuable when debugging
a system.  This variable is declared as follows:

@example
volatile rtems_unsigned32 Clock_driver_ticks;
@end example

@section Initialization

The initialization routine is responsible for
programming the hardware that will periodically
generate an interrupt.  A programmable interval timer is commonly
used as the source of the clock tick.

The device should be programmed such that an interrupt is generated
every @i{m} microseconds, where @i{m} is equal to 
@code{BSP_Configuration.microseconds_per_tick}. Sometimes the periodic interval
timer can use a prescaler so you have to look carefully at your user's
manual to determine the correct value. 

You must use the RTEMS primitive @code{rtems_interrupt_catch} to install
your clock interrupt service routine:

@example
rtems_interrupt_catch (Clock_ISR, CLOCK_VECTOR, &old_handler); 
@end example

Since there is currently not a driver entry point invoked at system
shutdown, many clock device drivers use the @code{atexit} routine
to schedule their @code{Clock_exit} routine to execute when the
system is shutdown.

By convention, many of the clock drivers do not install the clock
tick if the @code{ticks_per_timeslice} field of the Configuration
Table is 0.

@section System shutdown

Many drivers provide the routine @code{Clock_exit} that is scheduled
to be run during system shutdown via the @code{atexit} routine.
The @code{Clock_exit} routine will disable the clock tick source
if it was enabled.  This can be used to prevent clock ticks after the
system is shutdown.

@section Clock Interrupt Subroutine

It only has to inform the kernel that a ticker has elapsed, so call : 

@example
@group
rtems_isr Clock_isr( rtems_vector_number vector )
@{
  invoke the rtems_clock_tick() directive to announce the tick
  if necessary for this hardware
    reload the programmable timer
@}
@end group
@end example

@section IO Control

The clock driver must supply a handler for the IO control device driver
entry point.  This functionality is used by other components -- notably
the Shared Memory Driver to install a wrapper for the clock interrupt
service routine.  The following shows the functionality required:

@example
@group
rtems_device_driver Clock_control(
  rtems_device_major_number major,
  rtems_device_minor_number minor,
  void *pargp
)
@{
  error check the argument pointer parameter

  if the command is "ISR"
    invoke the clock interrupt service routine
  else if the command is "NEW"
    install the requested handler
@}
@end group
@end example