} void WinSerial::setupLink() { int ret; DCB dcb = {0}; COMMTIMEOUTS cto = {10,10,10,10,10}; dcb.DCBlength = sizeof(DCB); cto.ReadIntervalTimeout = 100; sprintf(logchunk, "opening com port <%s>\n", mDevName); log(logchunk); mPortFh = CreateFile(mDevName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 ); if (mPortFh == INVALID_HANDLE_VALUE) { // Handle the error. printf ("CreateFile failed with error %ld.\n", GetLastError()); exit(1); } sprintf(logchunk, " port %d\n", mPortFh); log(logchunk); assert(mPortFh); ret = GetCommState(mPortFh, &dcb); if (!ret) { fprintf(stderr, "GetCommState failed %d\n", GetLastError()); exit(2); } // dcb.BaudRate = CBR_57600; dcb.BaudRate = CBR_256000; dcb.ByteSize = 8; dcb.StopBits = ONESTOPBIT; dcb.Parity = NOPARITY; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fNull = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; // need to send binary data dcb.fBinary = 1; // * fInX, fOutX,fOutXDsrFlow, fOutXCtsFlow are set to FALSE // * fDtrControl is set to DTR_CONTROL_ENABLE // * fRtsControl is set to RTS_CONTROL_ENABLE ret = SetCommState(mPortFh, &dcb); if (!ret) { fprintf(stderr, "SetCommState failed %d\n", GetLastError()); exit(3); } ret = SetCommTimeouts(mPortFh, &cto); if (!ret) { fprintf(stderr, "SetCommTimeouts failed %d\n", GetLastError()); exit(3); } log("setup\n"); mSetup = 1;
int main(void){ /* I searched for this topic and found no real leads so i looked it up. * Opening the serial port * First point is to open a connection. Before opening any connection several informations must be acquired. * * The name of the serial port.(Usually COM1-COM6 ) * The direction of communication. * (It is possible to set the communication to an asynchronic mode but it is far mor complex and unintuitive than the synchronic mode used here) */ LPCSTR portname = "COM4"; DWORD accessdirection =GENERIC_READ | GENERIC_WRITE; HANDLE hSerial = CreateFile(portname, accessdirection, 0, 0, OPEN_EXISTING, 0, 0); if (hSerial == INVALID_HANDLE_VALUE) { //call GetLastError(); to gain more information printf("Error 1\n"); } /* * After opening the port further settings like Baudrate, Byte size, the number of stopbits and the Parity need to be set. */ DCB dcbSerialParams = {0}; dcbSerialParams.DCBlength=sizeof(dcbSerialParams); if (!GetCommState(hSerial, &dcbSerialParams)) { //could not get the state of the comport } dcbSerialParams.BaudRate=9600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY; if(!SetCommState(hSerial, &dcbSerialParams)){ //analyse error printf("Error 2\n"); } /* Finally timeouts need to be set so that the program does not hang up when receiving nothing. */ COMMTIMEOUTS timeouts={0}; timeouts.ReadIntervalTimeout=50; timeouts.ReadTotalTimeoutConstant=50; timeouts.ReadTotalTimeoutMultiplier=10; timeouts.WriteTotalTimeoutConstant=50; timeouts.WriteTotalTimeoutMultiplier=10; if(!SetCommTimeouts(hSerial, &timeouts)){ //handle error printf("Error 3\n"); } { uint8_t symbol = 'A'; for(symbol = 'A'; symbol <= 'Z'; ++symbol){ (void)writeToSerialPort(hSerial, &symbol, 1); } } /* Closing: when the serial port is not longer needed, it can be freed by closing the associated handle. */ CloseHandle(hSerial); printf("Hello\n"); } /* main */
serial_source open_serial_source(const char *device, int baud_rate, int non_blocking, void (*message)(serial_source_msg problem)) /* Effects: opens serial port device at specified baud_rate. If non_blocking is true, read_serial_packet calls will be non-blocking (writes are always blocking, for now at least) Returns: descriptor for serial forwarder at host:port, or NULL for failure (bad device or bad baud rate) */ { #ifndef LOSE32 struct termios newtio; int fd; tcflag_t baudflag = parse_baudrate(baud_rate); if (!baudflag) return NULL; fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) return NULL; /* Serial port setting */ memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | IGNBRK; cfsetispeed(&newtio, baudflag); cfsetospeed(&newtio, baudflag); /* Raw output_file */ newtio.c_oflag = 0; if (tcflush(fd, TCIFLUSH) >= 0 && tcsetattr(fd, TCSANOW, &newtio) >= 0) { serial_source src = malloc(sizeof *src); if (src) { memset(src, 0, sizeof *src); src->fd = fd; src->non_blocking = non_blocking; src->message = message; src->send.seqno = 37; return src; } } close(fd); return NULL; #else // LOSE32 LPCTSTR ComName = (LPCTSTR)device; HANDLE hComm; DCB dcb; serial_source src; int buflen = MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,0); MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,buflen); //syncronize hComm = CreateFile(ComName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hComm == INVALID_HANDLE_VALUE) { return NULL; } PurgeComm(hComm, PURGE_RXCLEAR); GetCommState(hComm, &dcb); dcb.BaudRate = baud_rate; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.fParity = FALSE; dcb.StopBits = ONESTOPBIT; if (SetCommState(hComm, &dcb) == 0) { return NULL; } src = malloc(sizeof *src); if (src) { memset(src, 0, sizeof *src); src->hComm = hComm; src->non_blocking = non_blocking; src->message = message; src->send.seqno = 37; } return src; #endif // LOSE32 }
int setAttributes(int baudRate, Parity parity, int dataBits, StopBits bits, Handshake hs, int readTimeout, int writeTimeout) { DCB dcb; if (!GetCommState(this->handle, &dcb)) { return GetLastError(); } dcb.BaudRate = baudRate; dcb.Parity = (byte)parity; dcb.ByteSize = (byte)dataBits; switch (bits) { case StopBits_10: dcb.StopBits = ONESTOPBIT; break; case StopBits_15: dcb.StopBits = ONE5STOPBITS; break; case StopBits_20: dcb.StopBits = TWOSTOPBITS; break; default: break; } // Clear Handshake flags dcb.fOutxCtsFlow = 0; dcb.fOutX = 0; dcb.fInX = 0; dcb.fRtsControl = 0; // Set Handshake flags switch (hs) { case Handshake_None: break; case Handshake_XonXoff: dcb.fOutX = 1; dcb.fInX = 1; break; case Handshake_RequestToSend: dcb.fOutxCtsFlow = 1; dcb.fRtsControl = 1; break; case Handshake_RequestToSendXonXoff: dcb.fOutX = 1; dcb.fInX = 1; dcb.fOutxCtsFlow = 1; dcb.fRtsControl = 1; break; default: // Shouldn't happen break; } if (!SetCommState(handle, &dcb)) { return GetLastError(); } return S_OK; }
void serialDriver::open(std::string com_port, long baud_rate, int databits, sdff_serial_paritymodes parity, double stopbits, sdff_serial_handshaking handshaking){ std::string par="NO_PARITY"; if (parity==sdffserEVEN) par="EVEN_PARITY"; if (parity==sdffserODD) par="ODD_PARITY"; std::string name="serialDriver::open(port="+com_port+", baud_rate="+inttostr(baud_rate)+", databits="+inttostr(databits)+", stopbits="+floattostr(stopbits)+" parity="+par+")"; if (ports.find(com_port)!=ports.end()) { SEQUENCER_ERRORV(SEQUENCER_SERERROR_PORTALREADYOPEN_NUM, name, com_port.c_str()); } BOOL fSuccess; DCB dcb; /* device control block */ BYTE StopBits; if (stopbits==1) { StopBits=ONESTOPBIT; } else if (stopbits==1.5) { StopBits=ONE5STOPBITS; } else if (stopbits==2) { StopBits=TWOSTOPBITS; } else { SEQUENCER_ERRORV(SEQUENCER_SERERROR_IMPOSSIBLEARG_NUM, name, com_port.c_str(), floattostr(stopbits).c_str(), "stop_bits", "1, 1.5, 2"); } BYTE Parity=NOPARITY; DWORD fParity; if (parity==sdffserEVEN) { Parity=EVENPARITY; fParity=TRUE; } else if (parity==sdffserODD) { Parity=ODDPARITY; fParity=TRUE; } else if (parity==sdffserNOPARITY) { Parity=NOPARITY; fParity=FALSE; } ports[com_port] = CreateFileA(com_port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (ports[com_port]==INVALID_HANDLE_VALUE) { ports.erase(com_port); win32_error(name); } fSuccess = GetCommState(ports[com_port], &dcb); if (!fSuccess) { CloseHandle(ports[com_port]); ports.erase(com_port); win32_error(name); } /* configure the port */ dcb.BaudRate = baud_rate; dcb.ByteSize = databits; dcb.Parity = Parity; dcb.StopBits = StopBits; /* configure handshaking */ switch (handshaking) { case sdffserNOHANDSHAKING: dcb.fOutxCtsFlow = false; // Disable CTS monitoring dcb.fOutxDsrFlow = false; // Disable DSR monitoring dcb.fDtrControl = DTR_CONTROL_DISABLE; // Disable DTR monitoring dcb.fOutX = false; // Disable XON/XOFF for transmission dcb.fInX = false; // Disable XON/XOFF for receiving dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send) break; case sdffserHARDWARE: dcb.fOutxCtsFlow = true; // Enable CTS monitoring dcb.fOutxDsrFlow = true; // Enable DSR monitoring dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; // Enable DTR handshaking dcb.fOutX = false; // Disable XON/XOFF for transmission dcb.fInX = false; // Disable XON/XOFF for receiving dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; // Enable RTS handshaking break; case sdffserXONXOFF: dcb.fOutxCtsFlow = false; // Disable CTS (Clear To Send) dcb.fOutxDsrFlow = false; // Disable DSR (Data Set Ready) dcb.fDtrControl = DTR_CONTROL_DISABLE; // Disable DTR (Data Terminal Ready) dcb.fOutX = true; // Enable XON/XOFF for transmission dcb.fInX = true; // Enable XON/XOFF for receiving dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send) break; } fSuccess = SetCommState(ports[com_port], &dcb); if (!fSuccess) { CloseHandle(ports[com_port]); ports.erase(com_port); win32_error(name); } COMMTIMEOUTS commTimeout; if(GetCommTimeouts(ports[com_port], &commTimeout)) { commTimeout.ReadIntervalTimeout = 500; commTimeout.ReadTotalTimeoutConstant = 100; commTimeout.ReadTotalTimeoutMultiplier = 500; commTimeout.WriteTotalTimeoutConstant = 100; commTimeout.WriteTotalTimeoutMultiplier = 500; } else { CloseHandle(ports[com_port]); ports.erase(com_port); win32_error(name); } if(!SetCommTimeouts(ports[com_port], &commTimeout)) { CloseHandle(ports[com_port]); ports.erase(com_port); win32_error(name); } }
COMMNG cmserial_create(UINT port, UINT8 param, UINT32 speed) { TCHAR commstr[16]; HANDLE hdl; DCB dcb; UINT i; COMMNG ret; CMSER serial; wsprintf(commstr, _T("COM%u"), port); hdl = CreateFile(commstr, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL); if (hdl == INVALID_HANDLE_VALUE) { goto cscre_err1; } GetCommState(hdl, &dcb); for (i=0; i<NELEMENTS(cmserial_speed); i++) { if (cmserial_speed[i] >= speed) { dcb.BaudRate = cmserial_speed[i]; break; } } dcb.ByteSize = (UINT8)(((param >> 2) & 3) + 5); switch(param & 0x30) { case 0x10: dcb.Parity = ODDPARITY; break; case 0x30: dcb.Parity = EVENPARITY; break; default: dcb.Parity = NOPARITY; break; } switch(param & 0xc0) { case 0x80: dcb.StopBits = ONE5STOPBITS; break; case 0xc0: dcb.StopBits = TWOSTOPBITS; break; default: dcb.StopBits = ONESTOPBIT; break; } SetCommState(hdl, &dcb); ret = (COMMNG)_MALLOC(sizeof(_COMMNG) + sizeof(_CMSER), "SERIAL"); if (ret == NULL) { goto cscre_err2; } ret->connect = COMCONNECT_MIDI; ret->read = serialread; ret->write = serialwrite; ret->getstat = serialgetstat; ret->msg = serialmsg; ret->release = serialrelease; serial = (CMSER)(ret + 1); serial->hdl = hdl; return(ret); cscre_err2: CloseHandle(hdl); cscre_err1: return(NULL); }
////////////////////////////////////////////////////////////////////////////////////////// // Open a communication channel to the given serial port name. XsensResultValue Cmt1s::open( const char *portName, const uint32_t baudRate, uint32_t readBufSize, uint32_t writeBufSize) { MRPT_UNUSED_PARAM(readBufSize); MRPT_UNUSED_PARAM(writeBufSize); m_endTime = 0; CMT1LOG("L1: Open port %s at %d baud\n", portName, baudRate); if (m_isOpen) { CMT1LOG("L1: Port already open\n"); return (m_lastResult = XRV_ALREADYOPEN); } m_baudrate = baudRate; #ifdef _WIN32 char winPortName[32]; // Open port sprintf(winPortName, "\\\\.\\%s", portName); m_handle = CreateFileA(winPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (m_handle == INVALID_HANDLE_VALUE) { CMT1LOG("L1: Port cannot be opened\n"); return (m_lastResult = XRV_INPUTCANNOTBEOPENED); } // Once here, port is open m_isOpen = true; //Get the current state & then change it GetCommState(m_handle, &m_commState); // Get current state m_commState.BaudRate = baudRate; // Setup the baud rate m_commState.Parity = NOPARITY; // Setup the Parity m_commState.ByteSize = 8; // Setup the data bits m_commState.StopBits = TWOSTOPBITS; // Setup the stop bits m_commState.fDsrSensitivity = FALSE; // Setup the flow control m_commState.fOutxCtsFlow = FALSE; // NoFlowControl: m_commState.fOutxDsrFlow = FALSE; m_commState.fOutX = FALSE; m_commState.fInX = FALSE; if (!SetCommState(m_handle, (LPDCB)&m_commState)) {// Set new state // Bluetooth ports cannot always be opened with 2 stopbits // Now try to open port with 1 stopbit. m_commState.StopBits = ONESTOPBIT; if (!SetCommState(m_handle, (LPDCB)&m_commState)) { CloseHandle(m_handle); m_handle = INVALID_HANDLE_VALUE; m_isOpen = false; return (m_lastResult = XRV_INPUTCANNOTBEOPENED); } } m_port = atoi(&portName[3]); sprintf(m_portname, "%s", portName); setTimeout(m_timeout); // Other initialization functions EscapeCommFunction(m_handle, SETRTS); // Enable RTS (for Xbus Master use) // Set DTR (Calibration sensors need DTR to startup, won't hurt otherwise EscapeCommFunction(m_handle, SETDTR); SetupComm(m_handle,readBufSize,writeBufSize); // Set queue size // Remove any 'old' data in buffer //PurgeComm(m_handle, PURGE_TXCLEAR | PURGE_RXCLEAR); PurgeComm(m_handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); #else // !_WIN32 // Open port m_handle = ::open(portName, O_RDWR | O_NOCTTY); // O_RDWR: Read+Write // O_NOCTTY: Raw input, no "controlling terminal" // O_NDELAY: Don't care about DCD signal if (m_handle < 0) { // Port not open return m_lastResult = XRV_INPUTCANNOTBEOPENED; } // Once here, port is open m_isOpen = true; /* Start configuring of port for non-canonical transfer mode */ // Get current options for the port tcgetattr(m_handle, &m_commState); // Set baudrate. cfsetispeed(&m_commState, baudRate); cfsetospeed(&m_commState, baudRate); // Enable the receiver and set local mode m_commState.c_cflag |= (CLOCAL | CREAD); // Set character size to data bits and set no parity Mask the characte size bits m_commState.c_cflag &= ~(CSIZE|PARENB); m_commState.c_cflag |= CS8; // Select 8 data bits m_commState.c_cflag |= CSTOPB; // send 2 stop bits // Disable hardware flow control m_commState.c_cflag &= ~CRTSCTS; m_commState.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); // Disable software flow control m_commState.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); // Set Raw output m_commState.c_oflag &= ~OPOST; // Timeout 0.001 sec for first byte, read minimum of 0 bytes m_commState.c_cc[VMIN] = 0; m_commState.c_cc[VTIME] = (m_timeout+99)/100; // 1 // Set the new options for the port tcsetattr(m_handle,TCSANOW, &m_commState); m_port = 0; sprintf(m_portname, "%s", portName); tcflush(m_handle, TCIOFLUSH); // setting RTS and DTR; RTS for Xbus Master, DTR for calibration sensors int cmbits; if (ioctl(m_handle, TIOCMGET, &cmbits) < 0) { return (m_lastResult = XRV_ERROR); } cmbits |= TIOCM_RTS|TIOCM_DTR; if (ioctl(m_handle, TIOCMSET, &cmbits) < 0) { return (m_lastResult = XRV_ERROR); } #endif // !_WIN32 CMT1LOG("L1: Port opened\n"); return (m_lastResult = XRV_OK); }
Serial::Serial(char *portName) { //We're not yet connected this->connected = false; //Try to connect to the given port through CreateFile this->hSerial = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //Check if the connection was successfull if(this->hSerial==INVALID_HANDLE_VALUE) { //If not successful display an Error if(GetLastError()==ERROR_FILE_NOT_FOUND){ //Print Error if neccessary printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName); } else { printf("ERROR!!!"); } } else { //If connected we try to set the comm parameters DCB dcbSerialParams = {0}; //Try to get the current if (!GetCommState(this->hSerial, &dcbSerialParams)) { //If impossible, show an error printf("failed to get current serial parameters!"); } else { //Define serial connection parameters for the arduino board dcbSerialParams.BaudRate=CBR_9600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY; //Set the parameters and check for their proper application if(!SetCommState(hSerial, &dcbSerialParams)) { printf("ALERT: Could not set Serial Port parameters"); } else { //If everything went fine we're connected this->connected = true; //We wait 2s as the arduino board will be reseting Sleep(ARDUINO_WAIT_TIME); } } } }
/* 打开串口 */ HANDLE CComInit::OpenComm(int ncom) { memset( &m_read_os, 0, sizeof( OVERLAPPED ) ) ; memset( &m_write_os, 0, sizeof( OVERLAPPED ) ) ; CString Com; Com.Format(_T("COM%d"),ncom); HANDLE hCom = CreateFile(Com,GENERIC_READ | GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); if(INVALID_HANDLE_VALUE==hCom) { CloseHandle(hCom); return hCom; } //创建事件 m_read_os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); m_write_os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); if(NULL == m_read_os.hEvent || NULL == m_write_os.hEvent){ CloseHandle(hCom); CloseHandle(m_read_os.hEvent); CloseHandle(m_write_os.hEvent); hCom = INVALID_HANDLE_VALUE; return hCom; } //设置com事件类型,参见msdn SetCommMask(hCom,EV_RXCHAR | EV_TXEMPTY); SetupComm( hCom, 1024,512 );//设置缓冲区大小; PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); //清干净输入、输出缓冲区 DCB dcb={0}; dcb.DCBlength=sizeof(dcb); BOOL bres=GetCommState(hCom,&dcb); if(!bres) { CloseHandle(hCom); hCom=INVALID_HANDLE_VALUE; return hCom; } dcb.ByteSize=8;//后改 dcb.fParity=0; dcb.BaudRate=CBR_9600; dcb.StopBits=ONESTOPBIT; bres=SetCommState(hCom,&dcb); if(!bres) { CloseHandle(hCom); hCom=INVALID_HANDLE_VALUE; return hCom; } COMMTIMEOUTS comm_time={0}; comm_time.ReadIntervalTimeout=MAXDWORD; bres=SetCommTimeouts(hCom,&comm_time); // SetupComm(m_hComWndScreen, 4096, 1024); if(!bres) { CloseHandle(hCom); CloseHandle(m_read_os.hEvent); CloseHandle(m_write_os.hEvent); hCom = INVALID_HANDLE_VALUE; return hCom; } return hCom; }
static co_rc_t coserial_main(int argc, char *argv[]) { co_rc_t rc; co_module_t module; HANDLE out_handle, in_handle; int select_time; rc = handle_parameters(&g_daemon_parameters, argc, argv); if (!CO_OK(rc)) return rc; rc = co_reactor_create(&g_reactor); if (!CO_OK(rc)) return rc; co_debug("connecting to monitor"); module = CO_MODULE_SERIAL0 + g_daemon_parameters.index; rc = co_user_monitor_open(g_reactor, monitor_receive, g_daemon_parameters.instance, &module, 1, &g_monitor_handle); if (!CO_OK(rc)) return rc; if (g_daemon_parameters.filename_specified == PTRUE) { char name [strlen(g_daemon_parameters.filename) + 4+1]; DCB dcb; COMMTIMEOUTS commtimeouts = { 1, /* ReadIntervalTimeout */ 0, /* ReadTotalTimeoutMultiplier */ 0, /* ReadTotalTimeoutConstant */ 0, /* WriteTotalTimeoutMultiplier */ 0 }; /* WriteTotalTimeoutConstant */ if (g_daemon_parameters.filename[0] != '\\') { /* short windows name */ if (strncasecmp(g_daemon_parameters.filename, "COM", 3) != 0) co_terminal_print("warning: host serial device '%s' is not a COM port\n", g_daemon_parameters.filename); snprintf(name, sizeof(name), "\\\\.\\%s", g_daemon_parameters.filename); } else { /* windows full name device */ strncpy(name, g_daemon_parameters.filename, sizeof(name)); } co_debug("open device '%s'", name); out_handle = \ in_handle = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (in_handle == INVALID_HANDLE_VALUE) { co_terminal_print_last_error(g_daemon_parameters.filename); return CO_RC(ERROR); } if (g_daemon_parameters.mode_specified == PTRUE) { co_debug("set mode: %s", g_daemon_parameters.mode); if (!GetCommState(in_handle, &dcb)) { co_terminal_print_last_error("GetCommState"); return CO_RC(ERROR); } /* Set defaults. user can overwrite ot */ dcb.fOutxCtsFlow = FALSE; /* Disable Handshake */ dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fRtsControl = RTS_CONTROL_ENABLE; if (!BuildCommDCB(g_daemon_parameters.mode, &dcb)) { /*co_terminal_print_last_error("colinux-serial-daemon: BuildCommDCB");*/ co_terminal_print("colinux-serial-daemon: error in mode parameter '%s'\n", g_daemon_parameters.mode); return CO_RC(ERROR); } if (!SetCommState(in_handle, &dcb)) { co_terminal_print_last_error("SetCommState"); return CO_RC(ERROR); } } else { if (!EscapeCommFunction(in_handle, SETDTR)) { co_terminal_print_last_error("Warning EscapeCommFunction DTR"); /* return CO_RC(ERROR); */ } if (!EscapeCommFunction(in_handle, SETRTS)) { co_terminal_print_last_error("Warning EscapeCommFunction RTS"); /* return CO_RC(ERROR); */ } } if (!SetCommTimeouts(in_handle, &commtimeouts)) { co_terminal_print_last_error("SetCommTimeouts"); return CO_RC(ERROR); } if (!SetupComm(in_handle, 2048, 2048)) { co_terminal_print_last_error("SetupComm"); return CO_RC(ERROR); } select_time = -1; } else { co_debug("std input/output"); out_handle = GetStdHandle(STD_OUTPUT_HANDLE); in_handle = GetStdHandle(STD_INPUT_HANDLE); select_time = 100; } co_debug("connected"); rc = co_winnt_reactor_packet_user_create(g_reactor, out_handle, in_handle, std_receive, &g_reactor_handle); if (!CO_OK(rc)) return rc; co_terminal_print("colinux-serial-daemon: running\n"); while (CO_OK(rc)) { rc = co_reactor_select(g_reactor, select_time); if (CO_RC_GET_CODE(rc) == CO_RC_BROKEN_PIPE) return CO_RC(OK); /* Normal, if linux shut down */ if (!g_daemon_parameters.filename_specified) if ( _kbhit() ) send_userinput(); } return -1; }
bool PrinterSerial::RawConnect( string device, int baudrate ) { #ifdef WIN32 if ( IsConnected() || device_handle != INVALID_HANDLE_VALUE ) { Disconnect(); if ( device_handle != INVALID_HANDLE_VALUE ) return false; } device_handle = CreateFile( device.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( device_handle == INVALID_HANDLE_VALUE ) { char err_str[ 256 ]; snprintf( err_str, 256, _("Error opening port %s"), device.c_str() ); err_str[ 256 ] = '\0'; ostringstream os; os << err_str << " (" << GetLastError() << ")"<< endl; LogError( os.str().c_str() ); return false; } DCB dcb = { 0 }; dcb.DCBlength = sizeof( dcb ); if ( ! GetCommState( device_handle, &dcb ) ) { CloseHandle( device_handle ); device_handle = INVALID_HANDLE_VALUE; char err_str[ 256 ]; snprintf( err_str, 256, _("Error getting port %s state"), device.c_str() ); err_str[ 255 ] = '\0'; ostringstream os; os << err_str << " (" << GetLastError() << ")"<< endl; LogError( os.str().c_str() ); return false; } dcb.BaudRate = baudrate; dcb.fBinary = 1; dcb.fParity = 0; dcb.fOutxCtsFlow = 0; dcb.fOutxDsrFlow = 0; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fDsrSensitivity = 0; dcb.fOutX = 0; dcb.fInX = 0; dcb.fNull = 0; dcb.fRtsControl = RTS_CONTROL_ENABLE; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; if ( ! SetCommState( device_handle, &dcb ) ) { CloseHandle( device_handle ); device_handle = INVALID_HANDLE_VALUE; char err_str[ 256 ]; snprintf( err_str, 256, _("Error setting port %s state"), device.c_str() ); err_str[ 255 ] = '\0'; ostringstream os; os << err_str << " (" << GetLastError() << ")"<< endl; LogError( os.str().c_str() ); return false; } COMMTIMEOUTS ct; if ( ! GetCommTimeouts( device_handle, &ct ) ) { CloseHandle( device_handle ); device_handle = INVALID_HANDLE_VALUE; char err_str[ 256 ]; snprintf( err_str, 256, _("Error getting port %s timeouts"), device.c_str() ); err_str[ 255 ] = '\0'; ostringstream os; os << err_str << " (" << GetLastError() << ")"<< endl; LogError( os.str().c_str() ); return false; } ct.ReadIntervalTimeout = 5; ct.ReadTotalTimeoutConstant = max_recv_block_ms; ct.ReadTotalTimeoutMultiplier = 0; ct.WriteTotalTimeoutConstant = max_recv_block_ms; ct.WriteTotalTimeoutMultiplier= 0; if ( ! SetCommTimeouts( device_handle, &ct ) ) { CloseHandle( device_handle ); device_handle = INVALID_HANDLE_VALUE; char err_str[ 256 ]; snprintf( err_str, 256, _("Error setting port %s timeouts"), device.c_str() ); err_str[ 255 ] = '\0'; ostringstream os; os << err_str << " (" << GetLastError() << ")"<< endl; LogError( os.str().c_str() ); return false; } *raw_recv = '\0'; #else // Verify speed is valid and convert to posix value speed_t speed = B0; bool custom_baud = false; switch ( baudrate ) { case 50: speed = B50; break; case 75: speed = B75; break; case 110: speed = B110; break; case 134: speed = B134; break; case 150: speed = B150; break; case 200: speed = B200; break; case 300: speed = B300; break; case 600: speed = B600; break; case 1200: speed = B1200; break; case 1800: speed = B1800; break; case 2400: speed = B2400; break; case 4800: speed = B4800; break; case 9600: speed = B9600; break; case 19200: speed = B19200; break; case 38400: speed = B38400; break; case 57600: speed = B57600; break; case 115200: speed = B115200; break; case 230400: speed = B230400; break; default: ostringstream ostr; ostr << "Nonstandard baudrate " << baudrate << endl; LogLine( ostr.str().c_str() ); speed = baudrate; custom_baud = true; // char err_str[ 256 ]; // snprintf( err_str, 256, _( %d\n"), baudrate ); // if ( err_str[ 254 ] != '\0' ) // err_str[ 254 ] = '\n'; // err_str[ 255 ] = '\0'; //LogError( err_str ); // return false; } if ( IsConnected() || device_fd >= 0 ) { Disconnect(); if ( device_fd >= 0 ) return false; } // Open file if ( ( device_fd = open( device.c_str(), O_RDWR | O_NOCTTY ) ) < 0 ) { int err = errno; char err_str[ 256 ]; snprintf( err_str, 256, _("Error opening port %s"), device.c_str() ); err_str[ 255 ] = '\0'; ostringstream os; os << err_str << ": " << strerror( err ) << endl; LogError( os.str().c_str() ); return false; } // Configure port struct termios attribs; if ( tcgetattr( device_fd, &attribs ) < 0 ) { int err = errno; close( device_fd ); device_fd = -1; char err_str[ 256 ]; snprintf( err_str, 256, _("Error getting port %s state"), device.c_str() ); err_str[ 255 ] = '\0'; ostringstream os; os << err_str << ": " << strerror( err ) << endl; LogError( os.str().c_str() ); return false; } // Use RAW settings, except add ICANON. ICANON makes the port line buffered // and read will return immediately when a newline is received. // HUPCL lowers the modem control lines (hang up) when the port is closed cfmakeraw( &attribs ); attribs.c_lflag |= ICANON; attribs.c_cflag |= HUPCL; if( tcsetattr( device_fd, TCSANOW, &attribs ) < 0 ) { close( device_fd ); device_fd = -1; char err_str[ 256 ]; snprintf( err_str, 256, _("Error enabling port %s raw mode\n"), device.c_str() ); if ( err_str[ 254 ] != '\0' ) err_str[ 254 ] = '\n'; err_str[ 255 ] = '\0'; LogError( err_str ); return false; } // Set port speed bool baudrate_succeeded = false; #if HAVE_ASM_TERMBITS_H if ( custom_baud ) { // non-standard baud rate baudrate_succeeded = set_custom_baudrate( device_fd, speed ); } else { baudrate_succeeded = cfsetispeed( &attribs, speed ) >= 0 && cfsetospeed( &attribs, speed ) >= 0 && tcsetattr( device_fd, TCSANOW, &attribs ) >= 0; } #else baudrate_succeeded = cfsetispeed( &attribs, speed ) >= 0 && cfsetospeed( &attribs, speed ) >= 0 && tcsetattr( device_fd, TCSANOW, &attribs ) >= 0; #endif if ( ! baudrate_succeeded ) { close( device_fd ); device_fd = -1; char err_str[ 256 ]; snprintf( err_str, 256, _("Error setting port %s baudrate to %d\n"), device.c_str(), baudrate ); if ( err_str[ 254 ] != '\0' ) err_str[ 254 ] = '\n'; err_str[ 255 ] = '\0'; LogError( err_str ); return false; } #endif char msg[ 256 ]; memcpy( msg, "--- ", 4 ); snprintf( msg + 4, 256 - 4, _("Connected to port %s at %d baud\n"), device.c_str(), baudrate ); if ( msg[ 254 ] != '\0' ) msg[ 254 ] = '\n'; msg[ 255 ] = '\0'; LogLine( msg ); // Reset line number prev_cmd_line_number = 0; return true; }
BOOL SerialOpen(int port, int baud) { HANDLE Comport; DCB myDCB; COMMTIMEOUTS CTout; char str[100]; if (port > 9) sprintf(str, "\\\\.\\COM%d", port); else sprintf(str, "COM%d", port); // Open the serial port if ((Comport = CreateFile(str, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) return FALSE; // Configure Serial port (Setup Comm) // Buffer sizes if (!SetupComm(Comport, 128, 128)) return FALSE; // Setup DCB using current values if (!GetCommState(Comport, &myDCB)) return FALSE; myDCB.fInX = FALSE; // Turn off xon/xoff handler myDCB.fOutX = FALSE; myDCB.fOutxDsrFlow = FALSE; myDCB.fOutxCtsFlow = FALSE; // no hardware flow control. myDCB.BaudRate = baud; myDCB.DCBlength = sizeof(DCB); myDCB.fBinary = 1; myDCB.fParity = 0; myDCB.fDtrControl = DTR_CONTROL_DISABLE; myDCB.fDsrSensitivity = 0; myDCB.fTXContinueOnXoff = 1; myDCB.fNull = 0; myDCB.fRtsControl = RTS_CONTROL_DISABLE; myDCB.fDummy2 = 0; myDCB.wReserved = 0; myDCB.Parity = NOPARITY; myDCB.StopBits = ONESTOPBIT; myDCB.wReserved1 = 0; myDCB.ByteSize = 8; if (!SetCommState(Comport, &myDCB)) return FALSE; // Set timeouts CTout.ReadIntervalTimeout = 0xffffffff; CTout.ReadTotalTimeoutMultiplier = 0; CTout.ReadTotalTimeoutConstant = 0; CTout.WriteTotalTimeoutMultiplier = 0; CTout.WriteTotalTimeoutConstant = 5000; // don't hang if CTS is locked, for example SetCommTimeouts(Comport, &CTout); EscapeCommFunction(Comport, SETDTR); PurgeComm(Comport, PURGE_TXCLEAR | PURGE_RXCLEAR); SerialPort = Comport; return TRUE; }
// 打开串口 HANDLE CMySerialPort::OpenPort() { if (IsOpen()) { return m_portHandle; } if (0 >= m_strComName.GetLength()) { LOG.err_log("请先设置串口参数"); CString strTip = "请先设置串口参数"; SHOWTIP(strTip); return INVALID_HANDLE_VALUE; } // 以重叠方式打开串口 m_strComName = "\\\\.\\" + m_strComName; m_portHandle = CreateFile(m_strComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, //FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL); if (INVALID_HANDLE_VALUE == m_portHandle) { CString strTip; LOG.err_log("打开串口[%s]失败", (LPCSTR)m_strComName); strTip.Format("打开串口[%s]失败", m_strComName); SHOWTIP(strTip); return INVALID_HANDLE_VALUE; } // 设置串口参数 DCB dcb; BOOL ret = GetCommState(m_portHandle, &dcb); if (FALSE == ret) { LOG.err_log("获取串口默认配置参数失败"); CString strTip("获取串口默认配置参数失败"); SHOWTIP(strTip); return INVALID_HANDLE_VALUE; } dcb.BaudRate = m_baud; dcb.StopBits = m_stopbits; dcb.Parity = m_check; dcb.ByteSize = m_databits; //dcb.fParity = FALSE; // 禁止奇偶检查 //dcb.fBinary = TRUE;//是否允许传二进制 if (FALSE == SetCommState(m_portHandle,&dcb)) { LOG.err_log("配置串口参数失败!"); CString strTip("配置串口参数失败!"); SHOWTIP(strTip); return INVALID_HANDLE_VALUE; } // 设置缓冲区大小 if (FALSE == SetupComm(m_portHandle, 1024, 1024)) { LOG.err_log("缓冲区设置失败!"); CString strTip("缓冲区设置失败!"); SHOWTIP(strTip); return INVALID_HANDLE_VALUE; } // 设置串口超时时间 COMMTIMEOUTS CommTimeOuts; CommTimeOuts.ReadIntervalTimeout = 100; CommTimeOuts.ReadTotalTimeoutMultiplier = 100; CommTimeOuts.ReadTotalTimeoutConstant = 100; CommTimeOuts.WriteTotalTimeoutMultiplier = 500; CommTimeOuts.WriteTotalTimeoutConstant = 2000; if(false == SetCommTimeouts(m_portHandle,&CommTimeOuts)) { LOG.err_log("设置读写超时时间失败!"); CString strTip("设置读写超时时间失败!"); SHOWTIP(strTip); return INVALID_HANDLE_VALUE; } // 清空发送和接收缓冲区 PurgeComm(m_portHandle, PURGE_TXCLEAR|PURGE_RXCLEAR); m_bClosePort = false; return m_portHandle; }
//open // Opens the serial port using stored information // Sets the baud rate to the stored baud rate // 8 data bits, no parity, one stop bit bool serial_port::serial_open() { printf("SerialPort: Opening serial port %s at baud rate %d.\n", port_name, baud_rate); #ifdef WINDOWS file_descriptor = CreateFile(port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if((int)file_descriptor < 0) { printf("SerialPort: Port %s could not be opened: %d.\n", port_name, file_descriptor); return false; } SetupComm(file_descriptor, 1, 128); GetCommState(file_descriptor, &dcb); dcb.BaudRate = baud_rate; //Set baud rate dcb.ByteSize = 8; //8 data bits dcb.Parity = NOPARITY; //Parity = none dcb.StopBits = ONESTOPBIT; //One stop bit dcb.fAbortOnError = TRUE; //Abort on error dcb.fOutX = FALSE; //XON/XOFF off for transmit dcb.fInX = FALSE; //XON/XOFF off for receive dcb.fOutxCtsFlow = FALSE; //Turn off CTS flow control dcb.fRtsControl = RTS_CONTROL_DISABLE; //Options DISABLE, ENABLE, HANDSHAKE dcb.fOutxDsrFlow = FALSE; //Turn off DSR flow control dcb.fDtrControl = DTR_CONTROL_DISABLE; //Disable DTR control SetCommState(file_descriptor, &dcb); COMMTIMEOUTS timeouts = {0}; timeouts.ReadIntervalTimeout = 50; timeouts.ReadTotalTimeoutConstant=50; timeouts.ReadTotalTimeoutMultiplier=10; timeouts.WriteTotalTimeoutConstant=50; timeouts.WriteTotalTimeoutMultiplier=10; SetCommTimeouts(file_descriptor, &timeouts); #endif #ifdef LINUX file_descriptor = open(port_name, O_RDWR | O_NOCTTY | O_NDELAY); if(file_descriptor < 0) { printf("SerialPort: Port %s could not be opened: %d.\n", port_name, file_descriptor); return false; } serial_struct ss; ioctl(file_descriptor, TIOCGSERIAL, &ss); ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST | ASYNCB_LOW_LATENCY; ss.custom_divisor = (ss.baud_base + (baud_rate / 2)) / baud_rate; int closestSpeed = ss.baud_base / ss.custom_divisor; if((float)closestSpeed < ((float)baud_rate * (98.0f/100.0f)) || (float)closestSpeed > ((float)baud_rate * (102.0f/100.0f))) { printf("SerialPort: Cannot set %s to %d. Closest possible speed is %d.\n", port_name, baud_rate, closestSpeed); } else { printf("SerialPort: %s speed set to %d.\n", port_name, baud_rate); } fcntl(file_descriptor, F_SETFL, 0); #endif printf("SerialPort: Serial port %s opened successfully.\n", port_name); return true; }
ATMO_BOOL CAtmoClassicConnection::OpenConnection() { #if defined(_ATMO_VLC_PLUGIN_) char *serdevice = m_pAtmoConfig->getSerialDevice(); if(!serdevice) return ATMO_FALSE; #else int portNummer = m_pAtmoConfig->getComport(); m_dwLastWin32Error = 0; if(portNummer < 1) return ATMO_FALSE; // make no real sense;-) #endif CloseConnection(); #if !defined(_ATMO_VLC_PLUGIN_) char serdevice[16]; // com4294967295 sprintf(serdevice,"com%d",portNummer); #endif #if defined(WIN32) m_hComport = CreateFile(serdevice, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(m_hComport == INVALID_HANDLE_VALUE) { // we have a problem here can't open com port... somebody else may use it? // m_dwLastWin32Error = GetLastError(); return ATMO_FALSE; } /* change serial settings (Speed, stopbits etc.) */ DCB dcb; // für comport-parameter dcb.DCBlength = sizeof(DCB); GetCommState (m_hComport, &dcb); // ger current serialport settings dcb.BaudRate = 38400; // set speed dcb.ByteSize = 8; // set databits dcb.Parity = NOPARITY; // set parity dcb.StopBits = ONESTOPBIT; // set one stop bit SetCommState (m_hComport, &dcb); // apply settings #else int bconst = B38400; m_hComport = open(serdevice,O_RDWR |O_NOCTTY); if(m_hComport < 0) { return ATMO_FALSE; } struct termios tio; memset(&tio,0,sizeof(tio)); tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL); tio.c_iflag = (INPCK | BRKINT); cfsetispeed(&tio, bconst); cfsetospeed(&tio, bconst); if(!tcsetattr(m_hComport, TCSANOW, &tio)) { tcflush(m_hComport, TCIOFLUSH); } else { // can't change parms close(m_hComport); m_hComport = -1; return false; } #endif return true; }
bool SerialPort::Initialize() { TCHAR sysPortName[20]; DCB PortDCB; #if (WINDOWSPC>0) // Do not use COMn , use \\.\COMnn on PC version _stprintf(sysPortName, _T("\\\\.\\%s"), GetPortName()); #else // Do not use COMn , use COMn: on WinCE version _stprintf(sysPortName, _T("%s:"), GetPortName()); #endif StartupStore(_T(". ComPort %u Initialize <%s> speed=%u bit=%u %s"),GetPortIndex()+1,GetPortName(),_dwPortSpeed,8-_dwPortBit,NEWLINE); hPort = CreateFile(sysPortName, // Pointer to the name of the port GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode 0, // Share mode NULL, // Pointer to the security attribute OPEN_EXISTING, // How to open the serial port FILE_ATTRIBUTE_NORMAL, // Port attributes NULL); // Handle to port with attribute // to copy if (hPort == INVALID_HANDLE_VALUE) { DWORD dwError = GetLastError(); StartupStore(_T("... ComPort %u Init failed, error=%u%s"), GetPortIndex() + 1, dwError, NEWLINE); // 091117 StatusMessage(MB_OK, NULL, TEXT("%s %s"), gettext(TEXT("_@M762_")), GetPortName()); goto failed; } StartupStore(_T(". ComPort %u <%s> is now open%s"), GetPortIndex() + 1, GetPortName(), NEWLINE); PortDCB.DCBlength = sizeof (DCB); // Get the default port setting information. if (GetCommState(hPort, &PortDCB)==0) { StartupStore(_T("... ComPort %u GetCommState failed, error=%u%s"),GetPortIndex()+1,GetLastError(),NEWLINE); // @M759 = Unable to Change Settings on Port StatusMessage(MB_OK|MB_ICONINFORMATION, NULL, TEXT("%s %s"), gettext(TEXT("_@M759_")), GetPortName()); goto failed; } // Change the DCB structure settings. PortDCB.BaudRate = _dwPortSpeed; // Current baud PortDCB.fBinary = TRUE; // Binary mode; no EOF check PortDCB.fParity = TRUE; // Enable parity checking PortDCB.fOutxCtsFlow = FALSE; // CTS output flow control: when TRUE, and CTS off, output suspended PortDCB.fOutxDsrFlow = FALSE; // DSR output flow control PortDCB.fDtrControl = DTR_CONTROL_ENABLE; PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx PortDCB.fOutX = FALSE; // No XON/XOFF out flow control PortDCB.fInX = FALSE; // No XON/XOFF in flow control PortDCB.fErrorChar = FALSE; // Disable error replacement PortDCB.fNull = FALSE; // Disable null removal PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control PortDCB.fAbortOnError = FALSE; switch (_dwPortBit) { case bit7E1: PortDCB.ByteSize = 7; PortDCB.Parity = EVENPARITY; break; case bit8N1: default: PortDCB.ByteSize = 8; PortDCB.Parity = NOPARITY; break; } PortDCB.StopBits = ONESTOPBIT; PortDCB.EvtChar = '\n'; // wait for end of line, RXFLAG should detect it if (!SetCommState(hPort, &PortDCB)) { DWORD dwError = GetLastError(); StartupStore(_T("... ComPort %u Init <%s> change setting FAILED, error=%u%s"), GetPortIndex() + 1, GetPortName(), dwError, NEWLINE); // 091117 // @M759 = Unable to Change Settings on Port StatusMessage(MB_OK, TEXT("Error"), TEXT("%s %s"), gettext(TEXT("_@M759_")), GetPortName()); goto failed; } if (SetRxTimeout(RXTIMEOUT) == -1) { DWORD dwError = GetLastError(); StartupStore(_T("... ComPort %u Init <%s> change TimeOut FAILED, error=%u%s"), GetPortIndex() + 1, GetPortName(), dwError, NEWLINE); // 091117 // LKTOKEN _@M760_ = "Unable to Set Serial Port Timers" StatusMessage(MB_OK, TEXT("Error"), TEXT("%s %s"), gettext(TEXT("_@M760_")), GetPortName()); goto failed; } SetupComm(hPort, 1024, 1024); // Direct the port to perform extended functions SETDTR and SETRTS // SETDTR: Sends the DTR (data-terminal-ready) signal. // SETRTS: Sends the RTS (request-to-send) signal. EscapeCommFunction(hPort, SETDTR); EscapeCommFunction(hPort, SETRTS); if(!ComPort::Initialize()) { // no need to log failed of StartRxThread it's already made in ComPort::Initialize(); goto failed; } StartupStore(_T(". ComPort %u Init <%s> end OK%s"), GetPortIndex() + 1, GetPortName(), NEWLINE); return true; failed: if(hPort != INVALID_HANDLE_VALUE) { if (!CloseHandle(hPort)) { StartupStore(_T("... ComPort %u Init <%s> close failed, error=%u%s"),GetPortIndex() + 1, GetPortName(),NEWLINE); } else { StartupStore(_T("... ComPort %u Init <%s> closed%s"),GetPortIndex() + 1, GetPortName(),NEWLINE); } hPort = INVALID_HANDLE_VALUE; #if (WINDOWSPC>0) || NEWCOMM // 091206 Sleep(2000); // needed for windows bug #endif #if !(WINDOWSPC>0) if (_PollingMode) Sleep(2000); #endif } return false; }
Serial::Serial() { //We're not yet connected this->connected = false; HKEY hKey; if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Tyler Menezes\\Rfid Login", 0, KEY_READ, &hKey) != ERROR_SUCCESS){ delete hKey; return; // Token not recognized. } std::wstring port; GetStringRegKey(hKey, L"Port", port, L"COM3"); //Try to connect to the given port throuh CreateFile this->hSerial = CreateFile(port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //Check if the connection was successfull if(this->hSerial==INVALID_HANDLE_VALUE) { //If not success full display an Error if(GetLastError()==ERROR_FILE_NOT_FOUND){ //Print Error if neccessary printf("ERROR: Handle was not attached. Reason: %s not available.\n"); } else { printf("ERROR!!!"); } } else { //If connected we try to set the comm parameters DCB dcbSerialParams = {0}; //Try to get the current if (!GetCommState(this->hSerial, &dcbSerialParams)) { //If impossible, show an error printf("failed to get current serial parameters!"); } else { //Define serial connection parameters for the arduino board dcbSerialParams.BaudRate=CBR_9600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY; //Set the parameters and check for their proper application if(!SetCommState(hSerial, &dcbSerialParams)) { printf("ALERT: Could not set Serial Port parameters"); } else { //If everything went fine we're connected this->connected = true; //We wait 2s as the arduino board will be reseting Sleep(ARDUINO_WAIT_TIME); } } } }
static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) { DCB dcb; COMMTIMEOUTS timeouts; /* * Set up the serial port parameters. If we can't even * GetCommState, we ignore the problem on the grounds that the * user might have pointed us at some other type of two-way * device instead of a serial port. */ if (GetCommState(serport, &dcb)) { const char *str; /* * Boilerplate. */ dcb.fBinary = true; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fDsrSensitivity = false; dcb.fTXContinueOnXoff = false; dcb.fOutX = false; dcb.fInX = false; dcb.fErrorChar = false; dcb.fNull = false; dcb.fRtsControl = RTS_CONTROL_ENABLE; dcb.fAbortOnError = false; dcb.fOutxCtsFlow = false; dcb.fOutxDsrFlow = false; /* * Configurable parameters. */ dcb.BaudRate = conf_get_int(conf, CONF_serspeed); logeventf(serial->logctx, "Configuring baud rate %lu", dcb.BaudRate); dcb.ByteSize = conf_get_int(conf, CONF_serdatabits); logeventf(serial->logctx, "Configuring %u data bits", dcb.ByteSize); switch (conf_get_int(conf, CONF_serstopbits)) { case 2: dcb.StopBits = ONESTOPBIT; str = "1"; break; case 3: dcb.StopBits = ONE5STOPBITS; str = "1.5"; break; case 4: dcb.StopBits = TWOSTOPBITS; str = "2"; break; default: return "Invalid number of stop bits (need 1, 1.5 or 2)"; } logeventf(serial->logctx, "Configuring %s data bits", str); switch (conf_get_int(conf, CONF_serparity)) { case SER_PAR_NONE: dcb.Parity = NOPARITY; str = "no"; break; case SER_PAR_ODD: dcb.Parity = ODDPARITY; str = "odd"; break; case SER_PAR_EVEN: dcb.Parity = EVENPARITY; str = "even"; break; case SER_PAR_MARK: dcb.Parity = MARKPARITY; str = "mark"; break; case SER_PAR_SPACE: dcb.Parity = SPACEPARITY; str = "space"; break; } logeventf(serial->logctx, "Configuring %s parity", str); switch (conf_get_int(conf, CONF_serflow)) { case SER_FLOW_NONE: str = "no"; break; case SER_FLOW_XONXOFF: dcb.fOutX = dcb.fInX = true; str = "XON/XOFF"; break; case SER_FLOW_RTSCTS: dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; dcb.fOutxCtsFlow = true; str = "RTS/CTS"; break; case SER_FLOW_DSRDTR: dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; dcb.fOutxDsrFlow = true; str = "DSR/DTR"; break; } logeventf(serial->logctx, "Configuring %s flow control", str); if (!SetCommState(serport, &dcb)) return "Unable to configure serial port"; timeouts.ReadIntervalTimeout = 1; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (!SetCommTimeouts(serport, &timeouts)) return "Unable to configure serial timeouts"; } return NULL; }
/** * @brief Opens the serial device * * @param pDevice Pointer to string containing device name to open * @param baudRate The baud rate to open, valid values are 9600, 38400, 57600, 115200 * @param timeoutMs Read timeout in milliseconds * * @return Status of open, 0 on success, -1 on failure to open */ int SerialDevice::openDevice(const char* pDevice, const unsigned int baudRate, unsigned int timeoutMs) { #ifdef WIN32 // Open serial port on Windows m_deviceHandle = CreateFileA(pDevice, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (m_deviceHandle == INVALID_HANDLE_VALUE) { if(GetLastError() == ERROR_FILE_NOT_FOUND) { printf("SerialDevice: Error, serial device not found\n"); } else { printf("SerialDevice: Error while opening serial device\n"); } return -1; } // Set parameters DCB dcbSerialParams = { 0 }; dcbSerialParams.DCBlength = sizeof(dcbSerialParams); // Get the port parameters if (!GetCommState(m_deviceHandle, &dcbSerialParams)) { printf("SerialDevice: Error, could not get serial port params\n"); return -1; } switch (baudRate) { case 9600: dcbSerialParams.BaudRate = CBR_9600; break; case 38400: dcbSerialParams.BaudRate = CBR_38400; break; case 57600: dcbSerialParams.BaudRate = CBR_57600; break; case 115200: dcbSerialParams.BaudRate = CBR_115200; break; default: printf("SerialDevice: Invalid baud rate specified: %i\n", baudRate); return -1; } dcbSerialParams.ByteSize = 8; // 8 data bits dcbSerialParams.StopBits = ONESTOPBIT; // One stop bit dcbSerialParams.Parity = NOPARITY; // No parity if (!SetCommState(m_deviceHandle, &dcbSerialParams)) { printf("SerialDevice: Error setting CommState\n"); return -1; } // Set Timeout m_timeouts.ReadIntervalTimeout = 0; m_timeouts.ReadTotalTimeoutConstant = (DWORD)timeoutMs; // Set the Timeout in Milliseconds m_timeouts.ReadTotalTimeoutMultiplier = 0; m_timeouts.WriteTotalTimeoutConstant = MAXDWORD; m_timeouts.WriteTotalTimeoutMultiplier = 0; if(!SetCommTimeouts(m_deviceHandle, &m_timeouts)) { printf("SerialDevice: Error setting CommTimeouts\n"); return -1; } #endif #ifdef __linux__ speed_t speedSetting; // Open device m_deviceFd = open(pDevice, O_RDWR | O_NOCTTY | O_NDELAY); if (m_deviceFd == -1) { return -1; } // Open the device in nonblocking mode fcntl(m_deviceFd, F_SETFL, FNDELAY); // Set parameters tcgetattr(m_deviceFd, &m_portSettings); // Get the current options of the port bzero(&m_portSettings, sizeof(m_portSettings)); // Clear all the options switch (baudRate) { case 9600: speedSetting = B9600; break; case 38400: speedSetting = B38400; break; case 57600: speedSetting = B57600; break; case 115200: speedSetting = B115200; break; default: printf("SerialDevice: Invalid baud rate specified: %i\n", baudRate); return -1; } cfsetispeed(&m_portSettings, speedSetting); cfsetospeed(&m_portSettings, speedSetting); m_portSettings.c_cflag |= (CLOCAL | CREAD | CS8); m_portSettings.c_iflag |= (IGNPAR | IGNBRK ); m_portSettings.c_cc[VTIME] = timeoutMs / 100; // Timeout is in 1/10th second increments m_portSettings.c_cc[VMIN] = 0; tcsetattr(m_deviceFd, TCSANOW, &m_portSettings); #endif return 0; }
Serial::Serial(char *portName) { wchar_t PortName[100]; std::mbstowcs(PortName, portName, 100); //We're not yet connected this->connected = false; //Try to connect to the given port throuh CreateFile this->hSerial = CreateFile(PortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //Check if the connection was successfull if (this->hSerial == INVALID_HANDLE_VALUE) { //If not success full display an Error if (GetLastError() == ERROR_FILE_NOT_FOUND) { //Print Error if neccessary printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName); } else { printf("ERROR!!!"); } } else { //If connected we try to set the comm parameters DCB dcbSerialParams = { 0 }; //Try to get the current if (!GetCommState(this->hSerial, &dcbSerialParams)) { //If impossible, show an error printf("failed to get current serial parameters!"); } else { //Define serial connection parameters for the arduino board dcbSerialParams.BaudRate = CBR_115200; dcbSerialParams.ByteSize = 8; dcbSerialParams.StopBits = ONESTOPBIT; dcbSerialParams.Parity = NOPARITY; //Setting the DTR to Control_Enable ensures that the Arduino is properly //reset upon establishing a connection dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; //Set the parameters and check for their proper application if (!SetCommState(hSerial, &dcbSerialParams)) { printf("ALERT: Could not set Serial Port parameters"); } else { //If everything went fine we're connected this->connected = true; //Flush any remaining characters in the buffers PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR); //We wait 2s as the arduino board will be reseting Sleep(ARDUINO_WAIT_TIME); } } } }
Serial::Serial(TCHAR *strPort,int nRate,BOOL bSoftHandshake) { m_bBacked=FALSE; m_bOK=TRUE; int nDelay[] = {2000, 1000, 400}; m_hComm = CreateFile(strPort, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(m_hComm == INVALID_HANDLE_VALUE) { m_bOK=FALSE; return; } int nTry = 3; BOOL bPass; while (nTry-- > 0) { // bPass = FlushFileBuffers(m_hComm); // if(!bPass) break; bPass = EscapeCommFunction(m_hComm,CLRDTR); if(!bPass) break; Sleep(nDelay[nTry]); bPass = EscapeCommFunction(m_hComm,SETDTR); if(!bPass) break; DCB dcb; bPass = GetCommState(m_hComm,&dcb); if(!bPass) break; dcb.fBinary = TRUE; dcb.BaudRate = nRate; dcb.EvtChar = 0x0D; dcb.fParity = FALSE; dcb.Parity = 0; dcb.ByteSize = 8; dcb.StopBits = 0; if (!bSoftHandshake) { dcb.fInX = FALSE; dcb.fOutX = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fOutxCtsFlow = FALSE; } else { dcb.fInX = TRUE; dcb.fOutX = TRUE; dcb.fOutxDsrFlow = FALSE; dcb.fOutxCtsFlow = FALSE; } dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fRtsControl = RTS_CONTROL_ENABLE; bPass = SetCommState(m_hComm,&dcb); if(!bPass) break; Sleep(nDelay[nTry]); bPass = SetCommMask(m_hComm,EV_RXCHAR|EV_RXFLAG); if(!bPass) break; bPass = SetupComm(m_hComm,1024,1024); if(!bPass) break; bPass = PurgeComm(m_hComm,PURGE_RXABORT|PURGE_RXCLEAR); if(!bPass) break; COMMTIMEOUTS timeouts; memset(&timeouts,0,sizeof(COMMTIMEOUTS)); //缺省超时设置 timeouts.ReadIntervalTimeout=MAXDWORD; //读时如果缓冲区有数据,直接返回,否则等待 timeouts.ReadTotalTimeoutConstant=10000; //最长10秒 timeouts.ReadTotalTimeoutMultiplier=MAXDWORD; // timeouts.WriteTotalTimeoutConstant=0; //写时不计算超时 timeouts.WriteTotalTimeoutMultiplier=0; // bPass = SetCommTimeouts(m_hComm,&timeouts); if(!bPass) break; if(bPass) break; } m_bOK=bPass; }
void uart_initialize(uint8_t channel, const void* name, uint32_t baudrate, uint8_t databits, uart_parity parity, uart_stopbits stopbits) { const char* pipeIdentifier = "\\\\.\\pipe\\"; int pipeIdentifierLength = strlen(pipeIdentifier); char nameBuffer[1024]; uart_channel* uartChannel = look_up_uart_channel(channel); queue_init(&uartChannel->receiveQueue, uartChannel->receiveQueueBuffer, sizeof(uartChannel->receiveQueueBuffer)); if (memcmp(pipeIdentifier, name, pipeIdentifierLength) != 0 && strlen(name) > 4 && ((const char*)name)[0] != '\\') // it's a com port higher than 9 { sprintf_s(nameBuffer, sizeof(nameBuffer), "\\\\.\\%s", name); name = nameBuffer; } uartChannel->hPort = CreateFileA((LPCSTR)name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (uartChannel->hPort == INVALID_HANDLE_VALUE) { //DWORD error = GetLastError(); //char* errorString = strerror(error); //NABTO_LOG_TRACE(("Error:%l", error)); NABTO_LOG_FATAL(("Unable to open COM port '%s'!", (const char*)name)); } if (memcmp(pipeIdentifier, name, pipeIdentifierLength) == 0) // it's a pipe { DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT; if (!SetNamedPipeHandleState(uartChannel->hPort, &mode, NULL, NULL)) { //DWORD error = GetLastError(); //char* errorString = strerror(error); //NABTO_LOG_TRACE(("Error:%l", error)); NABTO_LOG_FATAL(("Unable to make pipe non-blocking '%s'!", (const char*)name)); } } else // it's a COM port { // Configure com port memset(&uartChannel->dcb, 0, sizeof(DCB)); uartChannel->dcb.DCBlength = sizeof(DCB); if (!GetCommState(uartChannel->hPort, &uartChannel->dcb)) { NABTO_LOG_FATAL(("Unable to get COM port state!")); } uartChannel->dcb.BaudRate = baudrate; if (databits < 5 || 8 < databits) { NABTO_LOG_FATAL(("Invalid number of databits for UART!")); } uartChannel->dcb.ByteSize = databits; switch (parity) { case UART_PARITY_NONE: uartChannel->dcb.Parity = NOPARITY; break; case UART_PARITY_EVEN: uartChannel->dcb.fParity = TRUE; uartChannel->dcb.fErrorChar = FALSE; uartChannel->dcb.Parity = EVENPARITY; break; case UART_PARITY_ODD: uartChannel->dcb.fParity = TRUE; uartChannel->dcb.fErrorChar = FALSE; uartChannel->dcb.Parity = ODDPARITY; break; case UART_PARITY_MARK: uartChannel->dcb.fParity = TRUE; uartChannel->dcb.fErrorChar = FALSE; uartChannel->dcb.Parity = MARKPARITY; break; case UART_PARITY_SPACE: uartChannel->dcb.fParity = TRUE; uartChannel->dcb.fErrorChar = FALSE; uartChannel->dcb.Parity = SPACEPARITY; break; default: NABTO_LOG_FATAL(("Invalid number of databits for UART!")); } switch (stopbits) { case UART_STOPBITS_ONE: uartChannel->dcb.StopBits = ONESTOPBIT; break; case UART_STOPBITS_TWO: uartChannel->dcb.StopBits = TWOSTOPBITS; break; default: NABTO_LOG_FATAL(("Invalid number of stopbits for UART!")); } uartChannel->dcb.fBinary = TRUE; if (!SetCommState(uartChannel->hPort, &uartChannel->dcb)) { NABTO_LOG_FATAL(("Unable to set COM port state!")); } // set event masks so the receive queue can be polled. if (!SetCommMask(uartChannel->hPort, EV_RXCHAR | EV_ERR)) { DWORD error = GetLastError(); NABTO_LOG_FATAL(("Unable to set COM port state (%lu)!", error)); } // set read timeouts so ReadFile performs non-blocking reads. // RMW the port's timeouts structure if (!GetCommTimeouts(uartChannel->hPort, &uartChannel->timeouts)) { NABTO_LOG_FATAL(("Unable to get COM port timeouts!")); } uartChannel->timeouts.ReadIntervalTimeout = MAXDWORD; uartChannel->timeouts.ReadTotalTimeoutConstant = 1; uartChannel->timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; uartChannel->timeouts.WriteTotalTimeoutConstant = 200; uartChannel->timeouts.WriteTotalTimeoutMultiplier = 1; if (!SetCommTimeouts(uartChannel->hPort, &uartChannel->timeouts)) { NABTO_LOG_FATAL(("Unable to set COM port timeouts!")); } } }
// // Initialize the port. This can be port 1 to 4. // BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (receives message) UINT portnr, // portnumber (1..4) UINT baud, // baudrate char parity, // parity UINT databits, // databits UINT stopbits, // stopbits DWORD dwCommEvents, // EV_RXCHAR, EV_CTS etc UINT writebuffersize) // size to the writebuffer { assert(portnr > 0 && portnr < MaxSerialPortNum+1); assert(pPortOwner != NULL); // if the thread is alive: Kill if (m_bThreadAlive) { do { SetEvent(m_hShutdownEvent); } while (m_bThreadAlive); TRACE("Thread ended\n"); } // create events if (m_ov.hEvent != NULL) ResetEvent(m_ov.hEvent); m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (m_hWriteEvent != NULL) ResetEvent(m_hWriteEvent); m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (m_hShutdownEvent != NULL) ResetEvent(m_hShutdownEvent); m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // initialize the event objects m_hEventArray[0] = m_hShutdownEvent; // highest priority m_hEventArray[1] = m_ov.hEvent; m_hEventArray[2] = m_hWriteEvent; // initialize critical section InitializeCriticalSection(&m_csCommunicationSync); // set buffersize for writing and save the owner m_pOwner = pPortOwner; if (m_szWriteBuffer != NULL) delete [] m_szWriteBuffer; m_szWriteBuffer = new char[writebuffersize]; m_nPortNr = portnr; m_nWriteBufferSize = writebuffersize; m_dwCommEvents = dwCommEvents; BOOL bResult = FALSE; char *szPort = new char[50]; char *szBaud = new char[50]; // now it critical! EnterCriticalSection(&m_csCommunicationSync); // if the port is already opened: close it if (m_hComm != NULL) { CloseHandle(m_hComm); m_hComm = NULL; } // prepare port strings sprintf(szPort, "COM%d", portnr); sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits); // get a handle to the port m_hComm = CreateFile(szPort, // communication port string (COMX) GENERIC_READ | GENERIC_WRITE, // read/write types 0, // comm devices must be opened with exclusive access NULL, // no security attributes OPEN_EXISTING, // comm devices must use OPEN_EXISTING FILE_FLAG_OVERLAPPED, // Async I/O 0); // template must be 0 for comm devices if (m_hComm == INVALID_HANDLE_VALUE) { // port not found delete [] szPort; delete [] szBaud; return FALSE; } // set the timeout values m_CommTimeouts.ReadIntervalTimeout = 1000; m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000; m_CommTimeouts.ReadTotalTimeoutConstant = 1000; m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000; m_CommTimeouts.WriteTotalTimeoutConstant = 1000; // configure if (SetCommTimeouts(m_hComm, &m_CommTimeouts)) { if (SetCommMask(m_hComm, dwCommEvents)) { if (GetCommState(m_hComm, &m_dcb)) { m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high! if (BuildCommDCB(szBaud, &m_dcb)) { if (SetCommState(m_hComm, &m_dcb)) ; // normal operation... continue else ProcessErrorMessage("SetCommState()"); } else ProcessErrorMessage("BuildCommDCB()"); } else ProcessErrorMessage("GetCommState()"); } else ProcessErrorMessage("SetCommMask()"); } else ProcessErrorMessage("SetCommTimeouts()"); delete [] szPort; delete [] szBaud; // flush the port PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // release critical section LeaveCriticalSection(&m_csCommunicationSync); TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr); return TRUE; }
int SerialPort::init (const char device[]) { #ifdef WIN32 idCom=CreateFile(device,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(idCom==INVALID_HANDLE_VALUE ) { idCom=NULL; printf("Error Opening port Win32\n"); return(PORT_ERROR_CREATEFILE); } else { GetCommState(idCom,&dcb); dcb.BaudRate=CBR_9600; dcb.fBinary=1; dcb.fOutxCtsFlow=0; dcb.fOutxDsrFlow=0; dcb.fDtrControl=1;////?????????? //dcb.fDtrControl=DTR_CONTROL_DISABLE;////?????????? dcb.fDsrSensitivity=0; dcb.fTXContinueOnXoff=1; dcb.fOutX=0; dcb.fInX=0; dcb.fErrorChar=0; dcb.fNull=0; dcb.fRtsControl=1; dcb.fAbortOnError=1; dcb.XonLim=2048; dcb.XoffLim=512; dcb.ByteSize=8; dcb.Parity=0; dcb.StopBits=0; // dcb.StopBits=ONESTOPBIT; dcb.XonChar=17; dcb.XoffChar=19; dcb.ErrorChar=0; dcb.EofChar=0; dcb.EvtChar=0; dcb.DCBlength=sizeof(dcb); if(SetCommState(idCom,&dcb)==0) { CloseHandle(idCom); idCom=NULL; printf("Unable to configure port\n"); return(PORT_ERROR_SETDCB); } timeouts.ReadIntervalTimeout=PORT_COMMS_INTERVAL_TIMEOUT; timeouts.ReadTotalTimeoutMultiplier=PORT_COMMS_TOTAL_TIMEOUT_MULTIPLIER; timeouts.ReadTotalTimeoutConstant=PORT_COMMS_TOTAL_TIMEOUT_CONSTANT; timeouts.WriteTotalTimeoutMultiplier=0; timeouts.WriteTotalTimeoutConstant=0; SetCommTimeouts(idCom,&timeouts); /* unsigned long flus=0; int ret; do { char dummy[1000]; ret=ReadFile(idCom,dummy,1000,&flus,NULL); if(flus!=0) printf("%d bytes have been flushed\n",flus); }while(flus!=0);*/ return(PORT_OK); } #else if(serialPort!=-1) close(); struct termios serialSettings; serialPort=-1; serialPort = open (device, O_RDWR |O_NOCTTY); if(serialPort==-1) { printf("Error al abrir el puerto\n"); return PORT_ERROR; } serialSettings.c_cc[VMIN] = 0; serialSettings.c_cc[VTIME] = 1; serialSettings.c_oflag = 0; serialSettings.c_iflag = ( IGNPAR ) ;//DRL( IGNBRK | IGNPAR ) ; serialSettings.c_cflag = ( CLOCAL| CREAD | B9600 | CS8 ); serialSettings.c_lflag = 0; cfsetospeed (&serialSettings, B9600); cfsetispeed (&serialSettings, B9600); if(tcsetattr (serialPort, TCSANOW, &serialSettings)!=0) return PORT_ERROR; else return PORT_OK; #endif }
// Automatic protocol detection DFUEngine::Result DFURequestsCOM::AutomaticPassiveBCSP() { // Ensure that any previous transport is disconnected impl_->transport.Disconnect(); // Purge any operations in progress if (!PurgeComm(impl_->com, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) { return DFUEngine::fail_os; } // Read the current COM port settings DCB dcb; COMMTIMEOUTS timeouts; if (!GetCommState(impl_->com, &dcb) || !GetCommTimeouts(impl_->com, &timeouts)) { return DFUEngine::fail_os; } // Set the basic COM port configuration dcb.fBinary = true; dcb.fParity = comParity != NOPARITY; dcb.fOutxCtsFlow = true; dcb.fOutxDsrFlow = false; dcb.fDsrSensitivity = false; dcb.fOutX = false; dcb.fInX = false; dcb.fErrorChar = false; dcb.fNull = false; dcb.fAbortOnError = false; dcb.ByteSize = comDataBits; dcb.Parity = comParity; dcb.StopBits = comStopBits; if (!SetCommState(impl_->com, &dcb)) { return DFUEngine::fail_os; } // Set the timeouts for reading uint32 timeout = impl_->baud && impl_->baud->next ? comReceiveMilliseconds : comReceiveMillisecondsSingle; timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutConstant = timeout; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; if (!SetCommTimeouts(impl_->com, &timeouts)) { return DFUEngine::fail_os; } // Attempt to reset the connection using the handshaking lines dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fRtsControl = RTS_CONTROL_DISABLE; if (!SetCommState(impl_->com, &dcb)) { return DFUEngine::fail_os; } Sleep(comHandshakeMilliseconds); dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; if (!SetCommState(impl_->com, &dcb)) { return DFUEngine::fail_os; } // Loop through each of the baud rates int bufferLength = 2 * sizeof(bcspSync); SmartPtr<uint8, true> buffer(new uint8[bufferLength]); bool connected = false; for (BaudRateList *pos = impl_->baud; !connected && pos; pos = pos->next) { // Check for an abort request DFUEngine::Result result = CheckAbort(); if (!result) return result; // Configure the port for this baud rate int baudRate = pos->baud; Progress(DFUEngine::transport_bcsp_passive_le, baudRate); dcb.BaudRate = baudRate; if (!SetCommState(impl_->com, &dcb)) { return DFUEngine::fail_os; } // Look for the BCSP sync message int bufferUsed = 0; uint32 endTick = GetTickCount() + timeout; while (!connected && (int32(GetTickCount() - endTick) < 0)) { // Ensure that there is sufficient space in the buffer DWORD read; int bufferLeave = sizeof(bcspSync) - 1; if (bufferLeave < bufferUsed) { // Shuffle the existing contents down memmove(buffer, buffer + bufferUsed - bufferLeave, bufferLeave); bufferUsed = bufferLeave; } // Read some more data from the serial port #if !defined _WINCE && !defined _WIN32_WCE OVERLAPPED overlapped; overlapped.Offset = 0; overlapped.OffsetHigh = 0; HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); if(!event) return DFUEngine::fail_os; overlapped.hEvent = event; if (!ReadFile(impl_->com, buffer + bufferUsed, bufferLength - bufferUsed, &read, &overlapped) && (GetLastError() != ERROR_IO_PENDING)) { CloseHandle(event); return DFUEngine::fail_os; } // Wait for the operation to complete WaitForSingleObject(event, timeout); CloseHandle(event); // Get the result if (!GetOverlappedResult(impl_->com, &overlapped, &read, false)) { return DFUEngine::fail_os; } #else // Set the serial port timeouts to return immediately COMMTIMEOUTS timeouts; memset(&timeouts, 0, sizeof(timeouts)); timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutConstant = 0; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (!SetCommTimeouts(impl_->com, &timeouts)) { return DFUEngine::fail_os; } // Read any waiting data if (!ReadFile(impl_->com, buffer + bufferUsed, bufferLength - bufferUsed, &read, 0)) { return DFUEngine::fail_os; } #endif // Update the buffer position bufferUsed += read; // Check if the BCSP sync message has been received for (int offset = 0; !connected && (offset + int(sizeof(bcspSync)) <= bufferUsed); ++offset) { connected = !memcmp(buffer + offset, bcspSync, sizeof(bcspSync)); } } // Store the baud rate and link establishment if successful if (connected) { FreeBaudRateList(impl_->baud); impl_->baud = new BaudRateList; impl_->baud->next = 0; impl_->baud->baud = baudRate; impl_->sync = sync_enabled; } } // Return an error if failed to connect if (!connected) return DFUEngine::fail_com_connect; // Attempt to start the actual transport DFUEngine::Result result = impl_->transport.ConnectBCSP(impl_->port, impl_->baud->baud, true, false, impl_->com); if (!result) return result; // Check if private channels work result = TestPrivateChannel(); if (!result) { // Try tunnelling if appropriate if ((impl_->protocol == protocol_unknown) || (impl_->protocol == protocol_bcsp_tunnel)) { // Try again with tunnelling result = impl_->transport.ConnectBCSP(impl_->port, impl_->baud->baud, true, true, impl_->com); if (result) result = TestPrivateChannel(); if (!result) return result; // Store the protocol if successful impl_->protocol = protocol_bcsp_tunnel; } else return result; } // Successful if this point reached return DFUEngine::success; }
/**************************************************************************** * Opens com port * * \param comPort Com port to be opened. * \param baud Baud rate * \param * \return Opens the com port *****************************************************************************/ void CComPort::OpenComPort(unsigned int comPort, unsigned int baud) { CString buff; DWORD bytes_read = 0; // Number of bytes read from port DWORD bytes_written = 0; // Number of bytes written to the port int bStatus; DCB comSettings; // Contains various port settings COMMTIMEOUTS CommTimeouts; if(comPortHandle) { // If com port is already open, close it. CloseComPort(); } buff = comPortStrng[comPort]; // Open COM port if ((comPortHandle = CreateFile(buff, // open com5: GENERIC_READ | GENERIC_WRITE, // for reading and writing 0, // exclusive access NULL, // no security attributes OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { // error processing code goes here MessageBox(NULL, "Not able to open com port!", NULL, 0); comPortHandle = NULL; } else { // Set timeouts in milliseconds CommTimeouts.ReadIntervalTimeout = 0; CommTimeouts.ReadTotalTimeoutMultiplier = 0; CommTimeouts.ReadTotalTimeoutConstant = 5; // Read time out 5ms. CommTimeouts.WriteTotalTimeoutMultiplier = 1; CommTimeouts.WriteTotalTimeoutConstant = 500; // Write time out 500ms. (void)SetCommTimeouts(comPortHandle,&CommTimeouts); // Set Port parameters. // Make a call to GetCommState() first in order to fill // the comSettings structure with all the necessary values. // Then change the ones you want and call SetCommState(). GetCommState(comPortHandle, &comSettings); baud = baudTable[baud]; comSettings.BaudRate = baud; comSettings.StopBits = ONESTOPBIT; comSettings.ByteSize = 8; comSettings.Parity = NOPARITY; // No Parity comSettings.fParity = FALSE; comSettings.fRtsControl = RTS_CONTROL_ENABLE; // Keep the RTS ON, to trigger bootloader enter bootload mode. bStatus = SetCommState(comPortHandle, &comSettings); if (bStatus == 0) { // error processing code goes here MessageBox(NULL, "Error in setting the COM port!", NULL, 0); CloseComPort(); } } }
/****************************************************************************** * @func : ReadConfig * * Rôle : Initialisation de donnees membres * @parm : LPCSTR | szIni | fichier de configuration *****************************************************************************/ BOOL CSerialPort::bReadConfig(LPCTSTR pszFileName) { TCHAR szPort[ 64 ]; long lSizeDataMax; BOOL bReturn; bReturn = CThreadInterface::bReadConfig(pszFileName); #ifndef TEST //TRACE_LOG_MSG(_T("! CThreadInterface::bReadConfig !")); // taille du buffer lSizeDataMax = iGetPrivateProfileInt(_T("Config"),_T("m_lSizeDataMax"),1024,pszFileName); //TRACE_LOG_MSG(_T("! m_lSizeDataMax !")); if (lSizeDataMax > 0) { if (m_pRxBuffer == NULL) { m_pRxBuffer = (BYTE*)malloc(lSizeDataMax + 16); } else if (m_lSizeDataMax != lSizeDataMax) { m_pRxBuffer = (BYTE*)realloc(m_pRxBuffer,lSizeDataMax + 16); } m_lSizeDataMax = lSizeDataMax; } //TRACE_LOG_MSG(_T("! if (m_pRxBuffer == NULL) !")); // port com m_nNumPort = iGetPrivateProfileInt(_T("Config"),_T("m_nNumPort"),m_nNumPort,pszFileName); //TRACE_LOG_MSG(_T("! m_nNumPort !")); m_DCB.DCBlength = sizeof(DCB); //TRACE_LOG_MSG(_T("! sizeof(DCB) !")); memset(&m_DCB,0,sizeof(m_DCB)); //TRACE_LOG_MSG(_T("! memset !")); #ifdef _WIN32_WCE _stprintf( szPort, _T("COM%d:"), m_nNumPort ); #else _stprintf( szPort, _T("\\\\.\\COM%d"), m_nNumPort ); #endif //TRACE_LOG_MSG(_T("! szPort !")); m_hTTY = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM/*FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED*/, NULL ); //TRACE_LOG_MSG(_T("! CreateFile !")); if (m_hTTY != INVALID_HANDLE_VALUE) { GetCommState( m_hTTY, &m_DCB ); CloseHandle(m_hTTY); m_hTTY = INVALID_HANDLE_VALUE; //TRACE_LOG_MSG(_T("! CreateFile ok!")); } else { TRACE_DEBUG_LAST_ERROR(eDebug,eConfig,GetLastError()); TRACE_LOG_MSG(_T("! CreateFile fail!")); } //TRACE_LOG_MSG(_T("! m_hTTY !")); m_DCB.BaudRate = iGetPrivateProfileInt(_T("Com"), _T("BaudRate"),m_DCB.BaudRate, pszFileName); m_DCB.ByteSize = iGetPrivateProfileInt(_T("Com"), _T("ByteSize"), m_DCB.ByteSize, pszFileName); m_DCB.Parity = iGetPrivateProfileInt(_T("Com"), _T("Parity"), m_DCB.Parity, pszFileName); m_DCB.fParity = iGetPrivateProfileInt(_T("Com"), _T("fParity"), m_DCB.fParity, pszFileName); m_DCB.StopBits = iGetPrivateProfileInt(_T("Com"), _T("StopBits"),m_DCB.StopBits, pszFileName); m_DCB.fBinary = iGetPrivateProfileInt(_T("Com"), _T("fBinary"), m_DCB.fBinary, pszFileName); m_DCB.fOutxCtsFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxCtsFlow"),m_DCB.fOutxCtsFlow, pszFileName); m_DCB.fOutxDsrFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxDsrFlow"),m_DCB.fOutxDsrFlow, pszFileName); m_DCB.fDtrControl = iGetPrivateProfileInt(_T("Com"), _T("fDtrControl"), m_DCB.fDtrControl, pszFileName); m_DCB.fDsrSensitivity = iGetPrivateProfileInt(_T("Com"), _T("fDsrSensitivity"), m_DCB.fDsrSensitivity, pszFileName); m_DCB.fTXContinueOnXoff = iGetPrivateProfileInt(_T("Com"), _T("fTXContinueOnXoff"),m_DCB.fTXContinueOnXoff, pszFileName); m_DCB.fOutX = iGetPrivateProfileInt(_T("Com"), _T("fOutX"), m_DCB.fOutX, pszFileName); m_DCB.fInX = iGetPrivateProfileInt(_T("Com"), _T("fInX"),m_DCB.fInX, pszFileName); m_DCB.fErrorChar = iGetPrivateProfileInt(_T("Com"), _T("fErrorChar"),m_DCB.fErrorChar, pszFileName); m_DCB.fNull = iGetPrivateProfileInt(_T("Com"), _T("fNull"),m_DCB.fNull, pszFileName); m_DCB.fRtsControl = iGetPrivateProfileInt(_T("Com"), _T("fRtsControl"), m_DCB.fRtsControl, pszFileName); m_DCB.fAbortOnError = iGetPrivateProfileInt(_T("Com"), _T("fAbortOnError"), m_DCB.fAbortOnError, pszFileName); m_DCB.XonLim = iGetPrivateProfileInt(_T("Com"), _T("XonLim"),m_DCB.XonLim, pszFileName); m_DCB.XoffLim = iGetPrivateProfileInt(_T("Com"), _T("XoffLim"),m_DCB.XoffLim, pszFileName); m_DCB.ErrorChar = iGetPrivateProfileInt(_T("Com"), _T("ErrorChar"),m_DCB.ErrorChar, pszFileName); m_DCB.XonChar = iGetPrivateProfileInt(_T("Com"), _T("XonChar"), m_DCB.XonChar, pszFileName); m_DCB.XoffChar = iGetPrivateProfileInt(_T("Com"), _T("XoffChar"), m_DCB.XoffChar, pszFileName); m_DCB.fDummy2 = 17; m_DCB.wReserved = 0; m_DCB.EofChar = iGetPrivateProfileInt(_T("Com"), _T("EofChar"), m_DCB.EofChar, pszFileName);//'\n'; m_DCB.EvtChar = iGetPrivateProfileInt(_T("Com"), _T("EvtChar"), m_DCB.EvtChar, pszFileName);//'\r'; //TRACE_LOG_MSG(_T("! all DCB !")); #else HANDLE hf ; long filelen = openFile(pszFileName, hf); // taille du buffer lSizeDataMax = iGetPrivateProfileInt(_T("Config"),_T("m_lSizeDataMax"),1024,hf, filelen); _tprintf(_T(" lSizeDataMax\n")); if (lSizeDataMax > 0) { if (m_pRxBuffer == NULL) { #ifndef TEST m_pRxBuffer = (BYTE*)malloc(lSizeDataMax + 16); #else m_pRxBuffer = (BYTE*)HeapAlloc(getPrivateHeap(), 1, lSizeDataMax + 16); #endif } else if (m_lSizeDataMax != lSizeDataMax) { _tprintf(_T("AV %d \n"),m_pRxBuffer); m_pRxBuffer = (BYTE*)realloc(m_pRxBuffer,lSizeDataMax + 16); _tprintf(_T("AV %d \n"),m_pRxBuffer); } m_lSizeDataMax = lSizeDataMax; } // port com m_nNumPort = iGetPrivateProfileInt(_T("Config"),_T("m_nNumPort"),m_nNumPort,hf, filelen); m_DCB.DCBlength = sizeof(DCB); memset(&m_DCB,0,sizeof(m_DCB)); _tprintf(_T(" memset\n")); closeFile(hf); #ifdef _WIN32_WCE _tprintf(_T(" _WIN32_WCE\n")); _stprintf( szPort, _T("COM%d:"), m_nNumPort ); #else _stprintf( szPort, _T("\\\\.\\COM%d"), m_nNumPort ); #endif _tprintf(_T(" m_hTTY\n")); m_hTTY = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM/*FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED*/, NULL ); _tprintf(_T(" CreateFile\n")); if (m_hTTY != INVALID_HANDLE_VALUE) { _tprintf(_T(" INVALID_HANDLE_VALUE\n")); GetCommState( m_hTTY, &m_DCB ); CloseHandle(m_hTTY); m_hTTY = INVALID_HANDLE_VALUE; } else { _tprintf(_T(" TRACE_DEBUG_LAST_ERROR\n")); TRACE_DEBUG_LAST_ERROR(eDebug,eConfig,GetLastError()); } filelen = openFile(pszFileName, hf); _tprintf(_T(" TRACE_DEBUG_LAST_ERROR\n")); m_DCB.BaudRate = iGetPrivateProfileInt(_T("Com"), _T("BaudRate"),m_DCB.BaudRate, hf, filelen); m_DCB.ByteSize = iGetPrivateProfileInt(_T("Com"), _T("ByteSize"), m_DCB.ByteSize, hf, filelen); m_DCB.Parity = iGetPrivateProfileInt(_T("Com"), _T("Parity"), m_DCB.Parity, hf, filelen); m_DCB.fParity = iGetPrivateProfileInt(_T("Com"), _T("fParity"), m_DCB.fParity, hf, filelen); m_DCB.StopBits = iGetPrivateProfileInt(_T("Com"), _T("StopBits"),m_DCB.StopBits, hf, filelen); m_DCB.fBinary = iGetPrivateProfileInt(_T("Com"), _T("fBinary"), m_DCB.fBinary, hf, filelen); m_DCB.fOutxCtsFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxCtsFlow"),m_DCB.fOutxCtsFlow, hf, filelen); m_DCB.fOutxDsrFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxDsrFlow"),m_DCB.fOutxDsrFlow, hf, filelen); m_DCB.fDtrControl = iGetPrivateProfileInt(_T("Com"), _T("fDtrControl"), m_DCB.fDtrControl, hf, filelen); m_DCB.fDsrSensitivity = iGetPrivateProfileInt(_T("Com"), _T("fDsrSensitivity"), m_DCB.fDsrSensitivity, hf, filelen); m_DCB.fTXContinueOnXoff = iGetPrivateProfileInt(_T("Com"), _T("fTXContinueOnXoff"),m_DCB.fTXContinueOnXoff, hf, filelen); m_DCB.fOutX = iGetPrivateProfileInt(_T("Com"), _T("fOutX"), m_DCB.fOutX, hf, filelen); m_DCB.fInX = iGetPrivateProfileInt(_T("Com"), _T("fInX"),m_DCB.fInX, hf, filelen); m_DCB.fErrorChar = iGetPrivateProfileInt(_T("Com"), _T("fErrorChar"),m_DCB.fErrorChar, hf, filelen); m_DCB.fNull = iGetPrivateProfileInt(_T("Com"), _T("fNull"),m_DCB.fNull, hf, filelen); m_DCB.fRtsControl = iGetPrivateProfileInt(_T("Com"), _T("fRtsControl"), m_DCB.fRtsControl, hf, filelen); m_DCB.fAbortOnError = iGetPrivateProfileInt(_T("Com"), _T("fAbortOnError"), m_DCB.fAbortOnError, hf, filelen); m_DCB.XonLim = iGetPrivateProfileInt(_T("Com"), _T("XonLim"),m_DCB.XonLim, hf, filelen); m_DCB.XoffLim = iGetPrivateProfileInt(_T("Com"), _T("XoffLim"),m_DCB.XoffLim, hf, filelen); m_DCB.ErrorChar = iGetPrivateProfileInt(_T("Com"), _T("ErrorChar"),m_DCB.ErrorChar, hf, filelen); m_DCB.XonChar = iGetPrivateProfileInt(_T("Com"), _T("XonChar"), m_DCB.XonChar, hf, filelen); m_DCB.XoffChar = iGetPrivateProfileInt(_T("Com"), _T("XoffChar"), m_DCB.XoffChar, hf, filelen); m_DCB.fDummy2 = 17; m_DCB.wReserved = 0; m_DCB.EofChar = iGetPrivateProfileInt(_T("Com"), _T("EofChar"), m_DCB.EofChar, hf, filelen);//'\n'; m_DCB.EvtChar = iGetPrivateProfileInt(_T("Com"), _T("EvtChar"), m_DCB.EvtChar, hf, filelen);//'\r'; _tprintf(_T(" m_DCB\n")); closeFile(hf); _tprintf(_T(" closeFile(hf);\n")); #endif if (!bReturn) TRACE_DEBUG(eDebug,eConfig,_T(__FILE__),_T(__FUNCTION__),__LINE__,_T("Error")); return bReturn; }
CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd) :CSerial (id, cmd) { InstallationSuccessful = false; hCom = INVALID_HANDLE_VALUE; // else destructor may close an invalid handle rx_retry = 0; rx_retry_max = 0; // open the port in NT object space (recommended by Microsoft) // allows the user to open COM10+ and custom port names. std::string prefix="\\\\.\\"; std::string tmpstring; if(!cmd->FindStringBegin("realport:",tmpstring,false)) return; #if SERIAL_DEBUG if(dbg_modemcontrol) fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n", PIC_FullIndex(),tmpstring.c_str()); #endif prefix.append(tmpstring); // rxdelay: How many milliseconds to wait before causing an // overflow when the application is unresponsive. if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) { if(!(rx_retry_max<=10000)) { rx_retry_max=0; } } const char* tmpchar=prefix.c_str(); LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str()); hCom = CreateFile (tmpchar, GENERIC_READ | GENERIC_WRITE, 0, // must be opened with exclusive-access NULL, // no security attributes OPEN_EXISTING, // must use OPEN_EXISTING 0, // non overlapped I/O NULL // hTemplate must be NULL for comm devices ); if (hCom == INVALID_HANDLE_VALUE) { int error = GetLastError (); LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.", COMNUMBER, tmpstring.c_str()); if (error == 2) { LOG_MSG ("The specified port does not exist."); } else if (error == 5) { LOG_MSG ("The specified port is already in use."); } else { LOG_MSG ("Windows error %d occurred.", error); } return; } dcb.DCBlength=sizeof(dcb); fSuccess = GetCommState (hCom, &dcb); if (!fSuccess) { // Handle the error. LOG_MSG ("GetCommState failed with error %d.\n", (int)GetLastError ()); hCom = INVALID_HANDLE_VALUE; return; } // initialize the port dcb.BaudRate=CBR_9600; dcb.fBinary=true; dcb.fParity=true; dcb.fOutxCtsFlow=false; dcb.fOutxDsrFlow=false; dcb.fDtrControl=DTR_CONTROL_DISABLE; dcb.fDsrSensitivity=false; dcb.fOutX=false; dcb.fInX=false; dcb.fErrorChar=0; dcb.fNull=false; dcb.fRtsControl=RTS_CONTROL_DISABLE; dcb.fAbortOnError=false; dcb.ByteSize=8; dcb.Parity=NOPARITY; dcb.StopBits=ONESTOPBIT; fSuccess = SetCommState (hCom, &dcb); if (!fSuccess) { // Handle the error. LOG_MSG ("SetCommState failed with error %d.\n", (int)GetLastError ()); hCom = INVALID_HANDLE_VALUE; return; } // Configure timeouts to effectively use polling COMMTIMEOUTS ct; ct.ReadIntervalTimeout = MAXDWORD; ct.ReadTotalTimeoutConstant = 0; ct.ReadTotalTimeoutMultiplier = 0; ct.WriteTotalTimeoutConstant = 0; ct.WriteTotalTimeoutMultiplier = 0; SetCommTimeouts (hCom, &ct); CSerial::Init_Registers(); InstallationSuccessful = true; receiveblock=false; ClearCommBreak (hCom); setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick }
/* Sets up a serial port for RTU communications */ static int _modbus_rtu_connect(modbus_t *ctx) { #if defined(_WIN32) DCB dcb; #else struct termios tios; speed_t speed; #endif modbus_rtu_t *ctx_rtu = ctx->backend_data; if (ctx->debug) { printf("Opening %s at %d bauds (%c, %d, %d)\n", ctx_rtu->device, ctx_rtu->baud, ctx_rtu->parity, ctx_rtu->data_bit, ctx_rtu->stop_bit); } #if defined(_WIN32) /* Some references here: * http://msdn.microsoft.com/en-us/library/aa450602.aspx */ win32_ser_init(&ctx_rtu->w_ser); /* ctx_rtu->device should contain a string like "COMxx:" xx being a decimal number */ ctx_rtu->w_ser.fd = CreateFileA(ctx_rtu->device, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); /* Error checking */ if (ctx_rtu->w_ser.fd == INVALID_HANDLE_VALUE) { fprintf(stderr, "ERROR Can't open the device %s (%s)\n", ctx_rtu->device, strerror(errno)); return -1; } /* Save params */ ctx_rtu->old_dcb.DCBlength = sizeof(DCB); if (!GetCommState(ctx_rtu->w_ser.fd, &ctx_rtu->old_dcb)) { fprintf(stderr, "ERROR Error getting configuration (LastError %d)\n", (int)GetLastError()); return -1; } /* Build new configuration (starting from current settings) */ dcb = ctx_rtu->old_dcb; /* Speed setting */ switch (ctx_rtu->baud) { case 110: dcb.BaudRate = CBR_110; break; case 300: dcb.BaudRate = CBR_300; break; case 600: dcb.BaudRate = CBR_600; break; case 1200: dcb.BaudRate = CBR_1200; break; case 2400: dcb.BaudRate = CBR_2400; break; case 4800: dcb.BaudRate = CBR_4800; break; case 9600: dcb.BaudRate = CBR_9600; break; case 19200: dcb.BaudRate = CBR_19200; break; case 38400: dcb.BaudRate = CBR_38400; break; case 57600: dcb.BaudRate = CBR_57600; break; case 115200: dcb.BaudRate = CBR_115200; break; default: dcb.BaudRate = CBR_9600; printf("WARNING Unknown baud rate %d for %s (B9600 used)\n", ctx_rtu->baud, ctx_rtu->device); } /* Data bits */ switch (ctx_rtu->data_bit) { case 5: dcb.ByteSize = 5; break; case 6: dcb.ByteSize = 6; break; case 7: dcb.ByteSize = 7; break; case 8: default: dcb.ByteSize = 8; break; } /* Stop bits */ if (ctx_rtu->stop_bit == 1) dcb.StopBits = ONESTOPBIT; else /* 2 */ dcb.StopBits = TWOSTOPBITS; /* Parity */ if (ctx_rtu->parity == 'N') { dcb.Parity = NOPARITY; dcb.fParity = FALSE; } else if (ctx_rtu->parity == 'E') { dcb.Parity = EVENPARITY; dcb.fParity = TRUE; } else { /* odd */ dcb.Parity = ODDPARITY; dcb.fParity = TRUE; } /* Hardware handshaking left as default settings retrieved */ /* No software handshaking */ dcb.fTXContinueOnXoff = TRUE; dcb.fOutX = FALSE; dcb.fInX = FALSE; /* Binary mode (it's the only supported on Windows anyway) */ dcb.fBinary = TRUE; /* Don't want errors to be blocking */ dcb.fAbortOnError = FALSE; /* TODO: any other flags!? */ /* Setup port */ if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) { fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n", (int)GetLastError()); return -1; } #else /* The O_NOCTTY flag tells UNIX that this program doesn't want to be the "controlling terminal" for that port. If you don't specify this then any input (such as keyboard abort signals and so forth) will affect your process Timeouts are ignored in canonical input mode or when the NDELAY option is set on the file via open or fcntl */ ctx->s = open(ctx_rtu->device, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL); if (ctx->s == -1) { fprintf(stderr, "ERROR Can't open the device %s (%s)\n", ctx_rtu->device, strerror(errno)); return -1; } /* Save */ tcgetattr(ctx->s, &(ctx_rtu->old_tios)); memset(&tios, 0, sizeof(struct termios)); /* C_ISPEED Input baud (new interface) C_OSPEED Output baud (new interface) */ switch (ctx_rtu->baud) { case 110: speed = B110; break; case 300: speed = B300; break; case 600: speed = B600; break; case 1200: speed = B1200; break; case 2400: speed = B2400; break; case 4800: speed = B4800; break; case 9600: speed = B9600; break; case 19200: speed = B19200; break; case 38400: speed = B38400; break; case 57600: speed = B57600; break; case 115200: speed = B115200; break; default: speed = B9600; if (ctx->debug) { fprintf(stderr, "WARNING Unknown baud rate %d for %s (B9600 used)\n", ctx_rtu->baud, ctx_rtu->device); } } /* Set the baud rate */ if ((cfsetispeed(&tios, speed) < 0) || (cfsetospeed(&tios, speed) < 0)) { return -1; } /* C_CFLAG Control options CLOCAL Local line - do not change "owner" of port CREAD Enable receiver */ tios.c_cflag |= (CREAD | CLOCAL); /* CSIZE, HUPCL, CRTSCTS (hardware flow control) */ /* Set data bits (5, 6, 7, 8 bits) CSIZE Bit mask for data bits */ tios.c_cflag &= ~CSIZE; switch (ctx_rtu->data_bit) { case 5: tios.c_cflag |= CS5; break; case 6: tios.c_cflag |= CS6; break; case 7: tios.c_cflag |= CS7; break; case 8: default: tios.c_cflag |= CS8; break; } /* Stop bit (1 or 2) */ if (ctx_rtu->stop_bit == 1) tios.c_cflag &=~ CSTOPB; else /* 2 */ tios.c_cflag |= CSTOPB; /* PARENB Enable parity bit PARODD Use odd parity instead of even */ if (ctx_rtu->parity == 'N') { /* None */ tios.c_cflag &=~ PARENB; } else if (ctx_rtu->parity == 'E') { /* Even */ tios.c_cflag |= PARENB; tios.c_cflag &=~ PARODD; } else { /* Odd */ tios.c_cflag |= PARENB; tios.c_cflag |= PARODD; } /* Read the man page of termios if you need more information. */ /* This field isn't used on POSIX systems tios.c_line = 0; */ /* C_LFLAG Line options ISIG Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT signals ICANON Enable canonical input (else raw) XCASE Map uppercase \lowercase (obsolete) ECHO Enable echoing of input characters ECHOE Echo erase character as BS-SP-BS ECHOK Echo NL after kill character ECHONL Echo NL NOFLSH Disable flushing of input buffers after interrupt or quit characters IEXTEN Enable extended functions ECHOCTL Echo control characters as ^char and delete as ~? ECHOPRT Echo erased character as character erased ECHOKE BS-SP-BS entire line on line kill FLUSHO Output being flushed PENDIN Retype pending input at next read or input char TOSTOP Send SIGTTOU for background output Canonical input is line-oriented. Input characters are put into a buffer which can be edited interactively by the user until a CR (carriage return) or LF (line feed) character is received. Raw input is unprocessed. Input characters are passed through exactly as they are received, when they are received. Generally you'll deselect the ICANON, ECHO, ECHOE, and ISIG options when using raw input */ /* Raw input */ tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* C_IFLAG Input options Constant Description INPCK Enable parity check IGNPAR Ignore parity errors PARMRK Mark parity errors ISTRIP Strip parity bits IXON Enable software flow control (outgoing) IXOFF Enable software flow control (incoming) IXANY Allow any character to start flow again IGNBRK Ignore break condition BRKINT Send a SIGINT when a break condition is detected INLCR Map NL to CR IGNCR Ignore CR ICRNL Map CR to NL IUCLC Map uppercase to lowercase IMAXBEL Echo BEL on input line too long */ if (ctx_rtu->parity == 'N') { /* None */ tios.c_iflag &= ~INPCK; } else { tios.c_iflag |= INPCK; } /* Software flow control is disabled */ tios.c_iflag &= ~(IXON | IXOFF | IXANY); /* C_OFLAG Output options OPOST Postprocess output (not set = raw output) ONLCR Map NL to CR-NL ONCLR ant others needs OPOST to be enabled */ /* Raw ouput */ tios.c_oflag &=~ OPOST; /* C_CC Control characters VMIN Minimum number of characters to read VTIME Time to wait for data (tenths of seconds) UNIX serial interface drivers provide the ability to specify character and packet timeouts. Two elements of the c_cc array are used for timeouts: VMIN and VTIME. Timeouts are ignored in canonical input mode or when the NDELAY option is set on the file via open or fcntl. VMIN specifies the minimum number of characters to read. If it is set to 0, then the VTIME value specifies the time to wait for every character read. Note that this does not mean that a read call for N bytes will wait for N characters to come in. Rather, the timeout will apply to the first character and the read call will return the number of characters immediately available (up to the number you request). If VMIN is non-zero, VTIME specifies the time to wait for the first character read. If a character is read within the time given, any read will block (wait) until all VMIN characters are read. That is, once the first character is read, the serial interface driver expects to receive an entire packet of characters (VMIN bytes total). If no character is read within the time allowed, then the call to read returns 0. This method allows you to tell the serial driver you need exactly N bytes and any read call will return 0 or N bytes. However, the timeout only applies to the first character read, so if for some reason the driver misses one character inside the N byte packet then the read call could block forever waiting for additional input characters. VTIME specifies the amount of time to wait for incoming characters in tenths of seconds. If VTIME is set to 0 (the default), reads will block (wait) indefinitely unless the NDELAY option is set on the port with open or fcntl. */ /* Unused because we use open with the NDELAY option */ tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = 0; if (tcsetattr(ctx->s, TCSANOW, &tios) < 0) { return -1; } #endif return 0; }
int CSeries::SerOpen(int PortNo, long BaudRate, int Parity, int ByteSize) { CString MsgStr; DCB dcb; BOOL fRetVal ; BYTE i,bSet; DWORD dwError; COMMTIMEOUTS to; TCHAR DevName[10]; wsprintf(DevName,"\\\\.\\COM%01d",(int)PortNo); SerClose(); if ((m_CommPort=CreateFile(DevName , GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , NULL , NULL )) == INVALID_HANDLE_VALUE) { return -1; } for(i=0; i<5; i++) { /*设置缓冲区大小*/ fRetVal = SetupComm(m_CommPort, MAX_BUFFER_IN ,MAX_BUFFER_OUT); if (fRetVal) { break; } Sleep(100); } // purge any information in the buffer PurgeComm(m_CommPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); // set up for overlapped I/O GetCommTimeouts(m_CommPort, &to); to.ReadIntervalTimeout = 0xFFFFFFFF; to.ReadTotalTimeoutMultiplier =0; to.ReadTotalTimeoutConstant =0; to.WriteTotalTimeoutMultiplier =10;//10ms to.WriteTotalTimeoutConstant =5000;//5000ms SetCommTimeouts(m_CommPort, &to) ; // set up DCB dcb.DCBlength = sizeof(DCB) ; for(i=0; i<5; i++) { fRetVal =GetCommState(m_CommPort, &dcb); if (fRetVal) { break; } Sleep(100); } if (fRetVal == 0) { dwError = GetLastError(); CloseHandle(m_CommPort); m_CommPort = INVALID_HANDLE_VALUE; return -2; } dcb.BaudRate=BaudRate; dcb.ByteSize=ByteSize; dcb.Parity = Parity; dcb.StopBits =ONESTOPBIT;//2009-10-29 // setup hardware flow control #if 2 bSet = false; dcb.fOutxDsrFlow = bSet ; if (bSet) dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; else dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fOutxCtsFlow = bSet ; if (bSet) dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; else dcb.fRtsControl = RTS_CONTROL_ENABLE; // setup software flow control bSet = false; dcb.fInX = dcb.fOutX = bSet ; dcb.XonLim = 100 ; dcb.XoffLim = 100 ; dcb.XonChar = XON; dcb.XoffChar = XOFF; dcb.fBinary = TRUE; if (dcb.Parity == 0) dcb.fParity = FALSE; else dcb.fParity = TRUE; #else /**/ dcb.fOutxCtsFlow = FALSE; // No CTS output flow control dcb.fOutxDsrFlow = FALSE; // No DSR output flow control dcb.fDtrControl = DTR_CONTROL_DISABLE; // DTR flow control type dcb.fDsrSensitivity = FALSE; // DSR sensitivity dcb.fTXContinueOnXoff = TRUE; // XOFF continues Tx dcb.fOutX = FALSE; // No XON/XOFF out flow control dcb.fInX = FALSE; // No XON/XOFF in flow control dcb.fErrorChar = FALSE; // Disable error replacement dcb.fNull = FALSE; // Disable null stripping dcb.fRtsControl = RTS_CONTROL_DISABLE; // RTS flow control dcb.fAbortOnError = FALSE; // 当串口发生错误,并不终止串口读写 #endif // set up DCB dcb.DCBlength = sizeof( DCB ); for(i=0; i<5; i++) { //Sleep(80); fRetVal = SetCommState(m_CommPort, &dcb); if (fRetVal) break; Sleep(100); } if (fRetVal == 0) { dwError = GetLastError(); // an error occurred, try to recover MsgStr.Format("<CE-%u>,Please Check ComPort", dwError); MessageBox(NULL, MsgStr, "SetCommState", MB_OK); CloseHandle(m_CommPort); m_CommPort = INVALID_HANDLE_VALUE; return -3; } GetCommState(m_CommPort, &dcb ) ; // EscapeCommFunction(m_CommPort, SETDTR ) ; PurgeComm(m_CommPort , PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ; return 0; }