004
20.03.2006, 17:34 Uhr
(un)wissender
Niveauwart
|
cpp noch verwurstet
C++: |
#include "stdafx.h" #include "SerialPort.hpp" #include "windows.h"
#include <stdexcept> #include <iostream>
namespace { class HandleGuard { public: HandleGuard(void* & handle) :m_handle(handle) {} ~HandleGuard() { if(m_handle) { ::CloseHandle(m_handle); m_handle = 0; }} private: void *& m_handle; };
class ExtHandleGuard { public: ExtHandleGuard(void* & handle) : m_success(false), m_handle(handle) {} ~ExtHandleGuard() { if(!m_success && m_handle) { ::CloseHandle(m_handle); m_handle = 0; }} void success() { m_success = true; } private: void *& m_handle; bool m_success; }; }
SerialPort::SerialPort() : m_handle(0) { }
SerialPort::SerialPort(Port port, int timeout) : m_handle(0) { open(port, timeout); }
SerialPort::SerialPort(Port port, int timeout, const SerialPortParams ¶ms) : m_handle(0) { open(port, timeout, params); }
SerialPort::~SerialPort() { close(); }
unsigned SerialPort::write(const void * buffer, unsigned length) { /*if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) { if (GetLastError() != ERROR_IO_PENDING) fRes = FALSE; else { dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE); switch(dwRes) { case WAIT_OBJECT_0: if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, FALSE)) fRes = FALSE; else if (dwWritten != dwToWrite) fRes = FALSE; else fRes = TRUE; break; default: fRes = FALSE; break; } } } else if (dwWritten != dwToWrite) fRes = FALSE; else fRes = TRUE; */
//Opened? if(!m_handle) throw std::runtime_error("Port not open!");
//Errorstate? DWORD error; COMSTAT ComState = {0}; ::ClearCommError(m_handle, &error, &ComState); if(error) throw std::runtime_error("Port in error state write!");
//async OVERLAPPED ov; ::ZeroMemory(&ov, sizeof(ov)); HANDLE event = ::CreateEvent(0, TRUE, FALSE, 0); if(event == INVALID_HANDLE_VALUE) throw std::runtime_error("Port not open event error!"); ov.hEvent = event; HandleGuard guard(event); DWORD dwWritten; // Schreiben if (!::WriteFile(m_handle, buffer, length, &dwWritten, &ov)) { if (::GetLastError() != ERROR_IO_PENDING) { ::CancelIo(m_handle); std::cout << "Aeghhh " << '\n'; std::cout << "::GetLastError(): " << ::GetLastError() << '\n'; throw std::runtime_error("write failed unknown"); } else { if(::WaitForSingleObject(ov.hEvent, INFINITE) != WAIT_OBJECT_0) //Times out, kein schreiben throw std::runtime_error("write timed out"); else if(!::GetOverlappedResult(m_handle, &ov, &dwWritten, FALSE)) //Schreibfehler throw std::runtime_error("write GetOverlappedResult failed"); } } ::ZeroMemory(&ComState, sizeof(ComState)); ::ClearCommError(m_handle, &error, &ComState); if(error) throw std::runtime_error("Port in error state write!");
// COMSTAT structure contains information regarding // communications status. if (ComState.fCtsHold) std::cout << "Tx waiting for CTS signal\n";
if (ComState.fDsrHold) std::cout << "Tx waiting for DSR signal\n";
if (ComState.fRlsdHold) std::cout << "Tx waiting for RLSD signal\n";
if (ComState.fXoffHold) std::cout << "Tx waiting, XOFF char rec'd\n";
if (ComState.fXoffSent) std::cout<< "Tx waiting, XOFF char sent\n"; if (ComState.fEof) std::cout << "EOF character received\n"; if (ComState.fTxim) std::cout << "Character waiting for Tx; char queued with TransmitCommChar\n";
if (ComState.cbInQue) std::cout << "comStat.cbInQue bytes have been received, but not read\n";
if (ComState.cbOutQue) std::cout << "comStat.cbOutQue bytes are awaiting transfer\n"; //if(dwWritten != length) throw std::runtime_error("write timed out 2"); //zu langsam geschrieben return dwWritten; // if(!m_handle) throw std::runtime_error("Port not open!"); // DWORD write = 0; // std::cout << "write start" << '\n'; // BOOL res = ::WriteFile(m_handle, buffer, length, &write, NULL); // ||MLC|| // std::cout << "write end" << '\n'; // if(!res) throw std::runtime_error("Write error!"); // return write; }
void SerialPort::setParams(const SerialPortParams ¶ms) { if(!m_handle) throw std::runtime_error("Port not open!");
DCB dcb; FillMemory(&dcb, sizeof(dcb), 0); dcb.DCBlength = sizeof(dcb); if (!BuildCommDCB("9600,n,8,1", &dcb)) // Couldn't build the DCB. Usually a problem // with the communications specification string. throw std::runtime_error("Couldn't set params!!"); //DCB dcb; //::ZeroMemory(&dcb, sizeof(dcb)); ////if(!::GetCommState(m_handle, &dcb)) //// throw std::runtime_error("Couldn't set params!!"); //switch(params.baud) //{ //case Baud_9600: // dcb.BaudRate = CBR_9600; // break; //} //switch(params.dataBits) //{ //case DataBits_8: // dcb.ByteSize = 8; // break; //} //switch(params.parity) //{ //case Parity_None: // dcb.Parity = NOPARITY; // break; //} //switch(params.stopBits) //{ //case StopBits_1: // dcb.StopBits = ONESTOPBIT; // break; //}
//dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; // | DTR_CONTROL_ENABLE; //dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; // | RTS_CONTROL_ENABLE;
std::cout << "dcb.XonLim: " << dcb.XonLim << '\n'; std::cout << "dcb.XoffLim: " << dcb.XoffLim << '\n'; dcb.fNull = TRUE; //dcb.fOutX = FALSE; //dcb.fInX = FALSE; //dcb.fOutxCtsFlow = FALSE; //dcb.fOutxDsrFlow = FALSE; dcb.DCBlength = sizeof(dcb); dcb.EofChar = 89; dcb.ErrorChar = 56; dcb.XoffChar = 78; if(!::SetCommState(m_handle, &dcb)) throw std::runtime_error("Couldn't set params!!");
SetupComm( m_handle, 1024, 1024 );
}
void SerialPort::setDTR(bool value) { if(!m_handle) throw std::runtime_error("Port not open!"); DCB dcb; if(!::GetCommState(m_handle, &dcb)) throw std::runtime_error("Couldn't set dtr!!"); if(value && dcb.fDtrControl == DTR_CONTROL_DISABLE) dcb.fDtrControl = DTR_CONTROL_ENABLE; else if(!value && dcb.fDtrControl == DTR_CONTROL_ENABLE) dcb.fDtrControl = DTR_CONTROL_DISABLE; else return; dcb.DCBlength = sizeof(dcb); if(!::SetCommState(m_handle, &dcb)) throw std::runtime_error("Couldn't set dtr!!"); }
void SerialPort::setRTS(bool value) { if(!m_handle) throw std::runtime_error("Port not open!"); DCB dcb; if(!::GetCommState(m_handle, &dcb)) throw std::runtime_error("Couldn't set rts!!"); if(value && dcb.fRtsControl == RTS_CONTROL_DISABLE) dcb.fRtsControl = RTS_CONTROL_ENABLE; else if(!value && dcb.fRtsControl == RTS_CONTROL_ENABLE) dcb.fRtsControl = RTS_CONTROL_DISABLE; else return; dcb.DCBlength = sizeof(dcb); if(!::SetCommState(m_handle, &dcb)) throw std::runtime_error("Couldn't set rts!!"); }
void SerialPort::close() { if(m_handle) { ::CloseHandle(m_handle); m_handle = 0; } }
void SerialPort::setTimeout(int timeout) { if(!m_handle) throw std::runtime_error("Port not open!"); COMMTIMEOUTS timeo; timeo.ReadIntervalTimeout = MAXDWORD ; timeo.ReadTotalTimeoutConstant = 1; timeo.ReadTotalTimeoutMultiplier = MAXDWORD ; timeo.WriteTotalTimeoutConstant = timeout; timeo.WriteTotalTimeoutMultiplier = 0; if(!::SetCommTimeouts(m_handle, &timeo)) throw std::runtime_error("Timeout couldn't be set!"); }
void SerialPort::open(Port port, int timeout) { if(m_handle) throw std::runtime_error("Port already open!");
const char * portName = 0; switch(port) { case COM1: portName = "COM1"; break; case COM2: portName = "COM2"; break; case COM3: portName = "COM3"; break; case COM4: portName = "COM4"; break; default: throw std::runtime_error("Unsupported port!"); }
HANDLE handlePort = ::CreateFile(portName, // Specify port device: default "COM1" GENERIC_WRITE | GENERIC_READ, // Specify mode that open device. 0, // the devide isn't shared. NULL, // the object gets a default security. OPEN_EXISTING, // Specify which action to take on file. FILE_FLAG_OVERLAPPED, // default. NULL); std::cout << "reached\n"; if(handlePort == 0 || handlePort == INVALID_HANDLE_VALUE) { std::cout << "GetLastError:: " << ::GetLastError() << '\n'; throw std::runtime_error("Couldn't open!"); }
m_handle = handlePort; ExtHandleGuard guard(m_handle); setTimeout(timeout);
//DCB dcb; //if(!::GetCommState(m_handle, &dcb)) // throw std::runtime_error("Couldn't open!"); // //eof = dcb.EofChar; guard.success(); }
void SerialPort::open(Port port, int timeout, const SerialPortParams ¶ms) { open(port, timeout); ExtHandleGuard guard(m_handle); setParams(params); guard.success(); }
|
-- Wer früher stirbt ist länger tot. |