summaryrefslogtreecommitdiffstats
path: root/doc/bsp_howto/console.t
blob: 09d8b256407bba182859b363f26da15f9cdb82e5 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
@c
@c  COPYRIGHT (c) 1988-1998.
@c  On-Line Applications Research Corporation (OAR).
@c  All rights reserved.
@c
@c  $Id$
@c

@chapter Console Driver

@section Introduction

This chapter describes how to do a console driver using RTEMS Termios
support. 

The serial driver is called as soon as printf/scanf or read/write kind of
input/output are needed. There are two main functioning modes: 

@itemize @bullet

@item console: formatted input/output, with special characters (end of
line, tabulations, etc...) recognition and processing,

@item raw: permits raw data processing. 

@end itemize

We may think that one need two serial drivers to deal with those two types
of data, but Termios permits having only one driver. 

@section Termios

Termios is a standard for terminal management, included in several Unix
versions. Termios is good because: 

@itemize @bullet

@item from the user's side: primitives to access the terminal and change
configuration settings are the same under Unix and Rtems. 

@item from the BSP developer's side: it frees you from dealing with buffer
states and mutual exclusions on them. 

@end itemize

Termios support includes: 

@itemize @bullet

@item raw and console handling,

@item blocking or non-blocking characters receive, with or without
Timeout. 

@end itemize

For more information on Termios, type man termios in your Unix box or go
to http://www.freebsd.org/cgi/man.cgi. 

@section Driver Functioning Modes

There are generally two main functioning modes for an UART (Universal
Asynchronous Receiver-Transmitter, i.e. the serial chip): 

@itemize @bullet

@item polling mode: the processor blocks on sending/receiving characters.
This mode is not powerful, but is necessary when one wants to print an
error message when the board hung. This is also the most simple mode to
program,

@item interrupt mode: the processor doesn't block on sending/receiving
characters. Two buffers (one for the in-going characters, the others for
the characters to be sent) are used. An interrupt is raised as soon as a
character is in the UART. Then the int errupt subroutine insert the
character at the input buffer queue. When a character is asked for input,
this at the head of the buffer is returned. When characters have to be
sent, one have to put the first characters (the number depends on the
UART) in th e UART. Then an interrupt is raised when all the characters
have been emitted. The interrupt subroutine has to send the characters
remaining in the output buffer the same way. 

@end itemize

@section Serial Driver Functioning Overview

Figure 5 is an attempt of showing how a Termios driven serial driver works : 

@itemize @bullet

@item the application programmer uses standard C library call (printf,
scanf, read, write, etc.),

@item C library (in fact that's Cygnus Newlib) calls RTEMS procedure: glue
is made in newlib*.c files which can be found under
$RTEMS_ROOT/c/src/lib/libc directory,

@item Glue code calls your serial driver entry routines. 

@end itemize

@subsection Termios and Polled I/O

You have to point Termios out which functions are used for simple
character input/output: 


Function

Description

@example
int pollWrite (int minor, const char *buf, int len) 

for (i=0; i<len; i++) @{
     put buf[i] into the UART channel minor
     wait for the character to be transmitted
     on the serial line
@}
int pollread(int minor)
@end example

wait for a character to be available in the UART channel minor, then return it.

@subsection Termios and Interrupt Driven I/O

The UART generally generates interrupts when it is ready to accept or to
emit a number of characters. In this mode, the interrupt subroutine is the
core of the driver: 

@example
rtems_isr InterruptHandler (rtems_vector_number v)
@end example

check whether there was an error

if some characters were received: 
   ask Termios to put them on his input buffer

if some characters have been transmitted (i.e. the UART output buffer is empty)
   tell TERMIOS that the characters have been
   transmitted. The TERMIOS routine will call
   the InterruptWrite function with the number
   of characters not transmitted yet if it is
   not zero.

@example
static int InterruptWrite(int minor, const char *buf, int len)
@end example

you have to put the n first buf characters in the UART channel minor
buffer (n is the UART channel size, n=1 on the MC68640). Generally, an
interrupt is raised after these n characters being transmitted. So you may
have to enable the UART interrupts after having put the characters in the
UART. 


Figure 5: general TERMIOS driven serial driver functioning

@subsection Initialization

The driver initialization is called once during RTEMS initialization
process. 

The console_initialize function has to : 

@itemize @bullet

@item initialize Termios support: call rtems_termios_initialize(),

@item initialize your integrated processor's UART: the operation is
normally described in your user's manual and you must follow these
instructions but it usually consists in: 

@item reinitialize the UART channels,

@item set the channels configuration to Termios default one, i.e.: 9600
bauds, no parity, 1 stop bit, 8 bits per character,

@item register your console interrupt routine to RTEMS: 

@example
	rtems_interrupt_catch (InterruptHandler,CONSOLE_VECTOR,&old_handler);
@end example

@item enable the UART channels,

@item register your device name: in order to use the console (i.e. being
able to do printf/scanf on stdin, stdout, and stderr), you have to
register the "/dev/console" device: 

@example
rtems_io_register_name ("dev/console", major, i);
@end example

@end itemize

@subsection Opening a serial device

The console device is opened during RTEMS initialization but the
console_open function is called when a new device is opened. For instance,
if you register the "/dev/tty1" device for the UART channel 2, the
console_open will be called with a fopen("/dev/t ty", mode) in your
application. 

The console_open function has to inform Termios of your low-level function
for serial line support; the "callbacks". 

The gen68340 BSP defines two kinds of callbacks: 

@itemize @bullet

@item functions to use with polled input/output,

@item functions to use with interrupt input/output. 

@end itemize

@subsubsection Polled I/O

You have to point Termios out which functions are used for simple
character input/output, i.e. pointers to pollWrite and pollRead functions
defined in 8.4.1. 

@subsubsection Interrupt Driven I/O

Driver functioning is quite different in this mode. You can see there's no
read function passed to Termios. Indeed a console_read call returns the
content of Termios input buffer. This buffer is filled in the driver
interrupt subroutine (cf. 8.4.2). 

But you actually have to provide a pointer to the InterruptWrite function. 

@subsection Closing a serial device

The driver entry point is: console_close. 

You just have to notify Termios that the serial device was closed, with a
call to rtems_termios_close. 

@subsection Reading characters from the serial device

The driver entry point is: console_read. 

You just have to return the content of the Termios input buffer. 

Call rtems_termios_read. 

@subsection Writing characters to the serial device

The driver entry point is: console_write. 

You just have to add the characters at the end of the Termios output
buffer. 

Call rtems_termios_write. 

@subsection Changing serial line parameters

The driver entry point is: console_control. 

The application write is able to control the serial line configuration
with Termios calls (such as the ioctl command, see Termios man page for
more details). If you want to support dynamic configuration, you have to
write the console_control piece of code . Look at the gen68340 BSP for an
example of how it is done. Basically ioctl commands call console_control
with the serial line configuration in a Termios structure. You just have
to reinitialize the UART with the correct settings.