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
73db415f
Commit
73db415f
authored
Oct 10, 2011
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(modbus): Добился компиляции. Приступил к реализации обработки функции 0x08.
parent
f475a091
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
182 additions
and
160 deletions
+182
-160
mbrtutester.cc
Utilities/MBTester/mbrtutester.cc
+44
-2
ModbusClient.h
include/modbus/ModbusClient.h
+4
-0
ModbusRTUSlaveSlot.h
include/modbus/ModbusRTUSlaveSlot.h
+3
-0
ModbusServer.h
include/modbus/ModbusServer.h
+9
-0
ModbusServerSlot.h
include/modbus/ModbusServerSlot.h
+9
-1
ModbusTCPServerSlot.h
include/modbus/ModbusTCPServerSlot.h
+3
-0
ModbusTypes.h
include/modbus/ModbusTypes.h
+15
-34
ModbusClient.cc
src/Communications/Modbus/ModbusClient.cc
+14
-0
ModbusRTUSlaveSlot.cc
src/Communications/Modbus/ModbusRTUSlaveSlot.cc
+9
-0
ModbusServerSlot.cc
src/Communications/Modbus/ModbusServerSlot.cc
+5
-0
ModbusTCPServerSlot.cc
src/Communications/Modbus/ModbusTCPServerSlot.cc
+9
-0
ModbusTypes.cc
src/Communications/Modbus/ModbusTypes.cc
+58
-123
No files found.
Utilities/MBTester/mbrtutester.cc
View file @
73db415f
...
...
@@ -19,6 +19,7 @@ static struct option longopts[] = {
{
"write06"
,
required_argument
,
0
,
'z'
},
{
"write0F"
,
required_argument
,
0
,
'm'
},
{
"write10"
,
required_argument
,
0
,
'w'
},
{
"diag08"
,
required_argument
,
0
,
'o'
},
// { "readfile14", required_argument, 0, 'g' },
// { "writefile15", required_argument, 0, 'p' },
{
"filetransfer66"
,
required_argument
,
0
,
'u'
},
...
...
@@ -45,6 +46,7 @@ static void print_help()
printf
(
"[--read02] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1
\n
"
);
printf
(
"[--read03] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1
\n
"
);
printf
(
"[--read04] slaveaddr reg count - read from reg (from slaveaddr). Default: count=1
\n
"
);
printf
(
"[--diag08] slaveaddr subfunc - diagnostics request
\n
"
);
// printf("[--readfile14] slaveaddr fileID - read file from slaveaddr).\n");
// printf("[--writefile15] slaveaddr id filename - write file to slaveaddr).\n");
printf
(
"[--filetransfer66] slaveaddr fileID [filename] - get file from slaveaddr. Default save to 'fileID.transfer'
\n
"
);
...
...
@@ -81,7 +83,8 @@ enum Command
cmdDetectSlave
,
cmdReadFile
,
cmdWriteFile
,
cmdFileTransfer
cmdFileTransfer
,
cmdDiag
};
// --------------------------------------------------------------------------
static
char
*
checkArg
(
int
ind
,
int
argc
,
char
*
argv
[]
);
...
...
@@ -103,6 +106,7 @@ int main( int argc, char **argv )
ModbusRTU
::
SlaveFunctionCode
fn
=
ModbusRTU
::
fnReadInputRegisters
;
ModbusRTU
::
ModbusAddr
beg
=
0
;
ModbusRTU
::
ModbusAddr
end
=
255
;
ModbusRTU
::
DiagnosticsSubFunction
subfunc
=
ModbusRTU
::
subEcho
;
int
tout
=
2000
;
DebugStream
dlog
;
string
tofile
(
""
);
...
...
@@ -111,7 +115,7 @@ int main( int argc, char **argv )
try
{
while
(
(
opt
=
getopt_long
(
argc
,
argv
,
"hva:w:z:m:r:x:c:b:d:s:t:qn:u:yl:t:"
,
longopts
,
&
optindex
))
!=
-
1
)
while
(
(
opt
=
getopt_long
(
argc
,
argv
,
"hva:w:z:m:r:x:c:b:d:s:t:qn:u:yl:t:
o:
"
,
longopts
,
&
optindex
))
!=
-
1
)
{
switch
(
opt
)
{
...
...
@@ -146,6 +150,20 @@ int main( int argc, char **argv )
count
=
uni_atoi
(
argv
[
optind
+
1
]);
break
;
case
'o'
:
cmd
=
cmdDiag
;
slaveaddr
=
ModbusRTU
::
str2mbAddr
(
optarg
);
if
(
!
checkArg
(
optind
,
argc
,
argv
)
)
{
cerr
<<
"diagnostic command error: bad or no arguments..."
<<
endl
;
return
1
;
}
else
subfunc
=
(
ModbusRTU
::
DiagnosticsSubFunction
)
uni_atoi
(
argv
[
optind
]);
break
;
case
'f'
:
cmd
=
cmdWrite05
;
case
'z'
:
...
...
@@ -508,7 +526,31 @@ int main( int argc, char **argv )
cout
<<
"(reply): "
<<
ret
<<
endl
;
}
break
;
case
cmdDiag
:
{
if
(
verb
)
{
cout
<<
"diag08: slaveaddr="
<<
ModbusRTU
::
addr2str
(
slaveaddr
)
<<
" subfunc="
<<
ModbusRTU
::
dat2str
(
subfunc
)
<<
"("
<<
(
int
)
subfunc
<<
")"
<<
endl
;
}
ModbusRTU
::
DiagnosticRetMessage
ret
=
mb
.
diag08
(
slaveaddr
,
subfunc
);
if
(
verb
)
cout
<<
"(reply): "
<<
ret
<<
endl
;
cout
<<
"(reply): count="
<<
ModbusRTU
::
dat2str
(
ret
.
count
)
<<
endl
;
for
(
int
i
=
0
;
i
<
ret
.
count
;
i
++
)
{
cout
<<
i
<<
": ("
<<
ModbusRTU
::
dat2str
(
reg
+
i
)
<<
") = "
<<
(
int
)(
ret
.
data
[
i
])
<<
" ("
<<
ModbusRTU
::
dat2str
(
ret
.
data
[
i
])
<<
")"
<<
endl
;
}
}
break
;
case
cmdDetectSlave
:
{
if
(
verb
)
...
...
include/modbus/ModbusClient.h
View file @
73db415f
...
...
@@ -82,6 +82,10 @@ class ModbusClient
ModbusRTU
::
WriteOutputRetMessage
write10
(
ModbusRTU
::
WriteOutputMessage
&
msg
)
throw
(
ModbusRTU
::
mbException
);
/*! Диагностика (0x08) */
ModbusRTU
::
DiagnosticRetMessage
diag08
(
ModbusRTU
::
ModbusAddr
addr
,
ModbusRTU
::
DiagnosticsSubFunction
subfunc
)
throw
(
ModbusRTU
::
mbException
);
/*! Установить системное время (0x50)
hour - часы [0..23]
...
...
include/modbus/ModbusRTUSlaveSlot.h
View file @
73db415f
...
...
@@ -50,6 +50,9 @@ class ModbusRTUSlaveSlot:
virtual
ModbusRTU
::
mbErrCode
writeOutputRegisters
(
ModbusRTU
::
WriteOutputMessage
&
query
,
ModbusRTU
::
WriteOutputRetMessage
&
reply
);
virtual
ModbusRTU
::
mbErrCode
diagnostics
(
ModbusRTU
::
DiagnosticMessage
&
query
,
ModbusRTU
::
DiagnosticRetMessage
&
reply
);
virtual
ModbusRTU
::
mbErrCode
journalCommand
(
ModbusRTU
::
JournalCommandMessage
&
query
,
ModbusRTU
::
JournalCommandRetMessage
&
reply
);
...
...
include/modbus/ModbusServer.h
View file @
73db415f
...
...
@@ -141,7 +141,16 @@ class ModbusServer
virtual
ModbusRTU
::
mbErrCode
writeOutputRegisters
(
ModbusRTU
::
WriteOutputMessage
&
query
,
ModbusRTU
::
WriteOutputRetMessage
&
reply
)
=
0
;
/*! Обработка запроса на запись данных (0x08).
\param query - запрос
\param reply - ответ. Заполняется в обработчике.
\return Результат обработки
*/
virtual
ModbusRTU
::
mbErrCode
diagnostics
(
ModbusRTU
::
DiagnosticMessage
&
query
,
ModbusRTU
::
DiagnosticRetMessage
&
reply
)
=
0
;
/*! Обработка запроса по журналу (0x65)
\param query - запрос
\param reply - ответ. Заполняется в обработчике.
...
...
include/modbus/ModbusServerSlot.h
View file @
73db415f
...
...
@@ -44,7 +44,11 @@ class ModbusServerSlot
typedef
sigc
::
slot
<
ModbusRTU
::
mbErrCode
,
ModbusRTU
::
WriteOutputMessage
&
,
ModbusRTU
::
WriteOutputRetMessage
&>
WriteOutputSlot
;
typedef
sigc
::
slot
<
ModbusRTU
::
mbErrCode
,
ModbusRTU
::
DiagnosticMessage
&
,
ModbusRTU
::
DiagnosticRetMessage
&>
DiagnosticsSlot
;
typedef
sigc
::
slot
<
ModbusRTU
::
mbErrCode
,
ModbusRTU
::
JournalCommandMessage
&
,
ModbusRTU
::
JournalCommandRetMessage
&>
JournalCommandSlot
;
...
...
@@ -79,6 +83,9 @@ class ModbusServerSlot
/*! подключение обработчика 'записи данных' 0x06 */
void
connectWriteSingleOutput
(
WriteSingleOutputSlot
sl
);
/*! подключение обработчика 'записи данных' 0x08 */
void
connectDiagnostics
(
DiagnosticsSlot
sl
);
/*! подключение обработчика 'записи данных' 0x0F */
void
connectForceCoils
(
ForceCoilsSlot
sl
);
...
...
@@ -108,6 +115,7 @@ class ModbusServerSlot
WriteOutputSlot
slWriteOutputs
;
ForceSingleCoilSlot
slForceSingleCoil
;
WriteSingleOutputSlot
slWriteSingleOutputs
;
DiagnosticsSlot
slDiagnostics
;
JournalCommandSlot
slJournalCommand
;
SetDateTimeSlot
slSetDateTime
;
RemoteServiceSlot
slRemoteService
;
...
...
include/modbus/ModbusTCPServerSlot.h
View file @
73db415f
...
...
@@ -44,6 +44,9 @@ class ModbusTCPServerSlot:
virtual
ModbusRTU
::
mbErrCode
writeOutputRegisters
(
ModbusRTU
::
WriteOutputMessage
&
query
,
ModbusRTU
::
WriteOutputRetMessage
&
reply
);
virtual
ModbusRTU
::
mbErrCode
diagnostics
(
ModbusRTU
::
DiagnosticMessage
&
query
,
ModbusRTU
::
DiagnosticRetMessage
&
reply
);
virtual
ModbusRTU
::
mbErrCode
journalCommand
(
ModbusRTU
::
JournalCommandMessage
&
query
,
ModbusRTU
::
JournalCommandRetMessage
&
reply
);
...
...
include/modbus/ModbusTypes.h
View file @
73db415f
...
...
@@ -948,46 +948,17 @@ namespace ModbusRTU
{
ModbusData
subf
;
ModbusData
data
[
MAXLENPACKET
/
sizeof
(
ModbusData
)];
/*!< данные */
ModbusCRC
crc
;
// ------- to slave -------
DiagnosticMessage
(
ModbusAddr
addr
,
ModbusData
dat
);
/*! преобразование для посылки в сеть */
ModbusMessage
transport_msg
();
// ------- from
master
-------
// ------- from
slave
-------
DiagnosticMessage
(
ModbusMessage
&
m
);
DiagnosticMessage
&
operator
=
(
ModbusMessage
&
m
);
void
init
(
ModbusMessage
&
m
);
/*! размер данных(после заголовка) у данного типа сообщения */
int
szData
();
// вспомогательное поле определяющее количество байт данных в данном сообщении
int
dcount
;
}
__attribute__
((
packed
));
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
&
m
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
*
m
);
// -----------------------------------------------------------------------
/*! Ответ для 0x08 */
struct
DiagnosticRetMessage
:
public
ModbusHeader
{
ModbusData
subf
;
ModbusData
data
[
MAXLENPACKET
/
sizeof
(
ModbusData
)];
/*!< данные */
// ------- from slave -------
DiagnosticRetMessage
(
ModbusMessage
&
m
);
DiagnosticRetMessage
&
operator
=
(
ModbusMessage
&
m
);
void
init
(
ModbusMessage
&
m
);
/*! размер предварительного заголовка
* (после основного до фактических данных)
*/
static
inline
int
szHead
()
{
// bcnt
return
sizeof
(
ModbusByte
);
return
sizeof
(
subf
);
}
/*! узнать длину данных следующий за предварительным заголовком ( в байтах ) */
...
...
@@ -995,7 +966,7 @@ namespace ModbusRTU
ModbusCRC
crc
;
// ------- to master -------
Diagnostic
RetMessage
(
ModbusAddr
_from
);
Diagnostic
Message
(
ModbusAddr
_from
,
DiagnosticsSubFunction
subf
);
/*! добавление данных.
* \return TRUE - если удалось
...
...
@@ -1009,7 +980,7 @@ namespace ModbusRTU
/*! проверка на переполнение */
inline
bool
isFull
()
{
return
(
d
count
*
sizeof
(
ModbusData
)
>=
MAXLENPACKET
);
return
(
sizeof
(
subf
)
+
count
*
sizeof
(
ModbusData
)
>=
MAXLENPACKET
);
}
/*! размер данных(после заголовка) у данного типа сообщения */
...
...
@@ -1023,7 +994,17 @@ namespace ModbusRTU
// преобразовании в ModbusMessage.
// Делать что-типа memcpy(buf,this,sizeof(*this)); будет не верно.
// Используйте специальную функцию transport_msg()
int
dcount
;
/*!< фактическое количество данных в сообщении */
int
count
;
/*!< фактическое количество данных в сообщении */
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
&
m
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
*
m
);
// -----------------------------------------------------------------------
/*! Ответ для 0x08 */
struct
DiagnosticRetMessage
:
public
DiagnosticMessage
{
DiagnosticRetMessage
(
ModbusMessage
&
m
);
DiagnosticRetMessage
(
DiagnosticMessage
&
m
);
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
DiagnosticRetMessage
&
m
);
...
...
src/Communications/Modbus/ModbusClient.cc
View file @
73db415f
...
...
@@ -148,6 +148,20 @@ WriteOutputRetMessage ModbusClient::write10( WriteOutputMessage& msg )
throw
mbException
(
res
);
}
// --------------------------------------------------------------------------------
DiagnosticRetMessage
ModbusClient
::
diag08
(
ModbusAddr
addr
,
DiagnosticsSubFunction
subfunc
)
throw
(
ModbusRTU
::
mbException
)
{
DiagnosticMessage
msg
(
addr
,
subfunc
);
qbuf
=
msg
.
transport_msg
();
mbErrCode
res
=
query
(
msg
.
addr
,
qbuf
,
reply
,
replyTimeOut_ms
);
if
(
res
==
erNoError
)
return
DiagnosticRetMessage
(
reply
);
throw
mbException
(
res
);
}
// --------------------------------------------------------------------------------
SetDateTimeRetMessage
ModbusClient
::
setDateTime
(
ModbusAddr
addr
,
ModbusByte
hour
,
ModbusByte
min
,
ModbusByte
sec
,
ModbusByte
day
,
ModbusByte
mon
,
ModbusByte
year
,
ModbusByte
century
)
...
...
src/Communications/Modbus/ModbusRTUSlaveSlot.cc
View file @
73db415f
...
...
@@ -81,6 +81,15 @@ mbErrCode ModbusRTUSlaveSlot::writeOutputRegisters( WriteOutputMessage& query,
}
// -------------------------------------------------------------------------
mbErrCode
ModbusRTUSlaveSlot
::
diagnostics
(
DiagnosticMessage
&
query
,
DiagnosticRetMessage
&
reply
)
{
if
(
!
slDiagnostics
)
return
erOperationFailed
;
return
slDiagnostics
(
query
,
reply
);
}
// -------------------------------------------------------------------------
mbErrCode
ModbusRTUSlaveSlot
::
forceSingleCoil
(
ForceSingleCoilMessage
&
query
,
ForceSingleCoilRetMessage
&
reply
)
{
...
...
src/Communications/Modbus/ModbusServerSlot.cc
View file @
73db415f
...
...
@@ -50,6 +50,11 @@ void ModbusServerSlot::connectWriteSingleOutput( WriteSingleOutputSlot sl )
}
// -------------------------------------------------------------------------
void
ModbusServerSlot
::
connectDiagnostics
(
DiagnosticsSlot
sl
)
{
slDiagnostics
=
sl
;
}
// -------------------------------------------------------------------------
void
ModbusServerSlot
::
connectForceSingleCoil
(
ForceSingleCoilSlot
sl
)
{
slForceSingleCoil
=
sl
;
...
...
src/Communications/Modbus/ModbusTCPServerSlot.cc
View file @
73db415f
...
...
@@ -75,6 +75,15 @@ mbErrCode ModbusTCPServerSlot::writeOutputRegisters( WriteOutputMessage& query,
}
// -------------------------------------------------------------------------
mbErrCode
ModbusTCPServerSlot
::
diagnostics
(
DiagnosticMessage
&
query
,
DiagnosticRetMessage
&
reply
)
{
if
(
!
slDiagnostics
)
return
erOperationFailed
;
return
slDiagnostics
(
query
,
reply
);
}
// -------------------------------------------------------------------------
mbErrCode
ModbusTCPServerSlot
::
forceSingleCoil
(
ForceSingleCoilMessage
&
query
,
ForceSingleCoilRetMessage
&
reply
)
{
...
...
src/Communications/Modbus/ModbusTypes.cc
View file @
73db415f
...
...
@@ -2145,67 +2145,10 @@ int ModbusRTU::szRequestDiagnosticData( DiagnosticsSubFunction f )
return
-
1
;
}
// -------------------------------------------------------------------------
DiagnosticMessage
::
DiagnosticMessage
(
ModbusAddr
a
,
ModbusData
sf
)
:
subf
(
sf
),
dcount
(
0
)
{
addr
=
a
;
func
=
fnDiagnostics
;
}
// -------------------------------------------------------------------------
int
DiagnosticMessage
::
szData
()
{
int
sz
=
szRequestDiagnosticData
(
(
DiagnosticsSubFunction
)
subf
);
if
(
sz
>=
0
)
// return subf + szData + CRC
return
(
sizeof
(
ModbusData
)
+
sizeof
(
ModbusData
)
*
sz
+
szCRC
);
return
0
;
}
// -------------------------------------------------------------------------
ModbusMessage
DiagnosticMessage
::
transport_msg
()
{
assert
(
sizeof
(
ModbusMessage
)
>=
sizeof
(
DiagnosticMessage
));
ModbusMessage
mm
;
// копируем заголовок
memcpy
(
&
mm
,
this
,
szModbusHeader
);
// копируем данные (переворачиваем байты)
ModbusData
d
=
SWAPSHORT
(
subf
);
int
last
=
sizeof
(
d
);
// индекс в массиве данных ( байтовый массив!!! )
memcpy
(
mm
.
data
,
&
d
,
last
);
int
count
=
szRequestDiagnosticData
((
DiagnosticsSubFunction
)
subf
);
// Создаём временно массив, переворачиваем байты
ModbusData
*
dtmp
=
new
ModbusData
[
count
];
for
(
int
i
=
0
;
i
<
count
;
i
++
)
dtmp
[
i
]
=
SWAPSHORT
(
data
[
i
]);
// копируем
memcpy
(
&
(
mm
.
data
[
last
]),
dtmp
,
sizeof
(
ModbusData
)
*
count
);
delete
dtmp
;
last
+=
sizeof
(
ModbusData
)
*
count
;
// пересчитываем CRC по перевёрнутым данным
ModbusData
crc
=
checkCRC
(
(
ModbusByte
*
)(
&
mm
),
szModbusHeader
+
last
);
// копируем CRC (последний элемент). Без переворачивания...
memcpy
(
&
(
mm
.
data
[
last
]),
&
crc
,
szCRC
);
// длина сообщения...
mm
.
len
=
szData
();
return
mm
;
}
// -------------------------------------------------------------------------
DiagnosticMessage
::
DiagnosticMessage
(
ModbusMessage
&
m
)
{
init
(
m
);
}
// -------------------------------------------------------------------------
DiagnosticMessage
&
DiagnosticMessage
::
operator
=
(
ModbusMessage
&
m
)
{
...
...
@@ -2216,53 +2159,15 @@ DiagnosticMessage& DiagnosticMessage::operator=( ModbusMessage& m )
void
DiagnosticMessage
::
init
(
ModbusMessage
&
m
)
{
assert
(
m
.
func
==
fnDiagnostics
);
memset
(
this
,
0
,
sizeof
(
*
this
));
memcpy
(
this
,
&
m
,
sizeof
(
*
this
));
// m.len
// переворачиваем слова
subf
=
SWAPSHORT
(
subf
);
int
count
=
szRequestDiagnosticData
(
(
DiagnosticsSubFunction
)
subf
);
if
(
count
>
MAXDATALEN
)
throw
mbException
(
erPacketTooLong
);
if
(
count
<
0
)
throw
mbException
(
erBadDataValue
);
for
(
int
i
=
0
;
i
<
count
;
i
++
)
data
[
i
]
=
SWAPSHORT
(
data
[
i
]);
}
// -------------------------------------------------------------------------
std
::
ostream
&
ModbusRTU
::
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
&
m
)
{
return
os
<<
"addr="
<<
addr2str
(
m
.
addr
)
<<
" subf="
<<
dat2str
(
m
.
subf
);
}
std
::
ostream
&
ModbusRTU
::
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
*
m
)
{
return
os
<<
(
*
m
);
}
// -------------------------------------------------------------------------
DiagnosticRetMessage
::
DiagnosticRetMessage
(
ModbusMessage
&
m
)
{
init
(
m
);
}
// -------------------------------------------------------------------------
DiagnosticRetMessage
&
DiagnosticRetMessage
::
operator
=
(
ModbusMessage
&
m
)
{
init
(
m
);
return
*
this
;
}
// -------------------------------------------------------------------------
void
DiagnosticRetMessage
::
init
(
ModbusMessage
&
m
)
{
assert
(
m
.
func
==
fnDiagnostics
);
memset
(
this
,
0
,
sizeof
(
*
this
));
addr
=
m
.
addr
;
func
=
m
.
func
;
memcpy
(
&
subf
,
m
.
data
,
sizeof
(
subf
)
);
int
last
=
sizeof
(
subf
);
subf
=
SWAPSHORT
(
subf
);
int
count
=
szRequestDiagnosticData
((
DiagnosticsSubFunction
)
subf
);
if
(
count
>
MAXDATALEN
)
throw
mbException
(
erPacketTooLong
);
...
...
@@ -2271,53 +2176,60 @@ void DiagnosticRetMessage::init( ModbusMessage& m )
throw
mbException
(
erBadDataValue
);
memcpy
(
&
data
,
&
(
m
.
data
[
1
]),
sizeof
(
ModbusData
)
*
count
);
last
+=
sizeof
(
ModbusData
)
*
count
;
// переворачиваем данные
for
(
unsigned
int
i
=
0
;
i
<
count
;
i
++
)
for
(
int
i
=
0
;
i
<
count
;
i
++
)
data
[
i
]
=
SWAPSHORT
(
data
[
i
]);
memcpy
(
&
crc
,
&
(
m
.
data
[
sizeof
(
ModbusData
)
*
count
+
1
]),
szCRC
);
memcpy
(
&
crc
,
&
(
m
.
data
[
last
]),
szCRC
);
}
// -------------------------------------------------------------------------
int
Diagnostic
Ret
Message
::
getDataLen
(
ModbusMessage
&
m
)
int
DiagnosticMessage
::
getDataLen
(
ModbusMessage
&
m
)
{
if
(
m
.
len
<
0
)
return
0
;
return
m
.
data
[
0
];
/*
DiagnosticMessage rm(m);
return (int)(rm.bcnt);
*/
ModbusData
d
;
memcpy
(
&
d
,
m
.
data
,
sizeof
(
d
)
);
d
=
SWAPSHORT
(
d
);
int
sz
=
szRequestDiagnosticData
((
DiagnosticsSubFunction
)
d
);
if
(
sz
>=
0
)
return
sz
+
sizeof
(
d
);
// subf + sz
return
0
;
}
// -------------------------------------------------------------------------
Diagnostic
RetMessage
::
DiagnosticRetMessage
(
ModbusAddr
_addr
)
:
d
count
(
0
)
Diagnostic
Message
::
DiagnosticMessage
(
ModbusAddr
_addr
,
DiagnosticsSubFunction
sf
)
:
count
(
0
)
{
addr
=
_addr
;
func
=
fnDiagnostics
;
subf
=
sf
;
memset
(
data
,
0
,
sizeof
(
data
));
}
// -------------------------------------------------------------------------
bool
Diagnostic
Ret
Message
::
addData
(
ModbusData
d
)
bool
DiagnosticMessage
::
addData
(
ModbusData
d
)
{
if
(
isFull
()
)
return
false
;
data
[
d
count
++
]
=
d
;
data
[
count
++
]
=
d
;
return
true
;
}
// -------------------------------------------------------------------------
void
Diagnostic
Ret
Message
::
clear
()
void
DiagnosticMessage
::
clear
()
{
memset
(
data
,
0
,
sizeof
(
data
));
d
count
=
0
;
count
=
0
;
}
// -------------------------------------------------------------------------
ModbusMessage
Diagnostic
Ret
Message
::
transport_msg
()
ModbusMessage
DiagnosticMessage
::
transport_msg
()
{
ModbusMessage
mm
;
// assert(sizeof(ModbusMessage)>=sizeof(Diagnostic
Ret
Message));
// assert(sizeof(ModbusMessage)>=sizeof(DiagnosticMessage));
assert
(
sizeof
(
ModbusMessage
)
>=
(
unsigned
int
)
szModbusHeader
+
szData
()
);
// копируем заголовок и данные
...
...
@@ -2329,19 +2241,19 @@ ModbusMessage DiagnosticRetMessage::transport_msg()
ind
+=
sizeof
(
subf
);
// Создаём временно массив, переворачиваем байты
ModbusData
*
dtmp
=
new
ModbusData
[
d
count
];
for
(
int
i
=
0
;
i
<
d
count
;
i
++
)
ModbusData
*
dtmp
=
new
ModbusData
[
count
];
for
(
int
i
=
0
;
i
<
count
;
i
++
)
dtmp
[
i
]
=
SWAPSHORT
(
data
[
i
]);
// копируем
memcpy
(
&
(
mm
.
data
[
ind
]),
dtmp
,
sizeof
(
ModbusData
)
*
d
count
);
memcpy
(
&
(
mm
.
data
[
ind
]),
dtmp
,
sizeof
(
ModbusData
)
*
count
);
delete
dtmp
;
ind
+=
sizeof
(
ModbusData
)
*
d
count
;
ind
+=
sizeof
(
ModbusData
)
*
count
;
// пересчитываем CRC по перевёрнутым данным
ModbusData
crc
=
checkCRC
(
(
ModbusByte
*
)(
&
mm
),
szModbusHeader
+
sizeof
(
subf
)
+
sizeof
(
ModbusData
)
*
d
count
);
ModbusData
crc
=
checkCRC
(
(
ModbusByte
*
)(
&
mm
),
szModbusHeader
+
sizeof
(
subf
)
+
sizeof
(
ModbusData
)
*
count
);
// копируем CRC (последний элемент). Без переворачивания...
memcpy
(
&
(
mm
.
data
[
ind
]),
&
crc
,
szCRC
);
...
...
@@ -2353,15 +2265,38 @@ ModbusMessage DiagnosticRetMessage::transport_msg()
return
mm
;
}
// -------------------------------------------------------------------------
int
Diagnostic
Ret
Message
::
szData
()
int
DiagnosticMessage
::
szData
()
{
// фактическое число данных + контрольная сумма
return
dcount
*
sizeof
(
ModbusData
)
+
szCRC
;
return
sizeof
(
subf
)
+
count
*
sizeof
(
ModbusData
)
+
szCRC
;
}
// -------------------------------------------------------------------------
DiagnosticRetMessage
::
DiagnosticRetMessage
(
ModbusMessage
&
m
)
:
DiagnosticMessage
(
m
)
{
}
// -------------------------------------------------------------------------
DiagnosticRetMessage
::
DiagnosticRetMessage
(
DiagnosticMessage
&
m
)
:
DiagnosticMessage
(
m
)
{
}
// -------------------------------------------------------------------------
std
::
ostream
&
ModbusRTU
::
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
&
m
)
{
// return mbPrintMessage(os,(ModbusByte*)(&m), szModbusHeader + m.szData() );
return
os
<<
"addr="
<<
addr2str
(
m
.
addr
)
<<
" subf="
<<
dat2str
(
m
.
subf
);
}
std
::
ostream
&
ModbusRTU
::
operator
<<
(
std
::
ostream
&
os
,
DiagnosticMessage
*
m
)
{
return
os
<<
(
*
m
);
}
// -------------------------------------------------------------------------
std
::
ostream
&
ModbusRTU
::
operator
<<
(
std
::
ostream
&
os
,
DiagnosticRetMessage
&
m
)
{
return
mbPrintMessage
(
os
,(
ModbusByte
*
)(
&
m
),
szModbusHeader
+
m
.
szData
()
);
return
mbPrintMessage
(
os
,(
ModbusByte
*
)(
&
m
),
sizeof
(
m
)
);
}
std
::
ostream
&
ModbusRTU
::
operator
<<
(
std
::
ostream
&
os
,
DiagnosticRetMessage
*
m
)
...
...
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