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

📄 utitech.c

📁 工业组态软件modbus驱动源代码, 包括帮助文件.共享.
💻 C
📖 第 1 页 / 共 2 页
字号:
    len = ReadSimComm(lpPort->mbCid, (LPSTR) lpPort->mbRspBuffer, 1024);
#endif
    if (len < 0) {
        /* error received on COM port, log error message and continue */
        UdprotCheckErrors(lpPort);
    }

    /* indicate whether port is quiet */
    return (len == 0);
} /* WaitForQuietPort */

/***********************************************************************/
/** Write message to indicated port,
    return 1 if successful,
           0 if not successful,
          -1 if serious error **/

int
WINAPI
WritePortMsg (LPPORT lpPort, LPUDMSG lpMsg)
{
    int len;
    int status;

    /* initialize return status */
    status = 1;

    /* write message to serial port, get status */
#ifndef SIMULATING
    len = WriteComm(lpPort->mbCid, (LPSTR) lpMsg->mmData, lpMsg->mmSize);
#else
    len = WriteSimComm(lpPort->mbCid, (LPSTR) lpMsg->mmData, lpMsg->mmSize);
#endif
    if ((len < 0) || (len != lpMsg->mmSize)) {
        /* error occurred on write, identify and display if appropriate */
        if (UdprotCheckErrors(lpPort))
            status = -1;
        else status = 0;
    }
    /* indicate success or failure */
    return (status);
} /* WritePortMsg */

/***********************************************************************/
/** get response from port,
    return 1 if successful,
           0 if not successful,
          -1 if serious error **/

int
WINAPI
ReadPortMsg (LPPORT lpPort)
{
    int len;
    int status;

    /* initialize return status */
    status = 0;

    /* attempt to read data from COM port */
    len = 0;
#ifndef SIMULATING
	len = Utitech_ReadComm(lpPort);
    /*len = ReadComm(lpPort->mbCid,
             (LPSTR) &lpPort->mbRspBuffer[lpPort->mbRspIndex],
             INQSIZE - lpPort->mbRspIndex);*/
#else
    len = ReadSimComm(lpPort->mbCid,
             (LPSTR) &lpPort->mbRspBuffer[lpPort->mbRspIndex],
             INQSIZE - lpPort->mbRspIndex);
#endif
    if (len <= 0) {
        /* if ReadComm() result < 0, it is -count and an error has occurred */
        len = -len;                              /* get actual length count */
        /* check for serious errors, print debug messages showing problem */
        if (UdprotCheckErrors(lpPort)) {
            /* serious error encountered, indicate problem */
            status = -1;
            return (status);
        }
    } else {
        /* indicate data received OK */
        status = 1;
    }

    /* check length of message received, if any */
    if (len > 0) {
        /* update length of message received so far */
        //lpPort->mbRspIndex += len;
    }

    /* indicate whether data was received OK */
    return (status);
} /* ReadPortMsg */

/***********************************************************************/
/** indicate whether port has data in receive buffer **/

BOOL
WINAPI
PortHasData (LPPORT lpPort)
{
    /* always indicate port has data -- at least, potentially */
    return (TRUE);
} /* PortHasData */

/***********************************************************************
 ***********************************************************************
 * PLC SIMULATION ROUTINES                                             *
 ***********************************************************************
 ***********************************************************************/

#ifndef SIMULATING
BOOL WINAPI IsSimulatorEnabled (void)
{
    return (FALSE);
} /* IsSimulatorEnabled */
#else
BOOL WINAPI IsSimulatorEnabled (void)
{
    return (TRUE);
} /* IsSimulatorEnabled */

/** The following routines simulate a simple PLC-type device for testing
    purposes.

    One simulated PLC is implemented for each of COM ports 1..4.

    The simulation has two memory segments:
        NAME  ADDRESS RANGE    DESCRIPTION           FUNCTION
          V      1..512      variable memory    holds value steady
          C      1..512      counter  memory    increments each time read
    Addressing wraps around, so V814 = V((814-1) mod 512)+1 = V302

    Messages are limited to no more than 100 characters, including the
    leading colon, checksum, and trailing semicolon.
    Read messages and write messages can access up to 22 consecutive
    locations (i.e. 44 bytes) within a memory type:
        Write to V  :81AAAANN[CCCC]....[CCCC]XX;
            return value is :81AAAANNXX;
        Write to C  :82AAAANN[CCCC]....[CCCC]XX;
            return value is :82AAAANNXX;
        Read from V :01AAAANNXX;
            return value is :01AAAANN[CCCC]...[CCCC]XX;
        Read from C :02AAAANNXX;
            return value is :02AAAANN[CCCC]...[CCCC]XX;
    where AAAA represents a 4-character hex ASCII address
          NN   represents a 2-character hex ASCII count
          CCCC represents a 4-character hex ASCII value
          XX   represents a 2-character hex ASCII checksum
    Any command which contains invalid hex ASCII characters, an odd number
    of bytes, or an invalid checksum will receive an error response
        :000000000000FF;
    Any command BB besides 01, 02, 81, or 82 will receive an error response
        :00BBAAAANN00XX;
    which echos back the first part of the bad command.
    Any valid command that has a bad address or a bad length (i.e. not
    enough characters, count = 0, or number of write values does not match
    the count) will receive an error response
        :00BBAAAANNDDXX;
    where for a write, DD represents the number of good values received,
    and for a read, DD represents the number of values that will fit.
    Only if the message is valid will the read or write be performed.
**/

