⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialport.cpp

📁 linux下串口通讯用的类库 c++编写
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // 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) ) ;    }    //    // If CSTOPB is set then we are using two stop bits, otherwise we    // are using 1 stop bit.    //    if ( port_settings.c_cflag & CSTOPB )    {        return SerialPort::STOP_BITS_2 ;    }    return SerialPort::STOP_BITS_1 ;}inlinevoidSerialPort::SerialPortImpl::SetFlowControl( const SerialPort::FlowControl   flowControl )    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 flow control.    //    switch( flowControl )    {    case SerialPort::FLOW_CONTROL_HARD:        port_settings.c_cflag |= CRTSCTS ;        break ;    case SerialPort::FLOW_CONTROL_NONE:        port_settings.c_cflag &= ~(CRTSCTS) ;        break ;    default:        throw std::invalid_argument( ERR_MSG_INVALID_FLOW_CONTROL ) ;        break ;    }    //    // Apply the modified settings.    //    if ( tcsetattr( mFileDescriptor,                    TCSANOW,                    &port_settings ) < 0 )    {        throw std::invalid_argument( strerror(errno) ) ;    }    return ;}inlineSerialPort::FlowControlSerialPort::SerialPortImpl::GetFlowControl() 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) ) ;    }    //    // If CRTSCTS is set then we are using hardware flow    // control. Otherwise, we are not using any flow control.    //    if ( port_settings.c_cflag & CRTSCTS )    {        return SerialPort::FLOW_CONTROL_HARD ;    }    return SerialPort::FLOW_CONTROL_NONE ;}inlineboolSerialPort::SerialPortImpl::IsDataAvailable() 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 ) ;    }    //    // Check if any data is available in the input buffer.    //    return ( mInputBuffer.size() > 0 ? true : false ) ;}inlineunsigned charSerialPort::SerialPortImpl::ReadByte(const unsigned int msTimeout)    throw( SerialPort::NotOpen,           SerialPort::ReadTimeout,           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 time. Throw an exception if we are unable    // to read the current time.    //    struct timeval entry_time ;    if ( gettimeofday( &entry_time,                       NULL ) < 0 )    {        throw std::runtime_error( strerror(errno) ) ;    }    //    // Wait for data to be available.    //    const int MICROSECONDS_PER_MS  = 1000 ;    const int MILLISECONDS_PER_SEC = 1000 ;    //    while( 0 == mInputBuffer.size() )    {        //        // Read the current time.        //        struct timeval curr_time ;        if ( gettimeofday( &curr_time,                           NULL ) < 0 )        {            throw std::runtime_error( strerror(errno) ) ;        }        //        // Obtain the elapsed time.        //        struct timeval elapsed_time = curr_time - entry_time ;        //        // Increase the elapsed number of milliseconds.        //        int elapsed_ms = ( elapsed_time.tv_sec  * MILLISECONDS_PER_SEC +                           elapsed_time.tv_usec / MICROSECONDS_PER_MS ) ;        //        // If more than msTimeout milliseconds have elapsed while        // waiting for data, then we throw a ReadTimeout exception.        //        if ( ( msTimeout > 0 ) &&             ( elapsed_ms > msTimeout ) )        {            throw SerialPort::ReadTimeout() ;        }        //        // Wait for 1ms (1000us) for data to arrive.        //        usleep( MICROSECONDS_PER_MS ) ;    }    //    // Return the first byte and remove it from the queue.    //    unsigned char next_char = mInputBuffer.front() ;    mInputBuffer.pop() ;    return next_char ;}inlinevoidSerialPort::SerialPortImpl::Read( SerialPort::DataBuffer& dataBuffer,                                  const unsigned int      numOfBytes,                                  const unsigned int      msTimeout )    throw( SerialPort::NotOpen,           SerialPort::ReadTimeout,           std::runtime_error ){    //    // Make sure that the serial port is open.    //    if ( ! this->IsOpen() )    {        throw SerialPort::NotOpen( ERR_MSG_PORT_NOT_OPEN ) ;    }    //    // Empty the data buffer.    //    dataBuffer.resize(0) ;    //    if ( 0 == numOfBytes )    {        //        // Read all available data if numOfBytes is zero.        //        while( this->IsDataAvailable() )        {            dataBuffer.push_back( ReadByte(msTimeout) ) ;        }    }    else    {        //        // Reserve enough space in the buffer to store the incoming        // data.        //        dataBuffer.reserve( numOfBytes ) ;        //        for(int i=0; i<numOfBytes; ++i)        {            dataBuffer.push_back( ReadByte(msTimeout) ) ;        }    }    return ;}inlineconst std::stringSerialPort::SerialPortImpl::ReadLine( const unsigned int msTimeout,                                      const char         lineTerminator )    throw( SerialPort::NotOpen,           SerialPort::ReadTimeout,           std::runtime_error ){    std::string result ;    char next_char = 0 ;    do    {        next_char = this->ReadByte( msTimeout ) ;        result += next_char ;    }    while( next_char != lineTerminator ) ;    return result ;}inlinevoidSerialPort::SerialPortImpl::WriteByte( const unsigned char dataByte )    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 ) ;    }    //    // Write the byte to the serial port.    //    this->Write( &dataByte,                 1 ) ;    return ;}inlinevoidSerialPort::SerialPortImpl::Write(const SerialPort::DataBuffer& dataBuffer)    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 ) ;    }    //    // Nothing needs to be done if there is no data in the buffer.    //    if ( 0 == dataBuffer.size() )    {        return ;    }    //    // Allocate memory for storing the contents of the    // dataBuffer. This allows us to write all the data using a single    // call to write() instead of writing one byte at a time.    //    unsigned char* local_buffer = new unsigned char[dataBuffer.size()] ;    if ( 0 == local_buffer )    {        throw std::runtime_error( std::string(__FUNCTION__) +                                  ": Cannot allocate memory while writing"                                  "data to the serial port." ) ;    }    //    // Copy the data into local_buffer.    //    std::copy( dataBuffer.begin(),               dataBuffer.end(),               local_buffer ) ;    //    // Write data to the serial port.    //    try    {        this->Write( local_buffer,                     dataBuffer.size() ) ;    }    catch( ... )    {        //        // Free the allocated memory.        //        delete [] local_buffer ;        throw ;    }    //    // Free the allocated memory.    //    delete [] local_buffer ;    return ;}inlinevoidSerialPort::SerialPortImpl::Write( const unsigned char* dataBuffer,                                   const unsigned int   bufferSize )    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 ) ;    }    //    // Write the data to the serial port. Keep retrying if EAGAIN    // error is received.    //    int num_of_bytes_written = -1 ;    do    {        num_of_bytes_written = write( mFileDescriptor,                                      dataBuffer,                                      bufferSize ) ;    }    while ( ( num_of_bytes_written < 0 ) &&            ( EAGAIN == errno ) ) ;    //    if ( num_of_bytes_written < 0 )    {        throw std::runtime_error( strerror(errno) ) ;    }    //    // :FIXME: What happens if num_of_bytes_written < bufferSize ?    //    return ;}inlinevoidSerialPort::SerialPortImpl::HandlePosixSignal( int signalNumber ){    //    // We only want to deal with SIGIO signals here.    //    if ( SIGIO != signalNumber )    {        return ;    }    //    // Check if any data is available at the specified file    // descriptor.    //    int num_of_bytes_available = 0 ;    if ( ioctl( mFileDescriptor,                FIONREAD,                &num_of_bytes_available ) < 0 )    {        /*         * Ignore any errors and return immediately.         */        return ;    }    //    // If data is available, read all available data and shove    // it into the corresponding input buffer.    //    for(int i=0; i<num_of_bytes_available; ++i)    {        unsigned char next_byte ;        if ( read( mFileDescriptor,                   &next_byte,                   1 ) > 0 )        {            mInputBuffer.push( next_byte ) ;        }        else        {            break ;        }    }    return ;}namespace{    const struct timeval    operator-( const struct timeval& firstOperand,               const struct timeval& secondOperand )    {        /*         * This implementation may result in undefined behavior if the         * platform uses unsigned values for storing tv_sec and tv_usec         * members of struct timeval.         */        //        // Number of microseconds in a second.        //        const int MICROSECONDS_PER_SECOND = 1000000 ;        struct timeval result ;        //        // Take the difference of individual members of the two operands.        //        result.tv_sec  = firstOperand.tv_sec - secondOperand.tv_sec ;        result.tv_usec = firstOperand.tv_usec - secondOperand.tv_usec ;        //        // If abs(result.tv_usec) is larger than MICROSECONDS_PER_SECOND,        // then increment/decrement result.tv_sec accordingly.        //        if ( abs( result.tv_usec ) > MICROSECONDS_PER_SECOND )        {            int num_of_seconds = (result.tv_usec / MICROSECONDS_PER_SECOND ) ;            result.tv_sec  += num_of_seconds ;            result.tv_usec -= ( MICROSECONDS_PER_SECOND * num_of_seconds ) ;        }        return result ;    }} ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -