source: rtems/doc/bsp_howto/console.t @ 24df6dd

4.9
Last change on this file since 24df6dd was 6449498, checked in by Joel Sherrill <joel.sherrill@…>, on 01/17/02 at 21:47:47

2001-01-17 Joel Sherrill <joel@…>

  • SUPPORT, LICENSE: New files.
  • Numerous files touched as part of merging the 4.5 branch onto the mainline development trunk and ensuring that the script that cuts snapshots and releases works on the documentation.
  • Property mode set to 100644
File size: 12.1 KB
Line 
1@c
2@c  COPYRIGHT (c) 1988-2002.
3@c  On-Line Applications Research Corporation (OAR).
4@c  All rights reserved.
5@c
6@c  $Id$
7@c
8
9@chapter Console Driver
10
11@section Introduction
12
13This chapter describes the operation of a console driver using
14the RTEMS POSIX Termios support.  Traditionally RTEMS has referred
15to all serial device drivers as console device drivers.  A
16console driver can be used to do raw data processing in addition
17to the "normal" standard input and output device functions required
18of a console.
19
20The serial driver may be called as the consequence of a C Library
21call such as @code{printf} or @code{scanf} or directly via the
22@code{read} or @code{write} system calls.
23There are two main functioning modes:
24
25@itemize @bullet
26
27@item console: formatted input/output, with special characters (end of
28line, tabulations, etc.) recognition and processing,
29
30@item raw: permits raw data processing.
31
32@end itemize
33
34One may think that two serial drivers are needed to handle these two types
35of data, but Termios permits having only one driver.
36
37@section Termios
38
39Termios is a standard for terminal management, included in the POSIX 1003.1b
40standard.  It is commonly provided on UNIX implementations. 
41Having RTEMS support for Termios is beneficial:
42
43@itemize @bullet
44
45@item from the user's side because it provides standard primitive operations
46to access the terminal and change configuration settings.  These operations
47are the same under Unix and Rtems.
48
49@item from the BSP developer's side because it frees the
50developer from dealing with buffer states and mutual exclusions on them.
51Early RTEMS console device drivers also did their own special
52character processing.
53
54@end itemize
55
56Termios 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
63Timeout.
64
65@end itemize
66
67At this time, RTEMS documentation does not include a thorough discussion
68of the Termios functionality.  For more information on Termios,
69type @code{man termios} on a Unix box or point a web browser
70at
71@uref{http://www.freebsd.org/cgi/man.cgi}.
72
73@section Driver Functioning Modes
74
75There are generally two main functioning modes for an UART (Universal
76Asynchronous 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
85In polled mode, the processor blocks on sending/receiving characters.
86This mode is not the most efficient way to utilize the UART. But
87polled mode is usually necessary when one wants to print an
88error message in the event of a fatal error such as a fatal error
89in the BSP.  This is also the simplest mode to
90program.  Polled mode is generally preferred if the serial port is
91to be used primarily as a debug console.  In a simple polled driver,
92the software will continuously check the status of the UART when
93it is reading or writing to the UART.  Termios improves on this
94by delaying the caller for 1 clock tick between successive checks
95of the UART on a read operation.
96
97In interrupt driven mode, the processor does not block on sending/receiving
98characters.  Data is buffered between the interrupt service routine
99and application code.  Two buffers are used to insulate the application
100from the relative slowness of the serial device.  One of the buffers is
101used for incoming characters, while the other is used for outgoing characters.
102
103An interrupt is raised when a character is received by the UART.
104The interrupt subroutine places the incoming character at the end
105of the input buffer.  When an application asks for input,
106the characters at the front of the buffer are returned.
107
108When the application prints to the serial device, the outgoing characters
109are placed at the end of the output buffer.  The driver will place
110one or more characters in the UART (the exact number depends on the UART)
111An interrupt will be raised when all the characters have been transmitted.
112The interrupt service routine has to send the characters
113remaining in the output buffer the same way.   When the transmitting side
114of the UART is idle, it is typically necessary to prime the transmitter
115before the first interrupt will occur.
116
117@section Serial Driver Functioning Overview
118
119The following Figure shows how a Termios driven serial driver works:
120
121@example
122Figure not included in this draft
123@end example
124
125The following list describes the basic flow.
126
127@itemize @bullet
128
129@item the application programmer uses standard C library call (printf,
130scanf, read, write, etc.),
131
132@item C library (in fact that's Cygnus Newlib) calls RTEMS
133system 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
142The following functions are provided by the driver and invoked by
143Termios for simple character input/output.  The specific names of
144these routines are not important as Termios invokes them indirectly
145via function pointers.
146
147@subsubsection pollWrite
148
149The @code{pollWrite} routine is responsible for writing @code{len} characters
150from @code{buf} to the serial device specified by @code{minor}.
151
152@example
153@group
154int pollWrite (int minor, const char *buf, int len)
155@{
156  for (i=0; i<len; 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
168The @code{pollRead} routine is responsible for reading a single character
169from the serial device specified by @code{minor}.  If no character is
170available, then the routine should return -1.
171
172@example
173@group
174int 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
186The UART generally generates interrupts when it is ready to accept or to
187emit a number of characters. In this mode, the interrupt subroutine is the
188core of the driver.
189
190@subsubsection InterruptHandler
191
192The @code{InterruptHandler} is responsible for processing asynchronous
193interrupts from the UART.  There may be multiple interrupt handlers for
194a single UART.  Some UARTs can generate a unique interrupt vector for
195each interrupt source such as a character has been received or the
196transmitter is ready for another character.
197
198In the simplest case, the @code{InterruptHandler} will have to check
199the status of the UART and determine what caused the interrupt.
200The following describes the operation of an @code{InterruptHandler}
201which has to do this:
202
203@example
204@group
205rtems_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
225The @code{InterruptWrite} is responsible for telling the UART
226that the @code{len} characters at @code{buf} are to be transmitted.
227
228@example
229static 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
236The driver has to put the @i{n} first buf characters in the UART channel minor
237buffer (@i{n} is the UART channel size, @i{n}=1 on the MC68640). Generally, an
238interrupt is raised after these @i{n} characters being transmitted. So
239UART interrupts may have to be enabled after putting the characters in the
240UART.
241
242
243@subsection Initialization
244
245The driver initialization is called once during the RTEMS initialization
246process.
247
248The @code{console_initialize} function has to:
249
250@itemize @bullet
251
252@item initialize Termios support: call @code{rtems_termios_initialize()}.  If
253Termios has already been initialized by another device driver, then
254this call will have no effect.
255
256@item Initialize the UART: This procedure should
257be described in the UART manual.  This procedure @b{MUST} be
258followed precisely.  This procedure varies but
259usually consists of:
260
261@itemize @bullet
262@item reinitialize the UART channels
263
264@item set the channels configuration to the Termios default:
2659600 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
271rtems_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
278able to do printf/scanf on stdin, stdout, and stderr), some device
279must be registered as "/dev/console":
280
281@example
282rtems_io_register_name ("dev/console", major, i);
283@end example
284
285@end itemize
286
287@subsection Opening a serial device
288
289The @code{console_open} function is called whenever a serial
290device is opened.  The device registered as @code{"/dev/console"}
291is opened automatically during RTEMS initialization.
292For instance, if UART channel 2 is registered as "/dev/tty1",
293the @code{console_open} entry point will be called as
294the result of an @code{fopen("/dev/tty1", mode)} in the
295application.
296
297The @code{console_open} function has to inform Termios of the low-level
298functions for serial line support; the "callbacks".
299
300The 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
310This code can be found in the file @code{$BSPROOT/console/console.c}.
311
312@subsubsection Polled I/O
313
314Termios must be told the addresses of the functions that are to be
315used for simple character input/output, i.e. pointers to the
316@code{pollWrite} and @code{pollRead} functions
317defined earlier in @ref{Console Driver Termios and Polled I/O}.
318
319@subsubsection Interrupt Driven I/O
320
321Driver functioning is quite different in this mode.  There is no
322device driver read function to be passed to Termios. Indeed a
323@code{console_read} call returns the contents of Termios input buffer.
324This buffer is filled in the driver interrupt subroutine
325(see @ref{Console Driver Termios and Interrupt Driven I/O}).
326
327The driver is responsible for providing a pointer to the
328@code{InterruptWrite} function.
329
330@subsection Closing a Serial Device
331
332The @code{console_close} is invoked when the serial device is to
333be closed.  This entry point corresponds to the device driver
334close entry point.
335
336This routine is responsible for notifying Termios that the serial
337device was closed.  This is done with a call to @code{rtems_termios_close}.
338
339@subsection Reading Characters From a Serial Device
340
341The @code{console_read} is invoked when the serial device is to
342be read from.  This entry point corresponds to the device driver
343read entry point.
344
345This routine is responsible for returning the content of the
346Termios input buffer.   This is done by invoking the
347@code{rtems_termios_read} routine.
348
349@subsection Writing Characters to a Serial Device
350
351The @code{console_write} is invoked when the serial device is to
352be written to.  This entry point corresponds to the device driver
353write entry point.
354
355This routine is responsible for adding the requested characters to
356the Termios output queue for this device.  This is done by
357calling the routine @code{rtems_termios_write}
358to add the characters at the end of the Termios output
359buffer.
360
361@subsection Changing Serial Line Parameters
362
363The @code{console_control} is invoked when the line parameters
364for a particular serial device are to be changed.
365This entry point corresponds to the device driver
366io_control entry point.
367
368The application write is able to control the serial line configuration
369with Termios calls (such as the @code{ioctl} command, see
370the Termios documentation for
371more details). If the driver is to support dynamic configuration, then
372is must have the @code{console_control} piece of code. Refer to the gen68340
373BSP for an example of how it is done.  Basically @code{ioctl}
374commands call @code{console_control} with the serial line
375configuration in a Termios defined data structure. The driver
376is responsible for reinitializing the UART with the correct settings.
377
Note: See TracBrowser for help on using the repository browser.