/* data storage for simulated PLC */
typedef struct tagSIM_PLC {
         WORD V[512];
         WORD C[512];
        } SIM_PLC;
SIM_PLC sim_plc [4];

/* communications buffers for simulated I/O channels */
typedef struct tagSIM_BUF {
         char read[100+1];
         char write[100+1];
        } SIM_BUF;
SIM_BUF sim_buf [4];

BOOL sim_buf_first = TRUE;
extern BOOL SimulatorWritePaused;
extern BOOL SimulatorReadPaused;

static VOID WINAPI InitializeSimulator (void);

/***********************************************************************/
/* initialize PLC simulator */

static
VOID
WINAPI
InitializeSimulator (void)
{
    int portID;

    sim_buf_first = FALSE;
    for (portID = 0; portID < 4; portID++)
        sim_buf[portID].read[0] = 0;
    debug ("Simulated I/O -- for test purposes only!");
} /* InitializeSimulator */

/***********************************************************************/
/** simulate start-up of communication with COM port **/

BOOL
WINAPI
OpenPort(LPPORT lpPort)
{
    char st [81];

    /* set COM port ID */
    lstrcpy (st, &lpPort->mbPortName[3]);
    lpPort->mbCid = atoi (st) - 1;

    /* check whether valid for simulator */
    if ((lpPort->mbCid < 0) || (3 < lpPort->mbCid)) {
        /* indicate selected COM port cannot be opened */
        lpPort->mbCid = IE_BADID;
        UdprotReportOpenErrorCode(lpPort);
        /* indicate error */
        return (FALSE);
    }

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

/***********************************************************************/
/** simulate shut-down of communication with COM port **/

void
WINAPI
ClosePort(LPPORT lpPort)
{
} /* ClosePort */

/***********************************************************************/
/** simulate COM port read from PLC **/

static
int ReadSimComm(int idComDev, void FAR *lpvBuf, int cbRead)
{
    int portID;
    int len;
    LPSTR read_buf;

    /* ensure readbacks are clear the first time */
    if (sim_buf_first) {
        InitializeSimulator ();
    }

    /* indicate nothing read if simulator is paused */
    if (SimulatorReadPaused)
        return (0);

    /* force COM port number to 0..3 */
    portID = idComDev & 0x03;

    /* select appropriate read buffer, get length */
    read_buf = (LPSTR) sim_buf[portID].read;
    len = lstrlen (read_buf);

    /* ensure length is within limits */
    if (len > cbRead)
        len = cbRead;
    if (cbRead > len)
        cbRead = len;

    /* copy read buffer to destination */
    _fstrncpy ((LPSTR) lpvBuf, read_buf, len);

    /* clear read buffer */
    read_buf[0] = '\0';

    /* return length of string */
    return (len);
} /* ReadSimComm */

/***********************************************************************/
/** simulate COM port write to PLC
    prepare read response, return written length **/

static
int WriteSimComm(int idComDev, const void FAR *lpvBuf, int cbWrite)
{
    int portID;
    int len;
    LPSTR write_buf, read_buf, ptr, rsp;
    int cks, cmd;
    WORD addr, count;
    WORD num_val;
    int errflg;
    BOOL bad_cmd;
    SIM_PLC *plc;

    /* ensure readbacks are clear the first time */
    if (sim_buf_first) {
        InitializeSimulator ();
    }

    /* indicate nothing written if simulator is paused */
    if (SimulatorWritePaused)
        return (0);

    /* force COM port number to 0..3 */
    portID = idComDev & 0x03;

    /* select appropriate write, read buffers */
    write_buf = (LPSTR) sim_buf[portID].write;
    read_buf  = (LPSTR) sim_buf[portID].read;

    /* select appropriate simulated PLC memory */
    plc = &sim_plc[portID];

    /* clear response */
    read_buf[0] = 0;

    /* get length of string, ensure within limits */
    if (cbWrite > 100)
        cbWrite = 100;
    len = cbWrite;

    /* copy source to write buffer, append terminating zero */
    _fstrncpy (write_buf, (LPSTR) lpvBuf, len);
    write_buf[len] = 0;

    /* check whether command has valid length, delimiters, checksum */
    if (!IsCommandValid (write_buf, len)) {
        /* bad or corrupt message, return error indicator */
        lstrcpy (read_buf, (LPSTR) ":0000000000FF;");
        /* return length written to simulator */
        return (cbWrite);
    }

    /* initialize pointer, scan length */
    ptr = write_buf+1;
    len -= 4;

    /* initialize flag */
    bad_cmd = FALSE;

    /* get command, update pointer and length, check for error */
    cmd = (int) GetHexVal (ptr, 2, &errflg);
    if ((cmd != 0x01) && (cmd != 0x02) && (cmd != 0x81) && (cmd != 0x82)) {
        /* indicate bad command */
        bad_cmd = TRUE;
    }
    ptr += 2; len -= 2;

    /* get address, update pointer and length, check for error */
    if (len < 4) {
        /* indicate bad command */
        bad_cmd = TRUE;
        /* pad the end with zeros */
        while (len < 4) {
           ptr[len++] = '0';
        }
    }
    addr = (WORD) GetHexVal (ptr, 4, &errflg);
    ptr += 4; len -= 4;

    /* get count, update pointer and length, check for error */
    if (len < 2) {
        /* indicate bad command */
        bad_cmd = TRUE;
        /* pad the end with zeros */
        while (len < 2) {
           ptr[len++] = '0';
        }
    }
    count = (WORD) GetHexVal (ptr, 2, &errflg);
    if (count == 0)
        /* indicate bad command */
        bad_cmd = TRUE;
    ptr += 2; len -= 2;

    /* check whether command is a read or a write */
    num_val = 0;
    if ((cmd == 0x81) || (cmd == 0x82)) {
        /* write, check count vs. number of values */
        if (count * 4 != (WORD) len) {
            /* indicate bad command */
            bad_cmd = TRUE;
            /* determine number of complete values supplied */
            num_val = (WORD) (len / 4);
        }
    }
    if ((cmd == 0x01) || (cmd == 0x02)) {
        /* read, check count vs. available length */
        if (count * 4 > 88) {
            /* indicate bad command */
            bad_cmd = TRUE;
            /* determine max number of values that will fit */
            num_val = 88 / 4;
        }
    }

    /* check whether command is invalid */
    if (bad_cmd) {
        /* construct and return error message */
        rsp = read_buf;
        *(rsp++) = ':';
        rsp = put_hex_byte (rsp, 0x00);
        rsp = put_hex_byte (rsp, (BYTE) cmd);
        rsp = put_hex_word (rsp, addr);
        rsp = put_hex_byte (rsp, (BYTE) count);
        rsp = put_hex_byte (rsp, (BYTE) num_val);
        len = (int) (rsp - read_buf);
        cks = BldCks (read_buf+1, len-1, &errflg);
        rsp = put_hex_byte (rsp, (BYTE) cks);
        *(rsp++) = ';';
        *rsp = 0;
        /* return length written to simulator */
        return (cbWrite);
    }

    /* command is valid, prepare beginnings of response */
    rsp = read_buf;
    *(rsp++) = ':';
    rsp = put_hex_byte (rsp, (BYTE) cmd);
    rsp = put_hex_word (rsp, addr);
    rsp = put_hex_byte (rsp, (BYTE) count);

    /* get (address - 1) mod 512 */
    addr = (WORD) ((addr - 1) & 0x01FF);

    /* determine whether to handle read or write */
    if ((cmd & 0x80) == 0) {
        /* command is a read */
        while (count > 0) {
            /* get appropriate value */
            if (cmd == 0x01) {
                num_val = plc->V[addr];
            } else {
                (plc->C[addr])++;
                num_val = plc->C[addr];
            }
            /* place value in return message */
            rsp = put_hex_word (rsp, num_val);
            /* advance address and decrement count */
            addr = (WORD) ((addr + 1) & 0x01FF);
            count--;
        }
    } else {
        /* command is a write */
        while (count > 0) {
            /* acquire value from write message */
            num_val = (WORD) GetHexVal (ptr, 4, &errflg);
            ptr += 4; len -= 4;
            /* store appropriate value */
            if (cmd == 0x81) {
                plc->V[addr] = num_val;
            } else {
                plc->C[addr] = num_val;
            }
            /* advance address and decrement count */
            addr = (WORD) ((addr + 1) & 0x01FF);
            count--;
        }
    }

    /* command complete, fill in remainder of response */
    len = (int) (rsp - read_buf);
    cks = BldCks (read_buf+1, len-1, &errflg);
    rsp = put_hex_byte (rsp, (BYTE) cks);
    *(rsp++) = ';';
    *rsp = 0;

    /* return length written to simulator */
    return (cbWrite);
} /* WriteSimComm */
#endif

⌨️ 快捷键说明

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