Compare commits
11 Commits
S7PLCFW_1_
...
1.0.8
Author | SHA1 | Date | |
---|---|---|---|
7d4f57750b | |||
54e258db1a | |||
644c824604 | |||
a470205454 | |||
59511616ae | |||
46bf87c99c | |||
9ea778a101 | |||
a5ed2fd234 | |||
f9b9b5192f | |||
4f4d43032d | |||
382c7d4184 |
4
Makefile
4
Makefile
@ -5,7 +5,3 @@ BUILDCLASSES+=Linux
|
||||
DBDS += s7plcFWBase.dbd
|
||||
DBDS_3.14 += s7plcFWCalcout.dbd
|
||||
DBDS_3.14 += s7plcFWReg.dbd
|
||||
|
||||
EPICS_VERSIONS =
|
||||
EPICS_VERSIONS += 3.14.8
|
||||
EPICS_VERSIONS += 3.14.12
|
||||
|
129
devS7plcFW.c
129
devS7plcFW.c
@ -1,8 +1,8 @@
|
||||
/* $Author: anicic $ */
|
||||
/* $Date: 2010/09/22 13:44:37 $ */
|
||||
/* $Id: devS7plcFW.c,v 1.1 2010/09/22 13:44:37 anicic Exp $ */
|
||||
/* $Date: 2012/03/06 10:53:08 $ */
|
||||
/* $Id: devS7plcFW.c,v 1.2 2012/03/06 10:53:08 anicic Exp $ */
|
||||
/* $Name: $ */
|
||||
/* $Revision: 1.1 $ */
|
||||
/* $Revision: 1.2 $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@ -34,22 +34,31 @@
|
||||
#include <stringoutRecord.h>
|
||||
#include <waveformRecord.h>
|
||||
|
||||
#if ((EPICS_VERSION==3 && EPICS_REVISION>=14) || EPICS_VERSION>3)
|
||||
/* R3.14 */
|
||||
#ifdef BASE_VERSION
|
||||
#define EPICS_3_13
|
||||
#include "compat3_13.h"
|
||||
#else
|
||||
#include <postfix.h>
|
||||
#include <calcoutRecord.h>
|
||||
#include <cantProceed.h>
|
||||
#include <epicsExport.h>
|
||||
#else
|
||||
/* R3.13 */
|
||||
#include "compat3_13.h"
|
||||
#endif
|
||||
|
||||
/* suppress compiler warning concerning long long with __extension__ */
|
||||
#ifndef __GNUC__
|
||||
#if (!defined __GNUC__) || (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
|
||||
#define __extension__
|
||||
#endif
|
||||
|
||||
#ifndef epicsUInt64
|
||||
#if (LONG_MAX > 2147483647L)
|
||||
#define epicsUInt64 unsigned long
|
||||
#define CONV64 "%016lx"
|
||||
#else
|
||||
#define epicsUInt64 unsigned long long
|
||||
#define CONV64 "%016llx"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define S7MEM_TIME 100
|
||||
|
||||
typedef struct { /* Private structure to save IO arguments */
|
||||
@ -63,7 +72,7 @@ typedef struct { /* Private structure to save IO arguments */
|
||||
} S7memPrivate_t;
|
||||
|
||||
static char cvsid_devS7plcFW[] =
|
||||
"$Id: devS7plcFW.c,v 1.1 2010/09/22 13:44:37 anicic Exp $";
|
||||
"$Id: devS7plcFW.c,v 1.2 2012/03/06 10:53:08 anicic Exp $";
|
||||
|
||||
STATIC long s7plcFWReport();
|
||||
|
||||
@ -351,7 +360,7 @@ struct devsup s7plcFWWaveform =
|
||||
epicsExportAddress(dset, s7plcFWWaveform);
|
||||
|
||||
/* calcout **********************************************************/
|
||||
#if ((EPICS_VERSION==3 && EPICS_REVISION>=14) || EPICS_VERSION>3)
|
||||
#ifndef EPICS_3_13
|
||||
|
||||
STATIC long s7plcFWInitRecordCalcout(calcoutRecord *);
|
||||
STATIC long s7plcFWWriteCalcout(calcoutRecord *);
|
||||
@ -1686,8 +1695,8 @@ STATIC long s7plcFWReadAi(aiRecord *record)
|
||||
epicsUInt16 uval16;
|
||||
epicsInt32 sval32;
|
||||
epicsUInt32 uval32;
|
||||
epicsFloat32 val32;
|
||||
epicsFloat64 val64;
|
||||
union {epicsFloat32 f; epicsUInt32 i; } val32;
|
||||
__extension__ union {epicsFloat64 f; epicsUInt64 i; } val64;
|
||||
|
||||
if (!priv)
|
||||
{
|
||||
@ -1744,15 +1753,15 @@ STATIC long s7plcFWReadAi(aiRecord *record)
|
||||
status = s7plcFWRead(priv->station, priv->offs,
|
||||
4, &val32);
|
||||
s7plcFWDebugLog(3, "ai %s: read 32bit %04x = %g\n",
|
||||
record->name, *(unsigned int*) &val32, val32);
|
||||
val64 = val32;
|
||||
record->name, val32.i, val32.f);
|
||||
val64.f = val32.f;
|
||||
floatval = TRUE;
|
||||
break;
|
||||
case epicsFloat64T:
|
||||
status = s7plcFWRead(priv->station, priv->offs,
|
||||
8, &val64);
|
||||
__extension__ s7plcFWDebugLog(3, "ai %s: read 64bit %08Lx = %g\n",
|
||||
record->name, *(long long*) &val64, val64);
|
||||
__extension__ s7plcFWDebugLog(3, "ai %s: read 64bit " CONV64 " = %g\n",
|
||||
record->name, val64.i, val64.f);
|
||||
floatval = TRUE;
|
||||
break;
|
||||
default:
|
||||
@ -1777,14 +1786,14 @@ STATIC long s7plcFWReadAi(aiRecord *record)
|
||||
if (floatval)
|
||||
{
|
||||
/* emulate scaling */
|
||||
if (record->aslo != 0.0) val64 *= record->aslo;
|
||||
val64 += record->aoff;
|
||||
if (record->aslo != 0.0) val64.f *= record->aslo;
|
||||
val64.f += record->aoff;
|
||||
if (record->udf)
|
||||
record->val = val64;
|
||||
record->val = val64.f;
|
||||
else
|
||||
/* emulate smoothing */
|
||||
record->val = record->val * record->smoo +
|
||||
val64 * (1.0 - record->smoo);
|
||||
val64.f * (1.0 - record->smoo);
|
||||
record->udf = FALSE;
|
||||
return 2;
|
||||
}
|
||||
@ -1858,8 +1867,8 @@ STATIC long s7plcFWWriteAo(aoRecord *record)
|
||||
epicsUInt8 rval8;
|
||||
epicsUInt16 rval16;
|
||||
epicsUInt32 rval32;
|
||||
epicsFloat32 val32;
|
||||
epicsFloat64 val64;
|
||||
union {epicsFloat32 f; epicsUInt32 i; } val32;
|
||||
__extension__ union {epicsFloat64 f; epicsUInt64 i; } val64;
|
||||
|
||||
if (!priv)
|
||||
{
|
||||
@ -1926,21 +1935,21 @@ STATIC long s7plcFWWriteAo(aoRecord *record)
|
||||
break;
|
||||
case epicsFloat32T:
|
||||
/* emulate scaling */
|
||||
val32 = record->oval - record->aoff;
|
||||
if (record->aslo != 0) val32 /= record->aslo;
|
||||
val32.f = record->oval - record->aoff;
|
||||
if (record->aslo != 0) val32.f /= record->aslo;
|
||||
|
||||
s7plcFWDebugLog(2, "ao %s: write 32bit %08x\n",
|
||||
record->name, *(epicsInt32*)&val32);
|
||||
s7plcFWDebugLog(2, "ao %s: write 32bit %08x = %g\n",
|
||||
record->name, val32.i, val32.f);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
4, &val32);
|
||||
break;
|
||||
case epicsFloat64T:
|
||||
/* emulate scaling */
|
||||
val64 = record->oval - record->aoff;
|
||||
if (record->aslo != 0) val64 /= record->aslo;
|
||||
val64.f = record->oval - record->aoff;
|
||||
if (record->aslo != 0) val64.f /= record->aslo;
|
||||
|
||||
__extension__ s7plcFWDebugLog(2, "ao %s: write 64bit %016Lx\n",
|
||||
record->name, *(long long*)&val64);
|
||||
__extension__ s7plcFWDebugLog(2, "ao %s: write 64bit " CONV64 " = %g\n",
|
||||
record->name, val64.i, val64.f);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
8, &val64);
|
||||
break;
|
||||
@ -2015,7 +2024,7 @@ STATIC long s7plcFWInitRecordStringin(stringinRecord *record)
|
||||
{
|
||||
errlogSevPrintf(errlogMinor,
|
||||
"%s: string size reduced from %d to %d\n",
|
||||
record->name, priv->dlen, sizeof(record->val));
|
||||
record->name, priv->dlen, (int)sizeof(record->val));
|
||||
priv->dlen = sizeof(record->val);
|
||||
}
|
||||
record->dpvt = priv;
|
||||
@ -2095,7 +2104,7 @@ STATIC long s7plcFWInitRecordStringout(stringoutRecord *record)
|
||||
{
|
||||
errlogSevPrintf(errlogMinor,
|
||||
"%s: string size reduced from %d to %d\n",
|
||||
record->name, priv->dlen, sizeof(record->val));
|
||||
record->name, priv->dlen, (int)sizeof(record->val));
|
||||
priv->dlen = sizeof(record->val);
|
||||
}
|
||||
record->dpvt = priv;
|
||||
@ -2358,8 +2367,8 @@ STATIC long s7plcFWReadWaveform(waveformRecord *record)
|
||||
return status;
|
||||
}
|
||||
|
||||
#if (EPICS_REVISION>=14)
|
||||
/* calcout **********************************************************/
|
||||
#ifndef EPICS_3_13
|
||||
|
||||
STATIC long s7plcFWInitRecordCalcout(calcoutRecord *record)
|
||||
{
|
||||
@ -2413,8 +2422,8 @@ STATIC long s7plcFWWriteCalcout(calcoutRecord *record)
|
||||
epicsInt8 sval8;
|
||||
epicsInt16 sval16;
|
||||
epicsInt32 sval32;
|
||||
epicsFloat32 val32;
|
||||
epicsFloat64 val64;
|
||||
union {epicsFloat32 f; epicsUInt32 i; } val32;
|
||||
__extension__ union {epicsFloat64 f; epicsUInt64 i; } val64;
|
||||
|
||||
if (!priv)
|
||||
{
|
||||
@ -2424,73 +2433,73 @@ STATIC long s7plcFWWriteCalcout(calcoutRecord *record)
|
||||
return -1;
|
||||
}
|
||||
assert(priv->station);
|
||||
val64 = record->oval;
|
||||
val64.f = record->oval;
|
||||
switch (priv->dtype)
|
||||
{
|
||||
case epicsInt8T:
|
||||
sval8 = val64;
|
||||
if (val64 > priv->hwHigh) sval8 = priv->hwHigh;
|
||||
if (val64 < priv->hwLow) sval8 = priv->hwLow;
|
||||
sval8 = val64.f;
|
||||
if (val64.f > priv->hwHigh) sval8 = priv->hwHigh;
|
||||
if (val64.f < priv->hwLow) sval8 = priv->hwLow;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 8bit %02x\n",
|
||||
record->name, sval8 & 0xff);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
1, &sval8);
|
||||
break;
|
||||
case epicsUInt8T:
|
||||
uval8 = val64;
|
||||
if (val64 > priv->hwHigh) uval8 = priv->hwHigh;
|
||||
if (val64 < priv->hwLow) uval8 = priv->hwLow;
|
||||
uval8 = val64.f;
|
||||
if (val64.f > priv->hwHigh) uval8 = priv->hwHigh;
|
||||
if (val64.f < priv->hwLow) uval8 = priv->hwLow;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 8bit %02x\n",
|
||||
record->name, uval8 & 0xff);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
1, &uval8);
|
||||
break;
|
||||
case epicsInt16T:
|
||||
sval16 = val64;
|
||||
if (val64 > priv->hwHigh) sval16 = priv->hwHigh;
|
||||
if (val64 < priv->hwLow) sval16 = priv->hwLow;
|
||||
sval16 = val64.f;
|
||||
if (val64.f > priv->hwHigh) sval16 = priv->hwHigh;
|
||||
if (val64.f < priv->hwLow) sval16 = priv->hwLow;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 16bit %04x\n",
|
||||
record->name, sval16 & 0xffff);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
2, &sval16);
|
||||
break;
|
||||
case epicsUInt16T:
|
||||
uval16 = val64;
|
||||
if (val64 > priv->hwHigh) uval16 = priv->hwHigh;
|
||||
if (val64 < priv->hwLow) uval16 = priv->hwLow;
|
||||
uval16 = val64.f;
|
||||
if (val64.f > priv->hwHigh) uval16 = priv->hwHigh;
|
||||
if (val64.f < priv->hwLow) uval16 = priv->hwLow;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 16bit %04x\n",
|
||||
record->name, uval16 & 0xffff);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
2, &uval16);
|
||||
break;
|
||||
case epicsInt32T:
|
||||
sval32 = val64;
|
||||
if (val64 > priv->hwHigh) sval32 = priv->hwHigh;
|
||||
if (val64 < priv->hwLow) sval32 = priv->hwLow;
|
||||
sval32 = val64.f;
|
||||
if (val64.f > priv->hwHigh) sval32 = priv->hwHigh;
|
||||
if (val64.f < priv->hwLow) sval32 = priv->hwLow;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 32bit %08x\n",
|
||||
record->name, sval32);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
4, &sval32);
|
||||
break;
|
||||
case epicsUInt32T:
|
||||
uval32 = val64;
|
||||
if (val64 > priv->hwHigh) uval32 = priv->hwHigh;
|
||||
if (val64 < priv->hwLow) uval32 = priv->hwLow;
|
||||
uval32 = val64.f;
|
||||
if (val64.f > priv->hwHigh) uval32 = priv->hwHigh;
|
||||
if (val64.f < priv->hwLow) uval32 = priv->hwLow;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 32bit %08x\n",
|
||||
record->name, uval32);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
4, &uval32);
|
||||
break;
|
||||
case epicsFloat32T:
|
||||
val32 = val64;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 32bit %08x\n",
|
||||
record->name, *(epicsInt32*)&val32);
|
||||
val32.f = val64.f;
|
||||
s7plcFWDebugLog(2, "calcout %s: write 32bit %08x = %g\n",
|
||||
record->name, val32.i, val32.f);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
4, &val32);
|
||||
break;
|
||||
case epicsFloat64T:
|
||||
__extension__ s7plcFWDebugLog(2, "calcout %s: write 64bit %016Lx\n",
|
||||
record->name, *(long long*)&val64);
|
||||
__extension__ s7plcFWDebugLog(2, "calcout %s: write 64bit " CONV64 " = %g\n",
|
||||
record->name, val64.i, val64.f);
|
||||
status = s7plcFWWrite(priv->station, priv->offs,
|
||||
8, &val64);
|
||||
break;
|
||||
|
78
drvS7plcFW.c
78
drvS7plcFW.c
@ -1,7 +1,7 @@
|
||||
/* $Date: 2010/09/22 13:44:37 $ */
|
||||
/* $Id: drvS7plcFW.c,v 1.1 2010/09/22 13:44:37 anicic Exp $ */
|
||||
/* $Date: 2013/07/11 12:43:21 $ */
|
||||
/* $Id: drvS7plcFW.c,v 1.6 2013/07/11 12:43:21 anicic Exp $ */
|
||||
/* $Name: $ */
|
||||
/* $Revision: 1.1 $ */
|
||||
/* $Revision: 1.6 $ */
|
||||
|
||||
/*
|
||||
* NOTE: s7plcFWwriteThread -is not used for writting (we write direct),
|
||||
@ -19,14 +19,20 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifdef __vxworks
|
||||
#if defined(vxWorks) || defined(__vxworks)
|
||||
#include <sockLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <selectLib.h>
|
||||
#include <taskHookLib.h>
|
||||
#define in_addr_t unsigned long
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef __rtems__
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <drvSup.h>
|
||||
#include <devLib.h>
|
||||
#include <epicsVersion.h>
|
||||
@ -34,7 +40,7 @@
|
||||
|
||||
#include "drvS7plcFW.h"
|
||||
|
||||
#if ((EPICS_VERSION==3 && EPICS_REVISION>=14) || EPICS_VERSION>3)
|
||||
#ifndef BASE_VERSION
|
||||
/* R3.14 */
|
||||
#include <dbAccess.h>
|
||||
#include <iocsh.h>
|
||||
@ -46,6 +52,7 @@
|
||||
#include <epicsExport.h>
|
||||
#else
|
||||
/* R3.13 */
|
||||
#define EPICS_3_13
|
||||
#include "compat3_13.h"
|
||||
#endif
|
||||
|
||||
@ -57,12 +64,13 @@
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#define STACK_SIZE 20000 /* io thread stack size */
|
||||
/* #define STACK_SIZE 20000 */ /* io thread stack size */
|
||||
#define STACK_SIZE epicsThreadGetStackSize(epicsThreadStackBig)
|
||||
#define CONNECT_TIMEOUT 5.0 /* connect timeout [s] */
|
||||
#define RECONNECT_DELAY 10.0 /* delay before reconnect [s] */
|
||||
|
||||
static char cvsid[] __attribute__((unused)) =
|
||||
"$Id: drvS7plcFW.c,v 1.1 2010/09/22 13:44:37 anicic Exp $";
|
||||
"$Id: drvS7plcFW.c,v 1.6 2013/07/11 12:43:21 anicic Exp $";
|
||||
|
||||
STATIC long s7plcFWIoReport(int level);
|
||||
STATIC long s7plcFWInit();
|
||||
@ -129,6 +137,8 @@ struct s7plcFWStation {
|
||||
char *fetchBuffer, *writeBuffer;
|
||||
int swapBytes;
|
||||
float recvTimeout, recvDelay, outIOintDelay;
|
||||
|
||||
int writeAll; // flag, when != 0 then always write the whole buffer to DB (needed for SINQ)
|
||||
};
|
||||
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
@ -164,8 +174,8 @@ STATIC long s7plcFWIoReport(int level)
|
||||
printf(" NOT CONNECTED\n");
|
||||
}
|
||||
|
||||
printf(" WRITE: Port=%5d Org=%3d Db=%3d Offs=%5d Size=%5d buffer@%p (%5d bytes)",
|
||||
station->writePort, station->writeOrg, station->writeDb, station->writeOffs, station->writeSize, station->writeBuffer, station->writeSize);
|
||||
printf(" WRITE: Port=%5d Org=%3d Db=%3d Offs=%5d Size=%5d buffer@%p (%5d bytes) %s",
|
||||
station->writePort, station->writeOrg, station->writeDb, station->writeOffs, station->writeSize, station->writeBuffer, station->writeSize, (station->writeAll ? "" : "writeAll"));
|
||||
if (station->writeConnStatus) {
|
||||
printf(" CONNECTED (fd=%d)\n", station->writeSocket);
|
||||
}
|
||||
@ -180,9 +190,9 @@ STATIC long s7plcFWIoReport(int level)
|
||||
"ioc:motorola <-> plc:intel" : "no (both motorola)"
|
||||
#endif
|
||||
);
|
||||
printf(" receive timeout %g sec\n", station->recvTimeout);
|
||||
printf(" receive delay %g sec\n", station->recvDelay);
|
||||
printf(" outIOint delay %g sec\n", station->outIOintDelay);
|
||||
printf(" receive timeout %d ms\n", (int)(station->recvTimeout * 1000.0));
|
||||
printf(" receive delay %d ms\n", (int)(station->recvDelay * 1000.0));
|
||||
printf(" outIOint delay %d ms\n", (int)(station->outIOintDelay * 1000.0));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -241,6 +251,7 @@ int s7plcFWConfigure(char *name, char* IPaddr, char *fetchInfo, char *writeInfo,
|
||||
unsigned char fetchDb, writeDb;
|
||||
unsigned int fetchOffs, writeOffs;
|
||||
unsigned int fetchSize, writeSize;
|
||||
int writeAll;
|
||||
|
||||
if (!name) {
|
||||
errlogSevPrintf(errlogFatal, "s7plcFWConfigure: missing name\n");
|
||||
@ -261,6 +272,7 @@ int s7plcFWConfigure(char *name, char* IPaddr, char *fetchInfo, char *writeInfo,
|
||||
|
||||
extractPGDOS(fetchInfo, &fetchPort, &fetchOrg, &fetchDb, &fetchOffs, &fetchSize);
|
||||
extractPGDOS(writeInfo, &writePort, &writeOrg, &writeDb, &writeOffs, &writeSize);
|
||||
writeAll = 0; if (strstr(writeInfo, "writeall") != NULL) writeAll = 1; // write the whole buffer to DB
|
||||
|
||||
if ((fetchPort == 0) || (fetchOrg == 0) || (fetchDb == 0) || ((fetchOffs%2) != 0) || (fetchSize == 0) || ((fetchSize%2) != 0)) { /* size & offs: only even numbers */
|
||||
fetchPort = fetchOrg = fetchDb = fetchOffs = fetchSize = 0;
|
||||
@ -302,6 +314,7 @@ int s7plcFWConfigure(char *name, char* IPaddr, char *fetchInfo, char *writeInfo,
|
||||
station->writeOffs = writeOffs;
|
||||
station->fetchSize = fetchSize;
|
||||
station->writeSize = writeSize;
|
||||
station->writeAll = writeAll;
|
||||
|
||||
if (fetchSize > 0)
|
||||
station->fetchBuffer = callocMustSucceed(1, fetchSize, "s7plcFWConfigure");
|
||||
@ -358,7 +371,7 @@ int s7plcFWConfigure(char *name, char* IPaddr, char *fetchInfo, char *writeInfo,
|
||||
}
|
||||
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
#if (EPICS_REVISION>=14)
|
||||
#ifndef EPICS_3_13
|
||||
static const iocshArg s7plcFWConfigureArg0 = { "name", iocshArgString };
|
||||
static const iocshArg s7plcFWConfigureArg1 = { "IPaddr", iocshArgString };
|
||||
static const iocshArg s7plcFWConfigureArg2 = { "fetchInfo", iocshArgString };
|
||||
@ -382,11 +395,9 @@ static const iocshArg * const s7plcFWConfigureArgs[] = {
|
||||
static const iocshFuncDef s7plcFWConfigureDef = { "s7plcFWConfigure", 8, s7plcFWConfigureArgs };
|
||||
static void s7plcFWConfigureFunc (const iocshArgBuf *args)
|
||||
{
|
||||
int status = s7plcFWConfigure(
|
||||
(void) s7plcFWConfigure(
|
||||
args[0].sval, args[1].sval, args[2].sval, args[3].sval,
|
||||
args[4].ival, args[5].ival, args[6].ival, args[7].ival);
|
||||
|
||||
if (status) exit(1);
|
||||
}
|
||||
|
||||
static void s7plcFWRegister ()
|
||||
@ -446,8 +457,8 @@ STATIC void s7plcFWMain ()
|
||||
}
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: Connect to %s:%d on fetch socket %d\n", station->name, station->serverIP, station->fetchPort, station->fetchSocket);
|
||||
if (s7plcFWEstablishConnection(station, FOR_FETCH) < 0) {
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: connect(%d, %s:%d) failed for fetch: %s. Retry in %g seconds\n",
|
||||
station->name, station->fetchSocket, station->serverIP, station->fetchPort, strerror(errno), (double)RECONNECT_DELAY);
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: connect(%d, %s:%d) failed for fetch: %s. Retry in %d ms\n",
|
||||
station->name, station->fetchSocket, station->serverIP, station->fetchPort, strerror(errno), (int)(RECONNECT_DELAY * 1000.0));
|
||||
if (close(station->fetchSocket) && errno != ENOTCONN) {
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: close(%d) failed for fetch (ignored): %s\n", station->name, station->fetchSocket, strerror(errno));
|
||||
}
|
||||
@ -470,8 +481,8 @@ STATIC void s7plcFWMain ()
|
||||
}
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: Connect to %s:%d on write socket %d\n", station->name, station->serverIP, station->writePort, station->writeSocket);
|
||||
if (s7plcFWEstablishConnection(station, FOR_WRITE) < 0) {
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: connect(%d, %s:%d) failed for write: %s. Retry in %g seconds\n",
|
||||
station->name, station->writeSocket, station->serverIP, station->writePort, strerror(errno), (double)RECONNECT_DELAY);
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: connect(%d, %s:%d) failed for write: %s. Retry in %d ms\n",
|
||||
station->name, station->writeSocket, station->serverIP, station->writePort, strerror(errno), (int)(RECONNECT_DELAY * 1000.0));
|
||||
if (close(station->writeSocket) && errno != ENOTCONN) {
|
||||
s7plcFWDebugLog(1, "s7plcFWMain %s: close(%d) failed for write (ignored): %s\n", station->name, station->writeSocket, strerror(errno));
|
||||
}
|
||||
@ -623,7 +634,7 @@ STATIC int s7plcFWdoFetch(s7plcFWStation *station, int org, int db, int offs, in
|
||||
req[0xd] = s7len % 0x100;
|
||||
|
||||
epicsMutexMustLock(station->fetchIo);
|
||||
status = write(station->fetchSocket, req, 16);
|
||||
status = write(station->fetchSocket, (void *) req, 16);
|
||||
epicsMutexUnlock(station->fetchIo);
|
||||
if (status != 16) {
|
||||
s7plcFWDebugLog(3, "s7plcFWdoFetch: write 16 byte header failed, returned status = %d, errno = %d\n", status, errno);
|
||||
@ -637,7 +648,7 @@ STATIC int s7plcFWdoFetch(s7plcFWStation *station, int org, int db, int offs, in
|
||||
}
|
||||
|
||||
epicsMutexMustLock(station->fetchIo);
|
||||
status = read(station->fetchSocket, ack, 16);
|
||||
status = read(station->fetchSocket, (void *) ack, 16);
|
||||
epicsMutexUnlock(station->fetchIo);
|
||||
if(status < 16) {
|
||||
s7plcFWDebugLog(3, "s7plcFWdoFetch: Got too few bytes (%d) ACK from PLC!\n", status);
|
||||
@ -653,7 +664,7 @@ STATIC int s7plcFWdoFetch(s7plcFWStation *station, int org, int db, int offs, in
|
||||
input = 0;
|
||||
while (input < size) {
|
||||
|
||||
s7plcFWDebugLog(3, "s7plcFWdoFetch: %s: waiting for input for %g seconds\n", station->name, station->recvTimeout);
|
||||
s7plcFWDebugLog(3, "s7plcFWdoFetch: %s: waiting for input for %d ms\n", station->name, (int)(station->recvTimeout * 1000.0));
|
||||
status = s7plcFWWaitForInput(station, FOR_FETCH, station->recvTimeout);
|
||||
if (status <= 0) {
|
||||
s7plcFWDebugLog(0, "s7plcFWdoFetch: %s: s7plcFWWaitForInput(%d, ..., %d, 0) failed\n", station->name, station->fetchSocket, size - input);
|
||||
@ -701,7 +712,7 @@ STATIC int s7plcFWdoWrite(s7plcFWStation *station, char *data, int offs, int len
|
||||
req[0xd] = s7len % 0x100;
|
||||
|
||||
epicsMutexMustLock(station->writeIo);
|
||||
status = write(station->writeSocket, req, 16);
|
||||
status = write(station->writeSocket, (void *) req, 16);
|
||||
dstatus = write(station->writeSocket, data, len);
|
||||
epicsMutexUnlock(station->writeIo);
|
||||
|
||||
@ -724,7 +735,7 @@ STATIC int s7plcFWdoWrite(s7plcFWStation *station, char *data, int offs, int len
|
||||
}
|
||||
|
||||
epicsMutexMustLock(station->writeIo);
|
||||
if((status = read(station->writeSocket, ack, 16)) < 16) {
|
||||
if((status = read(station->writeSocket, (void *) ack, 16)) < 16) {
|
||||
s7plcFWDebugLog(3, "Got too few bytes (%d) ACK from PLC!\n", status);
|
||||
/* printf("AD84: s7plcFWdoWrite: read too few bytes (%d) ACK from PLC!\n", status); */
|
||||
epicsMutexUnlock(station->writeIo);
|
||||
@ -805,7 +816,12 @@ int s7plcFWWriteMaskedArray(s7plcFWStation *station, unsigned int offset, unsign
|
||||
/* warning: we allways have to write even number of bytes - so it can happen that we have to write 1 or 2 bytes more than requested */
|
||||
woffs = offset & 0xFFFFFFFE; /* we need even byte offset */
|
||||
wlen = 0; if (woffs != offset) wlen += 1; wlen += nelem*dlen; if ((wlen % 2) != 0) wlen += 1;
|
||||
wstatus = s7plcFWdoWrite(station, &station->writeBuffer[woffs], woffs, wlen);
|
||||
if (station->writeAll == 0) {
|
||||
wstatus = s7plcFWdoWrite(station, &station->writeBuffer[woffs], woffs, wlen);
|
||||
}
|
||||
else {
|
||||
wstatus = s7plcFWdoWrite(station, &station->writeBuffer[0], 0, station->writeSize);
|
||||
}
|
||||
if (wstatus != 0) {
|
||||
s7plcFWDebugLog(0, "s7plcFWWriteMaskedArray %s: s7plcFWdoWrite(%d, ...) failed\n", station->name, station->writeSocket);
|
||||
s7plcFWCloseConnection(station, FOR_WRITE);
|
||||
@ -905,12 +921,12 @@ STATIC int s7plcFWWaitForInput(s7plcFWStation* station, int which, double timeou
|
||||
errno = 0;
|
||||
while ((iSelect=select(socket+1, &socklist, 0, 0, &to)) < 0) {
|
||||
if (errno != EINTR) {
|
||||
s7plcFWDebugLog(0, "s7plcFWWaitForInput %s: select(%d, %f sec) failed: %s\n", station->name, socket, timeout, strerror(errno));
|
||||
s7plcFWDebugLog(0, "s7plcFWWaitForInput %s: select(%d, %d ms) failed: %s\n", station->name, socket, (int)(timeout * 1000.0), strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (iSelect==0 && timeout > 0) { /* timed out */
|
||||
s7plcFWDebugLog(0, "s7plcFWWaitForInput %s: select(%d, %f sec) timed out\n", station->name, socket, timeout);
|
||||
s7plcFWDebugLog(0, "s7plcFWWaitForInput %s: select(%d, %d ms) timed out\n", station->name, socket, (int)(timeout * 1000.0));
|
||||
errno = ETIMEDOUT;
|
||||
}
|
||||
return iSelect;
|
||||
@ -949,7 +965,7 @@ STATIC int s7plcFWEstablishConnection(s7plcFWStation* station, int which)
|
||||
to.tv_usec=(int)(CONNECT_TIMEOUT-to.tv_sec)*1000000;
|
||||
#ifdef __vxworks
|
||||
if (connectWithTimeout(socket, (struct sockaddr *) &serverAddr, sizeof (serverAddr), &to) < 0) {
|
||||
s7plcFWDebugLog(0, "s7plcFWEstablishConnection %s: connectWithTimeout(%d,...,%g sec) failed: %s\n", station->name, socket, CONNECT_TIMEOUT, strerror(errno));
|
||||
s7plcFWDebugLog(0, "s7plcFWEstablishConnection %s: connectWithTimeout(%d,...,%d ms) failed: %s\n", station->name, socket, (int)(CONNECT_TIMEOUT * 1000.0), strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
@ -975,12 +991,12 @@ STATIC int s7plcFWEstablishConnection(s7plcFWStation* station, int which)
|
||||
/* wait for connection */
|
||||
while ((status = select(socket+1, NULL, &fdset, NULL, &to)) < 0) {
|
||||
if (errno != EINTR) {
|
||||
s7plcFWDebugLog(0, "s7plcFWEstablishConnection %s: select(%d, %f sec) failed: %s\n", station->name, socket, CONNECT_TIMEOUT, strerror(errno));
|
||||
s7plcFWDebugLog(0, "s7plcFWEstablishConnection %s: select(%d, %d ms) failed: %s\n", station->name, socket, (int)(CONNECT_TIMEOUT * 1000.0), strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (status == 0) {
|
||||
s7plcFWDebugLog(0, "s7plcFWEstablishConnection %s: select(%d, %f sec) timed out\n", station->name, socket, CONNECT_TIMEOUT);
|
||||
s7plcFWDebugLog(0, "s7plcFWEstablishConnection %s: select(%d, %d ms) timed out\n", station->name, socket, (int)(CONNECT_TIMEOUT * 1000.0));
|
||||
errno = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ Besides the
|
||||
<li>new communication protocol (FETCH/WRITE)</li>
|
||||
<li>the modified <code>s7plcFWConfigure</code> function</li>
|
||||
<li>additional support for write-connection-status (see <a href="#stat"> <code>"s7plcFW stat2"</code> </a>)</li>
|
||||
<li>when using bi and bo bits 0-7 and 8-15 are swapped (i.e. for bit 3 use 3+8=11, or for bit 13 use 13-8=5)</li>
|
||||
</ol>
|
||||
there should be no other differences.
|
||||
<br><br>
|
||||
@ -122,6 +123,9 @@ containing the
|
||||
and
|
||||
<code>"writePort,writeOrg,writeDb,writeOffsetInDb,writeSizeOfDb"</code>.
|
||||
<br>
|
||||
For <code><i>writeInfo</i></code> you can add at the end of string an <code><i>writeall</i></code> option,
|
||||
to allways write the whole buffer to DB. This is needed for PLCs as used in SINQ.
|
||||
<br>
|
||||
fetchPort and writePort come in pairs. Usualy starting at 2000,2001.
|
||||
<br>
|
||||
Offsets and Sizes are in bytes and must be <code>even numbers</code>. Offset will usualy be zero, but one does not neccessarilly have to start at the beginning of Db. The size is number of bytes to fetch or write starting from given offset - it does not have to go to the end of Db and it should never exceed the size of Db.
|
||||
|
Reference in New Issue
Block a user