⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utitech.c

📁 工业组态软件modbus驱动源代码, 包括帮助文件.共享.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: "%n Ver=%v  %f  LastEdit=%w  Locker=%l" */
/* "UDSERIAL.C Ver=4  25-Nov-97,17:08:20  LastEdit=JIMV  Locker=***_NOBODY_***" */
/***********************************************************************\
*                                                                       *
*       Copyright Wonderware Software Development Corp. 1992-1997       *
*                                                                       *
*       ThisFileName="L:\ww\dde_serv\src\udsample\udserial\udserial.c"  *
*       LastEditDate="1997 Nov 25  17:08:00"                            *
*                                                                       *
\***********************************************************************/

/******************************************/
/* >>>>>>>> Sample Serial Server <<<<<<<< */
/******************************************/

//#define SIMULATING              /* enable I/O to simulated device */

#define LINT_ARGS
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#if !defined(__MSC)
#include <conio.h>
#else
/* Note:  BORLAND conio.h include is disabled for Windows apps. */
/* It includes prototypes for inp & outp which are OK for Windows, */
/* but the whole include file is disabled so these are copied here: */
int         _Cdecl inport( int __portid );
void        _Cdecl outport( int __portid, int __value );
    /* These are in-line functions.  These prototypes just clean up
       some syntax checks and code generation.
     */
unsigned char _Cdecl    __inportb__( int __portid );
unsigned int _Cdecl     __inportw__( int __portid );
void        _Cdecl      __outportb__( int __portid, unsigned char __value );
void        _Cdecl      __outportw__( int __portid, unsigned int __value );
#define inportb         __inportb__
#define inportw         __inportw__
#define outportb        __outportb__
#define outportw        __outportw__
#define inp( portid ) inportb( portid )
#define outp( portid,v )  outportb( portid,v )
#define inpw( portid ) inportw( portid )
#define outpw( portid,v )  outportw( portid,v )
#endif

#include "ntconv.h"
#include "hmemcpy.h"
#include "chainmgr.h"
#include "Utitech.h"
#include "uddefs.h"
#include "config.h"
#include "ntsrvr.h"
#include "debug.h"
#include "tmpbuf.h"
#include "permissn.h"
#include "udgetstr.h"
#include "wwassert.h"

USES_ASSERT

BOOL bFlushOnError = TRUE;      /* =TRUE if should flush port buffers
                                   while processing an error */

static int WriteSimComm(int idComDev, const void FAR *lpvBuf, int cbWrite);
static int ReadSimComm(int idComDev, void FAR *lpvBuf, int cbRead);

/*加入一个函数用于切割读回的字符串。该函数将有效的读回数据写入变量lpPort,并把有效的字符串长度写入变量len。*/
static BYTE	inQueBuf[8][INQSIZE];
int	
WINAPI
Utitech_ReadComm(LPPORT lpPort)
{
	static	int		qIdx = -1;

	BOOL	eof_wait;
	BYTE cch,*pInQueBuf;
	int		i,idxQue;
	LPSTAT	lpTopic;
	BYTE	plcAddr;
	static WORD    len;

	// next QUEUE stack
	qIdx ++;
	eof_wait = FALSE;
	idxQue = 0;

	pInQueBuf = (BYTE *)&inQueBuf[qIdx];
	i = ReadComm(lpPort->mbCid,(LPSTR)pInQueBuf, INQSIZE);

	if (i > 0) {
		lpTopic = lpPort->mbCurTopic;
		plcAddr = lpTopic->statTopic;

		while (i--)  {
			cch = *pInQueBuf ++;
			idxQue = lpPort->mbRspIndex;
			lpPort->mbRspBuffer[idxQue] = cch;

			switch (idxQue) {
				case	0:
					len = 1023;
					if (cch == plcAddr)	++idxQue;		// start
					break;

				case	2:
					++ idxQue;
					// if ERROR return
					if (lpPort->mbRspBuffer[1] & 0x80) {
						len = 5;
					}
					else {
						switch (lpPort->mbRspBuffer[1]){
							
							case 0x1:
							case 0x2:
								len = (BYTE)cch + 5;
								break;
							case 0x10:
							case 0x0f:
							case 0x05:
								len = 8;
								break;

							default:
								len = (WORD)cch + 5;
								break;
							}
					}
					break;

				default:
					/*
					if ((cch == 10) || (cch == 13)) {			// BCC
						lpPort->mbRspExpLen = idxQue;
						eof_wait = TRUE;
						break;
					}
					*/

					if (++ idxQue >= ( INQSIZE-1)) {
						idxQue = 0;			// out of QUEUE
						break;
					}

					if (idxQue >= len) {
						lpPort->mbRspExpLen = idxQue;
						eof_wait = TRUE;
					}

					break;
			}	/* switch */

			lpPort->mbRspIndex = idxQue;
			if (idxQue >= lpPort->mbRspExpLen) break;
		} /* while */
	}

	// release QUEUE stack
	qIdx --;

	return	idxQue;
}

