Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
ac610fd2
Commit
ac610fd2
authored
Sep 07, 2015
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(ModbusMaster): рефаторинг (перешёл по возможности на shared_ptr),
переписал механизм реализации pollfactor (частота опроса).
parent
8ab0dba0
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
328 additions
and
302 deletions
+328
-302
TODO
TODO
+0
-2
libuniset2.spec
conf/libuniset2.spec
+4
-1
MBExchange.cc
extensions/ModbusMaster/MBExchange.cc
+263
-241
MBExchange.h
extensions/ModbusMaster/MBExchange.h
+20
-25
MBTCPMaster.cc
extensions/ModbusMaster/MBTCPMaster.cc
+2
-2
MBTCPMultiMaster.cc
extensions/ModbusMaster/MBTCPMultiMaster.cc
+2
-2
RTUExchange.cc
extensions/ModbusMaster/RTUExchange.cc
+37
-29
No files found.
TODO
View file @
ac610fd2
...
...
@@ -37,8 +37,6 @@ Version 2.0
- unetudp: добавить возмоность привязать номера текущего посылаемого и принимаемого пакетов к датчику
- ModbusMaster: встроить возможность задать 'pulsar' (регистр сердцебиения)
- ModbusMaster: сделать RegMap unordered_map-ом по pollfactor
(список регистров опроса формироваать по приоритету опроса и каждому такому списку уже применять oprimization-query)
- IOBase: выдавать warning если заданые одновременно jardelay,ondelay и offdelay
...
...
conf/libuniset2.spec
View file @
ac610fd2
...
...
@@ -13,7 +13,7 @@
Name: libuniset2
Version: 2.1
Release: alt2
1
Release: alt2
2
Summary: UniSet - library for building distributed industrial control systems
...
...
@@ -456,6 +456,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# ..
%changelog
* Sun Sep 06 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt22
- refactoring (use shared_ptr), change pollfactor realisation..
* Sat Sep 05 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt21
- (modbus slave): add more logs..
...
...
extensions/ModbusMaster/MBExchange.cc
View file @
ac610fd2
...
...
@@ -263,33 +263,6 @@ void MBExchange::help_print( int argc, const char* const* argv )
// -----------------------------------------------------------------------------
MBExchange
::~
MBExchange
()
{
for
(
auto
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
if
(
it1
->
second
->
rtu
)
{
try
{
delete
it1
->
second
->
rtu
;
it1
->
second
->
rtu
=
0
;
}
catch
(...)
{}
}
RTUDevice
*
d
(
it1
->
second
);
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
try
{
delete
it
->
second
;
}
catch
(...)
{}
}
delete
it1
->
second
;
}
mb
.
reset
();
}
// -----------------------------------------------------------------------------
void
MBExchange
::
waitSMReady
()
...
...
@@ -423,18 +396,22 @@ void MBExchange::initIterators()
shm
->
initIterator
(
itHeartBeat
);
shm
->
initIterator
(
itExchangeMode
);
for
(
auto
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
auto
it1
=
devices
.
begin
();
it1
!=
devices
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
)
;
auto
d
=
it1
->
second
;
shm
->
initIterator
(
d
->
resp_it
);
shm
->
initIterator
(
d
->
mode_it
);
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
auto
&&
m
:
d
->
pollmap
)
{
for
(
auto
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
auto
&
regmap
=
m
.
second
;
for
(
auto
it
=
regmap
->
begin
();
it
!=
regmap
->
end
();
++
it
)
{
shm
->
initIterator
(
it2
->
ioit
);
shm
->
initIterator
(
it2
->
t_ait
);
for
(
auto
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
{
shm
->
initIterator
(
it2
->
ioit
);
shm
->
initIterator
(
it2
->
t_ait
);
}
}
}
}
...
...
@@ -448,18 +425,22 @@ void MBExchange::initIterators()
// -----------------------------------------------------------------------------
void
MBExchange
::
initValues
()
{
for
(
auto
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
auto
it1
=
devices
.
begin
();
it1
!=
devices
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
)
;
auto
d
=
it1
->
second
;
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
auto
&&
m
:
d
->
pollmap
)
{
for
(
auto
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
auto
regmap
=
m
.
second
;
for
(
auto
it
=
regmap
->
begin
();
it
!=
regmap
->
end
();
++
it
)
{
it2
->
value
=
shm
->
localGetValue
(
it2
->
ioit
,
it2
->
si
.
id
);
}
for
(
auto
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
{
it2
->
value
=
shm
->
localGetValue
(
it2
->
ioit
,
it2
->
si
.
id
);
}
it
->
second
->
sm_initOK
=
true
;
it
->
second
->
sm_initOK
=
true
;
}
}
}
...
...
@@ -559,8 +540,11 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RTUDevice& d )
os
<<
" regs: "
<<
endl
;
for
(
auto
it
=
d
.
regmap
.
begin
();
it
!=
d
.
regmap
.
end
();
++
it
)
os
<<
" "
<<
*
(
it
->
second
)
<<
endl
;
for
(
const
auto
&
m
:
d
.
pollmap
)
{
for
(
const
auto
&
it
:
*
(
m
.
second
)
)
os
<<
" "
<<
it
.
second
<<
endl
;
}
return
os
;
}
...
...
@@ -587,70 +571,75 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RegInfo& r )
return
os
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
rtuQueryOptimization
(
RTUDeviceMap
&
m
)
void
MBExchange
::
rtuQueryOptimization
(
RTUDeviceMap
&
d
m
)
{
if
(
noQueryOptimization
)
return
;
mbinfo
<<
myname
<<
"(rtuQueryOptimization): optimization..."
<<
endl
;
for
(
auto
it1
=
m
.
begin
();
it1
!=
m
.
end
();
++
it1
)
for
(
auto
&&
it1
:
dm
)
{
RTUDevice
*
d
(
it1
->
second
)
;
auto
d
=
it1
.
second
;
// Вообще в map они уже лежат в нужном порядке, т.е. функция genRegID() гарантирует
// что регистры идущие подряд с одниковой функцией чтения/записи получат подряд идущие ID.
// так что оптимтизация это просто нахождение мест где id идут не подряд...
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
auto
&&
m
:
d
->
pollmap
)
{
auto
beg
=
it
;
ModbusRTU
::
RegID
id
=
it
->
second
->
id
;
// или собственно it->first
beg
->
second
->
q_num
=
1
;
beg
->
second
->
q_count
=
1
;
++
it
;
auto
&
regmap
=
m
.
second
;
for
(
;
it
!=
d
->
regmap
.
end
();
++
it
)
// Вообще в map они уже лежат в нужном порядке, т.е. функция genRegID() гарантирует
// что регистры идущие подряд с одниковой функцией чтения/записи получат подряд идущие ID.
// так что оптимтизация это просто нахождение мест где id идут не подряд...
for
(
auto
it
=
regmap
->
begin
();
it
!=
regmap
->
end
();
++
it
)
{
if
(
(
it
->
second
->
id
-
id
)
>
1
)
auto
beg
=
it
;
ModbusRTU
::
RegID
id
=
it
->
second
->
id
;
// или собственно it->first
beg
->
second
->
q_num
=
1
;
beg
->
second
->
q_count
=
1
;
++
it
;
for
(
;
it
!=
regmap
->
end
();
++
it
)
{
--
it
;
// раз это регистр уже следующий, то надо вернуть на шаг обратно..
break
;
}
if
(
(
it
->
second
->
id
-
id
)
>
1
)
{
--
it
;
// раз это регистр уже следующий, то надо вернуть на шаг обратно..
break
;
}
beg
->
second
->
q_count
++
;
beg
->
second
->
q_count
++
;
if
(
beg
->
second
->
q_count
>=
maxQueryCount
)
break
;
if
(
beg
->
second
->
q_count
>=
maxQueryCount
)
break
;
id
=
it
->
second
->
id
;
it
->
second
->
q_num
=
beg
->
second
->
q_count
;
it
->
second
->
q_count
=
0
;
}
id
=
it
->
second
->
id
;
it
->
second
->
q_num
=
beg
->
second
->
q_count
;
it
->
second
->
q_count
=
0
;
}
// check correct function...
if
(
beg
->
second
->
q_count
>
1
&&
beg
->
second
->
mbfunc
==
ModbusRTU
::
fnWriteOutputSingleRegister
)
{
mbwarn
<<
myname
<<
"(rtuQueryOptimization): "
<<
" optimization change func="
<<
ModbusRTU
::
fnWriteOutputSingleRegister
<<
" <--> func="
<<
ModbusRTU
::
fnWriteOutputRegisters
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
beg
->
second
->
mbreg
);
// check correct function...
if
(
beg
->
second
->
q_count
>
1
&&
beg
->
second
->
mbfunc
==
ModbusRTU
::
fnWriteOutputSingleRegister
)
{
mbwarn
<<
myname
<<
"(rtuQueryOptimization): "
<<
" optimization change func="
<<
ModbusRTU
::
fnWriteOutputSingleRegister
<<
" <--> func="
<<
ModbusRTU
::
fnWriteOutputRegisters
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
beg
->
second
->
mbreg
);
beg
->
second
->
mbfunc
=
ModbusRTU
::
fnWriteOutputRegisters
;
}
else
if
(
beg
->
second
->
q_count
>
1
&&
beg
->
second
->
mbfunc
==
ModbusRTU
::
fnForceSingleCoil
)
{
mbwarn
<<
myname
<<
"(rtuQueryOptimization): "
<<
" optimization change func="
<<
ModbusRTU
::
fnForceSingleCoil
<<
" <--> func="
<<
ModbusRTU
::
fnForceMultipleCoils
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
beg
->
second
->
mbreg
);
beg
->
second
->
mbfunc
=
ModbusRTU
::
fnWriteOutputRegisters
;
}
else
if
(
beg
->
second
->
q_count
>
1
&&
beg
->
second
->
mbfunc
==
ModbusRTU
::
fnForceSingleCoil
)
{
mbwarn
<<
myname
<<
"(rtuQueryOptimization): "
<<
" optimization change func="
<<
ModbusRTU
::
fnForceSingleCoil
<<
" <--> func="
<<
ModbusRTU
::
fnForceMultipleCoils
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
beg
->
second
->
mbreg
);
beg
->
second
->
mbfunc
=
ModbusRTU
::
fnForceMultipleCoils
;
}
beg
->
second
->
mbfunc
=
ModbusRTU
::
fnForceMultipleCoils
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
if
(
it
==
regmap
->
end
()
)
break
;
}
}
}
}
...
...
@@ -700,7 +689,7 @@ bool MBExchange::preInitRead( InitList::iterator& p )
if
(
p
->
initOK
)
return
true
;
RTUDevice
*
dev
=
p
->
dev
;
auto
dev
=
p
->
dev
;
int
q_count
=
p
->
p
.
rnum
;
if
(
mblog
->
is_level3
()
)
...
...
@@ -933,9 +922,9 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
return
false
;
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
pollRTU
(
RTUDevice
*
dev
,
RegMap
::
iterator
&
it
)
bool
MBExchange
::
pollRTU
(
std
::
shared_ptr
<
RTUDevice
>&
dev
,
RegMap
::
iterator
&
it
)
{
RegInfo
*
p
(
it
->
second
)
;
auto
p
=
it
->
second
;
if
(
dev
->
mode
==
emSkipExchange
)
{
...
...
@@ -945,9 +934,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
return
false
;
}
if
(
p
->
pollfactor
>
1
&&
ncycle
%
p
->
pollfactor
!=
0
)
return
false
;
if
(
mblog
->
is_level3
()
)
{
mblog3
<<
myname
<<
"(pollRTU): poll "
...
...
@@ -958,7 +944,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
<<
" mb_initOK="
<<
p
->
mb_initOK
<<
" sm_initOK="
<<
p
->
sm_initOK
<<
" mbval="
<<
p
->
mbval
<<
" pollfactor="
<<
p
->
pollfactor
<<
endl
;
if
(
p
->
q_count
>
maxQueryCount
/* ModbusRTU::MAXDATALEN */
)
...
...
@@ -1153,9 +1138,9 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
// -----------------------------------------------------------------------------
void
MBExchange
::
updateSM
()
{
for
(
auto
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
auto
it1
=
devices
.
begin
();
it1
!=
devices
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
)
;
auto
d
=
it1
->
second
;
if
(
d
->
mode_id
!=
DefaultObjectId
)
{
...
...
@@ -1191,50 +1176,56 @@ void MBExchange::updateSM()
}
}
// обновление датчиков связи происходит в другом потоке
// чтобы не зависеть от TCP таймаутов
// см. updateRespondSensors()
// update values...
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
auto
&&
m
:
d
->
pollmap
)
{
try
{
if
(
d
->
dtype
==
dtRTU
)
updateRTU
(
it
);
else
if
(
d
->
dtype
==
dtMTR
)
updateMTR
(
it
);
else
if
(
d
->
dtype
==
dtRTU188
)
updateRTU188
(
it
);
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
mblog3
<<
myname
<<
"(updateSM): (BadRange)..."
<<
endl
;
}
catch
(
const
Exception
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM): "
<<
ex
<<
endl
;
}
catch
(
const
CORBA
::
SystemException
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(
const
std
::
exception
&
ex
)
auto
&
regmap
=
m
.
second
;
// обновление датчиков связи происходит в другом потоке
// чтобы не зависеть от TCP таймаутов
// см. updateRespondSensors()
// update values...
for
(
auto
it
=
regmap
->
begin
();
it
!=
regmap
->
end
();
++
it
)
{
mblog3
<<
myname
<<
"(updateSM): catch ..."
<<
endl
;
}
try
{
if
(
d
->
dtype
==
dtRTU
)
updateRTU
(
it
);
else
if
(
d
->
dtype
==
dtMTR
)
updateMTR
(
it
);
else
if
(
d
->
dtype
==
dtRTU188
)
updateRTU188
(
it
);
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
mblog3
<<
myname
<<
"(updateSM): (BadRange)..."
<<
endl
;
}
catch
(
const
Exception
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM): "
<<
ex
<<
endl
;
}
catch
(
const
CORBA
::
SystemException
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(
const
std
::
exception
&
ex
)
{
mblog3
<<
myname
<<
"(updateSM): catch ..."
<<
endl
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
if
(
it
==
regmap
->
end
()
)
break
;
}
}
}
}
...
...
@@ -1242,17 +1233,17 @@ void MBExchange::updateSM()
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRTU
(
RegMap
::
iterator
&
rit
)
{
RegInfo
*
r
(
rit
->
second
)
;
auto
&
r
=
rit
->
second
;
for
(
auto
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
i
t
)
updateRSProperty
(
&
(
*
it
)
,
false
);
for
(
auto
&&
it
:
r
->
sls
t
)
updateRSProperty
(
&
it
,
false
);
}
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRSProperty
(
RSProperty
*
p
,
bool
write_only
)
{
using
namespace
ModbusRTU
;
RegInfo
*
r
(
p
->
reg
->
rit
->
second
)
;
auto
&
r
=
p
->
reg
->
rit
->
second
;
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
...
...
@@ -1654,7 +1645,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
// -----------------------------------------------------------------------------
void
MBExchange
::
updateMTR
(
RegMap
::
iterator
&
rit
)
{
RegInfo
*
r
(
rit
->
second
)
;
auto
&
r
=
rit
->
second
;
if
(
!
r
||
!
r
->
dev
)
return
;
...
...
@@ -1912,9 +1903,9 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRTU188
(
RegMap
::
iterator
&
rit
)
{
RegInfo
*
r
(
rit
->
second
)
;
auto
&
r
=
rit
->
second
;
if
(
!
r
||
!
r
->
dev
||
!
r
->
dev
->
rtu
)
if
(
!
r
||
!
r
->
dev
||
!
r
->
dev
->
rtu
188
)
return
;
using
namespace
ModbusRTU
;
...
...
@@ -1963,12 +1954,12 @@ void MBExchange::updateRTU188( RegMap::iterator& rit )
{
if
(
it
->
stype
==
UniversalIO
::
DI
)
{
bool
set
=
r
->
dev
->
rtu
->
getState
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
bool
set
=
r
->
dev
->
rtu
188
->
getState
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsDI
(
&
(
*
it
),
set
,
shm
,
force
);
}
else
if
(
it
->
stype
==
UniversalIO
::
AI
)
{
long
val
=
r
->
dev
->
rtu
->
getInt
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
long
val
=
r
->
dev
->
rtu
188
->
getInt
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsAI
(
&
(
*
it
),
val
,
shm
,
force
);
}
}
...
...
@@ -2001,7 +1992,7 @@ void MBExchange::updateRTU188( RegMap::iterator& rit )
}
// -----------------------------------------------------------------------------
MBExchange
::
RTUDevice
*
MBExchange
::
addDev
(
RTUDeviceMap
&
mp
,
ModbusRTU
::
ModbusAddr
a
,
UniXML
::
iterator
&
xmlit
)
std
::
shared_ptr
<
MBExchange
::
RTUDevice
>
MBExchange
::
addDev
(
RTUDeviceMap
&
mp
,
ModbusRTU
::
ModbusAddr
a
,
UniXML
::
iterator
&
xmlit
)
{
auto
it
=
mp
.
find
(
a
);
...
...
@@ -2028,12 +2019,12 @@ MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAd
return
it
->
second
;
}
MBExchange
::
RTUDevice
*
d
=
new
MBExchange
::
RTUDevice
();
auto
d
=
make_shared
<
MBExchange
::
RTUDevice
>
();
d
->
mbaddr
=
a
;
if
(
!
initRTUDevice
(
d
,
xmlit
)
)
{
d
elete
d
;
d
.
reset
()
;
return
0
;
}
...
...
@@ -2041,12 +2032,12 @@ MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAd
return
d
;
}
// ------------------------------------------------------------------------------------------
MBExchange
::
RegInfo
*
MBExchange
::
addReg
(
RegMap
&
mp
,
ModbusRTU
::
RegID
id
,
ModbusRTU
::
ModbusData
r
,
UniXML
::
iterator
&
xmlit
,
MBExchange
::
RTUDevice
*
dev
)
std
::
shared_ptr
<
MBExchange
::
RegInfo
>
MBExchange
::
addReg
(
std
::
shared_ptr
<
RegMap
>
&
mp
,
ModbusRTU
::
RegID
id
,
ModbusRTU
::
ModbusData
r
,
UniXML
::
iterator
&
xmlit
,
std
::
shared_ptr
<
MBExchange
::
RTUDevice
>
dev
)
{
auto
it
=
mp
.
find
(
id
);
auto
it
=
mp
->
find
(
id
);
if
(
it
!=
mp
.
end
()
)
if
(
it
!=
mp
->
end
()
)
{
if
(
!
it
->
second
->
dev
)
{
...
...
@@ -2071,19 +2062,18 @@ MBExchange::RegInfo* MBExchange::addReg( RegMap& mp, ModbusRTU::RegID id, Modbus
return
it
->
second
;
}
MBExchange
::
RegInfo
*
ri
=
new
MBExchange
::
RegInfo
();
auto
ri
=
make_shared
<
MBExchange
::
RegInfo
>
();
if
(
!
initRegInfo
(
ri
,
xmlit
,
dev
)
)
{
delete
ri
;
return
0
;
}
ri
->
mbreg
=
r
;
ri
->
id
=
id
;
mp
.
insert
(
std
::
make_pair
(
id
,
ri
));
ri
->
rit
=
mp
.
find
(
id
);
mp
->
insert
(
std
::
make_pair
(
id
,
ri
)
);
ri
->
rit
=
mp
->
find
(
id
);
mbinfo
<<
myname
<<
"(addReg): reg="
<<
ModbusRTU
::
dat2str
(
r
)
<<
"(id="
<<
id
<<
")"
<<
endl
;
return
ri
;
}
...
...
@@ -2180,12 +2170,10 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML::iterator& it )
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initRegInfo
(
RegInfo
*
r
,
UniXML
::
iterator
&
it
,
MBExchange
::
RTUDevice
*
dev
)
bool
MBExchange
::
initRegInfo
(
std
::
shared_ptr
<
RegInfo
>&
r
,
UniXML
::
iterator
&
it
,
std
::
shared_ptr
<
MBExchange
::
RTUDevice
>&
dev
)
{
r
->
dev
=
dev
;
r
->
mbval
=
IOBase
::
initIntProp
(
it
,
"default"
,
prop_prefix
,
false
);
r
->
pollfactor
=
IOBase
::
initIntProp
(
it
,
"pollfactor"
,
prop_prefix
,
false
,
0
);
if
(
dev
->
dtype
==
MBExchange
::
dtRTU
)
{
...
...
@@ -2257,7 +2245,7 @@ bool MBExchange::initRegInfo( RegInfo* r, UniXML::iterator& it, MBExchange::RTU
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initRTUDevice
(
RTUDevice
*
d
,
UniXML
::
iterator
&
it
)
bool
MBExchange
::
initRTUDevice
(
std
::
shared_ptr
<
RTUDevice
>&
d
,
UniXML
::
iterator
&
it
)
{
string
mbtype
(
IOBase
::
initProp
(
it
,
"mbtype"
,
prop_prefix
,
false
));
...
...
@@ -2289,8 +2277,8 @@ bool MBExchange::initRTUDevice( RTUDevice* d, UniXML::iterator& it )
if
(
d
->
dtype
==
MBExchange
::
dtRTU188
)
{
if
(
!
d
->
rtu
)
d
->
rtu
=
new
RTUStorage
(
d
->
mbaddr
);
if
(
!
d
->
rtu
188
)
d
->
rtu
188
=
make_shared
<
RTUStorage
>
(
d
->
mbaddr
);
}
return
true
;
...
...
@@ -2319,7 +2307,7 @@ bool MBExchange::initItem( UniXML::iterator& it )
ModbusRTU
::
ModbusAddr
mbaddr
=
ModbusRTU
::
str2mbAddr
(
addr
);
RTUDevice
*
dev
=
addDev
(
rmap
,
mbaddr
,
it
);
auto
dev
=
addDev
(
devices
,
mbaddr
,
it
);
if
(
!
dev
)
{
...
...
@@ -2332,16 +2320,17 @@ bool MBExchange::initItem( UniXML::iterator& it )
if
(
dev
->
dtype
==
dtRTU188
)
{
RegInfo
r_tmp
;
auto
r_tmp
=
make_shared
<
RegInfo
>
()
;
if
(
!
initRTU188item
(
it
,
&
r_tmp
)
)
if
(
!
initRTU188item
(
it
,
r_tmp
)
)
{
mbcrit
<<
myname
<<
"(initItem): init RTU188 failed for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
r_tmp
.
reset
();
return
false
;
}
mbreg
=
RTUStorage
::
getRegister
(
r_tmp
.
rtuJack
,
r_tmp
.
rtuChan
,
p
.
stype
);
fn
=
RTUStorage
::
getFunction
(
r_tmp
.
rtuJack
,
r_tmp
.
rtuChan
,
p
.
stype
);
mbreg
=
RTUStorage
::
getRegister
(
r_tmp
->
rtuJack
,
r_tmp
->
rtuChan
,
p
.
stype
);
fn
=
RTUStorage
::
getFunction
(
r_tmp
->
rtuJack
,
r_tmp
->
rtuChan
,
p
.
stype
);
}
else
{
...
...
@@ -2371,13 +2360,29 @@ bool MBExchange::initItem( UniXML::iterator& it )
}
}
/*! приоритет опроса:
* 1...n - задаёт "часоту" опроса. Т.е. каждые 1...n циклов
*/
unsigned
int
pollfactor
=
IOBase
::
initIntProp
(
it
,
"pollfactor"
,
prop_prefix
,
false
,
0
);
std
::
shared_ptr
<
RegMap
>
rmap
;
auto
rit
=
dev
->
pollmap
.
find
(
pollfactor
);
if
(
rit
==
dev
->
pollmap
.
end
()
)
{
rmap
=
make_shared
<
RegMap
>
();
dev
->
pollmap
.
emplace
(
pollfactor
,
rmap
);
}
else
rmap
=
rit
->
second
;
// формула для вычисления ID
// требования:
// - ID > диапазона возможных регитров
// - разные функции должны давать разный ID
ModbusRTU
::
RegID
rID
=
ModbusRTU
::
genRegID
(
mbreg
,
fn
);
RegInfo
*
ri
=
addReg
(
dev
->
reg
map
,
rID
,
mbreg
,
it
,
dev
);
auto
ri
=
addReg
(
r
map
,
rID
,
mbreg
,
it
,
dev
);
if
(
dev
->
dtype
==
dtMTR
)
{
...
...
@@ -2468,7 +2473,7 @@ bool MBExchange::initItem( UniXML::iterator& it )
for
(
auto
i
=
1
;
i
<
p1
->
rnum
;
i
++
)
{
ModbusRTU
::
RegID
id1
=
ModbusRTU
::
genRegID
(
mbreg
+
i
,
ri
->
mbfunc
);
RegInfo
*
r
=
addReg
(
dev
->
reg
map
,
id1
,
mbreg
+
i
,
it
,
dev
);
auto
r
=
addReg
(
r
map
,
id1
,
mbreg
+
i
,
it
,
dev
);
r
->
q_num
=
i
+
1
;
r
->
q_count
=
1
;
r
->
mbfunc
=
ri
->
mbfunc
;
...
...
@@ -2558,7 +2563,7 @@ bool MBExchange::initItem( UniXML::iterator& it )
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initMTRitem
(
UniXML
::
iterator
&
it
,
RegInfo
*
p
)
bool
MBExchange
::
initMTRitem
(
UniXML
::
iterator
&
it
,
std
::
shared_ptr
<
RegInfo
>&
p
)
{
p
->
mtrType
=
MTR
::
str2type
(
it
.
getProp
(
prop_prefix
+
"mtrtype"
));
...
...
@@ -2574,7 +2579,7 @@ bool MBExchange::initMTRitem( UniXML::iterator& it, RegInfo* p )
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initRTU188item
(
UniXML
::
iterator
&
it
,
RegInfo
*
p
)
bool
MBExchange
::
initRTU188item
(
UniXML
::
iterator
&
it
,
std
::
shared_ptr
<
RegInfo
>&
p
)
{
string
jack
(
IOBase
::
initProp
(
it
,
"jakc"
,
prop_prefix
,
false
));
string
chan
(
IOBase
::
initProp
(
it
,
"channel"
,
prop_prefix
,
false
));
...
...
@@ -2672,7 +2677,7 @@ void MBExchange::initDeviceList()
for
(;
it1
.
getCurrent
();
it1
.
goNext
()
)
{
ModbusRTU
::
ModbusAddr
a
=
ModbusRTU
::
str2mbAddr
(
it1
.
getProp
(
"addr"
));
initDeviceInfo
(
rmap
,
a
,
it1
);
initDeviceInfo
(
devices
,
a
,
it1
);
}
}
else
...
...
@@ -2757,7 +2762,7 @@ bool MBExchange::activateObject()
UniSetObject_LT
::
activateObject
();
if
(
!
shm
->
isLocalwork
()
)
rtuQueryOptimization
(
rmap
);
rtuQueryOptimization
(
devices
);
initIterators
();
setProcActive
(
true
);
...
...
@@ -2778,14 +2783,14 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage* sm )
logserv
->
run
(
logserv_host
,
logserv_port
,
true
);
}
if
(
rmap
.
empty
()
)
if
(
devices
.
empty
()
)
{
mbcrit
<<
myname
<<
"(sysCommand): ************* ITEM MAP EMPTY! terminated... *************"
<<
endl
;
raise
(
SIGTERM
);
return
;
}
mbinfo
<<
myname
<<
"(sysCommand): device map size= "
<<
rmap
.
size
()
<<
endl
;
mbinfo
<<
myname
<<
"(sysCommand): device map size= "
<<
devices
.
size
()
<<
endl
;
if
(
!
shm
->
isLocalwork
()
)
initDeviceList
();
...
...
@@ -2900,9 +2905,9 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
mbwarn
<<
myname
<<
"(askSensors): 'sidExchangeMode' catch..."
<<
std
::
endl
;
}
for
(
auto
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
auto
it1
=
devices
.
begin
();
it1
!=
devices
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
)
;
auto
d
=
it1
->
second
;
try
{
...
...
@@ -2921,24 +2926,28 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
if
(
force_out
)
return
;
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
auto
&&
m
:
d
->
pollmap
)
{
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
continue
;
for
(
auto
i
=
it
->
second
->
slst
.
begin
();
i
!=
it
->
second
->
slst
.
end
();
++
i
)
auto
&
regmap
=
m
.
second
;
for
(
auto
it
=
regmap
->
begin
();
it
!=
regmap
->
end
();
++
it
)
{
try
{
shm
->
askSensor
(
i
->
si
.
id
,
cmd
);
}
catch
(
UniSetTypes
::
Exception
&
ex
)
{
mbwarn
<<
myname
<<
"(askSensors): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
continue
;
for
(
auto
i
=
it
->
second
->
slst
.
begin
();
i
!=
it
->
second
->
slst
.
end
();
++
i
)
{
mbwarn
<<
myname
<<
"(askSensors): id="
<<
i
->
si
.
id
<<
" catch..."
<<
std
::
endl
;
try
{
shm
->
askSensor
(
i
->
si
.
id
,
cmd
);
}
catch
(
UniSetTypes
::
Exception
&
ex
)
{
mbwarn
<<
myname
<<
"(askSensors): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
{
mbwarn
<<
myname
<<
"(askSensors): id="
<<
i
->
si
.
id
<<
" catch..."
<<
std
::
endl
;
}
}
}
}
...
...
@@ -2954,9 +2963,9 @@ void MBExchange::sensorInfo( const UniSetTypes::SensorMessage* sm )
//return; // этот датчик может встречаться и в списке обмена.. поэтому делать return нельзя.
}
for
(
auto
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
auto
it1
=
devices
.
begin
();
it1
!=
devices
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
auto
d
(
it1
->
second
);
if
(
sm
->
id
==
d
->
mode_id
)
d
->
mode
=
sm
->
value
;
...
...
@@ -2964,26 +2973,31 @@ void MBExchange::sensorInfo( const UniSetTypes::SensorMessage* sm )
if
(
force_out
)
continue
;
for
(
const
auto
&
it
:
d
->
reg
map
)
for
(
const
auto
&
m
:
d
->
poll
map
)
{
if
(
!
isWriteFunction
(
it
.
second
->
mbfunc
)
)
continue
;
auto
&&
regmap
=
m
.
second
;
for
(
auto
&&
i
:
it
.
second
->
slst
)
for
(
const
auto
&
it
:
(
*
regmap
)
)
{
if
(
sm
->
id
==
i
.
si
.
id
&&
sm
->
node
==
i
.
si
.
node
)
if
(
!
isWriteFunction
(
it
.
second
->
mbfunc
)
)
continue
;
for
(
auto
&&
i
:
it
.
second
->
slst
)
{
mbinfo
<<
myname
<<
"(sensorInfo): si.id="
<<
sm
->
id
<<
" reg="
<<
ModbusRTU
::
dat2str
(
i
.
reg
->
mbreg
)
<<
" val="
<<
sm
->
value
<<
" mb_initOK="
<<
i
.
reg
->
mb_initOK
<<
endl
;
if
(
sm
->
id
==
i
.
si
.
id
&&
sm
->
node
==
i
.
si
.
node
)
{
mbinfo
<<
myname
<<
"(sensorInfo): si.id="
<<
sm
->
id
<<
" reg="
<<
ModbusRTU
::
dat2str
(
i
.
reg
->
mbreg
)
<<
" val="
<<
sm
->
value
<<
" mb_initOK="
<<
i
.
reg
->
mb_initOK
<<
endl
;
if
(
!
i
.
reg
->
mb_initOK
)
continue
;
if
(
!
i
.
reg
->
mb_initOK
)
continue
;
i
.
value
=
sm
->
value
;
updateRSProperty
(
&
i
,
true
);
return
;
i
.
value
=
sm
->
value
;
updateRSProperty
(
&
i
,
true
);
return
;
}
}
}
}
...
...
@@ -3026,54 +3040,62 @@ bool MBExchange::poll()
ncycle
++
;
bool
allNotRespond
=
true
;
for
(
auto
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
auto
it1
=
devices
.
begin
();
it1
!=
devices
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
auto
d
(
it1
->
second
);
if
(
d
->
mode_id
!=
DefaultObjectId
&&
d
->
mode
==
emSkipExchange
)
continue
;
mblog3
<<
myname
<<
"(poll): ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" regs="
<<
d
->
reg
map
.
size
()
<<
endl
;
<<
" regs="
<<
d
->
poll
map
.
size
()
<<
endl
;
d
->
prev_numreply
.
store
(
d
->
numreply
);
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
auto
&&
m
:
d
->
pollmap
)
{
if
(
!
checkProcActive
()
)
return
false
;
if
(
exchangeMode
==
emSkipExchange
)
if
(
m
.
first
>
1
&&
(
ncycle
%
m
.
first
)
!=
0
)
continue
;
try
auto
&&
regmap
=
m
.
second
;
for
(
auto
it
=
regmap
->
begin
();
it
!=
regmap
->
end
();
++
it
)
{
if
(
d
->
dtype
==
MBExchange
::
dtRTU
||
d
->
dtype
==
MBExchange
::
dtMTR
)
if
(
!
checkProcActive
()
)
return
false
;
if
(
exchangeMode
==
emSkipExchange
)
continue
;
try
{
if
(
pollRTU
(
d
,
it
)
)
if
(
d
->
dtype
==
MBExchange
::
dtRTU
||
d
->
dtype
==
MBExchange
::
dtMTR
)
{
d
->
numreply
++
;
allNotRespond
=
false
;
if
(
pollRTU
(
d
,
it
)
)
{
d
->
numreply
++
;
allNotRespond
=
false
;
}
}
}
}
catch
(
ModbusRTU
::
mbException
&
ex
)
{
mblog3
<<
myname
<<
"(poll): FAILED ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" reg="
<<
ModbusRTU
::
dat2str
(
it
->
second
->
mbreg
)
<<
" for sensors: "
;
print_plist
(
mblog
->
level3
(),
it
->
second
->
slst
)
<<
endl
<<
" err: "
<<
ex
<<
endl
;
catch
(
ModbusRTU
::
mbException
&
ex
)
{
mblog3
<<
myname
<<
"(poll): FAILED ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" reg="
<<
ModbusRTU
::
dat2str
(
it
->
second
->
mbreg
)
<<
" for sensors: "
;
print_plist
(
mblog
->
level3
(),
it
->
second
->
slst
)
<<
endl
<<
" err: "
<<
ex
<<
endl
;
if
(
ex
.
err
==
ModbusRTU
::
erTimeOut
&&
!
d
->
ask_every_reg
)
break
;
}
if
(
ex
.
err
==
ModbusRTU
::
erTimeOut
&&
!
d
->
ask_every_reg
)
if
(
it
==
regmap
->
end
()
)
break
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
if
(
!
checkProcActive
()
)
return
false
;
if
(
!
checkProcActive
()
)
return
false
;
}
}
if
(
stat_time
>
0
)
...
...
@@ -3138,9 +3160,9 @@ bool MBExchange::RTUDevice::checkRespond( std::shared_ptr<DebugStream>& mblog )
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRespondSensors
()
{
for
(
const
auto
&
it1
:
rmap
)
for
(
const
auto
&
it1
:
devices
)
{
RTUDevice
*
d
(
it1
.
second
);
auto
d
(
it1
.
second
);
if
(
d
->
resp_id
!=
DefaultObjectId
&&
(
d
->
checkRespond
(
mblog
)
||
d
->
resp_force
||
d
->
resp_ptInit
.
checkTime
())
)
{
...
...
@@ -3238,7 +3260,7 @@ UniSetTypes::SimpleInfo* MBExchange::getInfo()
inf
<<
"Devices:"
<<
endl
;
for
(
const
auto
&
it
:
rmap
)
for
(
const
auto
&
it
:
devices
)
inf
<<
" "
<<
it
.
second
->
getShortInfo
()
<<
endl
;
i
->
info
=
inf
.
str
().
c_str
();
...
...
extensions/ModbusMaster/MBExchange.h
View file @
ac610fd2
...
...
@@ -4,7 +4,7 @@
#include <ostream>
#include <string>
#include <map>
#include <
vector
>
#include <
unordered_map
>
#include <memory>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
...
...
@@ -84,7 +84,7 @@ class MBExchange:
RSProperty
()
:
nbit
(
-
1
),
vType
(
VTypes
::
vtUnknown
),
rnum
(
VTypes
::
wsize
(
VTypes
::
vtUnknown
)),
nbyte
(
0
)
,
reg
(
0
)
nbyte
(
0
)
{}
// т.к. IOBase содержит rwmutex с запрещённым конструктором копирования
...
...
@@ -94,7 +94,7 @@ class MBExchange:
RSProperty
(
RSProperty
&&
r
)
=
default
;
RSProperty
&
operator
=
(
RSProperty
&&
r
)
=
default
;
RegInfo
*
reg
;
std
::
shared_ptr
<
RegInfo
>
reg
;
};
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
RSProperty
&
p
);
...
...
@@ -102,7 +102,7 @@ class MBExchange:
typedef
std
::
list
<
RSProperty
>
PList
;
static
std
::
ostream
&
print_plist
(
std
::
ostream
&
os
,
const
PList
&
p
);
typedef
std
::
map
<
ModbusRTU
::
RegID
,
RegInfo
*
>
RegMap
;
typedef
std
::
map
<
ModbusRTU
::
RegID
,
std
::
shared_ptr
<
RegInfo
>
>
RegMap
;
struct
RegInfo
{
// т.к. RSProperty содержит rwmutex с запрещённым конструктором копирования
...
...
@@ -126,7 +126,7 @@ class MBExchange:
PList
slst
;
ModbusRTU
::
RegID
id
;
RTUDevice
*
dev
;
std
::
shared_ptr
<
RTUDevice
>
dev
;
// only for RTU188
RTUStorage
::
RTUJack
rtuJack
;
...
...
@@ -151,11 +151,6 @@ class MBExchange:
// Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров"
// ещё не инициализировано из SM
bool
sm_initOK
;
/*!< инициализировалось ли значение из SM */
/*! приоритет опроса, 0,1 - высший,
* 1...n - задаёт "часоту" опроса. Т.е. каждые 1...n циклов
*/
int
pollfactor
=
{
0
};
};
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RegInfo
&
r
);
...
...
@@ -175,12 +170,12 @@ class MBExchange:
mode_id
(
UniSetTypes
::
DefaultObjectId
),
mode
(
emNone
),
speed
(
ComPort
::
ComSpeed38400
),
rtu
(
0
)
rtu
188
(
0
)
{
}
ModbusRTU
::
ModbusAddr
mbaddr
;
/*!< адрес устройства */
RegMap
reg
map
;
std
::
unordered_map
<
unsigned
int
,
std
::
shared_ptr
<
RegMap
>>
poll
map
;
DeviceType
dtype
;
/*!< тип устройства */
...
...
@@ -208,14 +203,14 @@ class MBExchange:
// специфические поля для RS
ComPort
::
Speed
speed
;
RTUStorage
*
rtu
;
std
::
shared_ptr
<
RTUStorage
>
rtu188
;
std
::
string
getShortInfo
()
const
;
};
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUDevice
&
d
);
typedef
std
::
map
<
ModbusRTU
::
ModbusAddr
,
RTUDevice
*
>
RTUDeviceMap
;
typedef
std
::
map
<
ModbusRTU
::
ModbusAddr
,
std
::
shared_ptr
<
RTUDevice
>
>
RTUDeviceMap
;
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUDeviceMap
&
d
);
void
printMap
(
RTUDeviceMap
&
d
);
...
...
@@ -256,14 +251,14 @@ class MBExchange:
InitRegInfo
()
:
dev
(
0
),
mbreg
(
0
),
mbfunc
(
ModbusRTU
::
fnUnknown
),
initOK
(
false
)
,
ri
(
0
)
initOK
(
false
)
{}
RSProperty
p
;
RTUDevice
*
dev
;
std
::
shared_ptr
<
RTUDevice
>
dev
;
ModbusRTU
::
ModbusData
mbreg
;
ModbusRTU
::
SlaveFunctionCode
mbfunc
;
bool
initOK
;
RegInfo
*
ri
;
std
::
shared_ptr
<
RegInfo
>
ri
;
};
typedef
std
::
list
<
InitRegInfo
>
InitList
;
...
...
@@ -272,14 +267,14 @@ class MBExchange:
bool
initSMValue
(
ModbusRTU
::
ModbusData
*
data
,
int
count
,
RSProperty
*
p
);
bool
allInitOK
;
RTUDeviceMap
rmap
;
RTUDeviceMap
devices
;
InitList
initRegList
;
/*!< список регистров для инициализации */
UniSetTypes
::
uniset_rwmutex
pollMutex
;
virtual
std
::
shared_ptr
<
ModbusClient
>
initMB
(
bool
reopen
=
false
)
=
0
;
virtual
bool
poll
();
bool
pollRTU
(
RTUDevice
*
dev
,
RegMap
::
iterator
&
it
);
bool
pollRTU
(
std
::
shared_ptr
<
RTUDevice
>&
dev
,
RegMap
::
iterator
&
it
);
void
updateSM
();
void
updateRTU
(
RegMap
::
iterator
&
it
);
...
...
@@ -301,15 +296,15 @@ class MBExchange:
void
initDeviceList
();
void
initOffsetList
();
RTUDevice
*
addDev
(
RTUDeviceMap
&
dmap
,
ModbusRTU
::
ModbusAddr
a
,
UniXML
::
iterator
&
it
);
RegInfo
*
addReg
(
RegMap
&
rmap
,
ModbusRTU
::
RegID
id
,
ModbusRTU
::
ModbusData
r
,
UniXML
::
iterator
&
it
,
RTUDevice
*
dev
);
std
::
shared_ptr
<
RTUDevice
>
addDev
(
RTUDeviceMap
&
dmap
,
ModbusRTU
::
ModbusAddr
a
,
UniXML
::
iterator
&
it
);
std
::
shared_ptr
<
RegInfo
>
addReg
(
std
::
shared_ptr
<
RegMap
>&
devices
,
ModbusRTU
::
RegID
id
,
ModbusRTU
::
ModbusData
r
,
UniXML
::
iterator
&
it
,
std
::
shared_ptr
<
RTUDevice
>
dev
);
RSProperty
*
addProp
(
PList
&
plist
,
RSProperty
&&
p
);
bool
initMTRitem
(
UniXML
::
iterator
&
it
,
RegInfo
*
p
);
bool
initRTU188item
(
UniXML
::
iterator
&
it
,
RegInfo
*
p
);
bool
initMTRitem
(
UniXML
::
iterator
&
it
,
std
::
shared_ptr
<
RegInfo
>&
p
);
bool
initRTU188item
(
UniXML
::
iterator
&
it
,
std
::
shared_ptr
<
RegInfo
>&
p
);
bool
initRSProperty
(
RSProperty
&
p
,
UniXML
::
iterator
&
it
);
bool
initRegInfo
(
RegInfo
*
r
,
UniXML
::
iterator
&
it
,
RTUDevice
*
dev
);
bool
initRTUDevice
(
RTUDevice
*
d
,
UniXML
::
iterator
&
it
);
bool
initRegInfo
(
std
::
shared_ptr
<
RegInfo
>&
r
,
UniXML
::
iterator
&
it
,
std
::
shared_ptr
<
RTUDevice
>&
dev
);
bool
initRTUDevice
(
std
::
shared_ptr
<
RTUDevice
>&
d
,
UniXML
::
iterator
&
it
);
virtual
bool
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML
::
iterator
&
it
);
std
::
string
initPropPrefix
(
const
std
::
string
&
def_prop_prefix
=
""
);
...
...
extensions/ModbusMaster/MBTCPMaster.cc
View file @
ac610fd2
...
...
@@ -48,7 +48,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
if
(
shm
->
isLocalwork
()
)
{
readConfiguration
();
rtuQueryOptimization
(
rmap
);
rtuQueryOptimization
(
devices
);
initDeviceList
();
}
else
...
...
@@ -58,7 +58,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
pollThread
->
setFinalAction
(
this
,
&
MBTCPMaster
::
final_thread
);
if
(
mblog
->
is_info
()
)
printMap
(
rmap
);
printMap
(
devices
);
}
// -----------------------------------------------------------------------------
MBTCPMaster
::~
MBTCPMaster
()
...
...
extensions/ModbusMaster/MBTCPMultiMaster.cc
View file @
ac610fd2
...
...
@@ -128,7 +128,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
if
(
shm
->
isLocalwork
()
)
{
readConfiguration
();
rtuQueryOptimization
(
rmap
);
rtuQueryOptimization
(
devices
);
initDeviceList
();
}
else
...
...
@@ -145,7 +145,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
ptReopen
.
setTiming
(
default_timeout
);
if
(
mblog
->
is_info
()
)
printMap
(
rmap
);
printMap
(
devices
);
}
// -----------------------------------------------------------------------------
MBTCPMultiMaster
::~
MBTCPMultiMaster
()
...
...
extensions/ModbusMaster/RTUExchange.cc
View file @
ac610fd2
...
...
@@ -70,7 +70,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
if
(
shm
->
isLocalwork
()
)
{
readConfiguration
();
rtuQueryOptimization
(
rmap
);
rtuQueryOptimization
(
devices
);
initDeviceList
();
}
else
...
...
@@ -79,7 +79,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
initMB
(
false
);
if
(
dlog
()
->
is_info
()
)
printMap
(
rmap
);
printMap
(
devices
);
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
help_print
(
int
argc
,
const
char
*
const
*
argv
)
...
...
@@ -204,9 +204,9 @@ bool RTUExchange::poll()
bool
allNotRespond
=
true
;
ComPort
::
Speed
s
=
mbrtu
->
getSpeed
();
for
(
auto
it1
:
rmap
)
for
(
auto
it1
:
devices
)
{
RTUDevice
*
d
(
it1
.
second
)
;
auto
d
=
it1
.
second
;
if
(
d
->
mode_id
!=
DefaultObjectId
&&
d
->
mode
==
emSkipExchange
)
continue
;
...
...
@@ -221,7 +221,7 @@ bool RTUExchange::poll()
if
(
d
->
dtype
==
MBExchange
::
dtRTU188
)
{
if
(
!
d
->
rtu
)
if
(
!
d
->
rtu
188
)
continue
;
dlog3
<<
myname
<<
"(pollRTU188): poll RTU188 "
...
...
@@ -233,7 +233,7 @@ bool RTUExchange::poll()
if
(
rs_pre_clean
)
mb
->
cleanupChannel
();
d
->
rtu
->
poll
(
mbrtu
);
d
->
rtu
188
->
poll
(
mbrtu
);
d
->
numreply
++
;
allNotRespond
=
false
;
}
...
...
@@ -249,38 +249,46 @@ bool RTUExchange::poll()
else
{
dlog3
<<
myname
<<
"(poll): ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" regs="
<<
d
->
reg
map
.
size
()
<<
endl
;
<<
" regs="
<<
d
->
poll
map
.
size
()
<<
endl
;
for
(
auto
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
auto
&&
m
:
d
->
pollmap
)
{
try
if
(
m
.
first
!=
0
&&
(
ncycle
%
m
.
first
)
!=
0
)
continue
;
auto
rmap
=
m
.
second
;
for
(
auto
&&
it
=
rmap
->
begin
();
it
!=
rmap
->
end
();
++
it
)
{
if
(
d
->
dtype
==
RTUExchange
::
dtRTU
||
d
->
dtype
==
RTUExchange
::
dtMTR
)
try
{
if
(
rs_pre_clean
)
mb
->
cleanupChannel
();
if
(
pollRTU
(
d
,
it
)
)
if
(
d
->
dtype
==
RTUExchange
::
dtRTU
||
d
->
dtype
==
RTUExchange
::
dtMTR
)
{
d
->
numreply
++
;
allNotRespond
=
false
;
if
(
rs_pre_clean
)
mb
->
cleanupChannel
();
if
(
pollRTU
(
d
,
it
)
)
{
d
->
numreply
++
;
allNotRespond
=
false
;
}
}
}
}
catch
(
ModbusRTU
::
mbException
&
ex
)
{
dlog3
<<
myname
<<
"(poll): FAILED ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" reg="
<<
ModbusRTU
::
dat2str
(
it
->
second
->
mbreg
)
<<
" for sensors: "
;
print_plist
(
dlog
()
->
level3
(),
it
->
second
->
slst
);
dlog
()
->
level3
()
<<
" err: "
<<
ex
<<
endl
;
}
catch
(
ModbusRTU
::
mbException
&
ex
)
{
dlog3
<<
myname
<<
"(poll): FAILED ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" reg="
<<
ModbusRTU
::
dat2str
(
it
->
second
->
mbreg
)
<<
" for sensors: "
;
print_plist
(
dlog
()
->
level3
(),
it
->
second
->
slst
);
dlog
()
->
level3
()
<<
" err: "
<<
ex
<<
endl
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
if
(
it
==
rmap
->
end
()
)
break
;
if
(
!
checkProcActive
()
)
return
false
;
if
(
!
checkProcActive
()
)
return
false
;
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment