mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-07 00:12:21 +08:00
Add "(void) param;" annotation to address unused parameter warnings. Found with GCC's warning -Wunused-parameter.
445 lines
11 KiB
C
445 lines
11 KiB
C
/***************************************************************************
|
|
*
|
|
* MODULE DESCRIPTION:
|
|
* This module implements the RTEMS drivers for the PC serial ports
|
|
* as /dev/ttyS1 for COM1 and /dev/ttyS2 as COM2. If one of the ports
|
|
* is used as the console, this driver would fail to initialize.
|
|
*
|
|
* This code was based on the console driver. It is based on the
|
|
* current termios framework. This is just a shell around the
|
|
* termios support.
|
|
*
|
|
* by: Rosimildo da Silva:
|
|
* rdasilva@connecttel.com
|
|
* http://www.connecttel.com
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
#include <bsp.h>
|
|
#include <bsp/irq.h>
|
|
#include <rtems/bspIo.h>
|
|
#include <rtems/libio.h>
|
|
#include <rtems/termiostypes.h>
|
|
#include <termios.h>
|
|
#include <uart.h>
|
|
#include <libcpu/cpuModel.h>
|
|
#include <bsp/tty_drv.h>
|
|
|
|
int BSP_poll_read(int);
|
|
|
|
/* Internal routines */
|
|
static int tty1_conSetAttr( int minor, const struct termios *t);
|
|
static int tty2_conSetAttr( int minor, const struct termios *t);
|
|
|
|
extern BSP_polling_getchar_function_type BSP_poll_char;
|
|
extern int BSPConsolePort;
|
|
extern void rtems_set_waiting_id_comx( int port, rtems_id id, rtems_event_set event );
|
|
|
|
/*
|
|
* TTYS1 - device driver INITIALIZE entry point.
|
|
*/
|
|
rtems_device_driver
|
|
tty1_initialize(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg)
|
|
{
|
|
(void) minor;
|
|
(void) arg;
|
|
|
|
rtems_status_code status;
|
|
|
|
/* Check if this port is not been used as console */
|
|
if( BSPConsolePort == BSP_UART_COM1 )
|
|
{
|
|
status = -1;
|
|
printk("TTYS1: port selected as console.\n");
|
|
rtems_fatal_error_occurred( status );
|
|
}
|
|
|
|
/*
|
|
* Set up TERMIOS
|
|
*/
|
|
rtems_termios_initialize();
|
|
|
|
/*
|
|
* Do device-specific initialization
|
|
*/
|
|
/* 9600-8-N-1, without hardware flow control */
|
|
BSP_uart_init( BSP_UART_COM1, 9600, CHR_8_BITS, 0, 0, 0 );
|
|
status = rtems_interrupt_handler_install(
|
|
BSP_UART_COM1_IRQ,
|
|
"tty_drv",
|
|
RTEMS_INTERRUPT_UNIQUE,
|
|
BSP_uart_termios_isr_com1,
|
|
NULL
|
|
);
|
|
assert(status == RTEMS_SUCCESSFUL);
|
|
/*
|
|
* Register the device
|
|
*/
|
|
status = rtems_io_register_name ("/dev/ttyS1", major, 0);
|
|
if (status != RTEMS_SUCCESSFUL)
|
|
{
|
|
printk("Error registering ttyS1 device!\n");
|
|
rtems_fatal_error_occurred (status);
|
|
}
|
|
printk("Device: /dev/ttyS1 initialized.\n");
|
|
return RTEMS_SUCCESSFUL;
|
|
} /* tty_initialize */
|
|
|
|
static int tty1_last_close(int major, int minor, void *arg)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
(void) arg;
|
|
|
|
rtems_status_code status;
|
|
|
|
status = rtems_interrupt_handler_remove(
|
|
BSP_UART_COM1_IRQ,
|
|
BSP_uart_termios_isr_com1,
|
|
NULL
|
|
);
|
|
assert(status == RTEMS_SUCCESSFUL);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* TTY1 - device driver OPEN entry point
|
|
*/
|
|
rtems_device_driver
|
|
tty1_open(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg)
|
|
{
|
|
rtems_status_code status;
|
|
#ifndef USE_TASK_DRIVEN
|
|
static rtems_termios_callbacks cb =
|
|
{
|
|
NULL, /* firstOpen */
|
|
tty1_last_close, /* lastClose */
|
|
NULL, /* poll read */
|
|
BSP_uart_termios_write_com1, /* write */
|
|
tty1_conSetAttr, /* setAttributes */
|
|
NULL, /* stopRemoteTx */
|
|
NULL, /* startRemoteTx */
|
|
TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */
|
|
};
|
|
#else
|
|
static rtems_termios_callbacks cb =
|
|
{
|
|
NULL, /* firstOpen */
|
|
NULL, /* lastClose */
|
|
BSP_uart_termios_read_com1, /* poll read */
|
|
BSP_uart_termios_write_com1, /* write */
|
|
tty1_conSetAttr, /* setAttributes */
|
|
NULL, /* stopRemoteTx */
|
|
NULL, /* startRemoteTx */
|
|
TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */
|
|
};
|
|
#endif
|
|
|
|
status = rtems_termios_open( major, minor, arg, &cb );
|
|
if(status != RTEMS_SUCCESSFUL)
|
|
{
|
|
printk("Error openning tty1 device\n");
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* Pass data area info down to driver
|
|
*/
|
|
BSP_uart_termios_set( BSP_UART_COM1,
|
|
((rtems_libio_open_close_args_t *)arg)->iop->data1 );
|
|
/* Enable interrupts on channel */
|
|
BSP_uart_intr_ctrl( BSP_UART_COM1, BSP_UART_INTR_CTRL_TERMIOS);
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*
|
|
* TTY - device driver CLOSE entry point
|
|
*/
|
|
rtems_device_driver
|
|
tty_close(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
|
|
return (rtems_termios_close (arg));
|
|
} /* tty_close */
|
|
|
|
/*
|
|
* TTY device driver READ entry point.
|
|
* Read characters from the tty device.
|
|
*/
|
|
rtems_device_driver
|
|
tty_read(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
|
|
return rtems_termios_read (arg);
|
|
} /* tty_read */
|
|
|
|
/*
|
|
* TTY device driver WRITE entry point.
|
|
* Write characters to the tty device.
|
|
*/
|
|
rtems_device_driver
|
|
tty_write(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
|
|
return rtems_termios_write (arg);
|
|
|
|
} /* tty_write */
|
|
|
|
/*
|
|
* Handle ioctl request. This is a generic internal
|
|
* routine to handle both devices.
|
|
*/
|
|
static rtems_device_driver tty_control( int port, void *arg )
|
|
{
|
|
(void) port;
|
|
|
|
rtems_libio_ioctl_args_t *args = arg;
|
|
switch( args->command )
|
|
{
|
|
default:
|
|
return rtems_termios_ioctl (arg);
|
|
break;
|
|
}
|
|
args->ioctl_return = 0;
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*
|
|
* Handle ioctl request for ttyS1.
|
|
*/
|
|
rtems_device_driver
|
|
tty1_control(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg
|
|
)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
|
|
return tty_control( BSP_UART_COM1, arg );
|
|
}
|
|
|
|
static int
|
|
conSetAttr(int port, int minor, const struct termios *t)
|
|
{
|
|
(void) minor;
|
|
|
|
unsigned long baud, databits, parity, stopbits;
|
|
|
|
baud = rtems_termios_baud_to_number(t->c_ospeed);
|
|
if ( baud > 115200 )
|
|
rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
|
|
|
|
if (t->c_cflag & PARENB) {
|
|
/* Parity is enabled */
|
|
if (t->c_cflag & PARODD) {
|
|
/* Parity is odd */
|
|
parity = PEN;
|
|
}
|
|
else {
|
|
/* Parity is even */
|
|
parity = PEN | EPS;
|
|
}
|
|
}
|
|
else {
|
|
/* No parity */
|
|
parity = 0;
|
|
}
|
|
|
|
switch (t->c_cflag & CSIZE) {
|
|
case CS5: databits = CHR_5_BITS; break;
|
|
case CS6: databits = CHR_6_BITS; break;
|
|
case CS7: databits = CHR_7_BITS; break;
|
|
default: /* just to avoid warnings -- all cases are covered */
|
|
case CS8: databits = CHR_8_BITS; break;
|
|
}
|
|
|
|
if (t->c_cflag & CSTOPB) {
|
|
/* 2 stop bits */
|
|
stopbits = STB;
|
|
}
|
|
else {
|
|
/* 1 stop bit */
|
|
stopbits = 0;
|
|
}
|
|
|
|
printk("Setting attributes, port=%X, baud=%d, linemode = 0x%02x\n",
|
|
port, (int) baud, (int) (databits | parity | stopbits) );
|
|
BSP_uart_set_attributes(port, baud, databits, parity, stopbits);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Handle ioctl request for ttyS2.
|
|
*/
|
|
static int
|
|
tty1_conSetAttr( int minor, const struct termios *t)
|
|
{
|
|
return conSetAttr( BSP_UART_COM1, minor, t );
|
|
}
|
|
|
|
/*
|
|
* TTY2 device driver INITIALIZE entry point.
|
|
*/
|
|
rtems_device_driver
|
|
tty2_initialize(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg)
|
|
{
|
|
(void) minor;
|
|
(void) arg;
|
|
|
|
rtems_status_code status;
|
|
|
|
/* Check if this port is not been used as console */
|
|
if( BSPConsolePort == BSP_UART_COM2 )
|
|
{
|
|
status = -1;
|
|
printk("TTY2: port selected as console.\n");
|
|
rtems_fatal_error_occurred( status );
|
|
}
|
|
|
|
/*
|
|
* Set up TERMIOS
|
|
*/
|
|
rtems_termios_initialize();
|
|
|
|
/*
|
|
* Do device-specific initialization
|
|
*/
|
|
/* 9600-8-N-1, without hardware flow control */
|
|
BSP_uart_init( BSP_UART_COM2, 9600, CHR_8_BITS, 0, 0, 0);
|
|
status = rtems_interrupt_handler_install(
|
|
BSP_UART_COM2_IRQ,
|
|
"tty_drv",
|
|
RTEMS_INTERRUPT_UNIQUE,
|
|
BSP_uart_termios_isr_com2,
|
|
NULL
|
|
);
|
|
assert(status == RTEMS_SUCCESSFUL);
|
|
|
|
/*
|
|
* Register the device
|
|
*/
|
|
status = rtems_io_register_name ("/dev/ttyS2", major, 0);
|
|
if (status != RTEMS_SUCCESSFUL)
|
|
{
|
|
printk("Error registering tty2 device!\n");
|
|
rtems_fatal_error_occurred (status);
|
|
}
|
|
printk("Device: /dev/ttyS2 initialized.\n");
|
|
return RTEMS_SUCCESSFUL;
|
|
} /* tty_initialize */
|
|
|
|
static int tty2_last_close(int major, int minor, void *arg)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
(void) arg;
|
|
|
|
rtems_status_code status;
|
|
|
|
status = rtems_interrupt_handler_remove(
|
|
BSP_UART_COM2_IRQ,
|
|
BSP_uart_termios_isr_com2,
|
|
NULL
|
|
);
|
|
assert(status == RTEMS_SUCCESSFUL);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* TTY2 device driver OPEN entry point
|
|
*/
|
|
rtems_device_driver
|
|
tty2_open(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg)
|
|
{
|
|
rtems_status_code status;
|
|
#ifndef USE_TASK_DRIVEN
|
|
static rtems_termios_callbacks cb =
|
|
{
|
|
NULL, /* firstOpen */
|
|
tty2_last_close, /* lastClose */
|
|
NULL, /* poll read */
|
|
BSP_uart_termios_write_com2, /* write */
|
|
tty2_conSetAttr, /* setAttributes */
|
|
NULL, /* stopRemoteTx */
|
|
NULL, /* startRemoteTx */
|
|
TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */
|
|
};
|
|
#else
|
|
static rtems_termios_callbacks cb =
|
|
{
|
|
NULL, /* firstOpen */
|
|
NULL, /* lastClose */
|
|
BSP_uart_termios_read_com2, /* poll read */
|
|
BSP_uart_termios_write_com2, /* write */
|
|
tty2_conSetAttr, /* setAttributes */
|
|
NULL, /* stopRemoteTx */
|
|
NULL, /* startRemoteTx */
|
|
TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */
|
|
};
|
|
#endif
|
|
|
|
status = rtems_termios_open (major, minor, arg, &cb);
|
|
if(status != RTEMS_SUCCESSFUL)
|
|
{
|
|
printk("Error openning tty1 device\n");
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* Pass data area info down to driver
|
|
*/
|
|
BSP_uart_termios_set( BSP_UART_COM2,
|
|
((rtems_libio_open_close_args_t *)arg)->iop->data1 );
|
|
/* Enable interrupts on channel */
|
|
BSP_uart_intr_ctrl( BSP_UART_COM2, BSP_UART_INTR_CTRL_TERMIOS);
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*
|
|
* Handle ioctl request for TTY2
|
|
*/
|
|
rtems_device_driver
|
|
tty2_control(rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg
|
|
)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
|
|
return tty_control( BSP_UART_COM2, arg );
|
|
}
|
|
|
|
static int
|
|
tty2_conSetAttr( int minor, const struct termios *t)
|
|
{
|
|
return conSetAttr( BSP_UART_COM2, minor, t );
|
|
}
|