File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <stdlib.h>
0024 #include <assert.h>
0025 #include <inttypes.h>
0026
0027 #include <bsp.h>
0028 #include <bsp/irq.h>
0029 #include <rtems/bspIo.h>
0030 #include <rtems/libio.h>
0031 #include <rtems/console.h>
0032 #include <rtems/termiostypes.h>
0033 #include <termios.h>
0034 #include <bsp/uart.h>
0035 #include <rtems/bspIo.h> /* printk */
0036
0037
0038
0039
0040
0041
0042
0043
0044 int BSPConsolePort = BSP_CONSOLE_PORT;
0045
0046 int BSPBaseBaud = BSP_UART_BAUD_BASE;
0047
0048
0049
0050
0051
0052
0053 #if defined(USE_POLLED_IO)
0054 #define TERMIOS_OUTPUT_MODE TERMIOS_POLLED
0055 #elif defined(USE_TASK_DRIVEN_IO)
0056 #define TERMIOS_OUTPUT_MODE TERMIOS_TASK_DRIVEN
0057 #else
0058 #define TERMIOS_OUTPUT_MODE TERMIOS_IRQ_DRIVEN
0059 #endif
0060
0061
0062
0063
0064
0065 static int conSetAttr(int minor, const struct termios *);
0066
0067 typedef struct TtySTblRec_ {
0068 char *name;
0069 rtems_irq_hdl isr;
0070 } TtySTblRec, *TtySTbl;
0071
0072 static TtySTblRec ttyS[]={
0073 { "/dev/ttyS0",
0074 #ifdef BSP_UART_IOBASE_COM1
0075 BSP_uart_termios_isr_com1
0076 #else
0077 0
0078 #endif
0079 },
0080 { "/dev/ttyS1",
0081 #ifdef BSP_UART_IOBASE_COM2
0082 BSP_uart_termios_isr_com2
0083 #else
0084 0
0085 #endif
0086 },
0087 };
0088
0089
0090
0091
0092
0093
0094 rtems_device_driver console_initialize(
0095 rtems_device_major_number major,
0096 rtems_device_minor_number minor,
0097 void *arg
0098 )
0099 {
0100 rtems_status_code status;
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110 rtems_termios_initialize();
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) {
0121 char *nm;
0122
0123
0124
0125 if ( ! ttyS[minor].isr )
0126 continue;
0127
0128
0129
0130 status = rtems_io_register_name ((nm=ttyS[minor].name), major, minor);
0131 if ( RTEMS_SUCCESSFUL==status && BSPConsolePort == minor) {
0132 printk("Registering /dev/console as minor %" PRIu32 " (==%s)\n",
0133 minor,
0134 ttyS[minor].name);
0135
0136 status = rtems_io_register_name ( (nm="/dev/console"), major, minor);
0137 }
0138
0139 if (status != RTEMS_SUCCESSFUL) {
0140 printk("Error registering %s!\n",nm);
0141 rtems_fatal_error_occurred (status);
0142 }
0143 }
0144
0145 return RTEMS_SUCCESSFUL;
0146 }
0147
0148 #if !defined(USE_POLLED_IO)
0149 static int console_first_open(int major, int minor, void *arg)
0150 {
0151 rtems_status_code status;
0152
0153
0154 assert( minor>=0 && minor < sizeof(ttyS)/sizeof(ttyS[0]) && ttyS[minor].isr );
0155
0156
0157 BSP_uart_init(minor, BSP_CONSOLE_BAUD, 0);
0158 status = BSP_uart_install_isr(minor, ttyS[minor].isr);
0159 if (!status) {
0160 printk("Error installing serial console interrupt handler for '%s'!\n",
0161 ttyS[minor].name);
0162 rtems_fatal_error_occurred(status);
0163 }
0164
0165
0166
0167
0168 BSP_uart_termios_set(minor, ((rtems_libio_open_close_args_t *)arg)->iop->data1);
0169
0170
0171 BSP_uart_intr_ctrl(minor, BSP_UART_INTR_CTRL_TERMIOS);
0172
0173 return 0;
0174 }
0175 #endif
0176
0177 #if !defined(USE_POLLED_IO)
0178 static int console_last_close(int major, int minor, void *arg)
0179 {
0180 BSP_uart_remove_isr(minor, ttyS[minor].isr);
0181 return 0;
0182 }
0183 #endif
0184
0185
0186
0187
0188 rtems_device_driver console_open(
0189 rtems_device_major_number major,
0190 rtems_device_minor_number minor,
0191 void *arg
0192 )
0193 {
0194 rtems_status_code status;
0195 static rtems_termios_callbacks cb =
0196 #if defined(USE_POLLED_IO)
0197 {
0198 NULL,
0199 NULL,
0200 NULL,
0201 BSP_uart_termios_write_polled,
0202 conSetAttr,
0203 NULL,
0204 NULL,
0205 TERMIOS_POLLED
0206 };
0207 #else
0208 {
0209 console_first_open,
0210 console_last_close,
0211 #ifdef USE_TASK_DRIVEN_IO
0212 BSP_uart_termios_read_com,
0213 #else
0214 NULL,
0215 #endif
0216 BSP_uart_termios_write_com,
0217 conSetAttr,
0218 NULL,
0219 NULL,
0220 TERMIOS_OUTPUT_MODE
0221 };
0222 #endif
0223
0224 status = rtems_termios_open (major, minor, arg, &cb);
0225
0226 if (status != RTEMS_SUCCESSFUL) {
0227 printk("Error opening console device\n");
0228 return status;
0229 }
0230
0231 return RTEMS_SUCCESSFUL;
0232 }
0233
0234
0235
0236
0237 rtems_device_driver
0238 console_close(
0239 rtems_device_major_number major,
0240 rtems_device_minor_number minor,
0241 void *arg
0242 )
0243 {
0244 rtems_device_driver res = RTEMS_SUCCESSFUL;
0245
0246 res = rtems_termios_close (arg);
0247
0248 return res;
0249 }
0250
0251
0252
0253
0254
0255
0256 rtems_device_driver console_read(
0257 rtems_device_major_number major,
0258 rtems_device_minor_number minor,
0259 void *arg
0260 )
0261 {
0262 return rtems_termios_read (arg);
0263 }
0264
0265
0266
0267
0268
0269
0270 rtems_device_driver console_write(
0271 rtems_device_major_number major,
0272 rtems_device_minor_number minor,
0273 void *arg
0274 )
0275 {
0276 return rtems_termios_write (arg);
0277 }
0278
0279
0280
0281
0282 rtems_device_driver console_control(
0283 rtems_device_major_number major,
0284 rtems_device_minor_number minor,
0285 void *arg
0286 )
0287 {
0288
0289 #if defined(BIOCSETBREAKCB) && defined(BIOCGETBREAKCB)
0290 rtems_libio_ioctl_args_t *ioa=arg;
0291 switch (ioa->command) {
0292 case BIOCSETBREAKCB: return BSP_uart_set_break_cb(minor, ioa);
0293 case BIOCGETBREAKCB: return BSP_uart_get_break_cb(minor, ioa);
0294 default: break;
0295 }
0296 #endif
0297 return rtems_termios_ioctl (arg);
0298 }
0299
0300 static int conSetAttr(
0301 int minor,
0302 const struct termios *t
0303 )
0304 {
0305 rtems_termios_baud_t baud;
0306
0307 baud = rtems_termios_baud_to_number(t->c_ospeed);
0308 if ( baud > 115200 )
0309 rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
0310
0311 BSP_uart_set_baud(minor, baud);
0312
0313 return 0;
0314 }