OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [doc/] [bsp_howto/] [console.t] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
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  console.t,v 1.11 2002/01/17 21:47:44 joel Exp
7
@c
8
 
9
@chapter Console Driver
10
 
11
@section Introduction
12
 
13
This chapter describes the operation of a console driver using
14
the RTEMS POSIX Termios support.  Traditionally RTEMS has referred
15
to all serial device drivers as console device drivers.  A
16
console driver can be used to do raw data processing in addition
17
to the "normal" standard input and output device functions required
18
of a console.
19
 
20
The serial driver may be called as the consequence of a C Library
21
call such as @code{printf} or @code{scanf} or directly via the
22
@code{read} or @code{write} system calls.
23
There are two main functioning modes:
24
 
25
@itemize @bullet
26
 
27
@item console: formatted input/output, with special characters (end of
28
line, tabulations, etc.) recognition and processing,
29
 
30
@item raw: permits raw data processing.
31
 
32
@end itemize
33
 
34
One may think that two serial drivers are needed to handle these two types
35
of data, but Termios permits having only one driver.
36
 
37
@section Termios
38
 
39
Termios is a standard for terminal management, included in the POSIX 1003.1b
40
standard.  It is commonly provided on UNIX implementations.
41
Having RTEMS support for Termios is beneficial:
42
 
43
@itemize @bullet
44
 
45
@item from the user's side because it provides standard primitive operations
46
to access the terminal and change configuration settings.  These operations
47
are the same under Unix and Rtems.
48
 
49
@item from the BSP developer's side because it frees the
50
developer from dealing with buffer states and mutual exclusions on them.
51
Early RTEMS console device drivers also did their own special
52
character processing.
53
 
54
@end itemize
55
 
56
Termios support includes:
57
 
58
@itemize @bullet
59
 
60
@item raw and console handling,
61
 
62
@item blocking or non-blocking characters receive, with or without
63
Timeout.
64
 
65
@end itemize
66
 
