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

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

parent d1980bbf
......@@ -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="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="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="103" iotype="AI" name="AI103_AS" textname="AI102" mbaddr="0x01" mbfunc="0x03" mbreg="99" mbtype="rtu" tcp="6"/>
</sensors>
......
......@@ -985,12 +985,23 @@ bool MBSlave::initItem( UniXML::iterator& it )
else
{
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;
p_dummy.create_from_iobase(b);
p_dummy.bitreg = make_shared<BitRegProperty>();
p_dummy.bitreg->mbreg = mbreg;
p_dummy.regID = p.regID;
p.vtype = VTypes::vtUnknown;
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 использовать нельзя!
......@@ -1067,11 +1078,14 @@ bool MBSlave::initItem( UniXML::iterator& it )
// копируем минимум полей, который нужен для обработки.. т.к. нам другие не понадобятся..
int p_wnum = 0;
ModbusData p_mbreg = p.mbreg;
IOController_i::SensorInfo p_si = p.si;
UniversalIO::IOType p_stype = p.stype;
IOBase p_base(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;
int wsz = VTypes::wsize(p_vtype );
int wsz = VTypes::wsize(p.vtype);
int p_regID = p.regID;
// после std::move p - использовать нельзя!
......@@ -1084,11 +1098,13 @@ bool MBSlave::initItem( UniXML::iterator& it )
for( int i = 1; i < wsz; i++ )
{
IOProperty p_dummy;
p_dummy.create_from_iobase(p_base);
p_dummy.mbreg = p_mbreg + i;
p_dummy.wnum = p_wnum + i;
p_dummy.si = p_si;
p_dummy.stype = p_stype;
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_dummy.regID = p_regID;
......@@ -1802,6 +1818,7 @@ ModbusRTU::mbErrCode MBSlave::real_read_prop( IOProperty* p, ModbusRTU::ModbusDa
else if( p->vtype == VTypes::vtF2 )
{
float f = IOBase::processingFasAO(p, shm, force);
VTypes::F2 f2(f);
// оптимизируем и проверку не делаем
// считая, что при "загрузке" всё было правильно
......
......@@ -1159,6 +1159,7 @@ TEST_CASE("(0x10): write register outputs or memories [F2](precision)", "[modbus
float f = 200.4;
F2 f2(f);
// write..
ModbusRTU::WriteOutputMessage msg(slaveaddr, tREG);
msg.addData(f2.raw.v[0]);
msg.addData(f2.raw.v[1]);
......@@ -1167,6 +1168,15 @@ TEST_CASE("(0x10): write register outputs or memories [F2](precision)", "[modbus
REQUIRE( ret.quant == 2 );
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.. */
......@@ -23,6 +23,7 @@ struct IOBase
// приходится здесь тоже объявлять разрешенными только операции "перемещения"
IOBase( const IOBase& r ) = delete;
IOBase& operator=(const IOBase& r) = delete;
IOBase( IOBase&& r ) = default;
IOBase& operator=(IOBase&& r) = default;
......@@ -144,6 +145,9 @@ struct IOBase
IOController::IOStateList::iterator ioit;
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 );
static void processingFasAI( IOBase* it, float new_val, const std::shared_ptr<SMInterface>& shm, bool force );
......@@ -168,6 +172,7 @@ struct IOBase
// helpes
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 );
};
// -----------------------------------------------------------------------------
......
......@@ -742,3 +742,80 @@ std::ostream& operator<<( std::ostream& os, const IOBase::FrontType& f )
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