📄 termiostty.c
字号:
//==========================================================================//// termiostty.c//// POSIX Termios compatible TTY I/O driver////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2003 Jonathan Larmour// Copyright (C) 2003 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): jlarmour// Contributors: gthomas// Date: 2000-07-22// Purpose: Device driver for termios emulation tty I/O, layered on// top of serial I/O// Description: TODO: Add OPOST support for 80x25 (configurable) windows// TODO: Support _POSIX_VDISABLE////####DESCRIPTIONEND####////==========================================================================// CONFIGURATION#include <pkgconf/io_serial.h>#ifdef CYGPKG_IO_SERIAL_TERMIOS// INCLUDES#include <cyg/infra/cyg_type.h> // Common types #include <cyg/infra/cyg_ass.h> // Assertion support#include <cyg/infra/cyg_trac.h> // Tracing support#include <cyg/io/io.h>#include <cyg/io/devtab.h>#include <cyg/io/serialio.h> // public serial API#include <termios.h> // Termios header#include <cyg/hal/drv_api.h>#include <stdlib.h> // malloc#include <string.h>#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS# include <signal.h>#endif//==========================================================================// FUNCTION PROTOTYPESstatic booltermios_init(struct cyg_devtab_entry *tab);static Cyg_ErrNotermios_lookup(struct cyg_devtab_entry **tab, struct cyg_devtab_entry *sub_tab, const char *name);static Cyg_ErrNotermios_write(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len);static Cyg_ErrNotermios_read(cyg_io_handle_t handle, void *buf, cyg_uint32 *len);static cyg_booltermios_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info);static Cyg_ErrNo termios_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf, cyg_uint32 *len);static Cyg_ErrNo termios_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf, cyg_uint32 *len);//==========================================================================// TYPE DEFINITIONSstruct termios_private_info { struct termios termios; cyg_io_handle_t dev_handle; cyg_drv_mutex_t lock; cyg_bool init; cyg_uint8 *errbuf; cyg_uint8 *errbufpos; cyg_uint32 errbufsize;};typedef struct { struct termios *termios_p; int optact;} setattr_struct;//==========================================================================// STATIC OBJECTSstatic DEVIO_TABLE(termios_devio, termios_write, termios_read, termios_select, termios_get_config, termios_set_config);#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS0static struct termios_private_info termios_private_info0;DEVTAB_ENTRY(termios_io0, "/dev/termios0", CYGDAT_IO_SERIAL_TERMIOS_TERMIOS0_DEV, &termios_devio, termios_init, termios_lookup, &termios_private_info0);#endif#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS1static struct termios_private_info termios_private_info1;DEVTAB_ENTRY(termios_io1, "/dev/termios1", CYGDAT_IO_SERIAL_TERMIOS_TERMIOS1_DEV, &termios_devio, termios_init, termios_lookup, &termios_private_info1);#endif#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS2static struct termios_private_info termios_private_info2;DEVTAB_ENTRY(termios_io2, "/dev/termios2", CYGDAT_IO_SERIAL_TERMIOS_TERMIOS2_DEV, &termios_devio, termios_init, termios_lookup, &termios_private_info2);#endifstatic const cc_t c_cc_init[ NCCS ] = { 0x04, /* EOF == ^D */ 0, /* EOL */ 0x08, /* ERASE = BS ; NB DEL=0x7f */ 0x03, /* INTR = ^C */ 0x15, /* KILL = ^U */ 0, /* MIN = 0 */ 0x1c, /* QUIT = ^\ */ 0x1a, /* SUSP = ^Z ; NB ignored in this impl - no job control */ 0, /* TIME = 0 */#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE CYGDAT_IO_SERIAL_FLOW_CONTROL_XON_CHAR, CYGDAT_IO_SERIAL_FLOW_CONTROL_XOFF_CHAR,#else 17, 19,#endif};// map eCos bitrates to POSIX bitrates.static speed_t ecosbaud2posixbaud[] = { 0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B2400, B3600, B4800, B7200, B9600, B14400, B19200, B38400, B57600, B115200, B230400 };// map POSIX bitrates to eCos bitrates.static cyg_serial_baud_rate_t posixbaud2ecosbaud[] = { 0, CYGNUM_SERIAL_BAUD_50, CYGNUM_SERIAL_BAUD_75, CYGNUM_SERIAL_BAUD_110, CYGNUM_SERIAL_BAUD_134_5, CYGNUM_SERIAL_BAUD_150, CYGNUM_SERIAL_BAUD_200, CYGNUM_SERIAL_BAUD_300, CYGNUM_SERIAL_BAUD_600, CYGNUM_SERIAL_BAUD_1200, CYGNUM_SERIAL_BAUD_1800, CYGNUM_SERIAL_BAUD_2400, CYGNUM_SERIAL_BAUD_3600, CYGNUM_SERIAL_BAUD_4800, CYGNUM_SERIAL_BAUD_7200, CYGNUM_SERIAL_BAUD_9600, CYGNUM_SERIAL_BAUD_14400, CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_BAUD_57600, CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_BAUD_230400 };//==========================================================================// FUNCTIONSstatic __inline__ speed_tmap_ecosbaud_to_posixbaud( cyg_serial_baud_rate_t ebaud ){ if ( ebaud > (sizeof(ecosbaud2posixbaud) / sizeof(speed_t)) ) return 0; return ecosbaud2posixbaud[ ebaud ];}static __inline__ cyg_serial_baud_rate_tmap_posixbaud_to_ecosbaud( speed_t pbaud ){ if ( pbaud > (sizeof(posixbaud2ecosbaud)/sizeof(cyg_serial_baud_rate_t)) ) return 0; return posixbaud2ecosbaud[ pbaud ];}//==========================================================================// real_termios_init is used to initialize the termios structure. This is// called at lookup time, and not from termios_init() because it needs// to query the serial device which may not be set up yet at that point// in termios_init()#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS# define C_IFLAG_INIT (ICRNL|IGNBRK|BRKINT)#else# define C_IFLAG_INIT (ICRNL|IGNBRK)#endif#define C_OFLAG_INIT (ONLCR)#define C_CFLAG_INIT (CREAD)#define C_LFLAG_INIT (ECHO|ECHOE|ECHOK|ICANON)static Cyg_ErrNoreal_termios_init( struct termios_private_info *priv ){ Cyg_ErrNo res; struct termios *t; cyg_serial_info_t dev_conf; cyg_serial_buf_info_t dev_buf_conf; cyg_uint32 len = sizeof( dev_conf ); CYG_REPORT_FUNCTYPE("returning %d"); CYG_REPORT_FUNCARG1XV( priv ); CYG_CHECK_DATA_PTRC( priv ); t = &priv->termios; // Get info from driver res = cyg_io_get_config( priv->dev_handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &dev_conf, &len ); if ( ENOERR == res ) { len = sizeof( dev_buf_conf ); res = cyg_io_get_config( priv->dev_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO, &dev_buf_conf, &len ); } priv->errbuf = (cyg_uint8 *)malloc( dev_buf_conf.rx_bufsize ); if ( NULL == priv->errbuf ) res = ENOMEM; // FIXME: Are we allowed to do this? priv->errbufpos = priv->errbuf; priv->errbufsize = dev_buf_conf.rx_bufsize; if ( ENOERR != res ) { CYG_REPORT_RETVAL( res ); return res; } // we only support symmetric baud rates t->c_ispeed = t->c_ospeed = map_ecosbaud_to_posixbaud( dev_conf.baud ); t->c_iflag = C_IFLAG_INIT; t->c_oflag = C_OFLAG_INIT; t->c_cflag = C_CFLAG_INIT; t->c_lflag = C_LFLAG_INIT; memcpy( t->c_cc, c_cc_init, sizeof( t->c_cc ) ); switch ( dev_conf.parity ) { case CYGNUM_SERIAL_PARITY_NONE: t->c_iflag |= IGNPAR; break; case CYGNUM_SERIAL_PARITY_ODD: t->c_cflag |= PARODD; // DROPTHROUGH case CYGNUM_SERIAL_PARITY_EVEN: t->c_iflag |= PARENB; break; default: CYG_FAIL( "Unsupported default parity" ); break; } switch( dev_conf.word_length ) { case CYGNUM_SERIAL_WORD_LENGTH_5: t->c_cflag |= CS5; break; case CYGNUM_SERIAL_WORD_LENGTH_6: t->c_cflag |= CS6; break; case CYGNUM_SERIAL_WORD_LENGTH_7: t->c_cflag |= CS7; break; case CYGNUM_SERIAL_WORD_LENGTH_8: t->c_cflag |= CS8; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -