GE-863PRO3 C++ project issue

3 thoughts on “GE-863PRO3 C++ project issue

  1. Hi all,

     

    I have a strange problem with a simple Serial port communication test application written in C++.

    I wrote a small app and tried to test it with a loopback adapter attached on UART.

    The application opens the Serial Port, sets the read mode to Non-blocking and then sends and receives "Test." char[]. While receiving, it has some timeout defined – it waits _readTimeoutMiliseconds for the first character, and then it enter the loop to get remaining characters, with the _InteroctetTimeoutMiliseconds.

     

    …now, what happends is that receive loop constantly receives sent char[] over and over again and it never exits,despite the fact that "Test." string  has been sent only once.

    There is a limitation in the receiving buffer size, so when the program reaches it, the final printf command in the main() prints:

     

    "Test.Test.Test.Test…….." and so on..

     

    But, notice the commented "//int a;" line in the main() (code below). If I delete the comment in front of "int a;" declaration, and the build,download and execute the application, the result is ok, only once "Test." string is received, and the final printf in main prints:

     

    "Test."

     

    The "int a;" line is not the only one that fixes the problem. Almost any declaration before the instantiation of SerialPort class fixes the problem.

     

    In Telit Customized Eclipse, the default compiler for ARM Cpp/C project type is "arm-linux-uclibc-g++".

     

    Does anyone have a clue what can be the issue here? Are there some known compiler bugs or something? Or am I using wrong compiler version?

     

     

    //////////////////////////////////////////////////

    Main.cpp

    //////////////////////////////////////////////////

    #include "SerialPort.h"

    int main(int argc, char **argv)
    {   
     //int a; 
     
     char input[6] = "Test."; 
     
     SerialPort* sp=new SerialPort("/dev/ttyS1",B9600);  
     
     if(sp->OpenSerialPort());
      printf("Port openedrn");   
     
     if(sp->SendData(input))
      printf("Data sentrn");
       
     char* result = sp->ReceiveData();
      
     if(result==0) printf("Empty bufferrn");
     else printf(result);      
      
    }

     

     

    //////////////////////////////////////////////////

    SerialPort.h

    //////////////////////////////////////////////////

     #ifndef SERIALPORT_H_
    #define SERIALPORT_H_

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    class SerialPort
    {  
    private:
     const char *_portName;
     speed_t _Baud;
     int _serialFd;  
      
     unsigned int _readTimeoutMiliseconds;
     unsigned int _readIntervalMiliseconds;
     unsigned int _interoctetTimeoutMiliseconds;
     unsigned int _interoctetIntervalMiliseconds;
     unsigned int _initialReceiveBufferSize;
     unsigned int _currentReceiveBufferSize;
     unsigned int _receiveBufferSizeLimit;
     
     
    public: 
     
     SerialPort(__const char *portName, int Baud);
     virtual ~SerialPort();
     
     bool OpenSerialPort();
     bool SendData(const char* data);
     char* ReceiveData();
     
    };

    #endif /*SERIALPORT_H_*/

     

    //////////////////////////////////////////////////

    SerialPort.cpp

    //////////////////////////////////////////////////

    #include "SerialPort.h"

     

    SerialPort::SerialPort(__const char *portname, int Baud)
    {
     
     _serialFd=-1;
     
     _portName=portname; 
     _Baud=Baud;
     _readTimeoutMiliseconds=2500;
     _readIntervalMiliseconds=10;
     _interoctetTimeoutMiliseconds=50;
     _interoctetIntervalMiliseconds=10;
     _initialReceiveBufferSize = 50;  
      
    }

    SerialPort::~SerialPort()

    }

    bool SerialPort::OpenSerialPort()

     struct termios oldtio,newtio;

     if((_serialFd = open(_portName, O_RDWR |O_NOCTTY |O_NONBLOCK )) < 0)//O_NONBLOCK
      /* Can’t open port */
      return false;  
     
     tcgetattr(_serialFd,&oldtio); // save current port settings
       //set new port settings for canonical input processing
     newtio.c_cflag =  _Baud | CS8 | CLOCAL | CREAD;
     newtio.c_iflag=0;
     newtio.c_iflag = IGNPAR ;
     newtio.c_oflag = 0;
       //   newtio.c_lflag = ICANON;
     newtio.c_cc[VMIN]=1;
     newtio.c_cc[VTIME]=0;
     tcflush(_serialFd, TCIFLUSH);

     tcsetattr(_serialFd,TCSANOW,&newtio);
     
     
     return true;
    }

    bool SerialPort::SendData(const char* sendData)
    {   
     if (write(_serialFd,sendData,strlen(sendData))!=ssize_t(strlen(sendData)))
      return false;
         
     else return true;
    }

    char* SerialPort::ReceiveData()
    {      
     char *serBuffer = new char[_initialReceiveBufferSize+1];  
     char *serByte = new char[2];
         
     unsigned int readCnt=0;
     unsigned int maxReadCnt = _readTimeoutMiliseconds / _readIntervalMiliseconds;   
     unsigned int bytesReceived=0; 
     
     //First read 
     while(readCnt {  
      int received=read(_serialFd, serByte, 1);
      if (received>0)
      {     
       bytesReceived++;   
       serBuffer[bytesReceived-1]=serByte[0];
       break;      
      }
      else
      {      
       readCnt++;
       usleep(_readIntervalMiliseconds*1000);  
      }        
      }
       
      if(readCnt==maxReadCnt) //Read timeout occured
      {    
       delete [] serBuffer;
       delete [] serByte;
         
       return 0;
      }
      else //Read started
      {     
       readCnt=0;
       maxReadCnt = _interoctetTimeoutMiliseconds / _interoctetIntervalMiliseconds;  
       int received=-1;   
       while(readCnt   {    
        received=read(_serialFd, serByte, 1);   
        if (received>0)
        {       
         bytesReceived++;       
         serBuffer[bytesReceived-1]=serByte[0];     
         readCnt=0;               
         if(strlen(serBuffer)==_initialReceiveBufferSize) break; //Max buffer size reached
        }
        else
        {       
         readCnt++;
         usleep(_interoctetIntervalMiliseconds*1000);     
        }      
       }
            
       char* result = new char[strlen(serBuffer)];  
       strcpy(result,serBuffer);  
       delete [] serBuffer;   
       delete [] serByte;   
      
       return result;
      
       }
    }
      

     

     

    Thanks,

     

    Vladimir

     


    1. To resolve the issue I’ll note that there was a dereliction in the code – the newtio structure of serial port settings in OpenSerialPort() function was only declared and not initialized to zeros. That is the reason why
      newtio memory block remains dirty without "int a" declaration and we have a strange behavior, apparantely because of some strange and invalid values in the structure.
      With "int a", newtio memory block shifts to a clean intacted memory and behavior of serial port is normal, even without newtio structure initialization.
        Thanks,  Vladimir