/***********************************************************************/
/** get COMPORT name corresponding to the port for indicated station **/


void
WINAPI
ExtractPortName (LPSTNPARAM lpStnParam, LPSTR lpName, int iMax)
{
    int i;

    /* get length of name */
    i = lstrlen (lpStnParam->spChannelName);

    /* ensure name will fit in target buffer */
    if (i >= iMax)
        i = iMax - 1;

    /* copy name to destination */
    _fstrncpy (lpName, lpStnParam->spChannelName, i);
    lpName[i] = '\0';
} /* ExtractPortName */

/***********************************************************************/
/** Set up port configuration info for indicated station **/

void
WINAPI
SetPortConfigInfo (LPPORT lpPort, LPSTNPARAM lpStnParam)
{
    /* copy COMPORT mode string to port structure */
    lstrcpy (lpPort->mbConfigString, lpStnParam->spConfigString);
} /* SetPortConfigInfo */

/***********************************************************************/
/** This function checks the communications port for events and logs them. **/

void
WINAPI
checkEvents(LPPORT  lpPort)
{
    int events;

    /* get and clear event mask for indicated COM port */
    events = GetCommEventMask(lpPort->mbCid, EV_RXCHAR | EV_TXEMPTY);

    if (!ShowingEvents)
        /* not displaying events, just return */
        return;

    /* have logger display appropriate event string */
    if ((events & (EV_RXCHAR | EV_TXEMPTY)) == (EV_RXCHAR | EV_TXEMPTY)) {
        debug(GetString(STRUSER + 89) /* "RXCHAR and TXEMPTY" */ );
    } else if ((events & (EV_RXCHAR | EV_TXEMPTY)) == EV_RXCHAR) {
        debug(GetString(STRUSER + 90) /* "RXCHAR" */ );
    } else if ((events & (EV_RXCHAR | EV_TXEMPTY)) == EV_TXEMPTY) {
        debug(GetString(STRUSER + 91) /* "TXEMPTY" */ );
    }
} /* checkEvents */

/***********************************************************************/
/** Check the communications port for serious errors
    and print debug messages showing the problem.
    return TRUE if event is a serious problem **/