67
At this time, RTEMS documentation does not include a thorough discussion
68
of the Termios functionality.  For more information on Termios,
69
type @code{man termios} on a Unix box or point a web browser
70
at
71
@uref{http://www.freebsd.org/cgi/man.cgi}.
72
 
73
@section Driver Functioning Modes
74
 
75
There are generally two main functioning modes for an UART (Universal
76
Asynchronous Receiver-Transmitter, i.e. the serial chip):
77
 
78
@itemize @bullet
79
 
80
@item polled mode
81
@item interrupt driven mode
82
 
83
@end itemize
84
 
85
In polled mode, the processor blocks on sending/receiving characters.
86
This mode is not the most efficient way to utilize the UART. But
87
polled mode is usually necessary when one wants to print an
88
error message in the event of a fatal error such as a fatal error
89
in the BSP.  This is also the simplest mode to
90
program.  Polled mode is generally preferred if the serial port is
91
to be used primarily as a debug console.  In a simple polled driver,
92
the software will continuously check the status of the UART when
93
it is reading or writing to the UART.  Termios improves on this
94
by delaying the caller for 1 clock tick between successive checks
95
of the UART on a read operation.
96
 
97
In interrupt driven mode, the processor does not block on sending/receiving
98
characters.  Data is buffered between the interrupt service routine
99
and application code.  Two buffers are used to insulate the application
100
from the relative slowness of the serial device.  One of the buffers is
101
used for incoming characters, while the other is used for outgoing characters.
102
 
103
An interrupt is raised when a character is received by the UART.
104
The interrupt subroutine places the incoming character at the end
105
of the input buffer.  When an application asks for input,
106
the characters at the front of the buffer are returned.
107
 
108
When the application prints to the serial device, the outgoing characters
109
are placed at the end of the output buffer.  The driver will place
110
one or more characters in the UART (the exact number depends on the UART)
111
An interrupt will be raised when all the characters have been transmitted.
112
The interrupt service routine has to send the characters
113
remaining in the output buffer the same way.   When the transmitting side
114
of the UART is idle, it is typically necessary to prime the transmitter
115
before the first interrupt will occur.
116
 
117
@section Serial Driver Functioning Overview
118
 
119
The following Figure shows how a Termios driven serial driver works:
120
 
121
@example
122
Figure not included in this draft
123
@end example
124
 
125
The following list describes the basic flow.
126
 
127
@itemize @bullet
128
 
129
@item the application programmer uses standard C library call (printf,
130
scanf, read, write, etc.),
131
 
132
@item C library (in fact that's Cygnus Newlib) calls RTEMS
133
system call interface. This code can be found in the
134
@code{c/src/lib/libc} directory.
135
 
136
@item Glue code calls the serial driver entry routines.
137
 
138
@end itemize
139
 
140
@subsection Termios and Polled I/O
141
 
142
The following functions are provided by the driver and invoked by
143
Termios for simple character input/output.  The specific names of
144
these routines are not important as Termios invokes them indirectly
145
via function pointers.
146
 
147
@subsubsection pollWrite
148
 
149
The @code{pollWrite} routine is responsible for writing @code{len} characters
150
from @code{buf} to the serial device specified by @code{minor}.
151
 
152
@example
153
@group
154
int pollWrite (int minor, const char *buf, int len)
155
@{
156
  for (i=0; i
157
     put buf[i] into the UART channel minor
158
     wait for the character to be transmitted
159
     on the serial line
160
  @}
161
  return 0
162
@}
163
@end group
164
@end example
165
 
166
@subsubsection pollRead
167
 
168
The @code{pollRead} routine is responsible for reading a single character
169
from the serial device specified by @code{minor}.  If no character is
170
available, then the routine should return -1.
171
 
172
@example
173
@group
174
int pollRead(int minor)
175
@{
176
   read status of UART
177
   if status indicates a character is available
178
     return character
179
   return -1
180
@}
181
@end group
182
@end example
183
 
184
@subsection Termios and Interrupt Driven I/O
185
 
186
The UART generally generates interrupts when it is ready to accept or to
187
emit a number of characters. In this mode, the interrupt subroutine is the
188
core of the driver.
189
 
190
@subsubsection InterruptHandler
191
 
192
The @code{InterruptHandler} is responsible for processing asynchronous
193
interrupts from the UART.  There may be multiple interrupt handlers for
194
a single UART.  Some UARTs can generate a unique interrupt vector for
195
each interrupt source such as a character has been received or the
196
transmitter is ready for another character.
197
 
198
In the simplest case, the @code{InterruptHandler} will have to check
199
the status of the UART and determine what caused the interrupt.
200
The following describes the operation of an @code{InterruptHandler}
201
which has to do this:
202
 
203
@example
204
@group
205
rtems_isr InterruptHandler (rtems_vector_number v)
206
@{
207
  check whether there was an error
208
 
209
  if some characters were received:
210
     Ask Termios to put them on his input buffer
211
 
212
  if some characters have been transmitted
213
        (i.e. the UART output buffer is empty)
214
     Tell TERMIOS that the characters have been
215
     transmitted. The TERMIOS routine will call
216
     the InterruptWrite function with the number
217
     of characters not transmitted yet if it is
218
     not zero.
219
@}
220
@end group
221
@end example
222
 
223
@subsubsection InterruptWrite
224
 
225
The @code{InterruptWrite} is responsible for telling the UART
226
that the @code{len} characters at @code{buf} are to be transmitted.
227
 
228
@example
229
static int InterruptWrite(int minor, const char *buf, int len)
230
@{
231
  tell the UART to transmit len characters from buf
232
  return 0
233
@}
234
@end example
235
 
236
The driver has to put the @i{n} first buf characters in the UART channel minor
237
buffer (@i{n} is the UART channel size, @i{n}=1 on the MC68640). Generally, an
238
interrupt is raised after these @i{n} characters being transmitted. So
239
UART interrupts may have to be enabled after putting the characters in the
240
UART.
241
 
242
 
243
@subsection Initialization
244
 
245
The driver initialization is called once during the RTEMS initialization
246
process.
247
 
248
The @code{console_initialize} function has to:
249
 
250
@itemize @bullet
251
 
252
@item initialize Termios support: call @code{rtems_termios_initialize()}.  If
253
Termios has already been initialized by another device driver, then
254
this call will have no effect.
255
 
256
@item Initialize the UART: This procedure should
257
be described in the UART manual.  This procedure @b{MUST} be
258
followed precisely.  This procedure varies but
259
usually consists of:
260
 
261
@itemize @bullet
262
@item reinitialize the UART channels
263
 
264
@item set the channels configuration to the Termios default:
265
9600 bauds, no parity, 1 stop bit, and 8 bits per character
266
@end itemize
267
 
268
@item If interrupt driven, register the console interrupt routine to RTEMS:
269
 
270
@example
271
rtems_interrupt_catch(
272
    InterruptHandler, CONSOLE_VECTOR, &old_handler);
273
@end example
274
 
275
@item enable the UART channels.
276
 
277
@item register the device name: in order to use the console (i.e. being
278
able to do printf/scanf on stdin, stdout, and stderr), some device
279
must be registered as "/dev/console":
280
 
281
@example
282
rtems_io_register_name ("dev/console", major, i);
283
@end example
284
 
285
@end itemize
286
 
287
@subsection Opening a serial device
288
 
289
The @code{console_open} function is called whenever a serial
290
device is opened.  The device registered as @code{"/dev/console"}
291
is opened automatically during RTEMS initialization.
292
For instance, if UART channel 2 is registered as "/dev/tty1",
293
the @code{console_open} entry point will be called as
294
the result of an @code{fopen("/dev/tty1", mode)} in the
295
application.
296
 
297
The @code{console_open} function has to inform Termios of the low-level
298
functions for serial line support; the "callbacks".
299
 
300
The gen68340 BSP defines two sets of callback tables:
301
 
302
@itemize @bullet
303
 
304
@item one with functions for polled input/output
305
 
306
@item another with functions for interrupt driven input/output
307
 
308
@end itemize
309
 
310
This code can be found in the file @code{$BSPROOT/console/console.c}.
311
 
312
@subsubsection Polled I/O
313
 
314
Termios must be told the addresses of the functions that are to be
315
used for simple character input/output, i.e. pointers to the
316
@code{pollWrite} and @code{pollRead} functions
317
defined earlier in @ref{Console Driver Termios and Polled I/O}.
318
 
319
@subsubsection Interrupt Driven I/O
320
 
321
Driver functioning is quite different in this mode.  There is no
322
device driver read function to be passed to Termios. Indeed a
323
@code{console_read} call returns the contents of Termios input buffer.
324
This buffer is filled in the driver interrupt subroutine
325
(see @ref{Console Driver Termios and Interrupt Driven I/O}).
326
 
327
The driver is responsible for providing a pointer to the
328
@code{InterruptWrite} function.
329
 
330
@subsection Closing a Serial Device
331
 
332
The @code{console_close} is invoked when the serial device is to
333
be closed.  This entry point corresponds to the device driver
334
close entry point.
335
 
336
This routine is responsible for notifying Termios that the serial
337
device was closed.  This is done with a call to @code{rtems_termios_close}.
338
 
339
@subsection Reading Characters From a Serial Device
340
 
341
The @code{console_read} is invoked when the serial device is to
342
be read from.  This entry point corresponds to the device driver
343
read entry point.
344
 
345
This routine is responsible for returning the content of the
346
Termios input buffer.   This is done by invoking the
347
@code{rtems_termios_read} routine.
348
 
349
@subsection Writing Characters to a Serial Device
350
 
351
The @code{console_write} is invoked when the serial device is to
352
be written to.  This entry point corresponds to the device driver
353
write entry point.
354
 
355
This routine is responsible for adding the requested characters to
356
the Termios output queue for this device.  This is done by
357
calling the routine @code{rtems_termios_write}
358
to add the characters at the end of the Termios output
359
buffer.
360
 
361
@subsection Changing Serial Line Parameters
362
 
363
The @code{console_control} is invoked when the line parameters
364
for a particular serial device are to be changed.
365
This entry point corresponds to the device driver
366
io_control entry point.
367
 
368
The application write is able to control the serial line configuration
369
with Termios calls (such as the @code{ioctl} command, see
370
the Termios documentation for
371
more details). If the driver is to support dynamic configuration, then
372
is must have the @code{console_control} piece of code. Refer to the gen68340
373
BSP for an example of how it is done.  Basically @code{ioctl}
374
commands call @code{console_control} with the serial line
375
configuration in a Termios defined data structure. The driver
376
is responsible for reinitializing the UART with the correct settings.
377
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.