// SerialPortServer.hpp // #pragma once #ifndef _SerialPortServer_DLL #define SERIALPORTSERVER_API _declspec(dllimport) #else #define SERIALPORTSERVER_API _declspec(dllexport) #endif /* Controlcharacters */ #define DLE 0x10 /* Start of a message */ #define CON 0x11 /* Initialisation */ #define CONACK 0x12 /* Confirmation for CON */ #define STX 0x02 /* Start of DATA */ #define BUSY 0x16 /* receiver not ready */ #define ETX 0x03 #define ACK 0x06 #define NAK 0x15 #define ENQ 0x05 #define CR 0x0d #define LF 0x0a #include "Stream.hpp" #include "Buffer.hpp" // ---------------------------------------------------------------------------- // CSerialPortServer class SERIALPORTSERVER_API CSerialPortServer { public: class FrameStream; public: CSerialPortServer(); virtual ~CSerialPortServer(); public: bool OpenPort ( UINT portnr = 1, UINT baud = 19200, char parity = NOPARITY, UINT databits = 8, UINT stopsbits = 1); void ClosePort (); public: // 发送命令,在主线程中调用 int SendCommand (const char * cmd, int length); // 发送刷新命令,在主线程中调用 int SendRefreshCommand (const char * cmd, int length); // 把同步队列中的数据搬到异步队列中 int SyncToASync (); // 检查返回状态值, bRemove指定是否删除, bWait指定是否等待 bool PeekStatus (FrameStream * pStream, bool bRemove, bool bWait); // 检索状态队列的个数 int GetNbOfStatus (); protected: // 处理读队列, 在写周期中调用 int ProcessStatus (); protected: virtual int WriteCycle (); virtual int ReadCycle (); protected: virtual int OnCallback (FrameStream data) = 0; // 把一帧数据写到串口 virtual int WriteFrame (FrameStream data); virtual FrameStream ReadFrame () = 0; virtual int GetNbOfACK (FrameStream data) = 0; protected: // 写数据到串口,然后等待ACK virtual int WriteFrameWaitACK (FrameStream data); protected: class SerialPortBuffer * m_Port; public: bool StartServer (); void StopServer (); public: int SetMaxlenCommandBuffer (int max); int SetMaxlenRefreshBuffer (int max); protected: static int DaemonWrite (void * Arg); static int DaemonRead (void * Arg); virtual int RunWrite (); virtual int RunRead (); // 反向通知函数 protected: // 超时通知 virtual void OnTimeOut (FrameStream cmd) { } virtual int ShouldResend (FrameStream cmd) { return 0; } protected: HANDLE ThreadHandleWrite; HANDLE ThreadHandleRead; DWORD ThreadIDWrite; // 写线程ID DWORD ThreadIDRead; // 读线程ID DWORD ThreadIDMain; // 主线程ID HANDLE EventHandleWrite; // 当命令写入共享缓存时,发送事件 HANDLE EventHandleRead; // 当状态加入共享缓存时,发送事件 protected: class CLogFile * LogFile; public: class SERIALPORTSERVER_API FrameStream : public Stream { public: FrameStream (); FrameStream (const FrameStream &); FrameStream (const char * str); FrameStream (const char * lpsz, int length); FrameStream (int length); ~FrameStream (); public: int m_Index; public: enum { enUnknown = 0, enState = 1, enACK = 2, enNAK = 3, enBUSY = 4, enRequest = 5, enENQ = 8, enRefresh = 10, enRefreshCon = 11, enRefreshSys = 12, enOther = 100, }; int m_Type; public: bool IsFull () const; void Restart (); public: FrameStream & operator << (BYTE x); FrameStream & operator << (char x) { return ((*this) << (BYTE) x); }; public: Stream & operator = (const FrameStream & stringSrc); }; protected: class StreamArray * m_arCommand; class StreamArray * m_arRefreshCommand; class ExStreamArray * m_exCommand; class ExStreamArray * m_exRefreshCommand; class ExStreamArray * m_exStatus; protected: DWORD m_LastTickWriteCommand; // 最后一次写命令的时间 DWORD m_LastTickWriteRefresh; // 最后一次写刷新命令的时间 int m_MaxlenCommand; // CommandBuffer的最大尺寸,超过时,就把队列尾部的命令扔了 int m_MaxlenRefresh; // RefreshBuffer的最大尺寸,超过时,就把队列尾部的命令扔了 protected: int m_Reserved[256]; };