[9e633f5] | 1 | /*===============================================================*\ |
---|
| 2 | | File: termios_printk.c | |
---|
| 3 | +-----------------------------------------------------------------+ |
---|
| 4 | | Copyright (c) 2002 IMD | |
---|
| 5 | | Ingenieurbuero fuer Microcomputertechnik Th. Doerfler | |
---|
| 6 | | Hebststr. 8, 82178 Puchheim, Germany | |
---|
| 7 | | <Thomas.Doerfler@imd-systems.de> | |
---|
| 8 | | The license and distribution terms for this file may be | |
---|
| 9 | | found in the file LICENSE in this distribution or at | |
---|
| 10 | | http://www.OARcorp.com/rtems/license.html. | |
---|
| 11 | | all rights reserved | |
---|
| 12 | +-----------------------------------------------------------------+ |
---|
| 13 | | TERMIOS printk support | |
---|
| 14 | | this module performs low-level printk output using | |
---|
| 15 | | a polled termios driver | |
---|
| 16 | | | |
---|
| 17 | +-----------------------------------------------------------------+ |
---|
| 18 | | date history ID | |
---|
| 19 | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
---|
| 20 | | 13.05.02 creation doe | |
---|
| 21 | |*****************************************************************| |
---|
| 22 | |* $Id$ |
---|
| 23 | * |
---|
| 24 | |*****************************************************************| |
---|
| 25 | \*===============================================================*/ |
---|
| 26 | |
---|
| 27 | #include <rtems.h> |
---|
| 28 | #include <rtems/libio_.h> |
---|
| 29 | #include <errno.h> |
---|
| 30 | #include <stdio.h> |
---|
| 31 | #include <fcntl.h> |
---|
| 32 | #include <termios.h> |
---|
| 33 | |
---|
| 34 | #include <rtems/termiostypes.h> |
---|
| 35 | #include <rtems/bspIo.h> |
---|
| 36 | #include <termios_printk.h> |
---|
| 37 | |
---|
| 38 | /* |
---|
| 39 | * internal variables |
---|
| 40 | */ |
---|
| 41 | int termios_printk_fd = -1; |
---|
| 42 | struct rtems_termios_tty *termios_printk_tty; |
---|
| 43 | |
---|
| 44 | static void _termios_printk_null_char( char c ) {return;} |
---|
| 45 | |
---|
| 46 | BSP_output_char_function_type BSP_output_char = _termios_printk_null_char; |
---|
| 47 | BSP_polling_getchar_function_type BSP_poll_char; |
---|
| 48 | |
---|
| 49 | /*=========================================================================*\ |
---|
| 50 | | Function: | |
---|
| 51 | \*-------------------------------------------------------------------------*/ |
---|
| 52 | void termios_printk_outputchar |
---|
| 53 | /*-------------------------------------------------------------------------*\ |
---|
| 54 | | Purpose: | |
---|
| 55 | | send one character to serial port | |
---|
| 56 | +---------------------------------------------------------------------------+ |
---|
| 57 | | Input Parameters: | |
---|
| 58 | \*-------------------------------------------------------------------------*/ |
---|
| 59 | ( |
---|
| 60 | char c /* character to print */ |
---|
| 61 | ) |
---|
| 62 | /*-------------------------------------------------------------------------*\ |
---|
| 63 | | Return Value: | |
---|
| 64 | | <none> | |
---|
| 65 | \*=========================================================================*/ |
---|
| 66 | { |
---|
| 67 | static const char cr = '\r'; |
---|
| 68 | /* |
---|
| 69 | * check, whether printk serial port is available |
---|
| 70 | */ |
---|
| 71 | |
---|
| 72 | if ((termios_printk_tty != NULL) && |
---|
| 73 | (termios_printk_tty->device.write != NULL)) { |
---|
| 74 | /* |
---|
| 75 | * call termios_printk polling callout, if available |
---|
| 76 | */ |
---|
| 77 | if (termios_printk_conf.callout != NULL) { |
---|
| 78 | termios_printk_conf.callout(); |
---|
| 79 | } |
---|
| 80 | /* |
---|
| 81 | * send character to debug serial port |
---|
| 82 | */ |
---|
| 83 | if (c == '\n') { |
---|
| 84 | termios_printk_tty->device.write(termios_printk_tty->minor,&cr,1); |
---|
| 85 | } |
---|
| 86 | termios_printk_tty->device.write(termios_printk_tty->minor,&c,1); |
---|
| 87 | } |
---|
| 88 | } |
---|
| 89 | |
---|
| 90 | /*=========================================================================*\ |
---|
| 91 | | Function: | |
---|
| 92 | \*-------------------------------------------------------------------------*/ |
---|
| 93 | char termios_printk_inputchar |
---|
| 94 | /*-------------------------------------------------------------------------*\ |
---|
| 95 | | Purpose: | |
---|
| 96 | | wait for one character from serial port | |
---|
| 97 | +---------------------------------------------------------------------------+ |
---|
| 98 | | Input Parameters: | |
---|
| 99 | \*-------------------------------------------------------------------------*/ |
---|
| 100 | ( |
---|
| 101 | void /* none */ |
---|
| 102 | ) |
---|
| 103 | /*-------------------------------------------------------------------------*\ |
---|
| 104 | | Return Value: | |
---|
| 105 | | received character | |
---|
| 106 | \*=========================================================================*/ |
---|
| 107 | { |
---|
| 108 | int c = -1; |
---|
| 109 | /* |
---|
| 110 | * check, whether debug serial port is available |
---|
| 111 | */ |
---|
| 112 | if ((termios_printk_tty != NULL) && |
---|
| 113 | (termios_printk_tty->device.pollRead != NULL)) { |
---|
| 114 | do { |
---|
| 115 | /* |
---|
| 116 | * call termios_printk polling callout, if available |
---|
| 117 | */ |
---|
| 118 | if (termios_printk_conf.callout != NULL) { |
---|
| 119 | termios_printk_conf.callout(); |
---|
| 120 | } |
---|
| 121 | /* |
---|
| 122 | * get character from debug serial port |
---|
| 123 | */ |
---|
| 124 | c = termios_printk_tty->device.pollRead(termios_printk_tty->minor); |
---|
| 125 | } while (c < 0); |
---|
| 126 | } |
---|
| 127 | return c; |
---|
| 128 | } |
---|
| 129 | |
---|
| 130 | |
---|
| 131 | /*=========================================================================*\ |
---|
| 132 | | Function: | |
---|
| 133 | \*-------------------------------------------------------------------------*/ |
---|
| 134 | int termios_printk_open |
---|
| 135 | |
---|
| 136 | /*-------------------------------------------------------------------------*\ |
---|
| 137 | | Purpose: | |
---|
| 138 | | try to open given serial debug port | |
---|
| 139 | +---------------------------------------------------------------------------+ |
---|
| 140 | | Input Parameters: | |
---|
| 141 | \*-------------------------------------------------------------------------*/ |
---|
| 142 | ( |
---|
| 143 | const char *dev_name, /* name of device to open */ |
---|
| 144 | unsigned32 baudrate /* baud rate to use */ |
---|
| 145 | ) |
---|
| 146 | /*-------------------------------------------------------------------------*\ |
---|
| 147 | | Return Value: | |
---|
| 148 | | 0 on success, -1 and errno otherwise | |
---|
| 149 | \*=========================================================================*/ |
---|
| 150 | { |
---|
| 151 | boolean err_occurred = FALSE; |
---|
| 152 | rtems_libio_t *iop = NULL; |
---|
| 153 | struct termios act_termios; |
---|
| 154 | tcflag_t baudcode = B0; |
---|
| 155 | |
---|
| 156 | if (termios_printk_fd >= 0) { |
---|
| 157 | /* |
---|
| 158 | * already initialized |
---|
| 159 | */ |
---|
| 160 | return 0; |
---|
| 161 | } |
---|
| 162 | /* |
---|
| 163 | * translate baudrate into baud code |
---|
| 164 | */ |
---|
| 165 | switch(baudrate) { |
---|
| 166 | case 50: baudcode = B50; break; |
---|
| 167 | case 75: baudcode = B75; break; |
---|
| 168 | case 110: baudcode = B110; break; |
---|
| 169 | case 134: baudcode = B134; break; |
---|
| 170 | case 150: baudcode = B150; break; |
---|
| 171 | case 200: baudcode = B200; break; |
---|
| 172 | case 300: baudcode = B300; break; |
---|
| 173 | case 600: baudcode = B600; break; |
---|
| 174 | case 1200: baudcode = B1200; break; |
---|
| 175 | case 1800: baudcode = B1800; break; |
---|
| 176 | case 2400: baudcode = B2400; break; |
---|
| 177 | case 4800: baudcode = B4800; break; |
---|
| 178 | case 9600: baudcode = B9600; break; |
---|
| 179 | case 19200: baudcode = B19200; break; |
---|
| 180 | case 38400: baudcode = B38400; break; |
---|
| 181 | case 57600: baudcode = B57600; break; |
---|
| 182 | case 115200: baudcode = B115200; break; |
---|
| 183 | case 230400: baudcode = B230400; break; |
---|
| 184 | case 460800: baudcode = B460800; break; |
---|
| 185 | default : err_occurred = TRUE; errno = EINVAL; break; |
---|
| 186 | } |
---|
| 187 | /* |
---|
| 188 | * open device for serdbg operation |
---|
| 189 | */ |
---|
| 190 | if (!err_occurred && |
---|
| 191 | (dev_name != NULL) && |
---|
| 192 | (dev_name[0] != '\0')) { |
---|
| 193 | termios_printk_fd = open(dev_name,O_RDWR); |
---|
| 194 | if (termios_printk_fd < 0) { |
---|
| 195 | err_occurred = TRUE; |
---|
| 196 | } |
---|
| 197 | } |
---|
| 198 | /* |
---|
| 199 | * capture tty structure |
---|
| 200 | */ |
---|
| 201 | if (!err_occurred) { |
---|
| 202 | iop = &rtems_libio_iops[termios_printk_fd]; |
---|
| 203 | termios_printk_tty = iop->data1; |
---|
| 204 | } |
---|
| 205 | /* |
---|
| 206 | * set device baudrate |
---|
| 207 | * (and transp mode, this is not really needed) |
---|
| 208 | * ... |
---|
| 209 | */ |
---|
| 210 | /* |
---|
| 211 | * ... get fd settings |
---|
| 212 | */ |
---|
| 213 | if (!err_occurred && |
---|
| 214 | (0 != tcgetattr(termios_printk_fd,&act_termios))) { |
---|
| 215 | err_occurred = TRUE; |
---|
| 216 | } |
---|
| 217 | if (!err_occurred) { |
---|
| 218 | |
---|
| 219 | cfsetospeed(&act_termios,baudcode); |
---|
| 220 | cfsetispeed(&act_termios,baudcode); |
---|
| 221 | |
---|
| 222 | if (0 != tcsetattr(termios_printk_fd,TCSANOW,&act_termios)) { |
---|
| 223 | err_occurred = TRUE; |
---|
| 224 | } |
---|
| 225 | } |
---|
| 226 | if (!err_occurred) { |
---|
| 227 | BSP_output_char = termios_printk_outputchar; |
---|
| 228 | BSP_poll_char = termios_printk_inputchar; |
---|
| 229 | } |
---|
| 230 | return (err_occurred |
---|
| 231 | ? -1 |
---|
| 232 | : 0); |
---|
| 233 | } |
---|