📄 serialport.cpp
字号:
SerialPort::SerialPortImpl::~SerialPortImpl(){ // // Close the serial port if it is open. // if ( this->IsOpen() ) { this->Close() ; } return ;}inlinevoidSerialPort::SerialPortImpl::Open() throw( SerialPort::OpenFailed, SerialPort::AlreadyOpen ){ /* * Throw an exception if the port is already open. */ if ( this->IsOpen() ) { throw SerialPort::AlreadyOpen( ERR_MSG_PORT_ALREADY_OPEN ) ; } /* * Try to open the serial port and throw an exception if we are * not able to open it. * * :FIXME: Exception thrown by this method after opening the * serial port might leave the port open even though mIsOpen * is false. We need to close the port before throwing an * exception or close it next time this method is called before * calling open() again. */ mFileDescriptor = open( mSerialPortName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK ) ; if ( mFileDescriptor < 0 ) { throw SerialPort::OpenFailed( strerror(errno) ) ; } PosixSignalDispatcher& signal_dispatcher = PosixSignalDispatcher::Instance() ; signal_dispatcher.AttachHandler( SIGIO, *this ) ; /* * Direct all SIGIO and SIGURG signals for the port to the current * process. */ if ( fcntl( mFileDescriptor, F_SETOWN, getpid() ) < 0 ) { throw SerialPort::OpenFailed( strerror(errno) ) ; } /* * Enable asynchronous I/O with the serial port. */ if ( fcntl( mFileDescriptor, F_SETFL, FASYNC ) < 0 ) { throw SerialPort::OpenFailed( strerror(errno) ) ; } /* * Save the current settings of the serial port so they can be * restored when the serial port is closed. */ if ( tcgetattr( mFileDescriptor, &mOldPortSettings ) < 0 ) { throw SerialPort::OpenFailed( strerror(errno) ) ; } // // Start assembling the new port settings. // termios port_settings ; bzero( &port_settings, sizeof( port_settings ) ) ; // // Enable the receiver (CREAD) and ignore modem control lines // (CLOCAL). // port_settings.c_cflag |= CREAD | CLOCAL ; // // Set the VMIN and VTIME parameters to zero by default. VMIN is // the minimum number of characters for non-canonical read and // VTIME is the timeout in deciseconds for non-canonical // read. Setting both of these parameters to zero implies that a // read will return immediately only giving the currently // available characters. // port_settings.c_cc[ VMIN ] = 0 ; port_settings.c_cc[ VTIME ] = 0 ; /* * Flush the input buffer associated with the port. */ if ( tcflush( mFileDescriptor, TCIFLUSH ) < 0 ) { throw SerialPort::OpenFailed( strerror(errno) ) ; } /* * Write the new settings to the port. */ if ( tcsetattr( mFileDescriptor, TCSANOW, &port_settings ) < 0 ) { throw SerialPort::OpenFailed( strerror(errno) ) ; } /* * The serial port is open at this point. */ mIsOpen = true ; return ;}inlineboolSerialPort::SerialPortImpl::IsOpen() const{ return mIsOpen ;}inlinevoidSerialPort::SerialPortImpl::Close() throw( SerialPort::NotOpen ){ // // Throw an exception if the serial port is not open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // PosixSignalDispatcher& signal_dispatcher = PosixSignalDispatcher::Instance() ; signal_dispatcher.DetachHandler( SIGIO, *this ) ; // // Restore the old settings of the port. // tcsetattr( mFileDescriptor, TCSANOW, &mOldPortSettings ) ; // // Close the serial port file descriptor. // close(mFileDescriptor) ; // // The port is not open anymore. // mIsOpen = false ; // return ;}inlinevoidSerialPort::SerialPortImpl::SetBaudRate( const SerialPort::BaudRate baudRate ) throw( SerialPort::NotOpen, SerialPort::UnsupportedBaudRate, std::invalid_argument, std::runtime_error ){ // // Throw an exception if the serial port is not open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // // Get the current settings of the serial port. // termios port_settings ; if ( tcgetattr( mFileDescriptor, &port_settings ) < 0 ) { throw std::runtime_error( strerror(errno) ) ; } // // Set the baud rate for both input and output. // if ( ( cfsetispeed( &port_settings, baudRate ) < 0 ) || ( cfsetospeed( &port_settings, baudRate ) < 0 ) ) { // // If any of the settings fail, we abandon this method. // throw SerialPort::UnsupportedBaudRate( ERR_MSG_UNSUPPORTED_BAUD ) ; } // // Set the new attributes of the serial port. // if ( tcsetattr( mFileDescriptor, TCSANOW, &port_settings ) < 0 ) { throw SerialPort::UnsupportedBaudRate( strerror(errno) ) ; } return ;}inlineSerialPort::BaudRateSerialPort::SerialPortImpl::GetBaudRate() const throw( SerialPort::NotOpen, std::runtime_error ){ // // Make sure that the serial port is open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // // Read the current serial port settings. // termios port_settings ; if ( tcgetattr( mFileDescriptor, &port_settings ) < 0 ) { throw std::runtime_error( strerror(errno) ) ; } // // Obtain the input baud rate from the current settings. // return SerialPort::BaudRate(cfgetispeed( &port_settings )) ;}inlinevoidSerialPort::SerialPortImpl::SetCharSize( const SerialPort::CharacterSize charSize ) throw( SerialPort::NotOpen, std::invalid_argument, std::runtime_error ){ // // Make sure that the serial port is open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // // Get the current settings of the serial port. // termios port_settings ; if ( tcgetattr( mFileDescriptor, &port_settings ) < 0 ) { throw std::runtime_error( strerror(errno) ) ; } // // Set the character size. // port_settings.c_cflag &= ~CSIZE ; port_settings.c_cflag |= charSize ; // // Apply the modified settings. // if ( tcsetattr( mFileDescriptor, TCSANOW, &port_settings ) < 0 ) { throw std::invalid_argument( strerror(errno) ) ; } return ;}inlineSerialPort::CharacterSizeSerialPort::SerialPortImpl::GetCharSize() const throw( SerialPort::NotOpen, std::runtime_error ){ // // Make sure that the serial port is open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // // Get the current port settings. // termios port_settings ; if ( tcgetattr( mFileDescriptor, &port_settings ) < 0 ) { throw std::runtime_error( strerror(errno) ) ; } // // Read the character size from the setttings. // return SerialPort::CharacterSize( port_settings.c_cflag & CSIZE ) ;}inlinevoidSerialPort::SerialPortImpl::SetParity( const SerialPort::Parity parityType ) throw( SerialPort::NotOpen, std::invalid_argument, std::runtime_error ){ // // Make sure that the serial port is open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // // Get the current port settings. // termios port_settings ; if ( tcgetattr( mFileDescriptor, &port_settings ) < 0 ) { throw std::runtime_error( strerror(errno) ) ; } // // Set the parity type depending on the specified parameter. // switch( parityType ) { case SerialPort::PARITY_EVEN: port_settings.c_cflag |= PARENB ; port_settings.c_cflag &= ~PARODD ; port_settings.c_iflag |= INPCK ; break ; case SerialPort::PARITY_ODD: port_settings.c_cflag |= ( PARENB | PARODD ) ; port_settings.c_iflag |= INPCK ; break ; case SerialPort::PARITY_NONE: port_settings.c_cflag &= ~(PARENB) ; port_settings.c_iflag |= IGNPAR ; break ; default: throw std::invalid_argument( ERR_MSG_INVALID_PARITY ) ; break ; } // // Apply the modified port settings. // if ( tcsetattr( mFileDescriptor, TCSANOW, &port_settings ) < 0 ) { throw std::invalid_argument( strerror(errno) ) ; } return ;}inlineSerialPort::ParitySerialPort::SerialPortImpl::GetParity() const throw(SerialPort::NotOpen){ // // Make sure that the serial port is open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // // Get the current port settings. // termios port_settings ; if ( tcgetattr( mFileDescriptor, &port_settings ) < 0 ) { throw std::runtime_error( strerror(errno) ) ; } // // Get the parity type from the current settings. // if ( port_settings.c_cflag & PARENB ) { // // Parity is enabled. Lets check if it is odd or even. // if ( port_settings.c_cflag & PARODD ) { return SerialPort::PARITY_ODD ; } else { return SerialPort::PARITY_EVEN ; } } // // Parity is disabled. // return SerialPort::PARITY_NONE ;}inlinevoidSerialPort::SerialPortImpl::SetNumOfStopBits( const SerialPort::StopBits numOfStopBits ) throw( SerialPort::NotOpen, std::invalid_argument ){ // // Make sure that the serial port is open. // if ( ! this->IsOpen() ) { throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ; } // // Get the current port settings. // termios port_settings ; if ( tcgetattr( mFileDescriptor, &port_settings ) < 0 ) { throw std::runtime_error( strerror(errno) ) ; } // // Set the number of stop bits. // switch( numOfStopBits ) { case SerialPort::STOP_BITS_1: port_settings.c_cflag &= ~(CSTOPB) ; break ; case SerialPort::STOP_BITS_2: port_settings.c_cflag |= CSTOPB ; break ; default: throw std::invalid_argument( ERR_MSG_INVALID_STOP_BITS ) ; break ; } // // Apply the modified settings. // if ( tcsetattr( mFileDescriptor, TCSANOW, &port_settings ) < 0 ) { throw std::invalid_argument( strerror(errno) ) ; } return ;}inlineSerialPort::StopBitsSerialPort::SerialPortImpl::GetNumOfStopBits() const throw(SerialPort::NotOpen){ //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -