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
902e3a76
Commit
902e3a76
authored
Oct 31, 2011
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(Modbus): продолжаю выносить код в базовый класс
parent
78333cac
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
181 additions
and
1953 deletions
+181
-1953
configure.ac
configure.ac
+1
-0
Makefile.am
extensions/MBTCPMaster/Makefile.am
+4
-2
start_fg.sh
extensions/MBTCPMaster/start_fg.sh
+1
-1
Makefile.am
extensions/Makefile.am
+1
-1
MBExchange.cc
extensions/ModbusMaster/MBExchange.cc
+63
-0
MBExchange.h
extensions/ModbusMaster/MBExchange.h
+14
-7
Makefile.am
extensions/ModbusMaster/Makefile.am
+14
-0
RTUStorage.cc
extensions/ModbusMaster/RTUStorage.cc
+0
-0
RTUStorage.h
extensions/ModbusMaster/RTUStorage.h
+0
-0
Makefile.am
extensions/RTUExchange/Makefile.am
+9
-5
RTUExchange.cc
extensions/RTUExchange/RTUExchange.cc
+67
-1774
RTUExchange.h
extensions/RTUExchange/RTUExchange.h
+3
-162
MBExchange.h
extensions/include/MBExchange.h
+2
-0
Makefile.am
extensions/lib/Makefile.am
+2
-1
No files found.
configure.ac
View file @
902e3a76
...
...
@@ -181,6 +181,7 @@ AC_CONFIG_FILES([Makefile
extensions/IOControl/libUniSetIOControl.pc
extensions/RTUExchange/Makefile
extensions/RTUExchange/libUniSetRTU.pc
extensions/ModbusMaster/Makefile
extensions/ModbusSlave/Makefile
extensions/ModbusSlave/libUniSetMBSlave.pc
extensions/MBTCPMaster/Makefile
...
...
extensions/MBTCPMaster/Makefile.am
View file @
902e3a76
...
...
@@ -8,16 +8,18 @@ libUniSetMBTCPMaster_la_LDFLAGS = -version-info $(UMBTCP_VER)
libUniSetMBTCPMaster_la_LIBADD
=
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
libUniSetMBTCPMaster_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_SOURCES
=
MBTCPMaster.cc
@PACKAGE@
_mbtcpmaster_SOURCES
=
main.cc
@PACKAGE@
_mbtcpmaster_LDADD
=
libUniSetMBTCPMaster.la
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
@PACKAGE@
_mbtcpmaster_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
@PACKAGE@
_mbtcpmaster_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
# install
devel_include_HEADERS
=
*
.h
...
...
extensions/MBTCPMaster/start_fg.sh
View file @
902e3a76
#!/bin/sh
./uniset-start.sh
-
g
./uniset-mbtcpmaster
\
./uniset-start.sh
-
f
./uniset-mbtcpmaster
\
--confile
test.xml
\
--mbtcp-name
MBMaster1
\
--smemory-id
SharedMemory
\
...
...
extensions/Makefile.am
View file @
902e3a76
...
...
@@ -3,7 +3,7 @@
############################################################################
if
HAVE_EXTENTIONS
SUBDIRS
=
lib include SharedMemory IOControl RTUExchange LogicProcessor
\
SUBDIRS
=
lib include
ModbusMaster
SharedMemory IOControl RTUExchange LogicProcessor
\
ModbusSlave MBTCPMaster SMViewer UniNetwork UNet2 DBServer-MySQL tests
#SMDBServer
#SharedMemoryPlus
...
...
extensions/
lib
/MBExchange.cc
→
extensions/
ModbusMaster
/MBExchange.cc
View file @
902e3a76
...
...
@@ -1547,6 +1547,69 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
}
}
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRTU188
(
RegMap
::
iterator
&
it
)
{
RegInfo
*
r
(
it
->
second
);
if
(
!
r
->
dev
->
rtu
)
return
;
using
namespace
ModbusRTU
;
// bool save = false;
if
(
isWriteFunction
(
r
->
mbfunc
)
)
{
// save = true;
cerr
<<
myname
<<
"(updateRTU188): write reg("
<<
dat2str
(
r
->
mbreg
)
<<
") to RTU188 NOT YET!!!"
<<
endl
;
return
;
}
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
{
try
{
if
(
it
->
stype
==
UniversalIO
::
DigitalInput
)
{
bool
set
=
r
->
dev
->
rtu
->
getState
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsDI
(
&
(
*
it
),
set
,
shm
,
force
);
continue
;
}
if
(
it
->
stype
==
UniversalIO
::
AnalogInput
)
{
long
val
=
r
->
dev
->
rtu
->
getInt
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsAI
(
&
(
*
it
),
val
,
shm
,
force
);
continue
;
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): catch ..."
<<
endl
;
}
}
}
// -----------------------------------------------------------------------------
MBExchange
::
RTUDevice
*
MBExchange
::
addDev
(
RTUDeviceMap
&
mp
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
xmlit
)
{
RTUDeviceMap
::
iterator
it
=
mp
.
find
(
a
);
...
...
extensions/
include
/MBExchange.h
→
extensions/
ModbusMaster
/MBExchange.h
View file @
902e3a76
...
...
@@ -17,9 +17,9 @@
#include "IOBase.h"
#include "VTypes.h"
#include "MTR.h"
#include "RTUStorage.h"
#include "modbus/ModbusClient.h"
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
/*!
\par Базовый класс для реализация обмена по протоколу Modbus [RTU|TCP].
*/
...
...
@@ -106,8 +106,8 @@ class MBExchange:
RTUDevice
*
dev
;
// only for RTU188
//
RTUStorage::RTUJack rtuJack;
//
int rtuChan;
RTUStorage
::
RTUJack
rtuJack
;
int
rtuChan
;
// only for MTR
MTR
::
MTRType
mtrType
;
/*!< тип регистра (согласно спецификации на MTR) */
...
...
@@ -143,7 +143,9 @@ class MBExchange:
resp_invert
(
false
),
resp_real
(
false
),
resp_init
(
false
),
ask_every_reg
(
false
)
ask_every_reg
(
false
),
speed
(
ComPort
::
ComSpeed38400
),
rtu
(
0
)
{
resp_trTimeout
.
change
(
false
);
}
...
...
@@ -167,6 +169,9 @@ class MBExchange:
// return TRUE if state changed
bool
checkRespond
();
// специфические поля для RS
ComPort
::
Speed
speed
;
RTUStorage
*
rtu
;
};
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUDevice
&
d
);
...
...
@@ -221,14 +226,15 @@ class MBExchange:
InitList
initRegList
;
/*!< список регистров для инициализации */
UniSetTypes
::
uniset_mutex
pollMutex
;
virtual
ModbusClient
*
initMB
(
bool
reopen
=
false
)
=
0
;
virtual
ModbusClient
*
initMB
(
bool
reopen
=
false
)
=
0
;
void
poll
();
v
irtual
v
oid
poll
();
bool
pollRTU
(
RTUDevice
*
dev
,
RegMap
::
iterator
&
it
);
void
updateSM
();
void
updateRTU
(
RegMap
::
iterator
&
it
);
void
updateMTR
(
RegMap
::
iterator
&
it
);
void
updateRTU188
(
RegMap
::
iterator
&
it
);
void
updateRSProperty
(
RSProperty
*
p
,
bool
write_only
=
false
);
bool
checkUpdateSM
(
bool
wrFunc
);
...
...
@@ -250,10 +256,11 @@ class MBExchange:
RSProperty
*
addProp
(
PList
&
plist
,
RSProperty
&
p
);
bool
initMTRitem
(
UniXML_iterator
&
it
,
RegInfo
*
p
);
bool
initRTU188item
(
UniXML_iterator
&
it
,
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
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
);
virtual
bool
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
);
void
rtuQueryOptimization
(
RTUDeviceMap
&
m
);
...
...
extensions/ModbusMaster/Makefile.am
0 → 100644
View file @
902e3a76
noinst_LTLIBRARIES
=
libMBMaster.la
libMBMaster_la_LIBADD
=
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(SIGC_LIBS)
libMBMaster_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
libMBMaster_la_SOURCES
=
MBExchange.cc RTUStorage.cc
# install
devel_include_HEADERS
=
*
.h
devel_includedir
=
$(pkgincludedir)
/extensions
all-local
:
ln
-sf
../ModbusMaster/
$(devel_include_HEADERS)
../include
extensions/
RTUExchange
/RTUStorage.cc
→
extensions/
ModbusMaster
/RTUStorage.cc
View file @
902e3a76
File moved
extensions/
RTUExchange
/RTUStorage.h
→
extensions/
ModbusMaster
/RTUStorage.h
View file @
902e3a76
File moved
extensions/RTUExchange/Makefile.am
View file @
902e3a76
...
...
@@ -8,16 +8,18 @@ libUniSetRTU_la_LDFLAGS = -version-info $(URTU_VER)
libUniSetRTU_la_LIBADD
=
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
libUniSetRTU_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
libUniSetRTU_la_SOURCES
=
RTU
Storage.cc RTU
Exchange.cc
libUniSetRTU_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
libUniSetRTU_la_SOURCES
=
RTUExchange.cc
@PACKAGE@
_rtuexchange_SOURCES
=
rtuexchange.cc
@PACKAGE@
_rtuexchange_LDADD
=
libUniSetRTU.la
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
@PACKAGE@
_rtuexchange_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
@PACKAGE@
_rtuexchange_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
@PACKAGE@
_mtr_conv_SOURCES
=
mtrconv.cc
@PACKAGE@
_mtr_conv_LDADD
=
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
...
...
@@ -31,8 +33,10 @@ libUniSetRTU_la_SOURCES = RTUStorage.cc RTUExchange.cc
@PACKAGE@
_vtconv_LDADD
=
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
@PACKAGE@
_vtconv_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
@PACKAGE@
_rtu188_state_LDADD
=
libUniSetRTU.la
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
@PACKAGE@
_rtu188_state__CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
@PACKAGE@
_rtu188_state_LDADD
=
libUniSetRTU.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
@PACKAGE@
_rtu188_state_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/ModbusMaster
@PACKAGE@
_rtu188_state_SOURCES
=
rtustate.cc
# install
...
...
extensions/RTUExchange/RTUExchange.cc
View file @
902e3a76
...
...
@@ -11,13 +11,15 @@ using namespace UniSetExtensions;
RTUExchange
::
RTUExchange
(
UniSetTypes
::
ObjectId
objId
,
UniSetTypes
::
ObjectId
shmId
,
SharedMemory
*
ic
,
const
std
::
string
prefix_
)
:
MBExchange
(
objId
,
shmId
,
ic
,
prefix_
),
mb
(
0
),
mb
rtu
(
0
),
defSpeed
(
ComPort
::
ComSpeed0
),
use485F
(
false
),
transmitCtl
(
false
),
rs_pre_clean
(
false
),
allNotRespond
(
false
)
{
prop_prefix
=
""
;
if
(
objId
==
DefaultObjectId
)
throw
UniSetTypes
::
SystemError
(
"(RTUExchange): objId=-1?!! Use --"
+
prefix
+
"-name"
);
...
...
@@ -65,7 +67,7 @@ allNotRespond(false)
// -----------------------------------------------------------------------------
RTUExchange
::~
RTUExchange
()
{
for
(
RTU
Exchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
MB
Exchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
if
(
it1
->
second
->
rtu
)
{
...
...
@@ -80,58 +82,57 @@ RTUExchange::~RTUExchange()
delete
it1
->
second
;
}
delete
mb
;
delete
mb
rtu
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
initMB
(
bool
reopen
)
ModbusClient
*
RTUExchange
::
initMB
(
bool
reopen
)
{
if
(
!
file_exist
(
devname
)
)
{
if
(
mb
)
if
(
mb
rtu
)
{
delete
mb
;
delete
mb
rtu
;
mb
=
0
;
mbrtu
=
0
;
}
return
;
return
mbrtu
;
}
if
(
mb
)
if
(
mb
rtu
)
{
if
(
!
reopen
)
return
;
return
mbrtu
;
delete
mb
;
delete
mbrtu
;
mbrtu
=
0
;
mb
=
0
;
}
try
{
mb
=
new
ModbusRTUMaster
(
devname
,
use485F
,
transmitCtl
);
mb
rtu
=
new
ModbusRTUMaster
(
devname
,
use485F
,
transmitCtl
);
if
(
defSpeed
!=
ComPort
::
ComSpeed0
)
mb
->
setSpeed
(
defSpeed
);
mb
rtu
->
setSpeed
(
defSpeed
);
// mb->setLog(dlog);
if
(
recv_timeout
>
0
)
mb
->
setTimeout
(
recv_timeout
);
mb
rtu
->
setTimeout
(
recv_timeout
);
mb
->
setSleepPause
(
sleepPause_usec
);
mb
rtu
->
setSleepPause
(
sleepPause_usec
);
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(init): dev="
<<
devname
<<
" speed="
<<
ComPort
::
getSpeed
(
defSpeed
)
<<
endl
;
}
catch
(...)
{
if
(
mb
)
delete
mb
;
mb
=
0
;
if
(
mb
rtu
)
delete
mb
rtu
;
mb
rtu
=
0
;
}
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
timerInfo
(
TimerMessage
*
tm
)
{
if
(
tm
->
id
==
tmExchange
)
step
();
mb
=
mbrtu
;
return
mbrtu
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
step
()
...
...
@@ -161,23 +162,23 @@ void RTUExchange::poll()
initMB
(
false
);
if
(
!
mb
)
{
for
(
RTU
Exchange
::
RTUDeviceMap
::
iterator
it
=
rmap
.
begin
();
it
!=
rmap
.
end
();
++
it
)
for
(
MB
Exchange
::
RTUDeviceMap
::
iterator
it
=
rmap
.
begin
();
it
!=
rmap
.
end
();
++
it
)
it
->
second
->
resp_real
=
false
;
}
updateSM
();
return
;
}
ComPort
::
Speed
s
=
mb
->
getSpeed
();
ComPort
::
Speed
s
=
mb
rtu
->
getSpeed
();
for
(
RTU
Exchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
MB
Exchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
if
(
d
->
speed
!=
s
)
{
s
=
d
->
speed
;
mb
->
setSpeed
(
d
->
speed
);
mb
rtu
->
setSpeed
(
d
->
speed
);
}
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
...
...
@@ -200,7 +201,7 @@ void RTUExchange::poll()
if
(
rs_pre_clean
)
mb
->
cleanupChannel
();
d
->
rtu
->
poll
(
mb
);
d
->
rtu
->
poll
(
mb
rtu
);
d
->
resp_real
=
true
;
}
catch
(
ModbusRTU
::
mbException
&
ex
)
...
...
@@ -256,7 +257,7 @@ void RTUExchange::poll()
updateSM
();
// check thresholds
for
(
RTU
Exchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
MB
Exchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
for
(
RTUExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
...
...
@@ -270,209 +271,6 @@ void RTUExchange::poll()
// printMap(rmap);
}
// -----------------------------------------------------------------------------
bool
RTUExchange
::
pollRTU
(
RTUDevice
*
dev
,
RegMap
::
iterator
&
it
)
{
RegInfo
*
p
(
it
->
second
);
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): poll "
<<
" mbaddr="
<<
ModbusRTU
::
addr2str
(
dev
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" mboffset="
<<
p
->
offset
<<
" mbfunc="
<<
p
->
mbfunc
<<
" q_count="
<<
p
->
q_count
<<
" mb_init="
<<
p
->
mb_init
<<
endl
;
}
if
(
!
checkPoll
(
ModbusRTU
::
isWriteFunction
(
p
->
mbfunc
))
)
return
true
;
if
(
p
->
q_count
==
0
)
{
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(pollRTU): q_count=0 for mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE register..."
<<
endl
;
return
false
;
}
switch
(
p
->
mbfunc
)
{
case
ModbusRTU
:
:
fnReadInputRegisters
:
{
ModbusRTU
::
ReadInputRetMessage
ret
=
mb
->
read04
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
,
p
->
q_count
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
it
->
second
->
mbval
=
ret
.
data
[
i
];
it
--
;
}
break
;
case
ModbusRTU
:
:
fnReadOutputRegisters
:
{
ModbusRTU
::
ReadOutputRetMessage
ret
=
mb
->
read03
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
,
p
->
q_count
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
it
->
second
->
mbval
=
ret
.
data
[
i
];
it
--
;
}
break
;
case
ModbusRTU
:
:
fnReadInputStatus
:
{
ModbusRTU
::
ReadInputStatusRetMessage
ret
=
mb
->
read02
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
,
p
->
q_count
);
int
m
=
0
;
for
(
int
i
=
0
;
i
<
ret
.
bcnt
;
i
++
)
{
ModbusRTU
::
DataBits
b
(
ret
.
data
[
i
]);
for
(
int
k
=
0
;
k
<
ModbusRTU
::
BitsPerByte
&&
m
<
p
->
q_count
;
k
++
,
it
++
,
m
++
)
it
->
second
->
mbval
=
b
[
k
];
}
it
--
;
}
break
;
case
ModbusRTU
:
:
fnReadCoilStatus
:
{
ModbusRTU
::
ReadCoilRetMessage
ret
=
mb
->
read01
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
,
p
->
q_count
);
int
m
=
0
;
for
(
int
i
=
0
;
i
<
ret
.
bcnt
;
i
++
)
{
ModbusRTU
::
DataBits
b
(
ret
.
data
[
i
]);
for
(
int
k
=
0
;
k
<
ModbusRTU
::
BitsPerByte
&&
m
<
p
->
q_count
;
k
++
,
it
++
,
m
++
)
it
->
second
->
mbval
=
b
[
k
]
?
1
:
0
;
}
it
--
;
}
break
;
case
ModbusRTU
:
:
fnWriteOutputSingleRegister
:
{
if
(
p
->
q_count
!=
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE WRITE SINGLE REGISTER (0x06) q_count="
<<
p
->
q_count
<<
" ..."
<<
endl
;
return
false
;
}
if
(
!
p
->
mb_init
)
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(p->mbreg) << endl;
ModbusRTU
::
ReadInputRetMessage
ret1
=
mb
->
read04
(
dev
->
mbaddr
,
p
->
mb_init_mbreg
,
1
);
p
->
mbval
=
ret1
.
data
[
0
];
p
->
sm_init
=
true
;
return
true
;
}
// cerr << "**** mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU
::
WriteSingleOutputRetMessage
ret
=
mb
->
write06
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
,
p
->
mbval
);
}
break
;
case
ModbusRTU
:
:
fnWriteOutputRegisters
:
{
ModbusRTU
::
WriteOutputMessage
msg
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
{
if
(
!
it
->
second
->
mb_init
)
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(it->second->mbreg)
// << " mb_init mbreg=" << ModbusRTU::dat2str(it->second->mb_init_mbreg) << endl;
ModbusRTU
::
ReadOutputRetMessage
ret1
=
mb
->
read03
(
dev
->
mbaddr
,
it
->
second
->
mb_init_mbreg
,
1
);
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(it->second->mbreg)
// << " mb_init mbreg=" << ModbusRTU::dat2str(it->second->mb_init_mbreg)
// << " mbval=" << ret1.data[0] << endl;
it
->
second
->
mbval
=
ret1
.
data
[
0
];
it
->
second
->
sm_init
=
true
;
}
msg
.
addData
(
it
->
second
->
mbval
);
}
it
--
;
ModbusRTU
::
WriteOutputRetMessage
ret
=
mb
->
write10
(
msg
);
}
break
;
case
ModbusRTU
:
:
fnForceSingleCoil
:
{
if
(
p
->
q_count
!=
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE FORCE SINGLE COIL (0x05) q_count="
<<
p
->
q_count
<<
" ..."
<<
endl
;
return
false
;
}
if
(
!
p
->
mb_init
)
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(p->mbreg)
// << " init mbreg=" << ModbusRTU::dat2str(p->mb_init_mbreg) << endl;
ModbusRTU
::
ReadInputStatusRetMessage
ret1
=
mb
->
read02
(
dev
->
mbaddr
,
p
->
mb_init_mbreg
,
1
);
ModbusRTU
::
DataBits
b
(
ret1
.
data
[
0
]);
// cerr << "******* mb_init_mbreg=" << ModbusRTU::dat2str(p->mb_init_mbreg)
// << " read val=" << (int)b[0] << endl;
p
->
mbval
=
b
[
0
];
p
->
sm_init
=
true
;
return
true
;
}
// cerr << "****(coil) mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU
::
ForceSingleCoilRetMessage
ret
=
mb
->
write05
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
,
p
->
mbval
);
}
break
;
case
ModbusRTU
:
:
fnForceMultipleCoils
:
{
if
(
!
p
->
mb_init
)
{
// every register ask... (for mb_init_mbreg no some)
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
{
ModbusRTU
::
ReadInputStatusRetMessage
ret1
=
mb
->
read02
(
dev
->
mbaddr
,
it
->
second
->
mb_init_mbreg
,
1
);
ModbusRTU
::
DataBits
b
(
ret1
.
data
[
0
]);
it
->
second
->
mbval
=
b
[
0
]
?
1
:
0
;
it
->
second
->
sm_init
=
true
;
}
/*
// alone query for all register (if mb_init_mbreg ++ )
ModbusRTU::ReadInputStatusRetMessage ret1 = mb->read02(dev->mbaddr,p->mb_init_mbreg,p->q_count);
int m=0;
for( int i=0; i<ret1.bcnt; i++ )
{
ModbusRTU::DataBits b(ret1.data[i]);
for( int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ )
{
it->second->mbval = b[k] ? 1 : 0;
it->second->sm_init = true;
}
}
*/
p
->
sm_init
=
true
;
it
--
;
return
true
;
}
ModbusRTU
::
ForceCoilsMessage
msg
(
dev
->
mbaddr
,
p
->
mbreg
+
p
->
offset
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
msg
.
addBit
(
(
it
->
second
->
mbval
?
true
:
false
)
);
it
--
;
// cerr << "*********** (write multiple): " << msg << endl;
ModbusRTU
::
ForceCoilsRetMessage
ret
=
mb
->
write0F
(
msg
);
}
break
;
default
:
{
if
(
dlog
.
debugging
(
Debug
::
WARN
)
)
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE mfunc="
<<
(
int
)
p
->
mbfunc
<<
" ..."
<<
endl
;
return
false
;
}
break
;
}
return
true
;
}
// -----------------------------------------------------------------------------
bool
RTUExchange
::
RTUDevice
::
checkRespond
()
{
bool
prev
=
resp_state
;
...
...
@@ -500,1570 +298,65 @@ bool RTUExchange::RTUDevice::checkRespond()
return
(
prev
!=
resp_state
);
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
updateSM
(
)
void
RTUExchange
::
help_print
(
int
argc
,
const
char
*
const
*
argv
)
{
allNotRespond
=
true
;
for
(
RTUExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
if
(
dlog
.
debugging
(
Debug
::
LEVEL4
)
)
{
dlog
[
Debug
::
LEVEL4
]
<<
"check respond addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" respond_id="
<<
d
->
resp_id
<<
" real="
<<
d
->
resp_real
<<
" state="
<<
d
->
resp_state
<<
endl
;
}
if
(
d
->
resp_real
)
allNotRespond
=
false
;
// update respond sensors...
if
(
d
->
checkRespond
()
&&
d
->
resp_id
!=
DefaultObjectId
)
{
try
{
bool
set
=
d
->
resp_invert
?
!
d
->
resp_state
:
d
->
resp_state
;
shm
->
localSaveState
(
d
->
resp_dit
,
d
->
resp_id
,
set
,
getId
());
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(step): (respond) "
<<
ex
<<
std
::
endl
;
}
}
// cerr << "*********** allNotRespond=" << allNotRespond << endl;
// update values...
for
(
RTUExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
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
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): catch ..."
<<
endl
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
}
}
cout
<<
"Default: prefix='rs'"
<<
endl
;
MBExchange
::
help_print
(
argc
,
argv
);
// cout << " Настройки протокола RS: " << endl;
cout
<<
"--prefix-dev devname - файл устройства"
<<
endl
;
cout
<<
"--prefix-speed - Скорость обмена (9600,19920,38400,57600,115200)."
<<
endl
;
cout
<<
"--prefix-my-addr - адрес текущего узла"
<<
endl
;
cout
<<
"--prefix-recv-timeout - Таймаут на ожидание ответа."
<<
endl
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
processingMessage
(
UniSetTypes
::
VoidMessage
*
msg
)
RTUExchange
*
RTUExchange
::
init_rtuexchange
(
int
argc
,
const
char
*
const
*
argv
,
UniSetTypes
::
ObjectId
icID
,
SharedMemory
*
ic
,
const
std
::
string
prefix
)
{
try
{
switch
(
msg
->
type
)
{
case
UniSetTypes
:
:
Message
::
SysCommand
:
{
UniSetTypes
::
SystemMessage
sm
(
msg
);
sysCommand
(
&
sm
);
}
break
;
case
Message
:
:
Timer
:
string
name
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-name"
,
"RTUExchange1"
);
if
(
name
.
empty
()
)
{
TimerMessage
tm
(
msg
)
;
timerInfo
(
&
tm
)
;
cerr
<<
"(rtuexchange): Unknown 'name'. Use --"
<<
prefix
<<
"-name"
<<
endl
;
return
0
;
}
break
;
case
Message
:
:
SensorInfo
:
ObjectId
ID
=
conf
->
getObjectID
(
name
);
if
(
ID
==
UniSetTypes
::
DefaultObjectId
)
{
SensorMessage
sm
(
msg
);
sensorInfo
(
&
sm
);
cerr
<<
"(rtuexchange): Not found ID for '"
<<
name
<<
"'!"
<<
" in section <"
<<
conf
->
getObjectsSection
()
<<
">"
<<
endl
;
return
0
;
}
break
;
default
:
break
;
}
}
catch
(
SystemError
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(SystemError): "
<<
ex
<<
std
::
endl
;
// throw SystemError(ex);
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(processingMessage): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(processingMessage): catch ...
\n
"
;
}
dlog
[
Debug
::
INFO
]
<<
"(rtuexchange): name = "
<<
name
<<
"("
<<
ID
<<
")"
<<
endl
;
return
new
RTUExchange
(
ID
,
icID
,
ic
,
prefix
);
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
sysCommand
(
UniSetTypes
::
SystemMessage
*
sm
)
bool
RTUExchange
::
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
)
{
switch
(
sm
->
command
)
{
case
SystemMessage
:
:
StartUp
:
{
if
(
rmap
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(sysCommand): ************* rmap EMPTY! terminated... *************"
<<
endl
;
raise
(
SIGTERM
);
return
;
}
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(sysCommand): rmap size= "
<<
rmap
.
size
()
<<
endl
;
if
(
!
shm
->
isLocalwork
()
)
initDeviceList
();
waitSMReady
();
// подождать пока пройдёт инициализация датчиков
// см. activateObject()
msleep
(
initPause
);
PassiveTimer
ptAct
(
activateTimeout
);
while
(
!
activated
&&
!
ptAct
.
checkTime
()
)
{
cout
<<
myname
<<
"(sysCommand): wait activate..."
<<
endl
;
msleep
(
300
);
if
(
activated
)
break
;
}
if
(
!
activated
)
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(sysCommand): ************* don`t activate?! ************"
<<
endl
;
{
UniSetTypes
::
uniset_mutex_lock
l
(
mutex_start
,
10000
);
askSensors
(
UniversalIO
::
UIONotify
);
initOutput
();
}
// начальная инициализация
if
(
!
force
)
{
uniset_mutex_lock
l
(
pollMutex
,
2000
);
force
=
true
;
poll
();
force
=
false
;
}
askTimer
(
tmExchange
,
polltime
);
break
;
}
case
SystemMessage
:
:
FoldUp
:
case
SystemMessage
:
:
Finish
:
askSensors
(
UniversalIO
::
UIODontNotify
);
break
;
case
SystemMessage
:
:
WatchDog
:
{
// ОПТИМИЗАЦИЯ (защита от двойного перезаказа при старте)
// Если идёт локальная работа
// (т.е. RTUExchange запущен в одном процессе с SharedMemory2)
// то обрабатывать WatchDog не надо, т.к. мы и так ждём готовности SM
// при заказе датчиков, а если SM вылетит, то вместе с этим процессом(RTUExchange)
if
(
shm
->
isLocalwork
()
)
break
;
askSensors
(
UniversalIO
::
UIONotify
);
initOutput
();
if
(
!
MBExchange
::
initDeviceInfo
(
m
,
a
,
it
)
)
return
false
;
if
(
!
force
)
RTUDeviceMap
::
iterator
d
=
m
.
find
(
a
);
if
(
d
==
m
.
end
()
)
{
uniset_mutex_lock
l
(
pollMutex
,
2000
);
force
=
true
;
poll
();
force
=
false
;
}
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(initDeviceInfo): not found device for addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
endl
;
return
false
;
}
break
;
case
SystemMessage
:
:
LogRotate
:
{
// переоткрываем логи
unideb
<<
myname
<<
"(sysCommand): logRotate"
<<
std
::
endl
;
string
fname
=
unideb
.
getLogFile
();
if
(
!
fname
.
empty
()
)
string
s
=
it
.
getProp
(
"speed"
);
if
(
!
s
.
empty
()
)
{
unideb
.
logFile
(
fname
);
unideb
<<
myname
<<
"(sysCommand): ***************** UNIDEB LOG ROTATE *****************"
<<
std
::
endl
;
}
dlog
<<
myname
<<
"(sysCommand): logRotate"
<<
std
::
endl
;
fname
=
dlog
.
getLogFile
();
if
(
!
fname
.
empty
()
)
d
->
second
->
speed
=
ComPort
::
getSpeed
(
s
);
if
(
d
->
second
->
speed
==
ComPort
::
ComSpeed0
)
{
dlog
.
logFile
(
fname
);
dlog
<<
myname
<<
"(sysCommand): ***************** dlog LOG ROTATE *****************"
<<
std
::
endl
;
}
}
break
;
default
:
break
;
d
->
second
->
speed
=
defSpeed
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): Unknown speed="
<<
s
<<
" for addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
endl
;
return
false
;
}
}
// ------------------------------------------------------------------------------------------
void
RTUExchange
::
initOutput
()
{
}
// ------------------------------------------------------------------------------------------
void
RTUExchange
::
askSensors
(
UniversalIO
::
UIOCommand
cmd
)
{
if
(
!
shm
->
waitSMworking
(
test_id
,
activateTimeout
,
50
)
)
{
ostringstream
err
;
err
<<
myname
<<
"(askSensors): Не дождались готовности(work) SharedMemory к работе в течение "
<<
activateTimeout
<<
" мсек"
;
dlog
[
Debug
::
CRIT
]
<<
err
.
str
()
<<
endl
;
kill
(
SIGTERM
,
getpid
());
// прерываем (перезапускаем) процесс...
throw
SystemError
(
err
.
str
());
}
if
(
force_out
)
return
;
for
(
RTUExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
for
(
RTUExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
continue
;
for
(
PList
::
iterator
i
=
it
->
second
->
slst
.
begin
();
i
!=
it
->
second
->
slst
.
end
();
++
i
)
{
try
{
shm
->
askSensor
(
i
->
si
.
id
,
cmd
);
}
catch
(
UniSetTypes
::
Exception
&
ex
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): catch..."
<<
std
::
endl
;
}
}
}
}
}
// ------------------------------------------------------------------------------------------
void
RTUExchange
::
sensorInfo
(
UniSetTypes
::
SensorMessage
*
sm
)
{
if
(
force_out
)
return
;
MBExchange
::
sensorInfo
(
sm
);
for
(
RTUExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
for
(
RTUExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
continue
;
for
(
PList
::
iterator
i
=
it
->
second
->
slst
.
begin
();
i
!=
it
->
second
->
slst
.
end
();
++
i
)
{
if
(
sm
->
id
==
i
->
si
.
id
&&
sm
->
node
==
i
->
si
.
node
)
{
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
{
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(sensorInfo): si.id="
<<
sm
->
id
<<
" reg="
<<
ModbusRTU
::
dat2str
(
i
->
reg
->
mbreg
)
<<
" val="
<<
sm
->
value
<<
" mb_init="
<<
i
->
reg
->
mb_init
<<
endl
;
}
if
(
!
i
->
reg
->
mb_init
)
continue
;
i
->
value
=
sm
->
value
;
updateRSProperty
(
&
(
*
i
),
true
);
return
;
}
}
}
}
}
// ------------------------------------------------------------------------------------------
bool
RTUExchange
::
activateObject
()
{
// блокирование обработки Starsp
// пока не пройдёт инициализация датчиков
// см. sysCommand()
{
activated
=
false
;
UniSetTypes
::
uniset_mutex_lock
l
(
mutex_start
,
5000
);
UniSetObject_LT
::
activateObject
();
if
(
!
shm
->
isLocalwork
()
)
rtuQueryOptimization
(
rmap
);
initIterators
();
activated
=
true
;
}
return
true
;
}
// ------------------------------------------------------------------------------------------
void
RTUExchange
::
sigterm
(
int
signo
)
{
cerr
<<
myname
<<
": ********* SIGTERM("
<<
signo
<<
") ********"
<<
endl
;
MBExchange
::
sigterm
(
signo
);
}
// ------------------------------------------------------------------------------------------
RTUExchange
::
RTUDevice
*
RTUExchange
::
addDev
(
RTUDeviceMap
&
mp
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
xmlit
)
{
RTUDeviceMap
::
iterator
it
=
mp
.
find
(
a
);
if
(
it
!=
mp
.
end
()
)
{
DeviceType
dtype
=
getDeviceType
(
xmlit
.
getProp
(
"mbtype"
));
if
(
it
->
second
->
dtype
!=
dtype
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(addDev): OTHER mbtype="
<<
dtype
<<
" for "
<<
xmlit
.
getProp
(
"name"
)
<<
". Already used devtype="
<<
it
->
second
->
dtype
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
it
->
second
->
mbaddr
)
<<
endl
;
return
0
;
}
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(addDev): device for addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
" already added. Ignore device params for "
<<
xmlit
.
getProp
(
"name"
)
<<
" ..."
<<
endl
;
return
it
->
second
;
}
RTUExchange
::
RTUDevice
*
d
=
new
RTUExchange
::
RTUDevice
();
d
->
mbaddr
=
a
;
if
(
!
initRTUDevice
(
d
,
xmlit
)
)
{
delete
d
;
return
0
;
}
mp
.
insert
(
RTUDeviceMap
::
value_type
(
a
,
d
));
return
d
;
}
// ------------------------------------------------------------------------------------------
RTUExchange
::
RegInfo
*
RTUExchange
::
addReg
(
RegMap
&
mp
,
ModbusRTU
::
ModbusData
r
,
UniXML_iterator
&
xmlit
,
RTUExchange
::
RTUDevice
*
dev
,
RTUExchange
::
RegInfo
*
rcopy
)
{
RegMap
::
iterator
it
=
mp
.
find
(
r
);
if
(
it
!=
mp
.
end
()
)
{
if
(
!
it
->
second
->
dev
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(addReg): for reg="
<<
ModbusRTU
::
dat2str
(
r
)
<<
" dev=0!!!! "
<<
endl
;
return
0
;
}
if
(
it
->
second
->
dev
->
dtype
!=
dev
->
dtype
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(addReg): OTHER mbtype="
<<
dev
->
dtype
<<
" for reg="
<<
ModbusRTU
::
dat2str
(
r
)
<<
". Already used devtype="
<<
it
->
second
->
dev
->
dtype
<<
" for "
<<
it
->
second
->
dev
<<
endl
;
return
0
;
}
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
{
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(addReg): reg="
<<
ModbusRTU
::
dat2str
(
r
)
<<
" already added. Ignore register params for "
<<
xmlit
.
getProp
(
"name"
)
<<
" ..."
<<
endl
;
}
it
->
second
->
rit
=
it
;
return
it
->
second
;
}
RTUExchange
::
RegInfo
*
ri
;
if
(
rcopy
)
{
ri
=
new
RTUExchange
::
RegInfo
(
*
rcopy
);
ri
->
slst
.
clear
();
ri
->
mbreg
=
r
;
}
else
{
ri
=
new
RTUExchange
::
RegInfo
();
if
(
!
initRegInfo
(
ri
,
xmlit
,
dev
)
)
{
delete
ri
;
return
0
;
}
ri
->
mbreg
=
r
;
}
mp
.
insert
(
RegMap
::
value_type
(
r
,
ri
));
ri
->
rit
=
mp
.
find
(
r
);
return
ri
;
}
// ------------------------------------------------------------------------------------------
RTUExchange
::
RSProperty
*
RTUExchange
::
addProp
(
PList
&
plist
,
RSProperty
&
p
)
{
for
(
PList
::
iterator
it
=
plist
.
begin
();
it
!=
plist
.
end
();
++
it
)
{
if
(
it
->
si
.
id
==
p
.
si
.
id
&&
it
->
si
.
node
==
p
.
si
.
node
)
return
&
(
*
it
);
}
plist
.
push_back
(
p
);
PList
::
iterator
it
=
plist
.
end
();
it
--
;
return
&
(
*
it
);
}
// ------------------------------------------------------------------------------------------
bool
RTUExchange
::
initRSProperty
(
RSProperty
&
p
,
UniXML_iterator
&
it
)
{
if
(
!
IOBase
::
initItem
(
&
p
,
it
,
shm
,
&
dlog
,
myname
)
)
return
false
;
string
sbit
(
it
.
getProp
(
"nbit"
));
if
(
!
sbit
.
empty
()
)
{
p
.
nbit
=
UniSetTypes
::
uni_atoi
(
sbit
);
if
(
p
.
nbit
<
0
||
p
.
nbit
>=
ModbusRTU
::
BitsPerData
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRSProperty): BAD nbit="
<<
p
.
nbit
<<
". (0 >= nbit < "
<<
ModbusRTU
::
BitsPerData
<<
")."
<<
endl
;
return
false
;
}
}
if
(
p
.
nbit
>
0
&&
(
p
.
stype
==
UniversalIO
::
AnalogInput
||
p
.
stype
==
UniversalIO
::
AnalogOutput
)
)
{
dlog
[
Debug
::
WARN
]
<<
"(initRSProperty): (ignore) uncorrect param`s nbit>1 ("
<<
p
.
nbit
<<
")"
<<
" but iotype="
<<
p
.
stype
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
}
string
sbyte
(
it
.
getProp
(
"nbyte"
));
if
(
!
sbyte
.
empty
()
)
{
p
.
nbyte
=
UniSetTypes
::
uni_atoi
(
sbyte
);
if
(
p
.
nbyte
<
0
||
p
.
nbyte
>
VTypes
::
Byte
::
bsize
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRSProperty): BAD nbyte="
<<
p
.
nbyte
<<
". (0 >= nbyte < "
<<
VTypes
::
Byte
::
bsize
<<
")."
<<
endl
;
return
false
;
}
}
string
vt
(
it
.
getProp
(
"vtype"
));
if
(
vt
.
empty
()
)
{
p
.
rnum
=
VTypes
::
wsize
(
VTypes
::
vtUnknown
);
p
.
vType
=
VTypes
::
vtUnknown
;
}
else
{
VTypes
::
VType
v
(
VTypes
::
str2type
(
vt
));
if
(
v
==
VTypes
::
vtUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRSProperty): Unknown rtuVType="
<<
vt
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
p
.
vType
=
v
;
p
.
rnum
=
VTypes
::
wsize
(
v
);
}
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
RTUExchange
::
initRegInfo
(
RegInfo
*
r
,
UniXML_iterator
&
it
,
RTUExchange
::
RTUDevice
*
dev
)
{
r
->
dev
=
dev
;
r
->
mbval
=
it
.
getIntProp
(
"default"
);
r
->
offset
=
it
.
getIntProp
(
"mboffset"
);
r
->
mb_init
=
it
.
getIntProp
(
"mbinit"
);
if
(
dev
->
dtype
==
RTUExchange
::
dtMTR
)
{
// only for MTR
if
(
!
initMTRitem
(
it
,
r
)
)
return
false
;
}
else
if
(
dev
->
dtype
==
RTUExchange
::
dtRTU188
)
{
// only for RTU188
if
(
!
initRTU188item
(
it
,
r
)
)
return
false
;
}
else
if
(
dev
->
dtype
==
RTUExchange
::
dtRTU
)
{
}
else
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): Unknown mbtype='"
<<
dev
->
dtype
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
if
(
mbregFromID
)
r
->
mbreg
=
conf
->
getSensorID
(
it
.
getProp
(
"name"
));
else
if
(
dev
->
dtype
!=
RTUExchange
::
dtRTU188
)
{
string
reg
=
it
.
getProp
(
"mbreg"
);
if
(
reg
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): unknown mbreg for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
r
->
mbreg
=
ModbusRTU
::
str2mbData
(
reg
);
}
else
// if( dev->dtype == RTUExchange::dtRTU188 )
{
UniversalIO
::
IOTypes
stype
=
UniSetTypes
::
getIOType
(
it
.
getProp
(
"iotype"
));
r
->
mbreg
=
RTUStorage
::
getRegister
(
r
->
rtuJack
,
r
->
rtuChan
,
stype
);
if
(
r
->
mbreg
==
-
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): (RTU188) unknown mbreg for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
{
string
sr
=
it
.
getProp
(
"init_mbreg"
);
if
(
sr
==
"-1"
)
{
r
->
mb_init
=
true
;
// OFF mb_init
r
->
sm_init
=
true
;
}
else
if
(
sr
.
empty
()
)
r
->
mb_init_mbreg
=
r
->
mbreg
;
else
r
->
mb_init_mbreg
=
ModbusRTU
::
str2mbData
(
sr
);
}
r
->
mbfunc
=
ModbusRTU
::
fnUnknown
;
string
f
=
it
.
getProp
(
"mbfunc"
);
if
(
!
f
.
empty
()
)
{
r
->
mbfunc
=
(
ModbusRTU
::
SlaveFunctionCode
)
UniSetTypes
::
uni_atoi
(
f
);
if
(
r
->
mbfunc
==
ModbusRTU
::
fnUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): Unknown mbfunc ='"
<<
f
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
RTUExchange
::
initRTUDevice
(
RTUDevice
*
d
,
UniXML_iterator
&
it
)
{
d
->
dtype
=
getDeviceType
(
it
.
getProp
(
"mbtype"
));
if
(
d
->
dtype
==
dtUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRTUDevice): Unknown mbtype="
<<
it
.
getProp
(
"mbtype"
)
<<
". Use: rtu | mtr | rtu188"
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
string
addr
=
it
.
getProp
(
"mbaddr"
);
if
(
addr
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRTUDevice): Unknown mbaddr for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
d
->
speed
=
defSpeed
;
d
->
mbaddr
=
ModbusRTU
::
str2mbAddr
(
addr
);
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
RTUExchange
::
initItem
(
UniXML_iterator
&
it
)
{
RSProperty
p
;
if
(
!
initRSProperty
(
p
,
it
)
)
return
false
;
string
addr
=
it
.
getProp
(
"mbaddr"
);
if
(
addr
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): Unknown mbaddr='"
<<
addr
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
ModbusRTU
::
ModbusAddr
mbaddr
=
ModbusRTU
::
str2mbAddr
(
addr
);
RTUDevice
*
dev
=
addDev
(
rmap
,
mbaddr
,
it
);
if
(
!
dev
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): "
<<
it
.
getProp
(
"name"
)
<<
" CAN`T ADD for polling!"
<<
endl
;
return
false
;
}
ModbusRTU
::
ModbusData
mbreg
;
if
(
mbregFromID
)
mbreg
=
p
.
si
.
id
;
// conf->getSensorID(it.getProp("name"));
else
if
(
dev
->
dtype
!=
RTUExchange
::
dtRTU188
)
{
string
reg
=
it
.
getProp
(
"mbreg"
);
if
(
reg
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): unknown mbreg for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
mbreg
=
ModbusRTU
::
str2mbData
(
reg
);
}
else
// if( dev->dtype == RTUExchange::dtRTU188 )
{
RegInfo
rr
;
initRegInfo
(
&
rr
,
it
,
dev
);
mbreg
=
RTUStorage
::
getRegister
(
rr
.
rtuJack
,
rr
.
rtuChan
,
p
.
stype
);
if
(
mbreg
==
-
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): unknown mbreg for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
RegInfo
*
ri
=
addReg
(
dev
->
regmap
,
mbreg
,
it
,
dev
);
if
(
dev
->
dtype
==
dtMTR
)
{
p
.
rnum
=
MTR
::
wsize
(
ri
->
mtrType
);
if
(
p
.
rnum
<=
0
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): unknown word size for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
if
(
!
ri
)
return
false
;
ri
->
dev
=
dev
;
// п÷п═п·п▓п•п═п п░!
// п╣я│п╩п╦ я└я┐п╫п╨я├п╦я▐ п╫п╟ п╥п╟п©п╦я│я▄, я┌п╬ п╫п╟п╢п╬ п©я─п╬п╡п╣я─п╦я┌я▄
// я┤я┌п╬ п╬п╢п╦п╫ п╦ я┌п╬я┌п╤п╣ я─п╣пЁп╦я│я┌я─ п╫п╣ п©п╣я─п╣п╥п╟п©п╦я┬я┐я┌ п╫п╣я│п╨п╬п╩я▄п╨п╬ п╢п╟я┌я┤п╦п╨п╬п╡
// я█я┌п╬ п╡п╬п╥п╪п╬п╤п╫п╬ я┌п╬п╩я▄п╨п╬, п╣я│п╩п╦ п╬п╫п╦ п©п╦я┬я┐я┌ п╠п╦я┌я▀!!
// п≤п╒п·п⌠:
// п•я│п╩п╦ п╢п╩я▐ я└я┐п╫п╨я├п╦п╧ п╥п╟п©п╦я│п╦ я│п©п╦я│п╬п╨ п╢п╟я┌я┤п╦п╨п╬п╡ п╫п╟ п╬п╢п╦п╫ я─п╣пЁп╦я│я┌я─ > 1
// п╥п╫п╟я┤п╦я┌ п╡ я│п©п╦я│п╨п╣ п╪п╬пЁя┐я┌ п╠я▀я┌я▄ я┌п╬п╩я▄п╨п╬ п╠п╦я┌п╬п╡я▀п╣ п╢п╟я┌я┤п╦п╨п╦
// п╦ п╣я│п╩п╦ п╦п╢я▒я┌ п©п╬п©я▀я┌п╨п╟ п╡п╫п╣я│я┌п╦ п╡ я│п©п╦я│п╬п╨ п╫п╣ п╠п╦я┌п╬п╡я▀п╧ п╢п╟я┌я┤п╦п╨ я┌п╬ п·п╗п≤п▒п п░!
// п≤ п╫п╟п╬п╠п╬я─п╬я┌: п╣я│п╩п╦ п╦п╢я▒я┌ п©п╬п©я▀я┌п╨п╟ п╡п╫п╣я│я┌п╦ п╠п╦я┌п╬п╡я▀п╧ п╢п╟я┌я┤п╦п╨, п╟ п╡ я│п©п╦я│п╨п╣
// я┐п╤п╣ я│п╦п╢п╦я┌ п╢п╟я┌я┤п╦п╨ п╥п╟п╫п╦п╪п╟я▌я┴п╦п╧ я├п╣п╩я▀п╧ я─п╣пЁп╦я│я┌я─, я┌п╬ я┌п╬п╤п╣ п·п╗п≤п▒п п░!
if
(
ModbusRTU
::
isWriteFunction
(
ri
->
mbfunc
)
)
{
if
(
p
.
nbit
<
0
&&
ri
->
slst
.
size
()
>
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): FAILED! Sharing SAVE (not bit saving) to "
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
ri
->
mbreg
)
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
abort
();
// ABORT PROGRAM!!!!
return
false
;
}
if
(
p
.
nbit
>=
0
&&
ri
->
slst
.
size
()
==
1
)
{
PList
::
iterator
it2
=
ri
->
slst
.
begin
();
if
(
it2
->
nbit
<
0
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): FAILED! Sharing SAVE (mbreg="
<<
ModbusRTU
::
dat2str
(
ri
->
mbreg
)
<<
" already used)!"
<<
" IGNORE --> "
<<
it
.
getProp
(
"name"
)
<<
endl
;
abort
();
// ABORT PROGRAM!!!!
return
false
;
}
}
}
RSProperty
*
p1
=
addProp
(
ri
->
slst
,
p
);
if
(
!
p1
)
return
false
;
p1
->
reg
=
ri
;
if
(
p1
->
rnum
>
1
)
{
for
(
int
i
=
1
;
i
<
p1
->
rnum
;
i
++
)
{
RTUExchange
::
RegInfo
*
ri1
=
addReg
(
dev
->
regmap
,
mbreg
+
i
,
it
,
dev
,
ri
);
ri1
->
mb_init_mbreg
=
ri
->
mb_init_mbreg
+
i
;
}
}
if
(
dev
->
dtype
==
dtRTU188
)
{
if
(
!
dev
->
rtu
)
dev
->
rtu
=
new
RTUStorage
(
mbaddr
);
}
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
RTUExchange
::
initMTRitem
(
UniXML_iterator
&
it
,
RegInfo
*
p
)
{
p
->
mtrType
=
MTR
::
str2type
(
it
.
getProp
(
"mtrtype"
));
if
(
p
->
mtrType
==
MTR
::
mtUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readMTRItem): Unknown mtrtype '"
<<
it
.
getProp
(
"mtrtype"
)
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
RTUExchange
::
initRTU188item
(
UniXML_iterator
&
it
,
RegInfo
*
p
)
{
string
jack
=
it
.
getProp
(
"jack"
);
string
chan
=
it
.
getProp
(
"channel"
);
if
(
jack
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readRTU188Item): Unknown jack='' "
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
p
->
rtuJack
=
RTUStorage
::
s2j
(
jack
);
if
(
p
->
rtuJack
==
RTUStorage
::
nUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readRTU188Item): Unknown jack="
<<
jack
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
if
(
chan
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readRTU188Item): Unknown channel='' "
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
p
->
rtuChan
=
UniSetTypes
::
uni_atoi
(
chan
);
if
(
dlog
.
debugging
(
Debug
::
LEVEL2
)
)
dlog
[
Debug
::
LEVEL2
]
<<
myname
<<
"(readRTU188Item): "
<<
p
<<
endl
;
return
true
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
initIterators
()
{
MBExchange
::
initIterators
();
for
(
RTUExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
shm
->
initDIterator
(
d
->
resp_dit
);
for
(
RTUExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
for
(
PList
::
iterator
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
{
shm
->
initDIterator
(
it2
->
dit
);
shm
->
initAIterator
(
it2
->
ait
);
}
}
}
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
help_print
(
int
argc
,
const
char
*
const
*
argv
)
{
cout
<<
"Default: prefix='rs'"
<<
endl
;
MBExchange
::
help_print
(
argc
,
argv
);
// cout << " Настройки протокола RS: " << endl;
cout
<<
"--prefix-dev devname - файл устройства"
<<
endl
;
cout
<<
"--prefix-speed - Скорость обмена (9600,19920,38400,57600,115200)."
<<
endl
;
cout
<<
"--prefix-my-addr - адрес текущего узла"
<<
endl
;
cout
<<
"--prefix-recv-timeout - Таймаут на ожидание ответа."
<<
endl
;
}
// -----------------------------------------------------------------------------
RTUExchange
*
RTUExchange
::
init_rtuexchange
(
int
argc
,
const
char
*
const
*
argv
,
UniSetTypes
::
ObjectId
icID
,
SharedMemory
*
ic
,
const
std
::
string
prefix
)
{
string
name
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-name"
,
"RTUExchange1"
);
if
(
name
.
empty
()
)
{
cerr
<<
"(rtuexchange): Unknown 'name'. Use --"
<<
prefix
<<
"-name"
<<
endl
;
return
0
;
}
ObjectId
ID
=
conf
->
getObjectID
(
name
);
if
(
ID
==
UniSetTypes
::
DefaultObjectId
)
{
cerr
<<
"(rtuexchange): Not found ID for '"
<<
name
<<
"'!"
<<
" in section <"
<<
conf
->
getObjectsSection
()
<<
">"
<<
endl
;
return
0
;
}
dlog
[
Debug
::
INFO
]
<<
"(rtuexchange): name = "
<<
name
<<
"("
<<
ID
<<
")"
<<
endl
;
return
new
RTUExchange
(
ID
,
icID
,
ic
,
prefix
);
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
RTUExchange
::
RSProperty
&
p
)
{
os
<<
" ("
<<
ModbusRTU
::
dat2str
(
p
.
reg
->
mbreg
)
<<
")"
<<
" sid="
<<
p
.
si
.
id
<<
" stype="
<<
p
.
stype
<<
" nbit="
<<
p
.
nbit
<<
" nbyte="
<<
p
.
nbyte
<<
" rnum="
<<
p
.
rnum
<<
" safety="
<<
p
.
safety
<<
" invert="
<<
p
.
invert
;
if
(
p
.
stype
==
UniversalIO
::
AnalogInput
||
p
.
stype
==
UniversalIO
::
AnalogOutput
)
{
os
<<
p
.
cal
<<
" cdiagram="
<<
(
p
.
cdiagram
?
"yes"
:
"no"
);
}
return
os
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
initDeviceList
()
{
xmlNode
*
respNode
=
conf
->
findNode
(
cnode
,
"DeviceList"
);
if
(
respNode
)
{
UniXML_iterator
it1
(
respNode
);
if
(
it1
.
goChildren
()
)
{
for
(;
it1
.
getCurrent
();
it1
.
goNext
()
)
{
ModbusRTU
::
ModbusAddr
a
=
ModbusRTU
::
str2mbAddr
(
it1
.
getProp
(
"addr"
));
initDeviceInfo
(
rmap
,
a
,
it1
);
}
}
else
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(init): <DeviceList> empty section..."
<<
endl
;
}
else
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(init): <DeviceList> not found..."
<<
endl
;
}
// -----------------------------------------------------------------------------
bool
RTUExchange
::
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
)
{
RTUDeviceMap
::
iterator
d
=
m
.
find
(
a
);
if
(
d
==
m
.
end
()
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(initDeviceInfo): not found device for addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
endl
;
return
false
;
}
if
(
!
it
.
getProp
(
"respondSensor"
).
empty
()
)
{
d
->
second
->
resp_id
=
conf
->
getSensorID
(
it
.
getProp
(
"respondSensor"
));
if
(
d
->
second
->
resp_id
==
DefaultObjectId
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): not found ID for noRespondSensor="
<<
it
.
getProp
(
"respondSensor"
)
<<
endl
;
return
false
;
}
}
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(initDeviceInfo): add addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
endl
;
int
tout
=
it
.
getPIntProp
(
"timeout"
,
UniSetTimer
::
WaitUpTime
);
d
->
second
->
resp_ptTimeout
.
setTiming
(
tout
);
d
->
second
->
resp_invert
=
it
.
getIntProp
(
"invert"
);
string
s
=
it
.
getProp
(
"speed"
);
if
(
!
s
.
empty
()
)
{
d
->
second
->
speed
=
ComPort
::
getSpeed
(
s
);
if
(
d
->
second
->
speed
==
ComPort
::
ComSpeed0
)
{
d
->
second
->
speed
=
defSpeed
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): Unknown speed="
<<
s
<<
" for addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
endl
;
return
false
;
}
}
return
true
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
printMap
(
RTUExchange
::
RTUDeviceMap
&
m
)
{
cout
<<
"devices: num="
<<
m
.
size
()
<<
endl
;
for
(
RTUExchange
::
RTUDeviceMap
::
iterator
it
=
m
.
begin
();
it
!=
m
.
end
();
++
it
)
{
cout
<<
" "
<<
*
(
it
->
second
)
<<
endl
;
}
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUExchange
::
RTUDeviceMap
&
m
)
{
os
<<
"devices: "
<<
endl
;
for
(
RTUExchange
::
RTUDeviceMap
::
iterator
it
=
m
.
begin
();
it
!=
m
.
end
();
++
it
)
{
os
<<
" "
<<
*
(
it
->
second
)
<<
endl
;
}
return
os
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUExchange
::
RTUDevice
&
d
)
{
os
<<
"addr="
<<
ModbusRTU
::
addr2str
(
d
.
mbaddr
)
<<
" type="
<<
d
.
dtype
;
os
<<
" rtu="
<<
(
d
.
rtu
?
"yes"
:
"no"
);
os
<<
" respond_id="
<<
d
.
resp_id
<<
" respond_timeout="
<<
d
.
resp_ptTimeout
.
getInterval
()
<<
" respond_state="
<<
d
.
resp_state
<<
" respond_invert="
<<
d
.
resp_invert
<<
endl
;
os
<<
" regs: "
<<
endl
;
for
(
RTUExchange
::
RegMap
::
iterator
it
=
d
.
regmap
.
begin
();
it
!=
d
.
regmap
.
end
();
++
it
)
os
<<
" "
<<
*
(
it
->
second
)
<<
endl
;
return
os
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUExchange
::
RegInfo
&
r
)
{
os
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
r
.
mbreg
)
<<
" mbfunc="
<<
r
.
mbfunc
<<
" mtrType="
<<
MTR
::
type2str
(
r
.
mtrType
)
<<
" jack="
<<
RTUStorage
::
j2s
(
r
.
rtuJack
)
<<
" chan="
<<
r
.
rtuChan
<<
" q_num="
<<
r
.
q_num
<<
" q_count="
<<
r
.
q_count
<<
" value="
<<
ModbusRTU
::
dat2str
(
r
.
mbval
)
<<
"("
<<
(
int
)
r
.
mbval
<<
")"
<<
endl
;
for
(
RTUExchange
::
PList
::
iterator
it
=
r
.
slst
.
begin
();
it
!=
r
.
slst
.
end
();
++
it
)
os
<<
" "
<<
(
*
it
)
<<
endl
;
return
os
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
rtuQueryOptimization
(
RTUDeviceMap
&
m
)
{
if
(
noQueryOptimization
)
return
;
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(rtuQueryOptimization): optimization..."
<<
endl
;
for
(
RTUExchange
::
RTUDeviceMap
::
iterator
it1
=
m
.
begin
();
it1
!=
m
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
for
(
RTUExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
RTUExchange
::
RegMap
::
iterator
beg
=
it
;
ModbusRTU
::
ModbusData
reg
=
it
->
second
->
mbreg
+
it
->
second
->
offset
;
beg
->
second
->
q_num
=
1
;
beg
->
second
->
q_count
=
1
;
it
++
;
for
(
;
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
(
it
->
second
->
mbreg
+
it
->
second
->
offset
-
reg
)
>
1
)
break
;
if
(
beg
->
second
->
mbfunc
!=
it
->
second
->
mbfunc
)
break
;
beg
->
second
->
q_count
++
;
if
(
beg
->
second
->
q_count
>=
ModbusRTU
::
MAXDATALEN
)
break
;
reg
=
it
->
second
->
mbreg
+
it
->
second
->
offset
;
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
)
{
dlog
[
Debug
::
WARN
]
<<
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
)
{
dlog
[
Debug
::
WARN
]
<<
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
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
it
--
;
}
}
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
updateRTU
(
RegMap
::
iterator
&
rit
)
{
RegInfo
*
r
(
rit
->
second
);
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
updateRSProperty
(
&
(
*
it
),
false
);
if
(
r
->
sm_init
)
r
->
mb_init
=
true
;
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
updateRSProperty
(
RSProperty
*
p
,
bool
write_only
)
{
using
namespace
ModbusRTU
;
RegInfo
*
r
(
p
->
reg
->
rit
->
second
);
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
if
(
!
save
&&
write_only
)
return
;
if
(
!
checkUpdateSM
(
save
)
)
return
;
try
{
if
(
p
->
vType
==
VTypes
::
vtUnknown
)
{
ModbusRTU
::
DataBits16
b
(
r
->
mbval
);
if
(
p
->
nbit
>=
0
)
{
if
(
save
&&
r
->
mb_init
)
{
bool
set
=
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
b
.
set
(
p
->
nbit
,
set
);
r
->
mbval
=
b
.
mdata
();
}
else
{
bool
set
=
b
[
p
->
nbit
];
IOBase
::
processingAsDI
(
p
,
set
,
shm
,
force
);
}
return
;
}
if
(
p
->
rnum
<=
1
)
{
if
(
save
&&
r
->
mb_init
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
r
->
mbval
=
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
}
else
r
->
mbval
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
}
else
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
r
->
mbval
,
shm
,
force
);
}
else
IOBase
::
processingAsAI
(
p
,
(
signed
short
)
r
->
mbval
,
shm
,
force
);
}
return
;
}
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(updateRSProperty): IGNORE item: rnum="
<<
p
->
rnum
<<
" > 1 ?!! for id="
<<
p
->
si
.
id
<<
endl
;
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtSigned
)
{
if
(
save
&&
r
->
mb_init
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
r
->
mbval
=
(
signed
short
)
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
}
else
r
->
mbval
=
(
signed
short
)
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
}
else
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
r
->
mbval
,
shm
,
force
);
}
else
{
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
r
->
mbval
),
shm
,
force
);
}
}
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtUnsigned
)
{
if
(
save
&&
r
->
mb_init
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
r
->
mbval
=
(
unsigned
short
)
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
}
else
r
->
mbval
=
(
unsigned
short
)
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
}
else
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
r
->
mbval
,
shm
,
force
);
}
else
{
IOBase
::
processingAsAI
(
p
,
(
unsigned
short
)
r
->
mbval
,
shm
,
force
);
}
}
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtByte
)
{
if
(
p
->
nbyte
<=
0
||
p
->
nbyte
>
VTypes
::
Byte
::
bsize
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(updateRSProperty): IGNORE item: reg="
<<
ModbusRTU
::
dat2str
(
r
->
mbreg
)
<<
" vtype="
<<
p
->
vType
<<
" but nbyte="
<<
p
->
nbyte
<<
endl
;
return
;
}
if
(
save
&&
r
->
mb_init
)
{
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
VTypes
::
Byte
b
(
r
->
mbval
);
b
.
raw
.
b
[
p
->
nbyte
-
1
]
=
v
;
r
->
mbval
=
b
.
raw
.
w
;
}
else
{
VTypes
::
Byte
b
(
r
->
mbval
);
IOBase
::
processingAsAI
(
p
,
b
.
raw
.
b
[
p
->
nbyte
-
1
],
shm
,
force
);
}
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtF2
)
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
&&
r
->
mb_init
)
{
float
f
=
IOBase
::
processingFasAO
(
p
,
shm
,
force_out
);
VTypes
::
F2
f2
(
f
);
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f2
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
VTypes
::
F2
::
wsize
()];
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
VTypes
::
F2
f
(
data
,
VTypes
::
F2
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
}
else
if
(
p
->
vType
==
VTypes
::
vtF4
)
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
&&
r
->
mb_init
)
{
float
f
=
IOBase
::
processingFasAO
(
p
,
shm
,
force_out
);
VTypes
::
F4
f4
(
f
);
for
(
int
k
=
0
;
k
<
VTypes
::
F4
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f4
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
VTypes
::
F4
::
wsize
()];
for
(
int
k
=
0
;
k
<
VTypes
::
F4
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
VTypes
::
F4
f
(
data
,
VTypes
::
F4
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): catch ..."
<<
endl
;
}
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
updateMTR
(
RegMap
::
iterator
&
rit
)
{
RegInfo
*
r
(
rit
->
second
);
using
namespace
ModbusRTU
;
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
{
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
{
try
{
if
(
r
->
mtrType
==
MTR
::
mtT1
)
{
if
(
save
)
r
->
mbval
=
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
);
else
{
MTR
::
T1
t
(
r
->
mbval
);
IOBase
::
processingAsAI
(
&
(
*
it
),
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT2
)
{
if
(
save
)
{
MTR
::
T2
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
r
->
mbval
=
t
.
val
;
}
else
{
MTR
::
T2
t
(
r
->
mbval
);
IOBase
::
processingAsAI
(
&
(
*
it
),
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT3
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T3
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T3
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T3
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T3
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T3
t
(
data
,
MTR
::
T3
::
wsize
());
delete
[]
data
;
IOBase
::
processingAsAI
(
&
(
*
it
),
(
long
)
t
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT4
)
{
if
(
save
)
cerr
<<
myname
<<
"(updateMTR): write (T4) reg("
<<
dat2str
(
r
->
mbreg
)
<<
") to MTR NOT YET!!!"
<<
endl
;
else
{
MTR
::
T4
t
(
r
->
mbval
);
IOBase
::
processingAsAI
(
&
(
*
it
),
uni_atoi
(
t
.
sval
),
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT5
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T5
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T5
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T5
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T5
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T5
t
(
data
,
MTR
::
T5
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT6
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T6
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T6
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T6
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T6
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T6
t
(
data
,
MTR
::
T6
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT7
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T7
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T7
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T7
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T7
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T7
t
(
data
,
MTR
::
T7
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT16
)
{
if
(
save
)
{
MTR
::
T16
t
(
IOBase
::
processingFasAO
(
&
(
*
it
),
shm
,
force_out
));
r
->
mbval
=
t
.
val
;
}
else
{
MTR
::
T16
t
(
r
->
mbval
);
IOBase
::
processingFasAI
(
&
(
*
it
),
t
.
fval
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT17
)
{
if
(
save
)
{
MTR
::
T17
t
(
IOBase
::
processingFasAO
(
&
(
*
it
),
shm
,
force_out
));
r
->
mbval
=
t
.
val
;
}
else
{
MTR
::
T17
t
(
r
->
mbval
);
IOBase
::
processingFasAI
(
&
(
*
it
),
t
.
fval
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtF1
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
float
f
=
IOBase
::
processingFasAO
(
&
(
*
it
),
shm
,
force_out
);
MTR
::
F1
f1
(
f
);
for
(
int
k
=
0
;
k
<
MTR
::
F1
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f1
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
F1
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
F1
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
F1
t
(
data
,
MTR
::
F1
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
,
shm
,
force
);
}
continue
;
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): catch ..."
<<
endl
;
}
}
}
}
// -----------------------------------------------------------------------------
void
RTUExchange
::
updateRTU188
(
RegMap
::
iterator
&
it
)
{
RegInfo
*
r
(
it
->
second
);
if
(
!
r
->
dev
->
rtu
)
return
;
using
namespace
ModbusRTU
;
// bool save = false;
if
(
isWriteFunction
(
r
->
mbfunc
)
)
{
// save = true;
cerr
<<
myname
<<
"(updateRTU188): write reg("
<<
dat2str
(
r
->
mbreg
)
<<
") to RTU188 NOT YET!!!"
<<
endl
;
return
;
}
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
{
try
{
if
(
it
->
stype
==
UniversalIO
::
DigitalInput
)
{
bool
set
=
r
->
dev
->
rtu
->
getState
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsDI
(
&
(
*
it
),
set
,
shm
,
force
);
continue
;
}
if
(
it
->
stype
==
UniversalIO
::
AnalogInput
)
{
long
val
=
r
->
dev
->
rtu
->
getInt
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsAI
(
&
(
*
it
),
val
,
shm
,
force
);
continue
;
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188): catch ..."
<<
endl
;
}
}
}
// -----------------------------------------------------------------------------
//std::ostream& operator<<( std::ostream& os, MBTCPMaster::PList& lst )
std
::
ostream
&
RTUExchange
::
print_plist
(
std
::
ostream
&
os
,
RTUExchange
::
PList
&
lst
)
{
os
<<
"[ "
;
for
(
RTUExchange
::
PList
::
const_iterator
it
=
lst
.
begin
();
it
!=
lst
.
end
();
++
it
)
os
<<
"("
<<
it
->
si
.
id
<<
")"
<<
conf
->
oind
->
getBaseName
(
conf
->
oind
->
getMapName
(
it
->
si
.
id
))
<<
" "
;
os
<<
"]"
;
return
os
;
}
// -----------------------------------------------------------------------------
extensions/RTUExchange/RTUExchange.h
View file @
902e3a76
...
...
@@ -25,131 +25,8 @@ class RTUExchange:
/*! глобальная функция для вывода help-а */
static
void
help_print
(
int
argc
,
const
char
*
const
*
argv
);
enum
Timer
{
tmExchange
};
// --------------------------------------------------------
struct
RTUDevice
;
struct
RegInfo
;
struct
RSProperty
:
public
IOBase
{
// only for RTU
short
nbit
;
/*!< bit number) */
VTypes
::
VType
vType
;
/*!< type of value */
short
rnum
;
/*!< count of registers */
short
nbyte
;
/*!< byte number (1-2) */
RSProperty
()
:
nbit
(
-
1
),
vType
(
VTypes
::
vtUnknown
),
rnum
(
VTypes
::
wsize
(
VTypes
::
vtUnknown
)),
nbyte
(
0
),
reg
(
0
)
{}
RegInfo
*
reg
;
};
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
RSProperty
&
p
);
typedef
std
::
list
<
RSProperty
>
PList
;
static
std
::
ostream
&
print_plist
(
std
::
ostream
&
os
,
PList
&
p
);
typedef
std
::
map
<
ModbusRTU
::
ModbusData
,
RegInfo
*>
RegMap
;
struct
RegInfo
{
RegInfo
()
:
mbval
(
0
),
mbreg
(
0
),
mbfunc
(
ModbusRTU
::
fnUnknown
),
mtrType
(
MTR
::
mtUnknown
),
rtuJack
(
RTUStorage
::
nUnknown
),
rtuChan
(
0
),
dev
(
0
),
offset
(
0
),
q_num
(
0
),
q_count
(
1
),
mb_init
(
false
),
sm_init
(
false
),
mb_init_mbreg
(
0
)
{}
ModbusRTU
::
ModbusData
mbval
;
ModbusRTU
::
ModbusData
mbreg
;
/*!< регистр */
ModbusRTU
::
SlaveFunctionCode
mbfunc
;
/*!< функция для чтения/записи */
PList
slst
;
// only for MTR
MTR
::
MTRType
mtrType
;
/*!< тип регистра (согласно спецификации на MTR) */
// only for RTU188
RTUStorage
::
RTUJack
rtuJack
;
int
rtuChan
;
RTUDevice
*
dev
;
int
offset
;
// optimization
int
q_num
;
/*! number in query */
int
q_count
;
/*! count registers for query */
RegMap
::
iterator
rit
;
bool
mb_init
;
/*!< init before use */
bool
sm_init
;
/*!< SM init value */
ModbusRTU
::
ModbusData
mb_init_mbreg
;
/*!< mb_init register */
};
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RegInfo
&
r
);
struct
RTUDevice
{
RTUDevice
()
:
speed
(
ComPort
::
ComSpeed38400
),
respnond
(
false
),
mbaddr
(
0
),
dtype
(
dtUnknown
),
resp_id
(
UniSetTypes
::
DefaultObjectId
),
resp_state
(
false
),
resp_invert
(
false
),
resp_real
(
false
),
resp_init
(
false
),
rtu
(
0
)
{
resp_trTimeout
.
change
(
false
);
}
ComPort
::
Speed
speed
;
bool
respnond
;
ModbusRTU
::
ModbusAddr
mbaddr
;
/*!< адрес устройства */
RegMap
regmap
;
DeviceType
dtype
;
/*!< тип устройства */
UniSetTypes
::
ObjectId
resp_id
;
IOController
::
DIOStateList
::
iterator
resp_dit
;
PassiveTimer
resp_ptTimeout
;
Trigger
resp_trTimeout
;
bool
resp_state
;
bool
resp_invert
;
bool
resp_real
;
bool
resp_init
;
RTUStorage
*
rtu
;
// return TRUE if state changed
bool
checkRespond
();
};
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUDevice
&
d
);
typedef
std
::
map
<
ModbusRTU
::
ModbusAddr
,
RTUDevice
*>
RTUDeviceMap
;
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUDeviceMap
&
d
);
void
printMap
(
RTUDeviceMap
&
d
);
// ----------------------------------
protected
:
RTUDeviceMap
rmap
;
ModbusRTUMaster
*
mb
;
ModbusRTUMaster
*
mbrtu
;
UniSetTypes
::
uniset_mutex
mbMutex
;
std
::
string
devname
;
ComPort
::
Speed
defSpeed
;
...
...
@@ -159,45 +36,9 @@ class RTUExchange:
virtual
void
step
();
void
poll
();
bool
pollRTU
(
RTUDevice
*
dev
,
RegMap
::
iterator
&
it
);
void
updateSM
();
void
updateRTU
(
RegMap
::
iterator
&
it
);
void
updateMTR
(
RegMap
::
iterator
&
it
);
void
updateRTU188
(
RegMap
::
iterator
&
it
);
void
updateRSProperty
(
RSProperty
*
p
,
bool
write_only
=
false
);
virtual
void
processingMessage
(
UniSetTypes
::
VoidMessage
*
msg
);
virtual
void
sysCommand
(
UniSetTypes
::
SystemMessage
*
msg
);
virtual
void
sensorInfo
(
UniSetTypes
::
SensorMessage
*
sm
);
void
timerInfo
(
UniSetTypes
::
TimerMessage
*
tm
);
void
askSensors
(
UniversalIO
::
UIOCommand
cmd
);
void
initOutput
();
virtual
bool
activateObject
();
// действия при завершении работы
virtual
void
sigterm
(
int
signo
);
void
initMB
(
bool
reopen
=
false
);
virtual
void
initIterators
();
bool
initItem
(
UniXML_iterator
&
it
);
void
initDeviceList
();
void
initOffsetList
();
RTUDevice
*
addDev
(
RTUDeviceMap
&
dmap
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
);
RegInfo
*
addReg
(
RegMap
&
rmap
,
ModbusRTU
::
ModbusData
r
,
UniXML_iterator
&
it
,
RTUDevice
*
dev
,
RegInfo
*
rcopy
=
0
);
RSProperty
*
addProp
(
PList
&
plist
,
RSProperty
&
p
);
bool
initMTRitem
(
UniXML_iterator
&
it
,
RegInfo
*
p
);
bool
initRTU188item
(
UniXML_iterator
&
it
,
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
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
);
void
rtuQueryOptimization
(
RTUDeviceMap
&
m
);
virtual
ModbusClient
*
initMB
(
bool
reopen
=
false
);
virtual
bool
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
);
private
:
RTUExchange
();
...
...
extensions/include/MBExchange.h
0 → 120000
View file @
902e3a76
..
/
ModbusMaster
/
MBExchange
.
h
\ No newline at end of file
extensions/lib/Makefile.am
View file @
902e3a76
...
...
@@ -6,6 +6,6 @@ libUniSetExtensions_la_LDFLAGS = -version-info $(UEXT_VER)
libUniSetExtensions_la_CPPFLAGS
=
$(SIGC_CFLAGS)
-I
$(top_builddir)
/extensions/include
libUniSetExtensions_la_LIBADD
=
$(SIGC_LIBS)
$(top_builddir)
/lib/libUniSet.la
libUniSetExtensions_la_SOURCES
=
Extensions.cc SMInterface.cc Calibration.cc SingleProcess.cc
\
IOBase.cc DigitalFilter.cc PID.cc MTR.cc VTypes.cc
MBExchange.cc
IOBase.cc DigitalFilter.cc PID.cc MTR.cc VTypes.cc
#UObject_SK.cc
\ No newline at end of file
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