BOOL
WINAPI
UdprotCheckErrors(LPPORT  lpPort)
{
    int    ec;
    BOOL   serious;

    /* get and clear COM error mask for indicated port */
    if ((ec = GetCommError(lpPort->mbCid, (COMSTAT FAR *)NULL)) == 0)
        /* no errors, just return */
        return FALSE;
    /* determine whether error is serious */
    serious = (ec &
     (CE_OVERRUN | CE_RXPARITY | CE_FRAME | CE_BREAK | CE_TXFULL)) != 0;
    if (!ShowingErrors)
        /* not displaying errors, just return indicator */
        return serious;
    /* formulate appropriate error message */
    dbgBuf[0] = '\0';
    if (ec & CE_MODE)
        sprintf(&dbgBuf[strlen(dbgBuf)],
           GetString(STRUSER + 92) /* "Bad comm port handle. " */ );
    if (ec & CE_RXOVER)
        sprintf(&dbgBuf[strlen(dbgBuf)],
         GetString(STRUSER + 93) /* "Receive queue overflow. " */ );
    if (ec & CE_OVERRUN)
        sprintf(&dbgBuf[strlen(dbgBuf)],
            GetString(STRUSER + 94) /* "Receive overrun. " */ );
    if (ec & CE_RXPARITY)
        sprintf(&dbgBuf[strlen(dbgBuf)],
           GetString(STRUSER + 95) /* "Receive parity error. " */ );
    if (ec & CE_FRAME)
        sprintf(&dbgBuf[strlen(dbgBuf)],
          GetString(STRUSER + 96) /* "Receive framing error. " */ );
    if (ec & CE_BREAK)
        sprintf(&dbgBuf[strlen(dbgBuf)],
            GetString(STRUSER + 97) /* "Received BREAK. " */ );
#ifndef WIN32
    if (ec & CE_CTSTO)
        sprintf(&dbgBuf[strlen(dbgBuf)],
            GetString(STRUSER + 98) /* "CTS timeout. " */ );
    if (ec & CE_DSRTO)
        sprintf(&dbgBuf[strlen(dbgBuf)],
            GetString(STRUSER + 99) /* "DSR timeout. " */ );
    if (ec & CE_RLSDTO)
        sprintf(&dbgBuf[strlen(dbgBuf)],
            GetString(STRUSER + 100) /* "DCD timeout. " */ );
#endif
    if (ec & CE_TXFULL)
        sprintf(&dbgBuf[strlen(dbgBuf)],
            GetString(STRUSER + 101)    /* "Transmit queue overflow. " */ );
    /* output error message to logger */
    debug(dbgBuf);
    /* return indication of whether error is serious */
    return serious;
} /* UdprotCheckErrors */

/***********************************************************************/
/** Report error code
    Called when an OpenComm() fails.
    Translates the error code into plain English. **/

