📄 serial.c
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description:// Serial RS232 transport support.// Notes:// - This implementation requires pthread support.// - Serial port connections are typically always duplex, and always remain // 'connected' until the media is physically disconnected. A client may not // be aware that a physical disconnection/reconnection has occured, thus it // is the servers responibility to initiate all conversations when // connecting/reconnecting with a client.// ---// Change History:// 2006/02/19 Martin D. Flynn// -Initial release// 2007/01/28 Martin D. Flynn// -Initial support for Window CE (may not be fully complete)// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#include "custom/defaults.h"// ----------------------------------------------------------------------------#include <stdlib.h>#include <string.h>#include <ctype.h>#include "custom/log.h"#include "custom/transport/serial.h"#include "tools/stdtypes.h"#include "tools/strtools.h"#include "tools/bintools.h"#include "tools/comport.h"#include "tools/buffer.h"#include "tools/threads.h"#include "base/props.h"#include "base/propman.h"#include "base/packet.h"// ----------------------------------------------------------------------------/* transport structure */typedef struct { TransportType_t type;} SerialTransport_t;static SerialTransport_t serialXport;// ----------------------------------------------------------------------------// This should be set to the appropriate configured serial port speed#define SERIAL_SPEED_BPS BPS_57600// size of packet buffer#define MAX_PACKET_BUFFER (30000L)// ----------------------------------------------------------------------------#if defined(TARGET_WINCE)# include <winsock2.h>#endif// ----------------------------------------------------------------------------static TransportFtns_t serXportFtns = { MEDIA_SERIAL, "XportSerial" };static ComPort_t serComPort;static UInt32 serOpenTime = 0L;static UInt32 serCloseTime = 0L;static CircleBuffer_t *serBuffer;static utBool serRunThread = utFalse;static threadThread_t serThread;static threadMutex_t serMutex;static threadCond_t serCond;static struct timespec serCondWaitTime;#define BUFFER_LOCK MUTEX_LOCK(&serMutex);#define BUFFER_UNLOCK MUTEX_UNLOCK(&serMutex);#define BUFFER_WAIT(T) CONDITION_TIMED_WAIT(&serCond,&serMutex,utcGetAbsoluteTimespec(&serCondWaitTime,(T)));#define BUFFER_NOTIFY CONDITION_NOTIFY(&serCond);#define OPEN_LOCK BUFFER_LOCK#define OPEN_UNLOCK BUFFER_UNLOCK// ----------------------------------------------------------------------------/* test for active Serial/BT connection */static utBool btIsConnected(ComPort_t *com){ utBool ready = utTrue;#if defined(COMPORT_SUPPORT_BLUETOOTH) ready = comPortIsBluetoothReady(com);#else // ready = comPortGetCTS(com);#endif //logDEBUG(LOGSRC,"Bluetoth ready = %d", (int)ready); return ready;}// ----------------------------------------------------------------------------#define OPEN_FAILED_INVERVAL_SEC MINUTE_SECONDS(60)static long serLastOpenFailedMessageTime = 0L;/* open serial port (and check for Serial connection) */static utBool _serdevOpenCom(ComPort_t *com, utBool log){ /* port config */ const char *portName = propGetString(PROP_CFG_XPORT_PORT, ""); if (!portName || !*portName) { logERROR(LOGSRC,"Serial transport port name not specified"); threadSleepMS(MINUTE_SECONDS(3) * 1000L); // long sleep return utFalse; } UInt32 portBPS = propGetUInt32(PROP_CFG_XPORT_BPS, 0L); if (portBPS == 0L) { portBPS = SERIAL_SPEED_BPS; } /* open port */ //logDEBUG(LOGSRC,"Openning Serial port '%s' ...", portName); //comPortInitStruct(com); <-- port may already be open, don't initialize ComPort_t *openCom = (ComPort_t*)0; utBool portFound = utFalse; OPEN_LOCK { serOpenTime = 0L; if (comPortIsOpen(com)) { // ComPort already openned openCom = com; } else { // Open ComPort openCom = comPortOpen(com, portName, portBPS, "8N1", utFalse); } if (openCom) { // Serial port open portFound = utTrue; if (!btIsConnected(com)) { // No Serial connection openCom = (ComPort_t*)0; } else { // We have an active Serial connection serOpenTime = utcGetTimeSec(); serCloseTime = 0L; } } else { // Still closed // leave 'serCloseTime' as-is } } OPEN_UNLOCK /* open failed */ if (!openCom) { // The outer loop will retry the open later // We expect this to occur when the Serial port device is no longer available // (ie. when the Serial device has disconnected) if (utcIsTimerExpired(serLastOpenFailedMessageTime,OPEN_FAILED_INVERVAL_SEC)) { serLastOpenFailedMessageTime = utcGetTimer(); if (portFound) { logINFO(LOGSRC,"Waiting for Serial transport connection: %s", portName); } else { logERROR(LOGSRC,"Serial transport open failed: %s", portName); } } return utFalse; } /* additional port attributes */ //comPortAddOptions(com, COMOPT_NOESCAPE); //if (PORT_IsCONSOLE(com->port)) { // logINFO(LOGSRC,"Console port, backspace/echo enabled ..."); // comPortAddOptions(com, COMOPT_BACKSPACE); // comPortAddOptions(com, COMOPT_ECHO); //} /* return success */ logINFO(LOGSRC,"Serial port '%s' openned", portName); return utTrue; }/* close serial port */static void _serdevCloseCom(utBool closePort){ ComPort_t *com = &serComPort; OPEN_LOCK { comPortClose(com); serOpenTime = 0L; serCloseTime = utcGetTimeSec(); } OPEN_UNLOCK}/* return the time the connection was opened, or 0L if the connection is closed */static UInt32 serdevGetOpenTime(){ UInt32 openTime = 0L; OPEN_LOCK { openTime = serOpenTime; } OPEN_UNLOCK return openTime;}// ----------------------------------------------------------------------------/* initialize serial communications */static void serdevInitialize(){ /* init comport */ comPortInitStruct(&serComPort); /* create mutex */ threadMutexInit(&serMutex); threadConditionInit(&serCond); /* create buffer */ serBuffer = bufferCreate(MAX_PACKET_BUFFER);}// ----------------------------------------------------------------------------//static double maxBufferLoad = 0.0;/* continue reading until comport error, end of thread, or Serial disconnects */static int _serdevReadData(){ ComPort_t *com = &serComPort; /* flush everything currently in the comport buffers */ comPortFlush(com, 0L); /* read Serial device packet */ // continues until port read error, or Serial disconnects char buf[PACKET_MAX_ENCODED_LENGTH]; while (serRunThread) { /* test serial connection */ if (!btIsConnected(com)) { // no active connection return 0; } /* read data */ int cmdLen = comPortReadLine(com, buf, sizeof(buf), -1L); if (cmdLen < 0) { // com port closed? return -1; } else if ((cmdLen == 0) && COMERR_IsTimeout(com)) { // timeout, try again //logDEBUG(LOGSRC,"Serial device timeout"); continue; } /* check for EOL */ if (buf[cmdLen - 1] == 13) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -