Commit 30790f2d authored by Pavel Vainerman's avatar Pavel Vainerman

(MOdbusSlave): дописал реализацию обработки на запись для I2,I2r,U2,U2r,F2,F2r,F4.

Проверил тестами.
parent 4b2ecce9
...@@ -1039,7 +1039,8 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( ModbusRTU::ModbusData reg, Modbus ...@@ -1039,7 +1039,8 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( ModbusRTU::ModbusData reg, Modbus
{ {
if( it->first == reg ) if( it->first == reg )
{ {
real_write_it(it,dat[i]); real_write_it(it,dat,i,count);
--i; // т.к. внутри real_write_it будет сделан ++
++it; ++it;
} }
} }
...@@ -1047,22 +1048,32 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( ModbusRTU::ModbusData reg, Modbus ...@@ -1047,22 +1048,32 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( ModbusRTU::ModbusData reg, Modbus
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData mbval ) ModbusRTU::mbErrCode MBSlave::real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData val )
{ {
ModbusRTU::ModbusData dat[1] = {val};
int i=0;
return real_write(reg,dat,i,1);
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int &i, int count )
{
ModbusRTU::ModbusData mbval = dat[i];
dinfo << myname << "(write): save mbID=" dinfo << myname << "(write): save mbID="
<< ModbusRTU::dat2str(reg) << ModbusRTU::dat2str(reg)
<< " data=" << ModbusRTU::dat2str(mbval) << " data=" << ModbusRTU::dat2str(mbval)
<< "(" << (int)mbval << ")" << endl; << "(" << (int)mbval << ")" << endl;
auto it = iomap.find(reg); auto it = iomap.find(reg);
return real_write_it(it,mbval); return real_write_it(it,dat,i,count);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::ModbusData& mbval ) ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::ModbusData* dat, int &i, int count )
{ {
if( it == iomap.end() ) if( it == iomap.end() )
return ModbusRTU::erBadDataAddress; return ModbusRTU::erBadDataAddress;
ModbusRTU::ModbusData mbval = dat[i++];
try try
{ {
IOProperty* p(&it->second); IOProperty* p(&it->second);
...@@ -1094,40 +1105,125 @@ ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::Mod ...@@ -1094,40 +1105,125 @@ ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::Mod
long val = (signed short)(mbval); long val = (signed short)(mbval);
IOBase::processingAsAI( p, val, shm, force ); IOBase::processingAsAI( p, val, shm, force );
} }
/* else if( p->vtype == VTypes::vtI2 )
else if( p->vtype == VTypes::vtByte )
{ {
VTypes::Byte b(r->mbval); if( (i + VTypes::I2::wsize() - 1) > count )
IOBase::processingAsAI( p, b.raw.b[p->nbyte-1], shm, force ); {
return; i += VTypes::I2::wsize();
return ModbusRTU::erInvalidFormat;
} }
else if( p->vtype == VTypes::vtF2 )
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::I2::wsize()];
for( int k=0; k<VTypes::I2::wsize(); k++, i++ )
d[k] = dat[i-1];
VTypes::I2 i2(d,VTypes::I2::wsize());
delete[] d;
IOBase::processingAsAI( p, (long)i2, shm, force );
}
else if( p->vtype == VTypes::vtI2r )
{ {
RegMap::iterator i(p->reg->rit); if( (i + VTypes::I2r::wsize() - 1) > count )
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[VTypes::F2::wsize()]; {
for( unsigned int k=0; k<VTypes::F2::wsize(); k++, i++ ) i += VTypes::I2r::wsize();
data[k] = i->second->mbval; return ModbusRTU::erInvalidFormat;
}
VTypes::F2 f(data,VTypes::F2::wsize()); ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::I2r::wsize()];
delete[] data; for( int k=0; k<VTypes::I2r::wsize(); k++, i++ )
d[k] = dat[i-1];
IOBase::processingFasAI( p, (float)f, shm, force ); VTypes::I2r i2r(d,VTypes::I2r::wsize());
delete[] d;
IOBase::processingAsAI( p, (long)i2r, shm, force );
} }
else if( p->vtype == VTypes::vtF4 ) else if( p->vtype == VTypes::vtU2 )
{
if( (i + VTypes::U2::wsize() - 1) > count )
{ {
RegMap::iterator i(p->reg->rit); i += VTypes::U2::wsize();
return ModbusRTU::erInvalidFormat;
}
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::U2::wsize()];
for( int k=0; k<VTypes::U2::wsize(); k++, i++ )
d[k] = dat[i-1];
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[VTypes::F4::wsize()]; VTypes::U2 u2(d,VTypes::U2::wsize());
for( unsigned int k=0; k<VTypes::F4::wsize(); k++, i++ ) delete[] d;
data[k] = i->second->mbval; IOBase::processingAsAI( p, (unsigned long)u2, shm, force );
}
else if( p->vtype == VTypes::vtU2r )
{
if( (i + VTypes::U2r::wsize() - 1) > count )
{
i += VTypes::U2r::wsize();
return ModbusRTU::erInvalidFormat;
}
VTypes::F4 f(data,VTypes::F4::wsize()); ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::U2r::wsize()];
delete[] data; for( int k=0; k<VTypes::U2r::wsize(); k++, i++ )
d[k] = dat[i-1];
IOBase::processingFasAI( p, (float)f, shm, force ); VTypes::U2r u2r(d,VTypes::U2r::wsize());
delete[] d;
IOBase::processingAsAI( p, (unsigned long)u2r, shm, force );
} }
*/ else if( p->vtype == VTypes::vtF2 )
{
if( (i + VTypes::F2::wsize() - 1) > count )
{
i += VTypes::F2::wsize();
return ModbusRTU::erInvalidFormat;
}
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F2::wsize()];
for( int k=0; k<VTypes::F2::wsize(); k++, i++ )
d[k] = dat[i-1];
VTypes::F2 f2(d,VTypes::F2::wsize());
delete[] d;
IOBase::processingFasAI( p, (float)f2, shm, force );
}
else if( p->vtype == VTypes::vtF2r )
{
if( (i + VTypes::F2r::wsize() - 1) > count )
{
i += VTypes::F2r::wsize();
return ModbusRTU::erInvalidFormat;
}
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F2r::wsize()];
for( int k=0; k<VTypes::F2r::wsize(); k++, i++ )
d[k] = dat[i-1];
VTypes::F2r f2r(d,VTypes::F2r::wsize());
delete[] d;
IOBase::processingFasAI( p, (float)f2r, shm, force );
}
else if( p->vtype == VTypes::vtF4 )
{
if( (i + VTypes::F4::wsize() - 1) > count )
{
i += VTypes::F4::wsize();
return ModbusRTU::erInvalidFormat;
}
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F4::wsize()];
for( int k=0; k<VTypes::F4::wsize(); k++, i++ )
d[k] = dat[i-1];
VTypes::F4 f4(d,VTypes::F4::wsize());
delete[] d;
IOBase::processingFasAI( p, (float)f4, shm, force );
}
/*
else if( p->vtype == VTypes::vtByte )
{
VTypes::Byte b(r->mbval);
IOBase::processingAsAI( p, b.raw.b[p->nbyte-1], shm, force );
return;
}
/* /*
if( p->stype == UniversalIO::DI || if( p->stype == UniversalIO::DI ||
p->stype == UniversalIO::DO ) p->stype == UniversalIO::DO )
...@@ -1141,6 +1237,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::Mod ...@@ -1141,6 +1237,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::Mod
IOBase::processingAsAI( p, val, shm, force ); IOBase::processingAsAI( p, val, shm, force );
} }
*/ */
i++;
pingOK = true; pingOK = true;
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
......
...@@ -157,12 +157,13 @@ class MBSlave: ...@@ -157,12 +157,13 @@ class MBSlave:
bool check_item( UniXML_iterator& it ); bool check_item( UniXML_iterator& it );
ModbusRTU::mbErrCode real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData val ); ModbusRTU::mbErrCode real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData val );
ModbusRTU::mbErrCode real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int& i, int count );
ModbusRTU::mbErrCode real_read( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData& val ); ModbusRTU::mbErrCode real_read( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData& val );
ModbusRTU::mbErrCode much_real_read( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count ); ModbusRTU::mbErrCode much_real_read( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count );
ModbusRTU::mbErrCode much_real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count ); ModbusRTU::mbErrCode much_real_write( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count );
ModbusRTU::mbErrCode real_read_it( IOMap::iterator& it, ModbusRTU::ModbusData& val ); ModbusRTU::mbErrCode real_read_it( IOMap::iterator& it, ModbusRTU::ModbusData& val );
ModbusRTU::mbErrCode real_write_it( IOMap::iterator& it, ModbusRTU::ModbusData& val ); ModbusRTU::mbErrCode real_write_it( IOMap::iterator& it, ModbusRTU::ModbusData* dat, int& i, int count );
MBSlave(); MBSlave();
bool initPause; bool initPause;
......
#include <catch.hpp> #include <catch.hpp>
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include <time.h> #include <time.h>
#include <limits>
#include "MBSlave.h" #include "MBSlave.h"
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "modbus/ModbusTCPMaster.h" #include "modbus/ModbusTCPMaster.h"
...@@ -420,6 +421,40 @@ TEST_CASE("(0x10): write register outputs or memories","[modbus][mbslave][mbtcps ...@@ -420,6 +421,40 @@ TEST_CASE("(0x10): write register outputs or memories","[modbus][mbslave][mbtcps
REQUIRE( ex.err == ModbusRTU::erBadDataAddress ); REQUIRE( ex.err == ModbusRTU::erBadDataAddress );
} }
} }
SECTION("Test: write bad format packet..(incorrect data count)")
{
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG+20000);
msg.addData(10);
msg.addData(11);
msg.addData(12);
msg.quant-=1;
try
{
mb->write10(msg);
}
catch( ModbusRTU::mbException& ex )
{
REQUIRE( ex.err == ModbusRTU::erBadDataAddress );
}
}
SECTION("Test: write bad format packet..(incorrect size of bytes)")
{
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG+20000);
msg.addData(10);
msg.addData(11);
msg.addData(12);
msg.bcnt -= 1;
try
{
mb->write10(msg);
}
catch( ModbusRTU::mbException& ex )
{
REQUIRE( ex.err == ModbusRTU::erBadDataAddress );
}
}
} }
TEST_CASE("Read(0x03,0x04): vtypes..","[modbus][mbslave][mbtcpslave]") TEST_CASE("Read(0x03,0x04): vtypes..","[modbus][mbslave][mbtcpslave]")
...@@ -541,10 +576,144 @@ TEST_CASE("Read(0x03,0x04): vtypes..","[modbus][mbslave][mbtcpslave]") ...@@ -541,10 +576,144 @@ TEST_CASE("Read(0x03,0x04): vtypes..","[modbus][mbslave][mbtcpslave]")
} }
} }
// -------------------------------------------------------------
static void test_write10_I2( int val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 100;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
I2 tmp(val);
msg.addData( tmp.raw.v[0] );
msg.addData( tmp.raw.v[1] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == I2::wsize() );
REQUIRE( ui->getValue(2001) == val );
}
static void test_write10_I2r( int val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 102;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
I2r tmp(val);
msg.addData( tmp.raw_backorder.v[0] );
msg.addData( tmp.raw_backorder.v[1] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == I2r::wsize() );
REQUIRE( ui->getValue(2002) == val );
}
static void test_write10_U2( unsigned int val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 104;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
U2 tmp(val);
msg.addData( tmp.raw.v[0] );
msg.addData( tmp.raw.v[1] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == U2::wsize() );
REQUIRE( (unsigned int)ui->getValue(2003) == val );
}
static void test_write10_U2r( unsigned int val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 106;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
U2r tmp(val);
msg.addData( tmp.raw_backorder.v[0] );
msg.addData( tmp.raw_backorder.v[1] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == U2r::wsize() );
REQUIRE( (unsigned int)ui->getValue(2004) == val );
}
static void test_write10_F2( float val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 110;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
F2 tmp(val);
msg.addData( tmp.raw.v[0] );
msg.addData( tmp.raw.v[1] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == F2::wsize() );
IOController_i::SensorInfo si;
si.id = 2007;
si.node = conf->getLocalNode();
IOController_i::CalibrateInfo cal = ui->getCalibrateInfo(si);
float fval = (float)ui->getValue(si.id) / pow10(cal.precision);
REQUIRE( fval == val );
}
static void test_write10_F2r( float val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 112;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
F2r tmp(val);
msg.addData( tmp.raw_backorder.v[0] );
msg.addData( tmp.raw_backorder.v[1] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == F2r::wsize() );
IOController_i::SensorInfo si;
si.id = 2008;
si.node = conf->getLocalNode();
IOController_i::CalibrateInfo cal = ui->getCalibrateInfo(si);
float fval = (float)ui->getValue(si.id) / pow10(cal.precision);
REQUIRE( fval == val );
}
TEST_CASE("Write(0x10): vtypes..","[modbus][mbslave][mbtcpslave]") TEST_CASE("Write(0x10): vtypes..","[modbus][mbslave][mbtcpslave]")
{ {
using namespace VTypes;
InitTest(); InitTest();
FAIL("Tests for '0x10 and vtypes' not yet..");
SECTION("Test: write vtype 'I2'")
{
test_write10_I2(numeric_limits<int>::max());
test_write10_I2(0);
test_write10_I2(numeric_limits<int>::min());
}
SECTION("Test: write vtype 'I2r'")
{
test_write10_I2r(numeric_limits<int>::max());
test_write10_I2r(0);
test_write10_I2r(numeric_limits<int>::min());
}
SECTION("Test: write vtype 'U2'")
{
test_write10_U2(numeric_limits<unsigned int>::max());
test_write10_U2(0);
test_write10_U2(numeric_limits<unsigned int>::min());
}
SECTION("Test: write vtype 'U2r'")
{
test_write10_U2r(numeric_limits<unsigned int>::max());
test_write10_U2r(0);
test_write10_U2r(numeric_limits<unsigned int>::min());
}
SECTION("Test: write vtype 'F2'")
{
test_write10_F2(-0.05);
test_write10_F2(0);
test_write10_F2(100000.23);
}
SECTION("Test: write vtype 'F2r'")
{
test_write10_F2r(-0.05);
test_write10_F2r(0);
test_write10_F2r(100000.23);
}
SECTION("Test: write vtype 'F4'")
{
}
} }
#if 0 #if 0
......
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