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

(MOdbusSlave): исправлена ошибка в работе с float (чтение)

parent d1980bbf
...@@ -258,7 +258,7 @@ ...@@ -258,7 +258,7 @@
<item id="64" iotype="AI" name="AI64_AS" textname="AI64" mbaddr="0x01" mbfunc="0x03" mbreg="64" mbtype="rtu" rs="5" tcp="6"/> <item id="64" iotype="AI" name="AI64_AS" textname="AI64" mbaddr="0x01" mbfunc="0x03" mbreg="64" mbtype="rtu" rs="5" tcp="6"/>
<item id="66" iotype="DI" name="DI66_AS" textname="DI66" mbaddr="0x01" mbfunc="0x01" mbreg="66" mbtype="rtu" rs="5"/> <item id="66" iotype="DI" name="DI66_AS" textname="DI66" mbaddr="0x01" mbfunc="0x01" mbreg="66" mbtype="rtu" rs="5"/>
<item id="65" iotype="DI" name="D65_S" textname="D65" threshold_aid="AI64_AS" lowlimit="3" hilimit="5" threshold_invert="1" rs="5" /> <item id="65" iotype="DI" name="D65_S" textname="D65" threshold_aid="AI64_AS" lowlimit="3" hilimit="5" threshold_invert="1" rs="5" />
<item id="100" iotype="AI" name="AI100_AS" textname="AI100" mbaddr="0x01" mbfunc="0x03" mbreg="100" mbtype="rtu" tcp="6" vtype="F2"/> <item id="100" iotype="AI" name="AI100_AS" textname="AI100" mbaddr="0x01" mbfunc="0x03" mbreg="100" mbtype="rtu" tcp="6" vtype="F2" precision="1" mbtcp="3"/>
<item id="102" iotype="AI" name="AI102_AS" textname="AI101" mbaddr="0x01" mbfunc="0x03" mbreg="102" mbtype="rtu" tcp="6"/> <item id="102" iotype="AI" name="AI102_AS" textname="AI101" mbaddr="0x01" mbfunc="0x03" mbreg="102" mbtype="rtu" tcp="6"/>
<item id="103" iotype="AI" name="AI103_AS" textname="AI102" mbaddr="0x01" mbfunc="0x03" mbreg="99" mbtype="rtu" tcp="6"/> <item id="103" iotype="AI" name="AI103_AS" textname="AI102" mbaddr="0x01" mbfunc="0x03" mbreg="99" mbtype="rtu" tcp="6"/>
</sensors> </sensors>
......
...@@ -985,12 +985,23 @@ bool MBSlave::initItem( UniXML::iterator& it ) ...@@ -985,12 +985,23 @@ bool MBSlave::initItem( UniXML::iterator& it )
else else
{ {
ModbusData mbreg = p.mbreg; ModbusData mbreg = p.mbreg;
IOBase b = p.make_iobase_copy();
AccessMode p_amode = p.amode;
VTypes::VType p_vtype = p.vtype;
int p_nbyte = p.nbyte;
bool p_rawdata = p.rawdata;
IOProperty p_dummy; IOProperty p_dummy;
p_dummy.create_from_iobase(b);
p_dummy.bitreg = make_shared<BitRegProperty>(); p_dummy.bitreg = make_shared<BitRegProperty>();
p_dummy.bitreg->mbreg = mbreg; p_dummy.bitreg->mbreg = mbreg;
p_dummy.regID = p.regID; p_dummy.regID = p.regID;
p.vtype = VTypes::vtUnknown; p.vtype = VTypes::vtUnknown;
p.wnum = 0; p.wnum = 0;
p_dummy.amode = p_amode;
p_dummy.nbyte = p_nbyte;
p_dummy.rawdata = p_rawdata;
p_dummy.bitreg->bvec[nbit] = std::move(p); // после этого p использовать нельзя! p_dummy.bitreg->bvec[nbit] = std::move(p); // после этого p использовать нельзя!
...@@ -1067,11 +1078,14 @@ bool MBSlave::initItem( UniXML::iterator& it ) ...@@ -1067,11 +1078,14 @@ bool MBSlave::initItem( UniXML::iterator& it )
// копируем минимум полей, который нужен для обработки.. т.к. нам другие не понадобятся.. // копируем минимум полей, который нужен для обработки.. т.к. нам другие не понадобятся..
int p_wnum = 0; int p_wnum = 0;
ModbusData p_mbreg = p.mbreg; ModbusData p_mbreg = p.mbreg;
IOController_i::SensorInfo p_si = p.si; IOBase p_base(p.make_iobase_copy());
UniversalIO::IOType p_stype = p.stype;
AccessMode p_amode = p.amode;
VTypes::VType p_vtype = p.vtype; VTypes::VType p_vtype = p.vtype;
int p_nbyte = p.nbyte;
bool p_rawdata = p.rawdata;
int wsz = VTypes::wsize(p_vtype ); int wsz = VTypes::wsize(p.vtype);
int p_regID = p.regID; int p_regID = p.regID;
// после std::move p - использовать нельзя! // после std::move p - использовать нельзя!
...@@ -1084,11 +1098,13 @@ bool MBSlave::initItem( UniXML::iterator& it ) ...@@ -1084,11 +1098,13 @@ bool MBSlave::initItem( UniXML::iterator& it )
for( int i = 1; i < wsz; i++ ) for( int i = 1; i < wsz; i++ )
{ {
IOProperty p_dummy; IOProperty p_dummy;
p_dummy.create_from_iobase(p_base);
p_dummy.mbreg = p_mbreg + i; p_dummy.mbreg = p_mbreg + i;
p_dummy.wnum = p_wnum + i; p_dummy.wnum = p_wnum + i;
p_dummy.si = p_si;
p_dummy.stype = p_stype;
p_dummy.vtype = p_vtype; p_dummy.vtype = p_vtype;
p_dummy.amode = p_amode;
p_dummy.nbyte = p_nbyte;
p_dummy.rawdata = p_rawdata;
p_regID = genRegID(p_dummy.mbreg, mbfunc); p_regID = genRegID(p_dummy.mbreg, mbfunc);
p_dummy.regID = p_regID; p_dummy.regID = p_regID;
...@@ -1802,6 +1818,7 @@ ModbusRTU::mbErrCode MBSlave::real_read_prop( IOProperty* p, ModbusRTU::ModbusDa ...@@ -1802,6 +1818,7 @@ ModbusRTU::mbErrCode MBSlave::real_read_prop( IOProperty* p, ModbusRTU::ModbusDa
else if( p->vtype == VTypes::vtF2 ) else if( p->vtype == VTypes::vtF2 )
{ {
float f = IOBase::processingFasAO(p, shm, force); float f = IOBase::processingFasAO(p, shm, force);
VTypes::F2 f2(f); VTypes::F2 f2(f);
// оптимизируем и проверку не делаем // оптимизируем и проверку не делаем
// считая, что при "загрузке" всё было правильно // считая, что при "загрузке" всё было правильно
......
...@@ -1159,6 +1159,7 @@ TEST_CASE("(0x10): write register outputs or memories [F2](precision)", "[modbus ...@@ -1159,6 +1159,7 @@ TEST_CASE("(0x10): write register outputs or memories [F2](precision)", "[modbus
float f = 200.4; float f = 200.4;
F2 f2(f); F2 f2(f);
// write..
ModbusRTU::WriteOutputMessage msg(slaveaddr, tREG); ModbusRTU::WriteOutputMessage msg(slaveaddr, tREG);
msg.addData(f2.raw.v[0]); msg.addData(f2.raw.v[0]);
msg.addData(f2.raw.v[1]); msg.addData(f2.raw.v[1]);
...@@ -1167,6 +1168,15 @@ TEST_CASE("(0x10): write register outputs or memories [F2](precision)", "[modbus ...@@ -1167,6 +1168,15 @@ TEST_CASE("(0x10): write register outputs or memories [F2](precision)", "[modbus
REQUIRE( ret.quant == 2 ); REQUIRE( ret.quant == 2 );
REQUIRE( ui->getValue(tID) == 2004 ); REQUIRE( ui->getValue(tID) == 2004 );
// read..
ui->setValue(tID,203);
ModbusRTU::ReadOutputRetMessage ret2 = mb->read03(slaveaddr, tREG, 2);
F2 r_f2(ret2.data,F2::wsize());
REQUIRE( (float)r_f2 == 20.3f );
} }
// ------------------------------------------------------------- // -------------------------------------------------------------
/*! \todo Доделать тесты на считывание с разными prop_prefix.. */ /*! \todo Доделать тесты на считывание с разными prop_prefix.. */
...@@ -23,6 +23,7 @@ struct IOBase ...@@ -23,6 +23,7 @@ struct IOBase
// приходится здесь тоже объявлять разрешенными только операции "перемещения" // приходится здесь тоже объявлять разрешенными только операции "перемещения"
IOBase( const IOBase& r ) = delete; IOBase( const IOBase& r ) = delete;
IOBase& operator=(const IOBase& r) = delete; IOBase& operator=(const IOBase& r) = delete;
IOBase( IOBase&& r ) = default; IOBase( IOBase&& r ) = default;
IOBase& operator=(IOBase&& r) = default; IOBase& operator=(IOBase&& r) = default;
...@@ -144,6 +145,9 @@ struct IOBase ...@@ -144,6 +145,9 @@ struct IOBase
IOController::IOStateList::iterator ioit; IOController::IOStateList::iterator ioit;
UniSetTypes::uniset_rwmutex val_lock; /*!< блокировка на время "работы" со значением */ UniSetTypes::uniset_rwmutex val_lock; /*!< блокировка на время "работы" со значением */
IOBase make_iobase_copy();
void create_from_iobase( const IOBase& b );
friend std::ostream& operator<<(std::ostream& os, const IOBase& inf ); friend std::ostream& operator<<(std::ostream& os, const IOBase& inf );
static void processingFasAI( IOBase* it, float new_val, const std::shared_ptr<SMInterface>& shm, bool force ); static void processingFasAI( IOBase* it, float new_val, const std::shared_ptr<SMInterface>& shm, bool force );
...@@ -168,6 +172,7 @@ struct IOBase ...@@ -168,6 +172,7 @@ struct IOBase
// helpes // helpes
static std::string initProp( UniXML::iterator& it, const std::string& prop, const std::string& prefix, bool prefonly, const std::string& defval = "" ); static std::string initProp( UniXML::iterator& it, const std::string& prop, const std::string& prefix, bool prefonly, const std::string& defval = "" );
static int initIntProp( UniXML::iterator& it, const std::string& prop, const std::string& prefix, bool prefonly, const int defval = 0 ); static int initIntProp( UniXML::iterator& it, const std::string& prop, const std::string& prefix, bool prefonly, const int defval = 0 );
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -742,3 +742,80 @@ std::ostream& operator<<( std::ostream& os, const IOBase::FrontType& f ) ...@@ -742,3 +742,80 @@ std::ostream& operator<<( std::ostream& os, const IOBase::FrontType& f )
return os; return os;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
IOBase IOBase::make_iobase_copy()
{
IOBase b;
b.si = si;
b.cal = cal;
b.stype = stype;
b.cdiagram = cdiagram;
b.breaklim = breaklim;
b.value = value;
b.craw = craw;
b.cprev = cprev;
b.safety = safety;
b.defval = defval;
b.df = df;
b.nofilter = nofilter;
b.f_median = f_median;
b.f_ls = f_ls;
b.f_filter_iir = f_filter_iir;
b.ignore = ignore;
b.invert = invert;
b.noprecision = noprecision;
b.calcrop = calcrop;
b.d_id = d_id;
b.d_value = d_value;
b.d_off_value = d_off_value;
b.d_iotype = d_iotype;
b.t_ai = t_ai;
b.front_type = front_type;
b.front_prev_state = front_prev_state;
b.front_state = front_state;
b.rawdata = rawdata;
b.debounce_pause = debounce_pause;
b.debounce_state = debounce_state;
b.ondelay_state = ondelay_state;
b.offdelay_state = offdelay_state;
return std::move(b);
}
// ------------------------------------------------------------------------------------------
void IOBase::create_from_iobase( const IOBase& b )
{
si = b.si;
cal = b.cal;
stype = b.stype;
cdiagram = b.cdiagram;
breaklim = b.breaklim;
value = b.value;
craw = b.craw;
cprev = b.cprev;
safety = b.safety;
defval = b.defval;
df = b.df;
nofilter = b.nofilter;
f_median = b.f_median;
f_ls = b.f_ls;
f_filter_iir = b.f_filter_iir;
ignore = b.ignore;
invert = b.invert;
noprecision = b.noprecision;
calcrop = b.calcrop;
d_id = b.d_id;
d_value = b.d_value;
d_off_value = b.d_off_value;
d_iotype = b.d_iotype;
t_ai = b.t_ai;
front_type = b.front_type;
front_prev_state = b.front_prev_state;
front_state = b.front_state;
rawdata = b.rawdata;
debounce_pause = b.debounce_pause;
debounce_state = b.debounce_state;
ondelay_state = b.ondelay_state;
offdelay_state = b.offdelay_state;
}
// ------------------------------------------------------------------------------------------
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