어제 면접을 보러 갔는데 면접관이 이력서에 적힌 내가 했던 플젝들을 보더니 그동안 해온 작업중 기기통신은 어떤방식으로 했는지 물어봄.
시리얼 통신도 하고 USB통신도 하고 소켓통신도 사용했다고 답했다.
시리얼포트 인터페이스는 직접 만들었는지 아니면 라이브러리 가져다 썼냐고 물어봤는데
내 기억엔 시리얼 통신에 라이브러리 껀덕지가 있었다는 인식이 없어서 그냥 포트 열고 커넥트 해서 썼다고 했는데 면접관은 MFC에는 기본적으로 시리얼 통신 라이브러리가 없다고 함.
그럴리가 없는데 라이브러리 라고 할만한게 없는데.. 라고 생각하면서 면접 망치고 집에 오자마자 예전에 시리얼통신 작업 했던것을 뒤져봄 그리고 알게됨. 면접관 말대로 MFC 내장으로 지원하는건 아니였고 예전에 인터넷에 돌아다니는거 적당히 짜집기 해서 내가 쓰기 좋게 만들어 놓은걸 쓰고 있었음.
이게 딱히 잘 정리된 코드는 아니지만 생각난김에 여기 정리해서 올림.
#include <strsafe.h> #include "Serial.h" CSerial::CSerial() :m_bOpened(false),m_hIDComDev(NULL){ } CSerial::~CSerial(){ Close(); } bool CSerial::Open( int nPort, int nBaud ){ if( m_bOpened ) return (true); wchar_t szPort[25]; StringCbPrintfW( szPort, sizeof(szPort), L"\\\\.\\COM%d", nPort ); m_hIDComDev = CreateFileW( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if( m_hIDComDev == NULL ) return (false); //------------------------------------------------------------------ COMMTIMEOUTS CommTimeOuts; CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier = 0; CommTimeOuts.ReadTotalTimeoutConstant = 0; CommTimeOuts.WriteTotalTimeoutMultiplier = 0; CommTimeOuts.WriteTotalTimeoutConstant = 5000; SetCommTimeouts( m_hIDComDev, &CommTimeOuts ); //------------------------------------------------------------------ memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED)); memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED)); m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); //------------------------------------------------------------------ DCB dcb; dcb.DCBlength = sizeof(DCB); GetCommState(m_hIDComDev, &dcb); dcb.BaudRate = nBaud; dcb.ByteSize = 8; //dcb.Parity = Parity; //dcb.StopBits = StopBits; //dcb.fBinary = true; //dcb.fDsrSensitivity = false; //dcb.fParity = fParity; //dcb.fOutX = false; //dcb.fInX = false; //dcb.fNull = false; //dcb.fAbortOnError = true; //dcb.fOutxCtsFlow = false; //dcb.fOutxDsrFlow = false; //dcb.fDtrControl = DTR_CONTROL_DISABLE; //dcb.fDsrSensitivity = false; //dcb.fRtsControl = RTS_CONTROL_DISABLE; //dcb.fOutxCtsFlow = false; //dcb.fOutxCtsFlow = false; //------------------------------------------------------------------ if (SetCommState(m_hIDComDev, &dcb) == false || SetupComm(m_hIDComDev, 4096, 4096) ==false || //버퍼사이즈 m_OverlappedRead.hEvent == NULL || m_OverlappedWrite.hEvent == NULL) { if (m_OverlappedRead.hEvent != NULL) CloseHandle(m_OverlappedRead.hEvent); if (m_OverlappedWrite.hEvent != NULL) CloseHandle(m_OverlappedWrite.hEvent); if(m_hIDComDev !=NULL) CloseHandle(m_hIDComDev); return (false); } m_bOpened = true; return (true); } //------------------------------------------------------------------------------------------------------------------------------------ bool CSerial::Close( void ){ if( m_bOpened == false || m_hIDComDev == NULL ) return (true); if(m_OverlappedRead.hEvent != NULL) CloseHandle( m_OverlappedRead.hEvent ); if(m_OverlappedWrite.hEvent != NULL) CloseHandle( m_OverlappedWrite.hEvent ); if (m_hIDComDev != NULL) CloseHandle(m_hIDComDev); m_bOpened = false; m_hIDComDev = NULL; return (true); } //------------------------------------------------------------------------------------------------------------------------------------ bool CSerial::WriteCommByte( unsigned char ucByte ){ BOOL bWriteStat; DWORD dwBytesWritten; bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite ); if(!bWriteStat && (GetLastError() == ERROR_IO_PENDING)) { if(WaitForSingleObject(m_OverlappedWrite.hEvent, 1000)) dwBytesWritten = 0; else { GetOverlappedResult(m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE); m_OverlappedWrite.Offset += dwBytesWritten; } } return (true); } //------------------------------------------------------------------------------------------------------------------------------------ size_t CSerial::WriteData( char *buffer, size_t size ){ if( m_bOpened == false || m_hIDComDev == NULL ) return (0); DWORD dwBytesWritten = 0; unsigned i; for( i=0; i<size; i++ ){ WriteCommByte( buffer[i] ); dwBytesWritten++; } return (size_t) dwBytesWritten; } //------------------------------------------------------------------------------------------------------------------------------------ size_t CSerial::ReadData( void *buffer, size_t limit ){ if (m_bOpened == false || m_hIDComDev == NULL) return (0); BOOL bReadStatus; DWORD dwBytesRead, dwErrorFlags; COMSTAT ComStat; ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat ); if( !ComStat.cbInQue ) return (0); dwBytesRead = (DWORD) ComStat.cbInQue; if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit; bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead ); if( !bReadStatus ){ if( GetLastError() == ERROR_IO_PENDING ){ WaitForSingleObject( m_OverlappedRead.hEvent, 100 ); return( (int) dwBytesRead ); } return (0); } return (size_t) dwBytesRead; } //------------------------------------------------------------------------------------------------------------------------------------
serial.cpp
// Serial.h #ifndef __SERIAL_H__ #define __SERIAL_H__ #include <windows.h> class CSerial { public: CSerial(); ~CSerial(); bool Open( int nPort = 2, int nBaud = 38400 ); bool Close( void ); size_t ReadData( void *, size_t ); size_t WriteData( char *, size_t ); bool IsOpened( void ){ return( m_bOpened ); } bool WriteCommByte( unsigned char ); protected: HANDLE m_hIDComDev; OVERLAPPED m_OverlappedRead, m_OverlappedWrite; bool m_bOpened; }; #endif
serial.h
// SerialTest.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Serial.h" int main() { CSerial m_cSerial; char data[1024] = { 0, }; memset(data, 0, sizeof(data)); m_cSerial.Open(4, 38400); //읽을때 m_cSerial.ReadData(data, 7); //쓸때 data[0] = 'S'; data[1] = 'T'; data[2] = 0; m_cSerial.WriteData(data, 3); return 0; }
main.cpp
답글 남기기