📄 termiostty.c
字号:
default: CYG_FAIL( "Unsupported word length" ); break; } switch ( dev_conf.stop ) { case CYGNUM_SERIAL_STOP_1: // Don't need to do anything break; case CYGNUM_SERIAL_STOP_2: t->c_cflag |= CSTOPB; break; default: CYG_FAIL( "Unsupported number of stop bits" ); break; } switch ( dev_conf.flags ) { case CYGNUM_SERIAL_FLOW_RTSCTS_RX: t->c_cflag |= CRTSCTS; // drop through case CYGNUM_SERIAL_FLOW_XONXOFF_RX: t->c_iflag |= IXOFF; break; case CYGNUM_SERIAL_FLOW_RTSCTS_TX: t->c_cflag |= CRTSCTS; // drop through case CYGNUM_SERIAL_FLOW_XONXOFF_TX: t->c_iflag |= IXON; break; default: // Ignore flags we don't grok break; } return ENOERR;} // real_termios_init()//==========================================================================// set_attr() actually enacts the termios config. We come in here with// the mutex in priv locked//// Possible deviation from standard: POSIX says we should enact which ever// bits we can and only return EINVAL when none of them can be performed// Rather than tracking whether *none* of them worked, instead we just// always claim success. At the very least, setting c_cc is never to// fail so I'm not sure if this is really non-standard or not!static Cyg_ErrNoset_attr( struct termios *t, struct termios_private_info *priv ){ Cyg_ErrNo res = ENOERR; cyg_serial_info_t dev_conf, new_dev_conf; cyg_uint32 len = sizeof( dev_conf ); cc_t *tempcc = &priv->termios.c_cc[0]; struct termios *ptermios = &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 ) return res; // We need to set up each facet of config to change one by one because // POSIX says we should try and change as much of the config as possible // This is tedious and has to be done by steam :-( if ( t->c_ospeed != ptermios->c_ospeed ) { new_dev_conf = dev_conf; new_dev_conf.baud = map_posixbaud_to_ecosbaud( t->c_ospeed ); if ( 0 != new_dev_conf.baud ) { len = sizeof( new_dev_conf ); res = cyg_io_set_config( priv->dev_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &new_dev_conf, &len ); if ( ENOERR == res ) { // It worked, so update dev_conf to reflect the new state dev_conf.baud = new_dev_conf.baud; // and termios ptermios->c_ispeed = t->c_ospeed; ptermios->c_ospeed = t->c_ospeed; } } } if ( (t->c_cflag & CSTOPB) != (ptermios->c_cflag & CSTOPB) ) { new_dev_conf = dev_conf; if ( t->c_cflag & CSTOPB ) new_dev_conf.stop = CYGNUM_SERIAL_STOP_2; else new_dev_conf.stop = CYGNUM_SERIAL_STOP_1; len = sizeof( new_dev_conf ); res = cyg_io_set_config( priv->dev_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &new_dev_conf, &len ); if ( ENOERR == res ) { // It worked, so update dev_conf to reflect the new state dev_conf.stop = new_dev_conf.stop; // and termios ptermios->c_cflag &= ~CSTOPB; ptermios->c_cflag |= t->c_cflag & CSTOPB; } } if ( ((t->c_cflag & PARENB) != (ptermios->c_cflag & PARENB)) || ((t->c_cflag & PARODD) != (ptermios->c_cflag & PARODD)) ) { new_dev_conf = dev_conf; if ( t->c_cflag & PARENB ) if ( t->c_cflag & PARODD ) new_dev_conf.parity = CYGNUM_SERIAL_PARITY_ODD; else new_dev_conf.parity = CYGNUM_SERIAL_PARITY_EVEN; else new_dev_conf.parity = CYGNUM_SERIAL_PARITY_NONE; len = sizeof( new_dev_conf ); res = cyg_io_set_config( priv->dev_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &new_dev_conf, &len ); if ( ENOERR == res ) { // It worked, so update dev_conf to reflect the new state dev_conf.parity = new_dev_conf.parity; // and termios ptermios->c_cflag &= ~(PARENB|PARODD); ptermios->c_cflag |= t->c_cflag & (PARENB|PARODD); } } if ( (t->c_cflag & CSIZE) != (ptermios->c_cflag & CSIZE) ) { new_dev_conf = dev_conf; switch ( t->c_cflag & CSIZE ) { case CS5: new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_5; break; case CS6: new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_6; break; case CS7: new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_7; break; case CS8: new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_8; break; } len = sizeof( new_dev_conf ); res = cyg_io_set_config( priv->dev_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &new_dev_conf, &len ); if ( ENOERR == res ) { // It worked, so update dev_conf to reflect the new state dev_conf.word_length = new_dev_conf.word_length; // and termios ptermios->c_cflag &= ~CSIZE; ptermios->c_cflag |= t->c_cflag & CSIZE; } } if ( (t->c_cflag & IXOFF) != (ptermios->c_cflag & IXOFF) ) { new_dev_conf = dev_conf; new_dev_conf.flags &= ~(CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_RTSCTS_RX); if ( t->c_cflag & IXOFF ) if ( t->c_cflag & CRTSCTS) new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX; else new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX; else new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_NONE; len = sizeof( new_dev_conf ); res = cyg_io_set_config( priv->dev_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &new_dev_conf, &len ); if ( ENOERR == res ) { // It worked, so update dev_conf to reflect the new state dev_conf.flags = new_dev_conf.flags; // and termios ptermios->c_cflag &= ~(IXOFF|CRTSCTS); ptermios->c_cflag |= t->c_cflag & (IXOFF|CRTSCTS); } } if ( (t->c_cflag & IXON) != (ptermios->c_cflag & IXON) ) { new_dev_conf = dev_conf; new_dev_conf.flags &= ~(CYGNUM_SERIAL_FLOW_XONXOFF_TX|CYGNUM_SERIAL_FLOW_RTSCTS_TX); if ( t->c_cflag & IXON ) if ( t->c_cflag & CRTSCTS) new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_TX; else new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_TX; else new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_NONE; len = sizeof( new_dev_conf ); res = cyg_io_set_config( priv->dev_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &new_dev_conf, &len ); if ( ENOERR == res ) { // It worked, so update dev_conf to reflect the new state dev_conf.flags = new_dev_conf.flags; // and termios ptermios->c_cflag &= ~(IXON|CRTSCTS); ptermios->c_cflag |= t->c_cflag & (IXON|CRTSCTS); } } // Input/Output processing flags can just be set as we grok them all // with few exceptions (see lflags below) ptermios->c_iflag &= ~(BRKINT|ICRNL|IGNBRK|IGNCR|IGNPAR|INLCR|INPCK| ISTRIP|PARMRK); ptermios->c_iflag |= t->c_iflag & (#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS BRKINT|#endif ICRNL|IGNBRK|IGNCR|IGNPAR| INLCR|INPCK|ISTRIP|PARMRK ); ptermios->c_oflag &= ~(OPOST|ONLCR); ptermios->c_oflag |= t->c_oflag & (OPOST|ONLCR); ptermios->c_cflag &= ~(CLOCAL|CREAD|HUPCL); ptermios->c_cflag |= t->c_cflag & (CLOCAL|CREAD|HUPCL); ptermios->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON| IEXTEN|ISIG|NOFLSH|TOSTOP); // Note we don't support IEXTEN nor TOSTOP so we don't set them ptermios->c_lflag |= t->c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ICANON|#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS ISIG|#endif NOFLSH); // control characters. We don't support changing of VSTART, VSTOP, // VTIME or VSUSP though tempcc[VEOF] = t->c_cc[VEOF]; tempcc[VEOL] = t->c_cc[VEOL]; tempcc[VERASE] = t->c_cc[VERASE]; tempcc[VINTR] = t->c_cc[VINTR]; tempcc[VKILL] = t->c_cc[VKILL]; tempcc[VMIN] = t->c_cc[VMIN]; tempcc[VQUIT] = t->c_cc[VQUIT]; return res;}//==========================================================================static bool termios_init(struct cyg_devtab_entry *tab){ // can't initialize the termios structure because we can't // query the serial driver yet. Wait until lookup time. return true;} // termios_init()//==========================================================================static Cyg_ErrNo termios_lookup(struct cyg_devtab_entry **tab, struct cyg_devtab_entry *sub_tab, const char *name){ cyg_io_handle_t chan = (cyg_io_handle_t)sub_tab; struct termios_private_info *priv = (struct termios_private_info *)(*tab)->priv; Cyg_ErrNo err = ENOERR; if ( !priv->init ) { cyg_drv_mutex_lock( &priv->lock ); if ( !priv->init ) { // retest as we may have been pre-empted priv->dev_handle = chan; err = real_termios_init( priv ); } cyg_drv_mutex_unlock( &priv->lock ); } return err;}//==========================================================================#define WRITE_BUFSIZE 100 // FIXME: ->CDL// #define MAX_CANON 64 FIXME: relevance?static Cyg_ErrNo termios_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len){ cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle; struct termios_private_info *priv = (struct termios_private_info *)t->priv; cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle; cyg_int32 xbufsize, input_bytes_read; cyg_uint8 xbuf[WRITE_BUFSIZE]; cyg_uint8 *buf = (cyg_uint8 *)_buf; Cyg_ErrNo res; xbufsize = input_bytes_read = 0; while (input_bytes_read++ < *len) { if ( (*buf == '\n') && (priv->termios.c_oflag & (OPOST|ONLCR)) ) { xbuf[xbufsize++] = '\r'; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -