diff options
Diffstat (limited to 'doc/bsp_howto/console.t')
-rw-r--r-- | doc/bsp_howto/console.t | 336 |
1 files changed, 223 insertions, 113 deletions
diff --git a/doc/bsp_howto/console.t b/doc/bsp_howto/console.t index 09d8b25640..0b94cede70 100644 --- a/doc/bsp_howto/console.t +++ b/doc/bsp_howto/console.t @@ -10,16 +10,22 @@ @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: +This chapter describes the operation of a console driver using +the RTEMS POSIX Termios support. Traditionally RTEMS has referred +to all serial device drivers as console device drivers. A +console driver can be used to do raw data processing in addition +to the "normal" standard input and output device functions required +of a console. + +The serial driver may be called as the consequence of a C Library +call such as @code{printf} or @code{scanf} or directly via the +@code{read} or @code{write} system calls. +There are two main functioning modes: @itemize @bullet @item console: formatted input/output, with special characters (end of -line, tabulations, etc...) recognition and processing, +line, tabulations, etc.) recognition and processing, @item raw: permits raw data processing. @@ -30,16 +36,20 @@ 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: +Termios is a standard for terminal management, included in the POSIX 1003.1b +standard. It is commonly provided on UNIX implementations. +Having RTEMS support for Termios is beneficial: @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 user's side because it provides standard primitive operations +to access the terminal and change configuration settings. These operations +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. +@item from the BSP developer's side because it frees the +developer from dealing with buffer states and mutual exclusions on them. +Early RTEMS console device drivers also did their own special +character processing. @end itemize @@ -54,8 +64,16 @@ 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. +At this time, RTEMS documentation does not include a thorough discussion +of the Termios functionality. For more information on Termios, +type @code{man termios} on a Unix box or point a web browser +at +@ifset use-html +@href{http://www.freebsd.org/cgi/man.cgi,,,http://www.freebsd.org/cgi/man.cgi}. +@end ifset +@ifclear use-html +@code{http://www.freebsd.org/cgi/man.cgi}. +@end ifclear @section Driver Functioning Modes @@ -64,130 +82,203 @@ 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. +@item polled mode +@item interrupt driven mode @end itemize +In polled mode, the processor blocks on sending/receiving characters. +This mode is not the most efficient way to utilize the UART. But +polled mode is usually necessary when one wants to print an +error message in the event of a fatal error such as al fatal error +in the BSP. This is also the simplest mode to +program. Polled mode is generally preferred if the serial port is +to be used primarily as a debug console. In a simple polled driver, +the software will continuously check the status of the UART when +it is reading or writing to the UART. Termios improves on this +by delaying the caller for 1 clock tick between successive checks +of the UART on a read operation. + +In interrupt driven mode, the processor does not block on sending/receiving +characters. Data is buffered between the interrupt service routine +and application code. Two buffers are used to insulate the application +from the relative slowness of the serial device. One of the buffers is +used for incoming characters, while the other is used for outgoing characters. + +An interrupt is raised when a character is received by the UART. +The interrupt subroutine places the incoming character at the end +of the input buffer. When an application asks for input, +the characters at the front of the buffer are returned. + +When the application prints to the serial device, the outgoing characters +are placed at the end of the output buffer. The driver will place +one or more characters in the UART (the exact number depends on the UART) +An interrupt will be raised when all the characters have been transmitted. +The interrupt service routine has to send the characters +remaining in the output buffer the same way. When the transmitting side +of the UART is idle, it is typically necessary to prime the transmitter +before the first interrupt will occur. + @section Serial Driver Functioning Overview -Figure 5 is an attempt of showing how a Termios driven serial driver works : +The following Figure shows how a Termios driven serial driver works: + +@example +This figure needs to be inserted in this document. +@end example + +The following list describes the basic flow. @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 C library (in fact that's Cygnus Newlib) calls RTEMS +system call interface. This code can be found in the +@code{c/src/lib/libc} directory. -@item Glue code calls your serial driver entry routines. +@item Glue code calls the 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: - +The following functions are provided by the driver and invoked by +Termios for simple character input/output. The specific names of +these routines are not important as Termios invokes them indirectly +via function pointers. -Function +@subsubsection pollWrite -Description +The @code{pollWrite} routine is responsible for writing @code{len} characters +from @code{buf} to the serial device specified by @code{minor}. @example +@group int pollWrite (int minor, const char *buf, int len) - -for (i=0; i<len; i++) @{ +@{ + 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 group @end example -wait for a character to be available in the UART channel minor, then return it. +@subsubsection pollRead + +The @code{pollRead} routine is responsible for reading a single character +from the serial device specified by @code{minor}. If no character is +available, then the routine should return -1. + +@example +@group +int pollRead(int minor) +@{ + read status of UART + if status indicates a character is available + return character + return -1 +@} +@end group +@end example @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: +core of the driver. + +@subsubsection InterruptHandler + +The @code{InterruptHandler} is responsible for processing asynchronous +interrupts from the UART. There may be multiple interrupt handlers for +a single UART. Some UARTs can generate a unique interrupt vector for +each interrupt source such as a character has been received or the +transmitter is ready for another character. + +In the simplest case, the @code{InterruptHandler} will have to check +the status of the UART and determine what caused the interrupt. +The following describes the operation of an @code{InterruptHandler} +which has to do this: @example +@group rtems_isr InterruptHandler (rtems_vector_number v) +@{ + 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. +@} +@end group @end example -check whether there was an error - -if some characters were received: - ask Termios to put them on his input buffer +@subsubsection InterruptWrite -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. +The @code{InterruptWrite} is responsible for telling the UART +that the @code{len} characters at @code{buf} are to be transmitted. @example static int InterruptWrite(int minor, const char *buf, int len) +@{ + tell the UART to transmit len characters from buf +@} @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 +The driver has to put the @i{n} first buf characters in the UART channel minor +buffer (@i{n} is the UART channel size, @i{n}=1 on the MC68640). Generally, an +interrupt is raised after these @i{n} characters being transmitted. So +UART interrupts may have to be enabled after putting the characters in the UART. -Figure 5: general TERMIOS driven serial driver functioning - @subsection Initialization -The driver initialization is called once during RTEMS initialization +The driver initialization is called once during the RTEMS initialization process. -The console_initialize function has to : +The @code{console_initialize} function has to: @itemize @bullet -@item initialize Termios support: call rtems_termios_initialize(), +@item initialize Termios support: call @code{rtems_termios_initialize()}. If +Termios has already been initialized by another device driver, then +this call will have no effect. -@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 Initialize the UART: This procedure should +be described in the UART manual. This procedure @b{MUST} be +followed precisely. This procedure varies but +usually consists of: -@item reinitialize the UART channels, +@itemize @bullet +@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 set the channels configuration to the Termios default: +9600 bauds, no parity, 1 stop bit, and 8 bits per character +@end itemize -@item register your console interrupt routine to RTEMS: +@item If interrupt driven, register the console interrupt routine to RTEMS: @example rtems_interrupt_catch (InterruptHandler,CONSOLE_VECTOR,&old_handler); @end example -@item enable the UART channels, +@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: +@item register the device name: in order to use the console (i.e. being +able to do printf/scanf on stdin, stdout, and stderr), some device +must be registered as "/dev/console": @example rtems_io_register_name ("dev/console", major, i); @@ -197,73 +288,92 @@ rtems_io_register_name ("dev/console", major, i); @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 +The @code{console_open} function is called whenever a serial +device is opened. The device registered as @code{"/dev/console"} +is opened automatically during RTEMS initialization. +For instance, if UART channel 2 is registered as "/dev/tty1", +the @code{console_open} entry point will be called as +the result of an @code{fopen("/dev/tty1", mode)} in the application. -The console_open function has to inform Termios of your low-level function -for serial line support; the "callbacks". +The @code{console_open} function has to inform Termios of the low-level +functions for serial line support; the "callbacks". -The gen68340 BSP defines two kinds of callbacks: +The gen68340 BSP defines two sets of callback tables: @itemize @bullet -@item functions to use with polled input/output, +@item one with functions for polled input/output -@item functions to use with interrupt input/output. +@item another with functions for interrupt driven input/output @end itemize +This code can be found in the file @code{$BSPROOT/console/console.c}. + @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. +Termios must be told the addresses of the functions that are to be +used for simple character input/output, i.e. pointers to the +@code{pollWrite} and @code{pollRead} functions +defined earlier in @ref{Console Driver Termios and Polled I/O}. @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. +Driver functioning is quite different in this mode. There is no +device driver read function to be passed to Termios. Indeed a +@code{console_read} call returns the contents of Termios input buffer. +This buffer is filled in the driver interrupt subroutine +(see @ref{Console Driver Termios and Interrupt Driven I/O}). -@subsection Closing a serial device +The driver is responsible for providing a pointer to the +@code{InterruptWrite} function. -The driver entry point is: console_close. +@subsection Closing a Serial Device -You just have to notify Termios that the serial device was closed, with a -call to rtems_termios_close. +The @code{console_close} is invoked when the serial device is to +be closed. This entry point corresponds to the device driver +close entry point. -@subsection Reading characters from the serial device +This routine is responsible for notifying Termios that the serial +device was closed. This is done with a call to @code{rtems_termios_close}. -The driver entry point is: console_read. +@subsection Reading Characters From a Serial Device -You just have to return the content of the Termios input buffer. +The @code{console_read} is invoked when the serial device is to +be read from. This entry point corresponds to the device driver +read entry point. -Call rtems_termios_read. +This routine is responsible for returning the content of the +Termios input buffer. This is done by invoking the +@code{rtems_termios_read} routine. -@subsection Writing characters to the serial device +@subsection Writing Characters to a Serial Device -The driver entry point is: console_write. +The @code{console_write} is invoked when the serial device is to +be written to. This entry point corresponds to the device driver +write entry point. -You just have to add the characters at the end of the Termios output +This routine is responsible for adding the requested characters to +the Termios output queue for this device. This is done by +calling the routine @code{rtems_termios_write} +to add the characters at the end of the Termios output buffer. -Call rtems_termios_write. - -@subsection Changing serial line parameters +@subsection Changing Serial Line Parameters -The driver entry point is: console_control. +The @code{console_control} is invoked when the line parameters +for a particular serial device are to be changed. +This entry point corresponds to the device driver +io_control entry point. 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. +with Termios calls (such as the @code{ioctl} command, see +the Termios documentation for +more details). If the driver is to support dynamic configuration, then +is must have the @code{console_control} piece of code. Refer to the gen68340 +BSP for an example of how it is done. Basically @code{ioctl} +commands call @code{console_control} with the serial line +configuration in a Termios defined data structure. The driver +is responsible for reinitializing the UART with the correct settings. |