--- branches/linux-serial/Serial.cpp 2007/02/04 21:22:44 44 +++ branches/linux-serial/Serial.cpp 2007/02/05 07:14:33 50 @@ -1,19 +1,32 @@ -#ifdef _WINDOWS -#include "StdAfx.h" -#else //linux +#ifndef _MSC_VER //linux +#include +#include + +#include #include +#include +#include #endif +#include "StdAfx.h" #include "Serial.h" #include #include #include +#include #include +#define _POSIX_SOURCE 1 /* POSIX compliant source */ +#define BAUDRATE B9600 + +#ifndef _MSC_VER // ugly hack, else will gcc not accept this constant in openLinux() +const int flags = O_RDWR | O_NOCTTY | O_NONBLOCK; +#endif + std::string writeLastError() { -#ifdef _WINDOWS +#ifdef _MSC_VER LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, @@ -27,9 +40,7 @@ out << "Error" << lpMsgBuf; return out.str(); #else //linux - char message[256]; - strerror_r(errno, message, 255); - return std::string(message); + return std::string( strerror(errno) ); #endif } @@ -45,7 +56,7 @@ mBitrate = bitrate; mIsopen = false; -#ifdef _WINDOWS +#ifdef _MSC_VER openWindows(); #else openLinux(); @@ -65,14 +76,14 @@ mPortstr = port; mBitrate = bitrate; -#ifdef _WINDOWS +#ifdef _MSC_VER openWindows(); #else openLinux(); #endif } -#ifdef _WINDOWS +#ifdef _MSC_VER void CSerial::openWindows() { mComport = CreateFile( mPortstr, GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); @@ -106,7 +117,7 @@ { std::string error = writeLastError(); CloseHandle(mComport); - throw std::exception(error.c_str()); + throw std::runtime_error( error ); } mIsopen = true; @@ -114,9 +125,39 @@ #endif -#ifndef _WINDOWS +#ifndef _MSC_VER void CSerial::openLinux() { + termios newtio; + + std::cout << "opening port " << std::endl; + mFiledescriptor = ::open(mPortstr, flags); + if (mFiledescriptor < 0) + throw std::runtime_error( writeLastError() ); + + std::cout << "port opened" << std::endl; + bzero(&newtio, sizeof(newtio) ); + + // use a std. 8N1 config + newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; + newtio.c_iflag = IGNPAR; + newtio.c_oflag = 0; + + /* set input mode (non-canonical, no echo,...) */ + newtio.c_lflag = 0; + + newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ + newtio.c_cc[VMIN] = 0; /* blocking read until 1 chars received */ + + cfmakeraw(&newtio); + cfsetospeed(&newtio, BAUDRATE); + + + tcflush(mFiledescriptor, TCIFLUSH); + tcsetattr(mFiledescriptor, TCSANOW, &newtio); + + std::cout << "port configured " << std::endl; + mIsopen = true; } #endif @@ -124,26 +165,29 @@ { if (mIsopen) { -#ifdef _WINDOWS +#ifdef _MSC_VER while (getComstat().cbOutQue >0) Sleep(5); SetCommState(mComport,&mDcbRestore); CloseHandle(mComport); #else // linux close() + tcdrain(mFiledescriptor); + tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written + ::close(mFiledescriptor); //close()== system-call #endif mIsopen = false; } } -unsigned char CSerial::readByte() +int CSerial::readByte() { unsigned char out; unsigned long size; if (!mIsopen) throw std::runtime_error("Port not opened"); -#ifdef _WINDOWS +#ifdef _MSC_VER ReadFile(mComport,&out,1,&size,0); if (size != 1) { @@ -152,9 +196,15 @@ throw std::exception(error.c_str()); } #else //linux readByte() + size = read(mFiledescriptor, &out, 1); + if (size != 1) + { + std::cout << writeLastError() << std::endl; + return -1; + } #endif - //printByte("Read", out); + printByte("Read", out); return out; } @@ -163,11 +213,11 @@ { unsigned long size; - //printByte("Write", out); + printByte("Write", out); if (!mIsopen) throw std::runtime_error("Port not opened"); -#ifdef _WINDOWS +#ifdef _MSC_VER while (getComstat().cbOutQue >0) Sleep(2); @@ -179,9 +229,16 @@ throw std::exception(error.c_str()); } #else //linux writeByte() + //tcdrain(mFiledescriptor); + size = write(mFiledescriptor,&out,1); + Sleep(50); + //tcdrain(mFiledescriptor); + if (size != 1) + throw std::runtime_error(writeLastError() ); #endif } -#ifdef _WINDOWS + +#ifdef _MSC_VER COMSTAT CSerial::getComstat() const { if (!mIsopen) @@ -196,7 +253,7 @@ int CSerial::bytesReady() const { -#ifdef _WINDOWS +#ifdef _MSC_VER return getComstat().cbInQue; #else return 0; @@ -205,20 +262,21 @@ int CSerial::outQueueSize() const { -#ifdef _WINDOWS +#ifdef _MSC_VER return getComstat().cbOutQue; #else return 0; #endif } -/* Debug function +// Debug function +// void CSerial::printByte(char* description, unsigned char byte) { std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl; std::cout << std::dec; } -*/ + /* void CSerial::writeBytes(UCVector out)