Jonny007-MKD
e0a6d84a9f
Write values to struct MakeConfig.can Detect devices via IP port scan Analyze devices and generate sysVars appropriately ModbusClientUDP.can Don't analyze devices because this has to be done in MakeConfig.can
474 lines
No EOL
18 KiB
Text
474 lines
No EOL
18 KiB
Text
/*@!Encoding:1252*/
|
|
includes
|
|
{
|
|
#include "include/ModbusUdpClientCommon.cin"
|
|
#include "include/ModbusFunctions.cin"
|
|
}
|
|
|
|
variables
|
|
{
|
|
struct device
|
|
{
|
|
char Ip[16];
|
|
char IpLsb[4];
|
|
char IpNet[4];
|
|
word SerialCode;
|
|
word DeviceCode;
|
|
struct deviceIOs DeviceIOs;
|
|
};
|
|
|
|
char[16] gIps[long];
|
|
char gScanFirstIp[16];
|
|
char gScanLastIp[16];
|
|
word gScanPort = 502;
|
|
|
|
char fnSysvar[20]; // Filename of Sysvars
|
|
char fnDbc[20]; // Filename of DBC
|
|
char name[20]; // Name of project
|
|
dword ips[50]; // detected IPs
|
|
|
|
|
|
file f;
|
|
byte gIpNets[long];
|
|
struct device gIpsSorted[long];
|
|
dword gScanFirst, gScanLast;
|
|
word ADi, ADn, ADl;
|
|
}
|
|
|
|
on preStart
|
|
{/*
|
|
strncpy(gIps[0], "192.168.1.3", 16);
|
|
strncpy(gIps[2], "192.168.1.4", 16);
|
|
strncpy(gIps[3], "192.168.1.8", 16);*/
|
|
|
|
strncpy(gScanFirstIp, "192.168.1.1", 16);
|
|
strncpy(gScanLastIp, "192.168.1.100", 16);
|
|
|
|
strncpy(name, "Modbus", elCount(name));
|
|
strncpy(fnSysvar, "generated.vsysvar", elCount(fnSysvar));
|
|
strncpy(fnDbc, "generated.dbc", elCount(fnDbc));
|
|
}
|
|
|
|
on start
|
|
{
|
|
if (gIps.Size() == 0)
|
|
DetectDevices();
|
|
else
|
|
MakeIpNets();
|
|
}
|
|
|
|
void PutString(file f, char str[])
|
|
{
|
|
f.PutString(str, strlen(str));
|
|
}
|
|
void PutString(file f, word d)
|
|
{
|
|
char str[6];
|
|
ltoa(d, str, 10);
|
|
f.PutString(str, strlen(str));
|
|
}
|
|
void PutString(file f, byte d)
|
|
{
|
|
char str[4];
|
|
ltoa(d, str, 10);
|
|
f.PutString(str, strlen(str));
|
|
}
|
|
|
|
// Step 1: Detect active devices and collect IP addresses
|
|
/// <Step1>
|
|
void DetectDevices()
|
|
{
|
|
write("Scanning from %s to %s with timeout of %d ms", gScanFirstIp, gScanLastIp, @sysvar::Config::Modbus::RequestTimeout);
|
|
gScanFirst = ipGetAddressAsNumber(gScanFirstIp);
|
|
gScanLast = ipGetAddressAsNumber(gScanLastIp);
|
|
ModbusConnectTo(gScanFirst, 502);
|
|
ModbusReadBits(0, 1);
|
|
}
|
|
/// <Step1>
|
|
void DetectDevicesNext()
|
|
{
|
|
// next IP
|
|
// 0xFE...... --> Skip xxx.xxx.xxx.255 which is broadcast address in 192.168.xxx.0 nets
|
|
if ((gScanFirst & 0xFFFFFF00) == 0xFEFFFF00)
|
|
{
|
|
gScanFirst &= 0x000000FF;
|
|
gScanFirst += 0x00000001;
|
|
}
|
|
else if ((gScanFirst & 0xFFFF0000) == 0xFEFF0000)
|
|
{
|
|
gScanFirst &= 0x0000FFF;
|
|
gScanFirst += 0x00000100;
|
|
}
|
|
else if ((gScanFirst & 0xFF000000) == 0xFE000000)
|
|
{
|
|
gScanFirst &= 0x00FFFFFF;
|
|
gScanFirst += 0x00010000;
|
|
}
|
|
else
|
|
{
|
|
gScanFirst += 0x01000000;
|
|
}
|
|
if (gScanFirst == gScanLast)
|
|
{
|
|
MakeIpNets();
|
|
return;
|
|
}
|
|
gRemoteIP = gScanFirst; // Don't open new socket, it takes too much time.
|
|
ModbusReadBits(0, 1);
|
|
}
|
|
/// <Step1>
|
|
void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
{
|
|
DetectDevicesNext();
|
|
}
|
|
/// <Step1>
|
|
void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbr, byte bitStatus[], word numBits)
|
|
{
|
|
ipGetAddressAsString(gScanFirst, gIps[gScanFirst], 16);
|
|
DetectDevicesNext();
|
|
}
|
|
|
|
// Step 2: Sort into subnets
|
|
// Sort the IPs from gIps to gIpsSorted and add their subnet to gIpNets
|
|
/// <Step2>
|
|
void MakeIpNets()
|
|
{
|
|
long ipNum;
|
|
|
|
if (gIps.Size() == 0)
|
|
{
|
|
stop();
|
|
return;
|
|
}
|
|
|
|
for (long i : gIps)
|
|
{
|
|
ipNum = ipGetAddressAsNumber(gIps[i]); // convert IP to dword
|
|
|
|
gIpNets[(ipNum >> 16) & 0xFF] = 1; // add subnet
|
|
ips[gIpsSorted.size()] = ipNum; // add ip to array
|
|
strncpy(gIpsSorted[ipNum].IP, gIps[i], 16); // copy to new array
|
|
ltoa((ipNum >> 16) & 0xFF, gIpsSorted[ipNum].IpNet, 10); // add .IpNet
|
|
ltoa((ipNum >> 24) & 0xFF, gIpsSorted[ipNum].IpLsb, 10); // add .IpLsb
|
|
|
|
gIps.Remove(i);
|
|
}
|
|
|
|
AnalyzeDevices();
|
|
}
|
|
|
|
|
|
// Step 3: Retreive configuration of devices
|
|
/// <Step3>
|
|
void AnalyzeDevices()
|
|
{
|
|
ADn = 0;
|
|
ADi = 0;
|
|
ADl = gIpsSorted.Size();
|
|
write("Analyzing %s...", gIpsSorted[ips[ADi]].Ip);
|
|
if (gRemoteIP != INVALID_IP)
|
|
gRemoteIP = ips[ADi];
|
|
else
|
|
ModbusConnectTo(ips[ADi], gRemotePort);
|
|
ModbusReadRegisters(0x2011, 1);
|
|
ModbusReadRegisters(0x2012, 1);
|
|
ModbusReadRegisters(0x2030, 65);
|
|
ModbusReadRegisters(0x2031, 64);
|
|
ModbusReadRegisters(0x2032, 64);
|
|
ModbusReadRegisters(0x2033, 63);
|
|
}
|
|
|
|
/// <Step3>
|
|
void AnalyzeDevicesNext()
|
|
{
|
|
if (++ADi >= ADl) // we have analyzed all devices
|
|
{
|
|
MakeFiles();
|
|
return;
|
|
}
|
|
|
|
ADn = 0;
|
|
gRemoteIP = ips[ADi];
|
|
write("Analyzing %s...", gIpsSorted[ips[ADi]].Ip);
|
|
ModbusReadRegisters(0x2011, 1);
|
|
ModbusReadRegisters(0x2012, 1);
|
|
ModbusReadRegisters(0x2030, 65);
|
|
ModbusReadRegisters(0x2031, 64);
|
|
ModbusReadRegisters(0x2032, 64);
|
|
ModbusReadRegisters(0x2033, 63);
|
|
}
|
|
|
|
/// <Step3>
|
|
void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
{
|
|
switch (error)
|
|
{
|
|
case FinalTimeout:
|
|
writeLineEx(0, 3, "Error while analyzing %s! The device did not respond! Ignoring...", gIpsSorted[ips[ADi]].IP);
|
|
gQueueAck.Clear();
|
|
gQueuePending.Clear();
|
|
gQueueSent.Clear();
|
|
gIpsSorted.Remove(ips[ADi]);
|
|
AnalyzeDevicesNext();
|
|
break;
|
|
case Exception:
|
|
writeLineEx(0, 3, "Error while analyzing %s! The device respond with exception code %d! Ignoring...", gIpsSorted[ips[ADi]].IP, ex);
|
|
gQueueAck.Clear();
|
|
gQueuePending.Clear();
|
|
gQueueSent.Clear();
|
|
gIpsSorted.Remove(ips[ADi]);
|
|
AnalyzeDevicesNext();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// <Step3>
|
|
void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbr, word numRegs)
|
|
{
|
|
byte i;
|
|
struct ModbusReqRead mbrq;
|
|
|
|
if (!gQueueAck.ContainsKey(mbr.Header.TxID))
|
|
return;
|
|
|
|
memcpy_n2h(mbrq, gQueueAck[mbr.Header.TxID].Buffer);
|
|
|
|
switch (mbrq.Address)
|
|
{
|
|
case 0x2011:
|
|
gIpsSorted[ips[ADi]].serialCode = mbr.Data[0];
|
|
break;
|
|
case 0x2012:
|
|
gIpsSorted[ips[ADi]].deviceCode = mbr.Data[0];
|
|
break;
|
|
case 0x2030:
|
|
case 0x2031:
|
|
case 0x2032:
|
|
case 0x2033:
|
|
for (i = 0; i < 65; i++)
|
|
{
|
|
if (mbr.Data[i] == 0x0000)
|
|
break;
|
|
ParseDeviceCode(mbr.Data[i], gIpsSorted[ips[ADi]].DeviceIOs);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (++ADn == 6)
|
|
AnalyzeDevicesNext();
|
|
}
|
|
|
|
// Step 4: Create the files with the queried data
|
|
/// <Step4>
|
|
void MakeFiles()
|
|
{
|
|
GenSysvars();
|
|
GenDbc();
|
|
stop();
|
|
}
|
|
|
|
// Generate the SysVars XML
|
|
/// <Step4>
|
|
void GenSysvars()
|
|
{
|
|
write("GenSysvars() -> %s", fnSysvar);
|
|
f.Open(fnSysvar, 0, 0); // rewrite file in ASCII
|
|
|
|
PutString(f, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
|
PutString(f, "<systemvariables version=\"4\">\n");
|
|
PutString(f, " <namespace name=\"\" comment=\"\">\n");
|
|
|
|
PutString(f, " <namespace name=\"Config\" comment=\"\">\n");
|
|
PutString(f, " <namespace name=\"Modbus\" comment=\"\">\n");
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"ms\" name=\"RequestTimeout\" comment=\"The maximum duration for a Modbus-UDP/-TCP request in milliseconds. After timeout a retransmission may be started (see MaxRetransmissionCount). Use `ping` to get the maximum latency to a device, double it and add 2-3 ms for processing.\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"5\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"1000\" maxValuePhys=\"1000\" />\n");
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"Port\" comment=\"\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"502\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"65535\" maxValuePhys=\"65535\" />\n");
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"times\" name=\"MaxTransmissionCount\" comment=\"How often a retransmission of a request will be sent until it gets discarded and an error is thrown.\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"3\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"10\" maxValuePhys=\"10\" />\n");
|
|
PutString(f, " </namespace>\n");
|
|
PutString(f, " <namespace name=\"TcpIp\" comment=\"\">\n");
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"AdapterIndex\" comment=\"Index of network interface to use\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"2\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"20\" maxValuePhys=\"20\" />\n");
|
|
PutString(f, " </namespace>\n");
|
|
PutString(f, " </namespace>\n");
|
|
|
|
for (long net : gIpNets)
|
|
{
|
|
byte nett;
|
|
nett = net;
|
|
PutString(f, " <namespace name=\"Ethernet");
|
|
PutString(f, nett);
|
|
PutString(f, "\" comment=\"Subnet: 192.168.");
|
|
PutString(f, nett);
|
|
PutString(f, ".\">\n");
|
|
|
|
for (long ipN : gIpsSorted)
|
|
{
|
|
|
|
if (((ipN >> 16) & 0xFF) != net)
|
|
continue;
|
|
|
|
write("GenSysvars: %s", gIpsSorted[ipN].Ip);
|
|
|
|
PutString(f, " <namespace name=\"Client_");
|
|
//PutString(f, netS);
|
|
//PutString(f, "_");
|
|
PutString(f, gIpsSorted[ipN].IpLsb);
|
|
PutString(f, "\" comment=\"Server with ip address '");
|
|
PutString(f, gIpsSorted[ipN].Ip);
|
|
PutString(f, "'\">\n");
|
|
|
|
// Namespace Config
|
|
PutString(f, " <namespace name=\"Config\" comment=\"Configuration section for this server\">\n");
|
|
// IP
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"IP\" comment=\"The IP address of this server\" bitcount=\"8\" isSigned=\"true\" encoding=\"65001\" type=\"string\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].Ip);
|
|
PutString(f, "\" />\n");
|
|
// Intveral
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"ms\" name=\"Interval\" comment=\"The interval with which the device will be queried\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"100\" minValue=\"10\" minValuePhys=\"10\" maxValue=\"10000\" maxValuePhys=\"10000\" />\n");
|
|
PutString(f, " </namespace>\n");
|
|
|
|
//Namespace Info
|
|
PutString(f, " <namespace name=\"Info\" comment=\"Some information about the device\">\n");
|
|
// SerialCode
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"SerialCode\" comment=\"The serial code of the server\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].SerialCode);
|
|
PutString(f, "\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"10000\" maxValuePhys=\"10000\" />\n");
|
|
// DeviceCode
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"DeviceCode\" comment=\"The device code of the server\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceCode);
|
|
PutString(f, "\" minValue=\"1\" minValuePhys=\"1\" maxValue=\"10000\" maxValuePhys=\"10000\" />\n");
|
|
// Modules
|
|
gIpsSorted[ipN].DeviceIOs.Modules[strlen(gIpsSorted[ipN].DeviceIOs.Modules)] = 0;
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"Modules\" comment=\"The type and number of inputs of modules that are connected to the server\" bitcount=\"8\" isSigned=\"true\" encoding=\"65001\" type=\"string\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.Modules);
|
|
PutString(f, "\" />\n");
|
|
// InputRegisters
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"InputRegisters\" comment=\"Number of input registers\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.InputRegisters);
|
|
PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"123\" maxValuePhys=\"123\" />\n");
|
|
// InputBits
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"InputBits\" comment=\"Number of input bits\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.InputBits);
|
|
PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"2000\" maxValuePhys=\"2000\" />\n");
|
|
// OutputRegisters
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"OutputRegisters\" comment=\"Number of output registers\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.OutputRegisters);
|
|
PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"123\" maxValuePhys=\"123\" />\n");
|
|
// OutputBits
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"true\" valueSequence=\"false\" unit=\"\" name=\"OutputBits\" comment=\"Number of output bits\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"int\" startValue=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.OutputBits);
|
|
PutString(f, "\" minValue=\"0\" minValuePhys=\"0\" maxValue=\"2000\" maxValuePhys=\"2000\" />\n");
|
|
PutString(f, " </namespace>\n");
|
|
|
|
// Namespace Data
|
|
PutString(f, " <namespace name=\"Data\" comment=\"The actual process image\">\n");
|
|
// InputRegisters
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"InputRegisters\" comment=\"The values of the input registers\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.InputRegisters);
|
|
PutString(f, "\" />\n");
|
|
// InputBits
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"InputBits\" comment=\"The state of the input bits\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.InputBits);
|
|
PutString(f, "\" />\n");
|
|
// OutputRegisters
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"OutputRegisters\" comment=\"The values of the output registers. Write here and the values will be sent to the device\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.OutputRegisters);
|
|
PutString(f, "\" />\n");
|
|
// OutputBits
|
|
PutString(f, " <variable anlyzLocal=\"2\" readOnly=\"false\" valueSequence=\"false\" unit=\"\" name=\"OutputBits\" comment=\"The state of the output bits. Write here and the values will be sent to the device\" bitcount=\"32\" isSigned=\"true\" encoding=\"65001\" type=\"intarray\" arrayLength=\"");
|
|
PutString(f, gIpsSorted[ipN].DeviceIOs.OutputBits);
|
|
PutString(f, "\" />\n");
|
|
|
|
PutString(f, " </namespace>\n");
|
|
PutString(f, " </namespace>\n");
|
|
}
|
|
PutString(f, " </namespace>\n");
|
|
}
|
|
|
|
PutString(f, " </namespace>\n");
|
|
PutString(f, "</systemvariables>\n");
|
|
|
|
f.Close();
|
|
}
|
|
|
|
// Generate the Database
|
|
/// <Step4>
|
|
void GenDbc()
|
|
{
|
|
write("GenDbc() -> %s", fnDbc);
|
|
f.Open(fnDbc, 0, 0); // rewrite file in ASCII
|
|
|
|
PutString(f, "VERSION \"\"\n\n\n");
|
|
PutString(f, "NS_ :\n");
|
|
PutString(f, " NS_DESC_\n");
|
|
PutString(f, " CM_\n");
|
|
PutString(f, " BA_DEF_\n");
|
|
PutString(f, " BA_\n");
|
|
PutString(f, " VAL_\n");
|
|
PutString(f, " CAT_DEF_\n");
|
|
PutString(f, " CAT_\n");
|
|
PutString(f, " FILTER\n");
|
|
PutString(f, " BA_DEF_DEF_\n");
|
|
PutString(f, " EV_DATA_\n");
|
|
PutString(f, " ENVVAR_DATA_\n");
|
|
PutString(f, " SGTYPE_\n");
|
|
PutString(f, " SGTYPE_VAL_\n");
|
|
PutString(f, " BA_DEF_SGTYPE_\n");
|
|
PutString(f, " BA_SGTYPE_\n");
|
|
PutString(f, " SIG_TYPE_REF_\n");
|
|
PutString(f, " VAL_TABLE_\n");
|
|
PutString(f, " SIG_GROUP_\n");
|
|
PutString(f, " SIG_VALTYPE_\n");
|
|
PutString(f, " SIGTYPE_VALTYPE_\n");
|
|
PutString(f, " BO_TX_BU_\n");
|
|
PutString(f, " BA_DEF_REL_\n");
|
|
PutString(f, " BA_REL_\n");
|
|
PutString(f, " BA_DEF_DEF_REL_\n");
|
|
PutString(f, " BU_SG_REL_\n");
|
|
PutString(f, " BU_EV_REL_\n");
|
|
PutString(f, " BU_BO_REL_\n");
|
|
PutString(f, " SG_MUL_VAL_\n");
|
|
PutString(f, "\n");
|
|
PutString(f, "BS_:\n");
|
|
PutString(f, "\nBU_:");
|
|
|
|
for (long ipN : gIpsSorted)
|
|
{
|
|
write("GenDbc: %s", gIpsSorted[ipN].Ip);
|
|
|
|
PutString(f, " Client_");
|
|
//PutString(f, gIpsSorted[ipN].IpNet);
|
|
//PutString(f, "_");
|
|
PutString(f, gIpsSorted[ipN].IpLsb);
|
|
}
|
|
PutString(f, "\n\n\n\n");
|
|
PutString(f, "BA_DEF_ BU_ \"NodeLayerModules\" STRING ;\n");
|
|
PutString(f, "BA_DEF_ \"DBName\" STRING ;\n");
|
|
PutString(f, "BA_DEF_ \"BusType\" STRING ;\n");
|
|
PutString(f, "BA_DEF_DEF_ \"NodeLayerModules\" \"Ethernet_IL.DLL\";\n");
|
|
PutString(f, "BA_DEF_DEF_ \"DBName\" \"\";\n");
|
|
PutString(f, "BA_DEF_DEF_ \"BusType\" \"Ethernet\";\n");
|
|
PutString(f, "BA_ \"BusType\" \"Ethernet\";\n");
|
|
PutString(f, "BA_ \"DBName\" \"");
|
|
PutString(f, name);
|
|
PutString(f, "\";\n");
|
|
|
|
f.Close();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OnModbusWriteBitFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
|
|
void OnModbusWriteRegisterFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
|
|
void OnModbusWriteMasksFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
|
|
void OnModbusReadWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
|
|
void OnModbusWriteBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
|
|
void OnModbusWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}
|
|
void OnModbusWriteBitSuccess(struct ModbusResConfirmSingle mbc){}
|
|
void OnModbusWriteRegisterSuccess(struct ModbusResConfirmSingle mbc){}
|
|
void OnModbusWriteBitsSuccess(struct ModbusResConfirmMultiple mbc){}
|
|
void OnModbusWriteRegistersSuccess(struct ModbusResConfirmMultiple mbc){}
|
|
void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc){} |