void
WINAPI
UdprotReportOpenErrorCode (LPPORT lpPort)
{
    /* select appropriate message */
    switch (lpPort->mbCid) {
    case IE_BADID:
        /* "Failed to open device name (%Fs)" */
        sprintf(dbgBuf, GetString(STRUSER + 56), lpPort->mbPortName);
        break;
    case IE_OPEN:
        /* "Device already open (%Fs)" */
        sprintf(dbgBuf, GetString(STRUSER + 57), lpPort->mbPortName);
        break;
    case IE_NOPEN:
        /* "Device not open (%Fs)" */
        sprintf(dbgBuf, GetString(STRUSER + 58), lpPort->mbPortName);
        break;
    case IE_MEMORY:
        /* "Unable to allocate queues" */
        strcpy(dbgBuf, GetString(STRUSER + 59));
        break;
    case IE_DEFAULT:
        /* "Error in default parameters" */
        strcpy(dbgBuf, GetString(STRUSER + 60));
        break;
    case IE_HARDWARE:
        /* "Hardware not present or already allocated (%Fs)" */
        sprintf(dbgBuf, GetString(STRUSER + 61), lpPort->mbPortName);
        break;
    case IE_BYTESIZE:
        /* "Invalid byte size" */
        strcpy(dbgBuf, GetString(STRUSER + 62) );
        break;
    case IE_BAUDRATE:
        /* "Unsupported baud rate" */
        strcpy(dbgBuf, GetString(STRUSER + 63) );
        break;
    default:
        /* "Unknown error from OpenComm: 0x%x" */
        sprintf(dbgBuf, GetString(STRUSER + 64), lpPort->mbCid);
        break;

    }
    /* display message on screen */
    MessageBox(hWndParent, dbgBuf, GetAppName(),
           MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
} /* UdprotReportOpenErrorCode */

#ifndef SIMULATING

/***********************************************************************/
/* open indicated port */

BOOL
WINAPI
OpenPort (LPPORT lpPort)
{
    DCB             dcb;
    BOOL Trick19200 = FALSE;
    char ModeString [21], tempString [21];
    char *baudPtr;

    /* attempt to open COM port */
    lpPort->mbCid = OpenComm(lpPort->mbPortName, INQSIZE, OUTQSIZE);
    if (lpPort->mbCid < 0) {
        /* OpenComm() failed, display error code */
        UdprotReportOpenErrorCode(lpPort);
        return FALSE;
    }

    /*  initialize the DCB with current values */
    if( NTSrvr_GetCommState(lpPort->mbCid, (DCB FAR *)&dcb) != 0) {
        CloseComm(lpPort->mbCid);
        return FALSE;
    }
    /*
     * Translate the DOS MODE-style string into the corresponding fields
     * in the DCB.
     */

    /* copy the mode string to a local string */
    lstrcpy (ModeString, lpPort->mbConfigString);
    /* point to the baud rate */
    baudPtr = strchr (ModeString, ':');
    assert (baudPtr);
    baudPtr++;
    /* check whether the baud rate setting exceeds 4 characters */
    if (strncmp (baudPtr, "19200", 5) == 0) {
        /** Baud rate string is longer than BuildCommDCB can handle,
            so substitute 9600 in the string and set up the DCB.
            We will correct the baud rate in the DCB later. **/
        Trick19200 = TRUE;
        strncpy (baudPtr, " 9600 ", 5); /* Careful, string2 has to     */
                                        /* be longer than 5, or the    */
                                        /* function will insert a NULL */
        strcpy (tempString, baudPtr+1); /* drop out leading space */
        strcpy (baudPtr, tempString);
    }

    if (NTSrvr_BuildCommDCB(ModeString, (DCB FAR *) & dcb) == 0) {
        /* Set up the port as needed for the driver's operation */

        dcb.fBinary      = 1;    /* Binary operation               */

        /* enable RTS handshake, enable DTR */
        NTSrvr_SetDCB_Rts( (DCB FAR *)&dcb, NTSrvr_RTS_ENABLE );
        NTSrvr_SetDCB_Dtr( (DCB FAR *)&dcb, NTSrvr_DTR_ENABLE );

        dcb.fParity      = 0;    /* No Parity checking             */
        dcb.fOutxCtsFlow = 0;    /* No CTS output flow control     */
        dcb.fOutxDsrFlow = 0;    /* No DSR output flow control     */
        dcb.fOutX        = 0;    /* XON/XOFF output flow control   */
        dcb.fInX         = 0;    /* No XON/XOFF input flow control */
        dcb.fNull        = 0;    /* No null                        */
        dcb.XonChar      = 0x11; /* XON is ^Q                      */
        dcb.XoffChar     = 0x13; /* XOFF is ^S                     */

        /* check whether baud rate trick was used */
        if (Trick19200) {
            /* yes, force DCB baud rate to correct value */
            dcb.BaudRate = 19200;
        }

        /* Now set the port to the configuration in the DCB */
        if (NTSrvr_SetCommState( lpPort->mbCid, (DCB FAR *) & dcb) != 0) {
            /* unable to set COM port state, close COM port and exit */
            CloseComm(lpPort->mbCid);
            return FALSE;
        }

    } else {
        /* Parsing of config string failed, close COM port and exit */
        CloseComm(lpPort->mbCid);
        return FALSE;
    }

    /* indicate success */
    return TRUE;
} /* OpenPort */

/***********************************************************************/
/* shut down serial port */

void
WINAPI
ClosePort (LPPORT lpPort)
{
    CloseComm(lpPort->mbCid);
} /* ClosePort */

#endif

/***********************************************************************/
/** Flush indicated port **/

void
WINAPI
FlushPort (LPPORT lpPort, LPSTR lpErrMsg)
{
#ifndef SIMULATING
    /* flush COM port input and output buffers */
    FlushComm(lpPort->mbCid, 0);
    FlushComm(lpPort->mbCid, 1);
#endif
} /* FlushPort */

/***********************************************************************/
/** Read and discard any pending port input,
    return TRUE if port is quiet **/

BOOL
WINAPI
WaitForQuietPort (LPPORT lpPort, LPSTR lpErrMsg)
{
    int len;

    /* read any incoming characters, check for errors */
#ifndef SIMULATING
    len = ReadComm(lpPort->mbCid, (LPSTR) lpPort->mbRspBuffer, 1024);
#else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -