Commit 7a8e66a6 authored by Pavel Vainerman's avatar Pavel Vainerman

(Modbus): Исправил ошибку (сдвиг не единицу) в обработке количества возвращаемых…

(Modbus): Исправил ошибку (сдвиг не единицу) в обработке количества возвращаемых байтов в функции 0x02
parent 8a6b7c58
......@@ -3,27 +3,20 @@
//#include <string.h>
//#include <errno.h>
#include <sstream>
#include "UniSetTypes.h"
#include <UniSetTypes.h>
#include "MBSlave.h"
#include "uniset-config.h"
// -------------------------------------------------------------------------
#ifndef PACKAGE_URL
#define PACKAGE_URL "http://git.etersoft.ru/projects/?p=asu/uniset.git;a=summary"
#endif
// -------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace ModbusRTU;
// -------------------------------------------------------------------------
MBSlave::MBSlave( ModbusRTU::ModbusAddr addr, const std::string& dev, const std::string& speed, bool use485 ):
MBSlave::MBSlave( ModbusRTU::ModbusAddr addr, const std::string dev, const std::string speed, bool use485 ):
rscomm(NULL),
addr(addr),
// prev(ModbusRTU::erNoError),
// askCount(0),
verbose(false),
replyVal(-1),
replyVal2(-1),
replyVal3(-1)
replyVal(-1)
{
// int replyTimeout = uni_atoi( conf->getArgParam("--reply-timeout",it.getProp("reply_timeout")).c_str() );
// if( replyTimeout <= 0 )
......@@ -53,7 +46,6 @@ MBSlave::MBSlave( ModbusRTU::ModbusAddr addr, const std::string& dev, const std:
rscomm->connectRemoteService( sigc::mem_fun(this, &MBSlave::remoteService) );
rscomm->connectFileTransfer( sigc::mem_fun(this, &MBSlave::fileTransfer) );
rscomm->connectDiagnostics( sigc::mem_fun(this, &MBSlave::diagnostics) );
rscomm->connectMEIRDI( sigc::mem_fun(this, &MBSlave::read4314) );
rscomm->setRecvTimeout(2000);
......@@ -161,16 +153,9 @@ ModbusRTU::mbErrCode MBSlave::readInputStatus( ReadInputStatusMessage& query,
bcnt++;
for( int i=0; i<bcnt; i++ )
{
if( i == 1 )
reply.addData(replyVal2);
else if( i == 2 )
reply.addData(replyVal3);
else
reply.addData(replyVal);
}
reply.addData(replyVal);
}
return ModbusRTU::erNoError;
}
// -------------------------------------------------------------------------
......@@ -195,14 +180,7 @@ mbErrCode MBSlave::readInputRegisters( ReadInputMessage& query,
for( ; num<query.count; num++, reg++ )
{
if( replyVal != -1 )
{
if( num == 1 && replyVal2 != -1 )
reply.addData(replyVal2);
else if( num == 2 && replyVal3 != -1 )
reply.addData(replyVal3);
else
reply.addData(replyVal);
}
reply.addData(replyVal);
else
reply.addData(reg);
}
......@@ -239,14 +217,7 @@ ModbusRTU::mbErrCode MBSlave::readOutputRegisters(
for( ; num<query.count; num++, reg++ )
{
if( replyVal != -1 )
{
if( num == 1 && replyVal2 != -1 )
reply.addData(replyVal2);
else if( num == 2 && replyVal3 != -1 )
reply.addData(replyVal3);
else
reply.addData(replyVal);
}
reply.addData(replyVal);
else
reply.addData(reg);
}
......@@ -431,12 +402,12 @@ ModbusRTU::mbErrCode MBSlave::fileTransfer( ModbusRTU::FileTransferMessage& quer
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::diagnostics( ModbusRTU::DiagnosticMessage& query,
ModbusRTU::mbErrCode MBSlave::diagnostics( ModbusRTU::DiagnosticMessage& query,
ModbusRTU::DiagnosticRetMessage& reply )
{
if( verbose )
cout << "(diagnostics): " << query << endl;
if( query.subf == ModbusRTU::subEcho )
{
reply = query;
......@@ -449,7 +420,7 @@ ModbusRTU::mbErrCode MBSlave::diagnostics( ModbusRTU::DiagnosticMessage& query,
reply.data[0] = 10;
return ModbusRTU::erNoError;
}
if( query.subf == ModbusRTU::dgMsgSlaveCount || query.subf == ModbusRTU::dgBusMsgCount )
{
reply = query;
......@@ -468,73 +439,8 @@ ModbusRTU::mbErrCode MBSlave::diagnostics( ModbusRTU::DiagnosticMessage& query,
{
reply = query;
return ModbusRTU::erNoError;
}
return ModbusRTU::erOperationFailed;
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::read4314( ModbusRTU::MEIMessageRDI& query,
ModbusRTU::MEIMessageRetRDI& reply )
{
if( verbose )
cout << "(read4314): " << query << endl;
if( query.devID <= rdevMinNum || query.devID >= rdevMaxNum )
return erOperationFailed;
if( query.objID == rdiVendorName )
{
reply.mf = 0xFF;
reply.conformity = rdevBasicDevice;
reply.addData(query.objID,"etersoft");
// reply.addData(rdiProductCode, PACKAGE_NAME);
// reply.addData(rdiMajorMinorRevision,PACKAGE_VERSION);
return erNoError;
}
else if( query.objID == rdiProductCode )
{
reply.mf = 0xFF;
reply.conformity = rdevBasicDevice;
reply.addData(query.objID,PACKAGE_NAME);
return erNoError;
}
else if( query.objID == rdiMajorMinorRevision )
{
reply.mf = 0xFF;
reply.conformity = rdevBasicDevice;
reply.addData(query.objID,PACKAGE_VERSION);
return erNoError;
}
else if( query.objID == rdiVendorURL )
{
reply.mf = 0xFF;
reply.conformity = rdevRegularDevice;
reply.addData(query.objID,PACKAGE_URL);
return erNoError;
}
else if( query.objID == rdiProductName )
{
reply.mf = 0xFF;
reply.conformity = rdevRegularDevice;
reply.addData(query.objID,PACKAGE_NAME);
return erNoError;
}
else if( query.objID == rdiModelName )
{
reply.mf = 0xFF;
reply.conformity = rdevRegularDevice;
reply.addData(query.objID,"MBSlaveEcho");
return erNoError;
}
else if( query.objID == rdiUserApplicationName )
{
reply.mf = 0xFF;
reply.conformity = rdevRegularDevice;
reply.addData(query.objID,"uniset-mbrtuslave-echo");
return erNoError;
}
return ModbusRTU::erBadDataAddress;
return ModbusRTU::erOperationFailed;
}
// -------------------------------------------------------------------------
......@@ -16,11 +16,10 @@ static struct option longopts[] = {
{ "read03", required_argument, 0, 'r' },
{ "read04", required_argument, 0, 'x' },
{ "write05", required_argument, 0, 'f' },
{ "write06", required_argument, 0, 'z' },
{ "write06", required_argument, 0, 'z' },
{ "write0F", required_argument, 0, 'm' },
{ "write10", required_argument, 0, 'w' },
{ "diag08", required_argument, 0, 'o' },
{ "read4314", required_argument, 0, 'e' },
{ "diag08", required_argument, 0, 'o' },
// { "readfile14", required_argument, 0, 'g' },
// { "writefile15", required_argument, 0, 'p' },
{ "filetransfer66", required_argument, 0, 'u' },
......@@ -32,7 +31,7 @@ static struct option longopts[] = {
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ "num-cycles", required_argument, 0, 'l' },
{ "num-cycles", required_argument, 0, 'q' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
......@@ -48,7 +47,6 @@ static void print_help()
printf("[--read03] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1\n");
printf("[--read04] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1\n");
printf("[--diag08] slaveaddr subfunc [dat] - diagnostics request\n");
printf("[--read4314] slaveaddr devID objID - (0x2B/0x0E): read device identification (devID=[1...4], objID=[0..255])\n");
// printf("[--readfile14] slaveaddr fileID - read file from slaveaddr).\n");
// printf("[--writefile15] slaveaddr id filename - write file to slaveaddr).\n");
printf("[--filetransfer66] slaveaddr fileID [filename] - get file from slaveaddr. Default save to 'fileID.transfer'\n");
......@@ -58,7 +56,7 @@ static void print_help()
printf(" fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
printf("[--autodetect-slave] [beg end reg fn] - find slave\n");
printf(" beg - start addres Default: 0\n");
printf(" end - end addres Default: 254\n");
printf(" end - end addres Default: 255\n");
printf(" reg - register of test. Default: 0\n");
printf(" fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
......@@ -77,8 +75,6 @@ enum Command
cmdRead02,
cmdRead03,
cmdRead04,
cmdRead43_13,
cmdRead43_14,
cmdWrite05,
cmdWrite06,
cmdWrite0F,
......@@ -109,7 +105,7 @@ int main( int argc, char **argv )
ModbusRTU::ModbusAddr slaveaddr = 0x00;
ModbusRTU::SlaveFunctionCode fn = ModbusRTU::fnReadInputRegisters;
ModbusRTU::ModbusAddr beg = 0;
ModbusRTU::ModbusAddr end = 254;
ModbusRTU::ModbusAddr end = 255;
ModbusRTU::DiagnosticsSubFunction subfunc = ModbusRTU::subEcho;
ModbusRTU::ModbusData dat = 0;
int tout = 2000;
......@@ -117,14 +113,12 @@ int main( int argc, char **argv )
string tofile("");
int use485 = 0;
int ncycles = -1;
ModbusRTU::ModbusByte devID = 0;
ModbusRTU::ModbusByte objID = 0;
try
{
while( (opt = getopt_long(argc, argv, "hva:w:z:m:r:x:c:b:d:s:t:qn:u:yl:t:o:e:",longopts,&optindex)) != -1 )
while( (opt = getopt_long(argc, argv, "hva:w:z:m:r:x:c:b:d:s:t:qn:u:yl:t:o:",longopts,&optindex)) != -1 )
{
switch (opt)
switch (opt)
{
case 'h':
print_help();
......@@ -154,14 +148,14 @@ int main( int argc, char **argv )
reg = ModbusRTU::str2mbData(argv[optind]);
if( checkArg(optind+1,argc,argv) )
count = ModbusRTU::str2mbData(argv[optind+1]);
dat = uni_atoi(argv[optind+1]);
break;
case 'o':
cmd = cmdDiag;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
if( !checkArg(optind,argc,argv) )
{
cerr << "diagnostic command error: bad or no arguments..." << endl;
......@@ -169,30 +163,11 @@ int main( int argc, char **argv )
}
else
subfunc = (ModbusRTU::DiagnosticsSubFunction)uni_atoi(argv[optind]);
if( checkArg(optind+1,argc,argv) )
dat = uni_atoi(argv[optind+1]);
break;
case 'e':
{
if( cmd == cmdNOP )
cmd = cmdRead43_14;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
if( optind > argc )
{
cerr << "read command error: bad or no arguments..." << endl;
return 1;
}
if( checkArg(optind,argc,argv) )
devID = ModbusRTU::str2mbData(argv[optind]);
if( checkArg(optind+1,argc,argv) )
objID = uni_atoi(argv[optind+1]);
}
break;
case 'f':
cmd = cmdWrite05;
case 'z':
......@@ -346,7 +321,7 @@ int main( int argc, char **argv )
fn = (ModbusRTU::SlaveFunctionCode)UniSetTypes::uni_atoi(argv[optind+1]);
}
break;
case 'l':
ncycles = uni_atoi(optarg);
break;
......@@ -404,7 +379,7 @@ int main( int argc, char **argv )
{
ModbusRTU::DataBits b(ret.data[i]);
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
<< ModbusRTU::b2str(ret.data[i]) << ") " << b << endl;
}
}
......@@ -428,7 +403,7 @@ int main( int argc, char **argv )
{
ModbusRTU::DataBits b(ret.data[i]);
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
<< ModbusRTU::b2str(ret.data[i]) << ") " << b << endl;
}
}
......@@ -443,7 +418,7 @@ int main( int argc, char **argv )
<< " count=" << ModbusRTU::dat2str(count)
<< endl;
}
ModbusRTU::ReadOutputRetMessage ret = mb.read03(slaveaddr,reg,count);
if( verb )
cout << "(reply): " << ret << endl;
......@@ -484,24 +459,6 @@ int main( int argc, char **argv )
}
break;
case cmdRead43_14:
{
if( verb )
{
cout << "read4314: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< " devID=" << ModbusRTU::dat2str(devID)
<< " objID=" << ModbusRTU::dat2str(objID)
<< endl;
}
ModbusRTU::MEIMessageRetRDI ret = mb.read4314(slaveaddr,devID,objID);
if( verb )
cout << "(reply): " << ret << endl;
else
cout << "(reply): devID='" << (int)ret.devID << "' objNum='" << (int)ret.objNum << "'" << endl << ret.dlist << endl;
}
break;
case cmdWrite05:
{
if( verb )
......@@ -573,7 +530,7 @@ int main( int argc, char **argv )
cout << "(reply): " << ret << endl;
}
break;
case cmdDiag:
{
if( verb )
......@@ -590,15 +547,15 @@ int main( int argc, char **argv )
cout << "(reply): count=" << ModbusRTU::dat2str(ret.count) << endl;
for( int i=0; i<ret.count; i++ )
{
cout << i <<": (" << ModbusRTU::dat2str( reg + i ) << ") = " << (int)(ret.data[i])
<< " ("
<< ModbusRTU::dat2str(ret.data[i])
<< ")"
cout << i <<": (" << ModbusRTU::dat2str( reg + i ) << ") = " << (int)(ret.data[i])
<< " ("
<< ModbusRTU::dat2str(ret.data[i])
<< ")"
<< endl;
}
}
break;
case cmdDetectSlave:
{
if( verb )
......@@ -676,18 +633,18 @@ int main( int argc, char **argv )
catch( ModbusRTU::mbException& ex )
{
if( ex.err != ModbusRTU::erTimeOut )
throw;
throw ex;
cout << "timeout..." << endl;
cout << "timeout..." << endl;
}
if( ncycles > 0 )
{
nc--;
if( nc <=0 )
break;
}
}
msleep(200);
}
}
......
......@@ -14,8 +14,6 @@ static struct option longopts[] = {
{ "read02", required_argument, 0, 'b' },
{ "read03", required_argument, 0, 'r' },
{ "read04", required_argument, 0, 'x' },
// { "read4313", required_argument, 0, 'u' },
{ "read4314", required_argument, 0, 'e' },
{ "write05", required_argument, 0, 'f' },
{ "write06", required_argument, 0, 'z' },
{ "write0F", required_argument, 0, 'm' },
......@@ -42,16 +40,14 @@ static void print_help()
printf("[--read02] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1\n");
printf("[--read03] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1\n");
printf("[--read04] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1\n");
printf("[--diag08] slaveaddr subfunc [dat] - diagnostics request\n");
printf("[--read4314] slaveaddr devID objID - (0x2B/0x0E): read device identification (devID=[1...4], objID=[0..254])\n");
// printf("[--read43-13] slaveaddr ... - (0x2B/0x0D): CANopen General Reference Request and Response PDU \n");
printf("[--diag08] slaveaddr subfunc [dat] - diagnostics request\n");
printf("[-i|--iaddr] ip - Modbus server ip. Default: 127.0.0.1\n");
printf("[-a|--myaddr] addr - Modbus address for master. Default: 0x01.\n");
printf("[-p|--port] port - Modbus server port. Default: 502.\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-o|--persistent-connection] - Use persistent-connection.\n");
printf("[-l|--num-cycles] num - Number of cycles of exchange. Default: -1 - infinitely.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-a|--myaddr] addr - Modbus address for master. Default: 0x01.\n");
printf("[-p|--port] port - Modbus server port. Default: 502.\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-o|--persistent-connection] - Use persistent-connection.\n");
printf("[-l|--num-cycles] num - Number of cycles of exchange. Default: -1 - infinitely.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
}
// --------------------------------------------------------------------------
enum Command
......@@ -61,8 +57,6 @@ enum Command
cmdRead02,
cmdRead03,
cmdRead04,
cmdRead43_13,
cmdRead43_14,
cmdWrite05,
cmdWrite06,
cmdWrite0F,
......@@ -92,14 +86,12 @@ int main( int argc, char **argv )
int tout = 2000;
DebugStream dlog;
int ncycles = -1;
ModbusRTU::ModbusByte devID = 0;
ModbusRTU::ModbusByte objID = 0;
try
{
while( (opt = getopt_long(argc, argv, "hva:w:z:r:x:c:b:d:s:t:p:i:ol:d:e:u:",longopts,&optindex)) != -1 )
while( (opt = getopt_long(argc, argv, "hva:w:z:r:x:c:b:d:s:t:p:i:ol:d:",longopts,&optindex)) != -1 )
{
switch (opt)
switch (opt)
{
case 'h':
print_help();
......@@ -115,7 +107,7 @@ int main( int argc, char **argv )
if( cmd == cmdNOP )
cmd = cmdRead03;
case 'x':
{
if( cmd == cmdNOP )
cmd = cmdRead04;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
......@@ -130,29 +122,8 @@ int main( int argc, char **argv )
if( checkArg(optind+1,argc,argv) )
count = uni_atoi(argv[optind+1]);
}
break;
case 'e':
{
if( cmd == cmdNOP )
cmd = cmdRead43_14;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
if( optind > argc )
{
cerr << "read command error: bad or no arguments..." << endl;
return 1;
}
if( checkArg(optind,argc,argv) )
devID = ModbusRTU::str2mbData(argv[optind]);
if( checkArg(optind+1,argc,argv) )
objID = uni_atoi(argv[optind+1]);
}
break;
case 'f':
cmd = cmdWrite05;
case 'z':
......@@ -228,7 +199,7 @@ int main( int argc, char **argv )
cmd = cmdDiag;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
if( !checkArg(optind,argc,argv) )
{
cerr << "diagnostic command error: bad or no arguments..." << endl;
......@@ -236,7 +207,7 @@ int main( int argc, char **argv )
}
else
subfunc = (ModbusRTU::DiagnosticsSubFunction)uni_atoi(argv[optind]);
if( checkArg(optind+1,argc,argv) )
dat = uni_atoi(argv[optind+1]);
break;
......@@ -251,7 +222,7 @@ int main( int argc, char **argv )
if( verb )
{
cout << "(init): ip=" << iaddr << ":" << port
<< " mbaddr=" << ModbusRTU::addr2str(myaddr)
<< ModbusRTU::addr2str(myaddr)
<< " timeout=" << tout << " msec "
<< endl;
......@@ -303,7 +274,7 @@ int main( int argc, char **argv )
{
ModbusRTU::DataBits b(ret.data[i]);
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
<< ModbusRTU::b2str(ret.data[i]) << ") " << b << endl;
}
}
......@@ -327,7 +298,7 @@ int main( int argc, char **argv )
{
ModbusRTU::DataBits b(ret.data[i]);
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
cout << i <<": (" << ModbusRTU::dat2str( reg + 8*i ) << ") = ("
<< ModbusRTU::b2str(ret.data[i]) << ") " << b << endl;
}
}
......@@ -383,24 +354,6 @@ int main( int argc, char **argv )
}
break;
case cmdRead43_14:
{
if( verb )
{
cout << "read4314: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< " devID=" << ModbusRTU::dat2str(devID)
<< " objID=" << ModbusRTU::dat2str(objID)
<< endl;
}
ModbusRTU::MEIMessageRetRDI ret = mb.read4314(slaveaddr,devID,objID);
if( verb )
cout << "(reply): " << ret << endl;
else
cout << "(reply): devID='" << (int)ret.devID << "' objNum='" << (int)ret.objNum << "'" << endl << ret.dlist << endl;
}
break;
case cmdWrite05:
{
if( verb )
......@@ -489,10 +442,10 @@ int main( int argc, char **argv )
cout << "(reply): count=" << ModbusRTU::dat2str(ret.count) << endl;
for( int i=0; i<ret.count; i++ )
{
cout << i <<": (" << ModbusRTU::dat2str( reg + i ) << ") = " << (int)(ret.data[i])
<< " ("
<< ModbusRTU::dat2str(ret.data[i])
<< ")"
cout << i <<": (" << ModbusRTU::dat2str( reg + i ) << ") = " << (int)(ret.data[i])
<< " ("
<< ModbusRTU::dat2str(ret.data[i])
<< ")"
<< endl;
}
}
......@@ -507,7 +460,7 @@ int main( int argc, char **argv )
catch( ModbusRTU::mbException& ex )
{
if( ex.err != ModbusRTU::erTimeOut )
throw;
throw ex;
cout << "timeout..." << endl;
}
......@@ -520,7 +473,7 @@ int main( int argc, char **argv )
}
msleep(200);
} // end of while
mb.disconnect();
......
......@@ -3,7 +3,7 @@
Name: libuniset
Version: 1.0
Release: alt55
Release: alt56
Summary: UniSet - library for building distributed industrial control systems
License: GPL
Group: Development/C++
......@@ -212,6 +212,9 @@ rm -f %buildroot%_libdir/*.la
%changelog
* Sat Nov 26 2011 Pavel Vainerman <pv@altlinux.ru> 1.0-alt56
- (modbus): fixed bug (again) in ModbusSlave::readInputStatus(0x02)
* Sat Nov 26 2011 Pavel Vainerman <pv@altlinux.ru> 1.0-alt55
- (modbus): fixed bug in ModbusSlave::readInputStatus(0x02)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment