help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

When reading from a serialport read returns a Bad Address/EFAULT error


From: tlann
Subject: When reading from a serialport read returns a Bad Address/EFAULT error
Date: Mon, 1 Nov 2004 11:46:12 -0700

When I'm trying to read from a serial port configured as 9600baud 081 I
get a EFAULT/Bad address error.

Before I do a read, I check to make sure there is data at the port with
the function numInBuffer().
During the read I get a EFAULT/Bad address error.

However, if a bigger program I do a cout<<bytesToRead<<endl; before the
read I have no problem with reading bytes from the serial port.

I send data to the serial port from another computer.  I know the data
is good, because the other program talks to another program on a
different OS as well as term programs.  

I've looked through the man pages for read, ioctl, as well as the
webpage the serial programming guide for posix systems.
http://www.easysw.com/~mike/serial/serial.html

I'm wondering (out loud) if this is a configuration issue.  I've been
over all of the configuration options again and again in the
documentation and in constructor.  

Is this an error that someone else has experienced in the past?

Some sample code follows

Thanks,
Thomas



=============main.h
#include <iostream>
#include "SerialPort.h"
#include "SerialPortException.h"

using std::cin;
using std::cout;
using std::endl;
void menu();

SerialPort s;
int main()
{
        int choice =1;
                
        while (choice!= 0)
        {
                menu();
                cin>>choice;
                switch (choice)
                {
                        case 0:
                                return 0;
                                break;
                        case 1:
                                if (s.numInBuffer() > 0 )
                                {
                                        try {   
cout<<s.rcvChar(s.numInBuffer())<<endl; }
                                        catch (SerialPortException spe)
                                        {
                                                cout<<"SerialPort Exception: 
"<<spe<<endl;
                                        }
                                }
                                else
                                        cout<<"Nothing in buffer"<<endl;
                                break;
                default:
                        cout<<"Wrong selection.  Choose again!!!"<<endl;
                        break;
                }
        
        }
        
}

void menu()
{
        cout<<"+++++++++++++++++++++"<<endl;
        cout<<"1.  Check the recieve buffer"<<endl;
        cout<<"0.  Exit"<<endl;
        cout<<"Choice-->";
}



============SerialPort.h
#ifndef SERIALPORT_H
#define SERIALPORT_H

#include <iostream>
#include <string>
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include "SerialPortException.h"

using std::cout;
using std::endl;
using std::string;

class SerialPort  
{
public:
        
        int xmit(unsigned char* sendbuf, int dwToWrite);
        unsigned char* rcvChar(int bytestoread);
        int numInBuffer();
        int getPortNumber() {return m_iPort;}
        
        SerialPort();
        virtual ~SerialPort();
        
private:
        int m_iPort;  //the port number
        int m_iFd;  //the file descriptor for the port
        struct termios portConfig;  //a struct that holds the configuration of
the serialport

};

#endif 

============SerialPort.cpp
#include "SerialPort.h"



SerialPort::SerialPort():m_iPort(1)
{
                
        //open the fd comm port for read/write
        m_iFd=open("/dev/ttyS0",  O_RDWR | O_NOCTTY | O_NDELAY );
        if (m_iFd == -1)
        {
                string szError(strerror(errno));
                throw SerialPortException("Unable to open SerialPort:"+szError);
        }
        
        fcntl(m_iFd,F_SETFL,FNDELAY);
        
        //get the port info
        tcgetattr(m_iFd, &portConfig);
        
        //set input and output port speeds
        cfsetispeed(&portConfig, B9600);
        cfsetospeed(&portConfig, B9600);
        
        // 
        portConfig.c_iflag &=
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF);
        portConfig.c_oflag &= ~OPOST;
        portConfig.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
        portConfig.c_cflag &= ~CSIZE; //CHARACTER SIZE MASK
        portConfig.c_cflag |= CS8;  //8 BIT
        //cfmakeraw(&portConfig);
        
        portConfig.c_cflag |= INPCK; //Enable input parity checking.
        
        portConfig.c_cflag |= PARENB; //(Enable parity generation on output
and parity checking for input.)
        portConfig.c_cflag &= ~CSTOPB;  //One stop bit
        
        //set odd parity  (O81)
        portConfig.c_cflag |= PARODD;    //for odd parity
        
        //ignore the control chars      
        portConfig.c_cflag |= (CLOCAL | CREAD);
                
        //set the port options
        tcsetattr(m_iFd, TCSANOW, &portConfig);
        
}


SerialPort::~SerialPort()
{
        //close the comm port
        close(m_iFd);
}

int SerialPort::numInBuffer()
{
        int bytes=0;
        ioctl(m_iFd, FIONREAD, &bytes);
        return bytes;
}

unsigned char* SerialPort::rcvChar(int bytestoread)
{
        
        
        unsigned char* temp;
        if (read(m_iFd, temp, bytestoread) < 0)
        {
                cout<<"Errno is "<<errno<<endl;
                string szError(strerror(errno));
                throw SerialPortException("read() Error Reason:"+szError);
        }
        
        return temp;
}

int SerialPort::xmit(unsigned char* sendbuf, int dwToWrite)
{
        int f = write(m_iFd, sendbuf, dwToWrite);
        
        if (f < dwToWrite)
                throw SerialPortException("Write buffer is less then 
bytesToWrite");
        
        if (f ==-1)
        {
                string szError(strerror(errno));
                throw SerialPortException("Write buffer Error.  Reason: 
"+szError);
        }
                
        return 1;       

}
===============SerialPortException.h
#ifndef SERIALPORTEXCEPTION_class
#define SERIALPORTEXCEPTION_class
#include <iostream>
#include <string>

using std::ostream;

class SerialPortException
{
 public:
  SerialPortException ( std::string s="SerialPortException" ) : m_s ( s
) {};
  ~SerialPortException (){};

  std::string description() { return m_s; }

        friend ostream& operator<<(ostream& os, SerialPortException &spE)
        {
                os<<spE.description();
                return os;
        }

 private:

  std::string m_s;

};


#endif






reply via email to

[Prev in Thread] Current Thread [Next in Thread]