1 | .. comment SPDX-License-Identifier: CC-BY-SA-4.0 |
---|
2 | |
---|
3 | .. COMMENT: COPYRIGHT (c) 1988-2002. |
---|
4 | .. COMMENT: On-Line Applications Research Corporation (OAR). |
---|
5 | .. COMMENT: All rights reserved. |
---|
6 | |
---|
7 | Console Driver |
---|
8 | ############## |
---|
9 | |
---|
10 | Introduction |
---|
11 | ============ |
---|
12 | |
---|
13 | This chapter describes the operation of a console driver using the RTEMS POSIX |
---|
14 | Termios support. Traditionally RTEMS has referred to all serial device drivers |
---|
15 | as console device drivers. A console driver can be used to do raw data |
---|
16 | processing in addition to the "normal" standard input and output device |
---|
17 | functions required of a console. |
---|
18 | |
---|
19 | The serial driver may be called as the consequence of a C Library call such as |
---|
20 | ``printf`` or ``scanf`` or directly via the``read`` or ``write`` system calls. |
---|
21 | There are two main functioning modes: |
---|
22 | |
---|
23 | - console: formatted input/output, with special characters (end of line, |
---|
24 | tabulations, etc.) recognition and processing, |
---|
25 | |
---|
26 | - raw: permits raw data processing. |
---|
27 | |
---|
28 | One may think that two serial drivers are needed to handle these two types of |
---|
29 | data, but Termios permits having only one driver. |
---|
30 | |
---|
31 | Termios |
---|
32 | ======= |
---|
33 | |
---|
34 | Termios is a standard for terminal management, included in the POSIX 1003.1b |
---|
35 | standard. As part of the POSIX and Open Group Single UNIX Specification, is |
---|
36 | commonly provided on UNIX implementations. The Open Group has the termios |
---|
37 | portion of the POSIX standard online at |
---|
38 | http://opengroup.org/onlinepubs/007908775/xbd/termios.html. The requirements |
---|
39 | for the ``<termios.h>`` file are also provided and are at |
---|
40 | http://opengroup.org/onlinepubs/007908775/xsh/termios.h.html. |
---|
41 | |
---|
42 | Having RTEMS support for Termios is beneficial because: |
---|
43 | |
---|
44 | - from the user's side because it provides standard primitive operations to |
---|
45 | access the terminal and change configuration settings. These operations are |
---|
46 | the same under UNIX and RTEMS. |
---|
47 | |
---|
48 | - from the BSP developer's side because it frees the developer from dealing |
---|
49 | with buffer states and mutual exclusions on them. Early RTEMS console device |
---|
50 | drivers also did their own special character processing. |
---|
51 | |
---|
52 | - it is part of an internationally recognized standard. |
---|
53 | |
---|
54 | - it makes porting code from other environments easier. |
---|
55 | |
---|
56 | Termios support includes: |
---|
57 | |
---|
58 | - raw and console handling, |
---|
59 | |
---|
60 | - blocking or non-blocking characters receive, with or without Timeout. |
---|
61 | |
---|
62 | At this time, RTEMS documentation does not include a thorough discussion of the |
---|
63 | Termios functionality. For more information on Termios, type ``man termios`` |
---|
64 | on a Unix box or point a web browser athttp://www.freebsd.org/cgi/man.cgi. |
---|
65 | |
---|
66 | Driver Functioning Modes |
---|
67 | ======================== |
---|
68 | |
---|
69 | There are generally three main functioning modes for an UART (Universal |
---|
70 | Asynchronous Receiver-Transmitter, i.e. the serial chip): |
---|
71 | |
---|
72 | - polled mode |
---|
73 | |
---|
74 | - interrupt driven mode |
---|
75 | |
---|
76 | - task driven mode |
---|
77 | |
---|
78 | In polled mode, the processor blocks on sending/receiving characters. This |
---|
79 | mode is not the most efficient way to utilize the UART. But polled mode is |
---|
80 | usually necessary when one wants to print an error message in the event of a |
---|
81 | fatal error such as a fatal error in the BSP. This is also the simplest mode |
---|
82 | to program. Polled mode is generally preferred if the serial port is to be |
---|
83 | used primarily as a debug console. In a simple polled driver, the software |
---|
84 | will continuously check the status of the UART when it is reading or writing to |
---|
85 | the UART. Termios improves on this by delaying the caller for 1 clock tick |
---|
86 | between successive checks of the UART on a read operation. |
---|
87 | |
---|
88 | In interrupt driven mode, the processor does not block on sending/receiving |
---|
89 | characters. Data is buffered between the interrupt service routine and |
---|
90 | application code. Two buffers are used to insulate the application from the |
---|
91 | relative slowness of the serial device. One of the buffers is used for |
---|
92 | incoming characters, while the other is used for outgoing characters. |
---|
93 | |
---|
94 | An interrupt is raised when a character is received by the UART. The interrupt |
---|
95 | subroutine places the incoming character at the end of the input buffer. When |
---|
96 | an application asks for input, the characters at the front of the buffer are |
---|
97 | returned. |
---|
98 | |
---|
99 | When the application prints to the serial device, the outgoing characters are |
---|
100 | placed at the end of the output buffer. The driver will place one or more |
---|
101 | characters in the UART (the exact number depends on the UART) An interrupt will |
---|
102 | be raised when all the characters have been transmitted. The interrupt service |
---|
103 | routine has to send the characters remaining in the output buffer the same way. |
---|
104 | When the transmitting side of the UART is idle, it is typically necessary to |
---|
105 | prime the transmitter before the first interrupt will occur. |
---|
106 | |
---|
107 | The task driven mode is similar to interrupt driven mode, but the actual data |
---|
108 | processing is done in dedicated tasks instead of interrupt routines. |
---|
109 | |
---|
110 | Serial Driver Functioning Overview |
---|
111 | ================================== |
---|
112 | |
---|
113 | The following Figure shows how a Termios driven serial driver works: Figure not |
---|
114 | included in ASCII version |
---|
115 | |
---|
116 | The following list describes the basic flow. |
---|
117 | |
---|
118 | - the application programmer uses standard C library call (printf, scanf, read, |
---|
119 | write, etc.), |
---|
120 | |
---|
121 | - C library (ctx.g. RedHat (formerly Cygnus) Newlib) calls the RTEMS system |
---|
122 | call interface. This code can be found in the:file:`cpukit/libcsupport/src` |
---|
123 | directory. |
---|
124 | |
---|
125 | - Glue code calls the serial driver entry routines. |
---|
126 | |
---|
127 | Basics |
---|
128 | ------ |
---|
129 | |
---|
130 | The low-level driver API changed between RTEMS 4.10 and RTEMS 4.11. The legacy |
---|
131 | callback API is still supported, but its use is discouraged. The following |
---|
132 | functions are deprecated: |
---|
133 | |
---|
134 | - ``rtems_termios_open()`` - use ``rtems_termios_device_open()`` in combination |
---|
135 | with ``rtems_termios_device_install()`` instead. |
---|
136 | |
---|
137 | - ``rtems_termios_close()`` - use ``rtems_termios_device_close()`` instead. |
---|
138 | |
---|
139 | This manual describes the new API. A new console driver should consist of |
---|
140 | three parts. |
---|
141 | |
---|
142 | - The basic console driver functions using the Termios support. Add this the |
---|
143 | BSPs Makefile.am: |
---|
144 | |
---|
145 | .. code-block:: makefile |
---|
146 | |
---|
147 | [...] |
---|
148 | libbsp_a_SOURCES += ../../shared/console-termios.c |
---|
149 | [...] |
---|
150 | |
---|
151 | - A general serial module specific low-level driver providing the handler table |
---|
152 | for the Termios ``rtems_termios_device_install()`` function. This low-level |
---|
153 | driver could be used for more than one BSP. |
---|
154 | |
---|
155 | - A BSP specific initialization routine ``console_initialize()``, that calls |
---|
156 | ``rtems_termios_device_install()`` providing a low-level driver context for |
---|
157 | each installed device. |
---|
158 | |
---|
159 | You need to provide a device handler structure for the Termios device |
---|
160 | interface. The functions are described later in this chapter. The first open |
---|
161 | and set attributes handler return a boolean status to indicate success (true) |
---|
162 | or failure (false). The polled read function returns an unsigned character in |
---|
163 | case one is available or minus one otherwise. |
---|
164 | |
---|
165 | If you want to use polled IO it should look like the following. Termios must |
---|
166 | be told the addresses of the handler that are to be used for simple character |
---|
167 | IO, i.e. pointers to the ``my_driver_poll_read()`` and |
---|
168 | ``my_driver_poll_write()`` functions described later in `Termios and Polled |
---|
169 | IO`_. |
---|
170 | |
---|
171 | .. code-block:: c |
---|
172 | |
---|
173 | const rtems_termios_handler my_driver_handler_polled = { |
---|
174 | .first_open = my_driver_first_open, |
---|
175 | .last_close = my_driver_last_close, |
---|
176 | .poll_read = my_driver_poll_read, |
---|
177 | .write = my_driver_poll_write, |
---|
178 | .set_attributes = my_driver_set_attributes, |
---|
179 | .stop_remote_tx = NULL, |
---|
180 | .start_remote_tx = NULL, |
---|
181 | .mode = TERMIOS_POLLED |
---|
182 | } |
---|
183 | |
---|
184 | For an interrupt driven implementation you need the following. The driver |
---|
185 | functioning is quite different in this mode. There is no device driver read |
---|
186 | handler to be passed to Termios. Indeed a ``console_read()`` call returns the |
---|
187 | contents of Termios input buffer. This buffer is filled in the driver |
---|
188 | interrupt subroutine, see also `Termios and Interrupt Driven IO`_. The driver |
---|
189 | is responsible for providing a pointer to the``my_driver_interrupt_write()`` |
---|
190 | function. |
---|
191 | |
---|
192 | .. code-block:: c |
---|
193 | |
---|
194 | const rtems_termios_handler my_driver_handler_interrupt = { |
---|
195 | .first_open = my_driver_first_open, |
---|
196 | .last_close = my_driver_last_close, |
---|
197 | .poll_read = NULL, |
---|
198 | .write = my_driver_interrupt_write, |
---|
199 | .set_attributes = my_driver_set_attributes, |
---|
200 | .stopRemoteTx = NULL, |
---|
201 | .stop_remote_tx = NULL, |
---|
202 | .start_remote_tx = NULL, |
---|
203 | .mode = TERMIOS_IRQ_DRIVEN |
---|
204 | }; |
---|
205 | |
---|
206 | You can also provide hander for remote transmission control. This is not |
---|
207 | covered in this manual, so they are set to ``NULL`` in the above examples. |
---|
208 | |
---|
209 | The low-level driver should provide a data structure for its device context. |
---|
210 | The initialization routine must provide a context for each installed device via |
---|
211 | ``rtems_termios_device_install()``. For simplicity of the console |
---|
212 | initialization example the device name is also present. Here is an example |
---|
213 | header file. |
---|
214 | |
---|
215 | .. code-block:: c |
---|
216 | |
---|
217 | #ifndef MY_DRIVER_H |
---|
218 | #define MY_DRIVER_H |
---|
219 | |
---|
220 | #include <rtems/termiostypes.h> |
---|
221 | #include <some-chip-header.h> |
---|
222 | |
---|
223 | /* Low-level driver specific data structure \*/ |
---|
224 | typedef struct { |
---|
225 | rtems_termios_device_context base; |
---|
226 | const char \*device_name; |
---|
227 | volatile module_register_block \*regs; |
---|
228 | /* More stuff \*/ |
---|
229 | } my_driver_context; |
---|
230 | |
---|
231 | extern const rtems_termios_handler my_driver_handler_polled; |
---|
232 | extern const rtems_termios_handler my_driver_handler_interrupt; |
---|
233 | |
---|
234 | #endif /* MY_DRIVER_H \*/ |
---|
235 | |
---|
236 | Termios and Polled IO |
---|
237 | --------------------- |
---|
238 | |
---|
239 | The following handler are provided by the low-level driver and invoked by |
---|
240 | Termios for simple character IO. |
---|
241 | |
---|
242 | The ``my_driver_poll_write()`` routine is responsible for writing ``n`` |
---|
243 | characters from ``buf`` to the serial device specified by ``tty``. |
---|
244 | |
---|
245 | .. code-block:: c |
---|
246 | |
---|
247 | static void my_driver_poll_write( |
---|
248 | rtems_termios_device_context *base, |
---|
249 | const char *buf, |
---|
250 | size_t n |
---|
251 | ) |
---|
252 | { |
---|
253 | my_driver_context *ctx = (my_driver_context *) base; |
---|
254 | size_t i; |
---|
255 | /* Write */ |
---|
256 | for (i = 0; i < n; ++i) { |
---|
257 | my_driver_write_char(ctx, buf[i]); |
---|
258 | } |
---|
259 | } |
---|
260 | |
---|
261 | The ``my_driver_poll_read`` routine is responsible for reading a single |
---|
262 | character from the serial device specified by ``tty``. If no character is |
---|
263 | available, then the routine should return minus one. |
---|
264 | |
---|
265 | .. code-block:: c |
---|
266 | |
---|
267 | static int my_driver_poll_read(rtems_termios_device_context *base) |
---|
268 | { |
---|
269 | my_driver_context *ctx = (my_driver_context *) base; |
---|
270 | /* Check if a character is available */ |
---|
271 | if (my_driver_can_read_char(ctx)) { |
---|
272 | /* Return the character */ |
---|
273 | return my_driver_read_char(ctx); |
---|
274 | } else { |
---|
275 | /* Return an error status */ |
---|
276 | return -1; |
---|
277 | } |
---|
278 | } |
---|
279 | |
---|
280 | Termios and Interrupt Driven IO |
---|
281 | ------------------------------- |
---|
282 | |
---|
283 | The UART generally generates interrupts when it is ready to accept or to emit a |
---|
284 | number of characters. In this mode, the interrupt subroutine is the core of |
---|
285 | the driver. |
---|
286 | |
---|
287 | The ``my_driver_interrupt_handler()`` is responsible for processing |
---|
288 | asynchronous interrupts from the UART. There may be multiple interrupt |
---|
289 | handlers for a single UART. Some UARTs can generate a unique interrupt vector |
---|
290 | for each interrupt source such as a character has been received or the |
---|
291 | transmitter is ready for another character. |
---|
292 | |
---|
293 | In the simplest case, the ``my_driver_interrupt_handler()`` will have to check |
---|
294 | the status of the UART and determine what caused the interrupt. The following |
---|
295 | describes the operation of an ``my_driver_interrupt_handler`` which has to do |
---|
296 | this: |
---|
297 | |
---|
298 | .. code-block:: c |
---|
299 | |
---|
300 | static void my_driver_interrupt_handler( |
---|
301 | rtems_vector_number vector, |
---|
302 | void *arg |
---|
303 | ) |
---|
304 | { |
---|
305 | rtems_termios_tty *tty = arg; |
---|
306 | my_driver_context *ctx = rtems_termios_get_device_context(tty); |
---|
307 | char buf[N]; |
---|
308 | size_t n; |
---|
309 | |
---|
310 | /* |
---|
311 | * Check if we have received something. The function reads the |
---|
312 | * received characters from the device and stores them in the |
---|
313 | * buffer. It returns the number of read characters. |
---|
314 | */ |
---|
315 | n = my_driver_read_received_chars(ctx, buf, N); |
---|
316 | if (n > 0) { |
---|
317 | /* Hand the data over to the Termios infrastructure */ |
---|
318 | rtems_termios_enqueue_raw_characters(tty, buf, n); |
---|
319 | } |
---|
320 | |
---|
321 | /* |
---|
322 | * Check if we have something transmitted. The functions returns |
---|
323 | * the number of transmitted characters since the last write to the |
---|
324 | * device. |
---|
325 | */ |
---|
326 | n = my_driver_transmitted_chars(ctx); |
---|
327 | if (n > 0) { |
---|
328 | /* |
---|
329 | * Notify Termios that we have transmitted some characters. It |
---|
330 | * will call now the interrupt write function if more characters |
---|
331 | * are ready for transmission. |
---|
332 | */ |
---|
333 | rtems_termios_dequeue_characters(tty, n); |
---|
334 | } |
---|
335 | } |
---|
336 | |
---|
337 | The ``my_driver_interrupt_write()`` function is responsible for telling the |
---|
338 | device that the ``n`` characters at ``buf`` are to be transmitted. It the |
---|
339 | value ``n`` is zero to indicate that no more characters are to send. The |
---|
340 | driver can disable the transmit interrupts now. This routine is invoked either |
---|
341 | from task context with disabled interrupts to start a new transmission process |
---|
342 | with exactly one character in case of an idle output state or from the |
---|
343 | interrupt handler to refill the transmitter. If the routine is invoked to |
---|
344 | start the transmit process the output state will become busy and Termios starts |
---|
345 | to fill the output buffer. If the transmit interrupt arises before Termios was |
---|
346 | able to fill the transmit buffer you will end up with one interrupt per |
---|
347 | character. |
---|
348 | |
---|
349 | .. code-block:: c |
---|
350 | |
---|
351 | static void my_driver_interrupt_write( |
---|
352 | rtems_termios_device_context *base, |
---|
353 | const char *buf, |
---|
354 | size_t n |
---|
355 | ) |
---|
356 | { |
---|
357 | my_driver_context *ctx = (my_driver_context *) base; |
---|
358 | |
---|
359 | /* |
---|
360 | * Tell the device to transmit some characters from buf (less than |
---|
361 | * or equal to n). When the device is finished it should raise an |
---|
362 | * interrupt. The interrupt handler will notify Termios that these |
---|
363 | * characters have been transmitted and this may trigger this write |
---|
364 | * function again. You may have to store the number of outstanding |
---|
365 | * characters in the device data structure. |
---|
366 | */ |
---|
367 | /* |
---|
368 | * Termios will set n to zero to indicate that the transmitter is |
---|
369 | * now inactive. The output buffer is empty in this case. The |
---|
370 | * driver may disable the transmit interrupts now. |
---|
371 | */ |
---|
372 | } |
---|
373 | |
---|
374 | Initialization |
---|
375 | -------------- |
---|
376 | |
---|
377 | The BSP specific driver initialization is called once during the RTEMS |
---|
378 | initialization process. |
---|
379 | |
---|
380 | The ``console_initialize()`` function may look like this: |
---|
381 | |
---|
382 | .. code-block:: c |
---|
383 | |
---|
384 | #include <my-driver.h> |
---|
385 | #include <rtems/console.h> |
---|
386 | #include <bsp.h> |
---|
387 | #include <bsp/fatal.h> |
---|
388 | |
---|
389 | static my_driver_context driver_context_table[M] = { /* Some values */ }; |
---|
390 | |
---|
391 | rtems_device_driver console_initialize( |
---|
392 | rtems_device_major_number major, |
---|
393 | rtems_device_minor_number minor, |
---|
394 | void *arg |
---|
395 | ) |
---|
396 | { |
---|
397 | rtems_status_code sc; |
---|
398 | #ifdef SOME_BSP_USE_INTERRUPTS |
---|
399 | const rtems_termios_handler *handler = &my_driver_handler_interrupt; |
---|
400 | #else |
---|
401 | const rtems_termios_handler *handler = &my_driver_handler_polled; |
---|
402 | #endif |
---|
403 | |
---|
404 | /* |
---|
405 | * Initialize the Termios infrastructure. If Termios has already |
---|
406 | * been initialized by another device driver, then this call will |
---|
407 | * have no effect. |
---|
408 | */ |
---|
409 | rtems_termios_initialize(); |
---|
410 | |
---|
411 | /* Initialize each device */ |
---|
412 | for ( |
---|
413 | minor = 0; |
---|
414 | minor < RTEMS_ARRAY_SIZE(driver_context_table); |
---|
415 | ++minor |
---|
416 | ) { |
---|
417 | my_driver_context *ctx = &driver_context_table[minor]; |
---|
418 | |
---|
419 | /* |
---|
420 | * Install this device in the file system and Termios. In order |
---|
421 | * to use the console (i.e. being able to do printf, scanf etc. |
---|
422 | * on stdin, stdout and stderr), one device must be registered as |
---|
423 | * "/dev/console" (CONSOLE_DEVICE_NAME). |
---|
424 | */ |
---|
425 | sc = rtems_termios_device_install( |
---|
426 | ctx->device_name, |
---|
427 | major, |
---|
428 | minor, |
---|
429 | handler, |
---|
430 | NULL, |
---|
431 | ctx |
---|
432 | ); |
---|
433 | if (sc != RTEMS_SUCCESSFUL) { |
---|
434 | bsp_fatal(SOME_BSP_FATAL_CONSOLE_DEVICE_INSTALL); |
---|
435 | } |
---|
436 | } |
---|
437 | |
---|
438 | return RTEMS_SUCCESSFUL; |
---|
439 | } |
---|
440 | |
---|
441 | Opening a serial device |
---|
442 | ----------------------- |
---|
443 | |
---|
444 | The ``console_open()`` function provided by :file:`console-termios.c` is called |
---|
445 | whenever a serial device is opened. The device registered as |
---|
446 | ``"/dev/console"`` (``CONSOLE_DEVICE_NAME``) is opened automatically during |
---|
447 | RTEMS initialization. For instance, if UART channel 2 is registered as |
---|
448 | ``"/dev/tty1"``, the ``console_open()`` entry point will be called as the |
---|
449 | result of an ``fopen("/dev/tty1", mode)`` in the application. |
---|
450 | |
---|
451 | During the first open of the device Termios will call the |
---|
452 | ``my_driver_first_open()`` handler. |
---|
453 | |
---|
454 | .. code-block:: c |
---|
455 | |
---|
456 | static bool my_driver_first_open( |
---|
457 | rtems_termios_tty *tty, |
---|
458 | rtems_termios_device_context *base, |
---|
459 | struct termios *term, |
---|
460 | rtems_libio_open_close_args_t *args |
---|
461 | ) |
---|
462 | { |
---|
463 | my_driver_context *ctx = (my_driver_context *) base; |
---|
464 | rtems_status_code sc; |
---|
465 | bool ok; |
---|
466 | |
---|
467 | /* |
---|
468 | * You may add some initialization code here. |
---|
469 | */ |
---|
470 | |
---|
471 | /* |
---|
472 | * Sets the initial baud rate. This should be set to the value of |
---|
473 | * the boot loader. This function accepts only exact Termios baud |
---|
474 | * values. |
---|
475 | */ |
---|
476 | sc = rtems_termios_set_initial_baud(tty, MY_DRIVER_BAUD_RATE); |
---|
477 | if (sc != RTEMS_SUCCESSFUL) { |
---|
478 | /* Not a valid Termios baud */ |
---|
479 | } |
---|
480 | |
---|
481 | /* |
---|
482 | * Alternatively you can set the best baud. |
---|
483 | */ |
---|
484 | rtems_termios_set_best_baud(term, MY_DRIVER_BAUD_RATE); |
---|
485 | |
---|
486 | /* |
---|
487 | * To propagate the initial Termios attributes to the device use |
---|
488 | * this. |
---|
489 | */ |
---|
490 | ok = my_driver_set_attributes(base, term); |
---|
491 | if (!ok) { |
---|
492 | /* This is bad */ |
---|
493 | } |
---|
494 | |
---|
495 | /* |
---|
496 | * Return true to indicate a successful set attributes, and false |
---|
497 | * otherwise. |
---|
498 | */ |
---|
499 | return true; |
---|
500 | } |
---|
501 | |
---|
502 | Closing a Serial Device |
---|
503 | ----------------------- |
---|
504 | |
---|
505 | The ``console_close()`` provided by :file:`console-termios.c` is invoked when |
---|
506 | the serial device is to be closed. This entry point corresponds to the device |
---|
507 | driver close entry point. |
---|
508 | |
---|
509 | Termios will call the ``my_driver_last_close()`` handler if the last close |
---|
510 | happens on the device. |
---|
511 | |
---|
512 | .. code-block:: c |
---|
513 | |
---|
514 | static void my_driver_last_close( |
---|
515 | rtems_termios_tty *tty, |
---|
516 | rtems_termios_device_context *base, |
---|
517 | rtems_libio_open_close_args_t *args |
---|
518 | ) |
---|
519 | { |
---|
520 | my_driver_context *ctx = (my_driver_context *) base; |
---|
521 | |
---|
522 | /* |
---|
523 | * The driver may do some cleanup here. |
---|
524 | */ |
---|
525 | } |
---|
526 | |
---|
527 | Reading Characters from a Serial Device |
---|
528 | --------------------------------------- |
---|
529 | |
---|
530 | The ``console_read()`` provided by :file:`console-termios.c` is invoked when |
---|
531 | the serial device is to be read from. This entry point corresponds to the |
---|
532 | device driver read entry point. |
---|
533 | |
---|
534 | Writing Characters to a Serial Device |
---|
535 | ------------------------------------- |
---|
536 | |
---|
537 | The ``console_write()`` provided by :file:`console-termios.c` is invoked when |
---|
538 | the serial device is to be written to. This entry point corresponds to the |
---|
539 | device driver write entry point. |
---|
540 | |
---|
541 | Changing Serial Line Parameters |
---|
542 | ------------------------------- |
---|
543 | |
---|
544 | The ``console_control()`` provided by :file:`console-termios.c` is invoked when |
---|
545 | the line parameters for a particular serial device are to be changed. This |
---|
546 | entry point corresponds to the device driver IO control entry point. |
---|
547 | |
---|
548 | The application writer is able to control the serial line configuration with |
---|
549 | Termios calls (such as the ``ioctl()`` command, see the Termios documentation |
---|
550 | for more details). If the driver is to support dynamic configuration, then it |
---|
551 | must have the ``console_control()`` piece of code. Basically ``ioctl()`` |
---|
552 | commands call ``console_control()`` with the serial line configuration in a |
---|
553 | Termios defined data structure. |
---|
554 | |
---|
555 | The driver is responsible for reinitializing the device with the correct |
---|
556 | settings. For this purpose Termios calls the ``my_driver_set_attributes()`` |
---|
557 | handler. |
---|
558 | |
---|
559 | .. code-block:: c |
---|
560 | |
---|
561 | static bool my_driver_set_attributes( |
---|
562 | rtems_termios_device_context *base, |
---|
563 | const struct termios *term |
---|
564 | ) |
---|
565 | { |
---|
566 | my_driver_context *ctx = (my_driver_context *) base; |
---|
567 | |
---|
568 | /* |
---|
569 | * Inspect the termios data structure and configure the device |
---|
570 | * appropriately. The driver should only be concerned with the |
---|
571 | * parts of the structure that specify hardware setting for the |
---|
572 | * communications channel such as baud, character size, etc. |
---|
573 | */ |
---|
574 | /* |
---|
575 | * Return true to indicate a successful set attributes, and false |
---|
576 | * otherwise. |
---|
577 | */ |
---|
578 | return true; |
---|
579 | } |
---|