Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
proview
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Esteban Blanc
proview
Commits
7c5b1249
Commit
7c5b1249
authored
Oct 27, 2011
by
Claes Sjofors
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modbus RTU added
parent
e431ce45
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
4055 additions
and
12 deletions
+4055
-12
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_master.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_master.c
+795
-0
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_module.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_module.c
+180
-0
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_server.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_server.c
+1223
-0
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_servermodule.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_servermodule.c
+168
-0
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_slave.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_slave.c
+275
-0
otherio/lib/rt/src/os_linux/rt_io_mb_rtu.h
otherio/lib/rt/src/os_linux/rt_io_mb_rtu.h
+261
-0
otherio/lib/rt/src/rt_io_otherio.meth
otherio/lib/rt/src/rt_io_otherio.meth
+5
-0
otherio/wbl/mcomp/src/otherio.wb_load
otherio/wbl/mcomp/src/otherio.wb_load
+1049
-12
src/wbl/pwrb/src/pwrb_td_stallactionenum.wb_load
src/wbl/pwrb/src/pwrb_td_stallactionenum.wb_load
+88
-0
wb/exp/wb/src/pwr_wb_palette.cnf
wb/exp/wb/src/pwr_wb_palette.cnf
+11
-0
No files found.
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_master.c
0 → 100644
View file @
7c5b1249
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2011 SSAB Oxelosund AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
/* rt_io_m_mb_rtu_master.c -- io methods for the Modbus RTU Master object
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#if defined OS_LINUX
#include <termio.h>
#endif
#if defined OS_LINUX || defined OS_MACOS
#include <sgtty.h>
#endif
#include <sys/ioctl.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "rt_gdh.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "co_cdh.h"
#include "co_time.h"
#include "rt_mb_msg.h"
#include "rt_io_mb_rtu.h"
#include "rt_io_agent_init.h"
char
rcv_buffer
[
65536
];
static
pwr_tStatus
IoAgentInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
);
static
pwr_tStatus
IoAgentRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
);
static
pwr_tStatus
IoAgentWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
);
static
pwr_tStatus
IoAgentClose
(
io_tCtx
ctx
,
io_sAgent
*
ap
);
static
void
float_to_timeval
(
struct
timeval
*
tv
,
float
t
)
{
tv
->
tv_sec
=
t
;
tv
->
tv_usec
=
(
t
-
(
float
)
tv
->
tv_sec
)
*
1000000
;
}
static
void
float_to_timespec
(
struct
timespec
*
tv
,
float
t
)
{
tv
->
tv_sec
=
t
;
tv
->
tv_nsec
=
(
t
-
(
float
)
tv
->
tv_sec
)
*
1000000000
;
}
/*----------------------------------------------------------------------------*\
Init method for the Modbus RTU Master agent
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoAgentInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
)
{
struct
termios
tty_attributes
;
int
sts
;
io_sAgentLocal
*
local
;
pwr_sClass_Modbus_RTU_Master
*
op
=
(
pwr_sClass_Modbus_RTU_Master
*
)
ap
->
op
;
/* Allocate area for local data structure */
ap
->
Local
=
calloc
(
1
,
sizeof
(
io_sAgentLocal
));
local
=
ap
->
Local
;
local
->
fd
=
open
(
op
->
Device
,
O_RDWR
|
O_NDELAY
|
O_NOCTTY
);
if
(
local
->
fd
==
-
1
)
{
errh_Error
(
"Modbus RTU Master, open device error, %s"
,
ap
->
Name
);
return
IO__ERRINIDEVICE
;
}
tcgetattr
(
local
->
fd
,
&
tty_attributes
);
tty_attributes
.
c_cc
[
VMIN
]
=
1
;
tty_attributes
.
c_cc
[
VTIME
]
=
0
;
tty_attributes
.
c_lflag
&=
~
(
ICANON
|
ISIG
|
ECHO
|
IEXTEN
);
tty_attributes
.
c_cflag
|=
(
CLOCAL
|
CREAD
);
tty_attributes
.
c_oflag
&=
~
(
OPOST
);
tty_attributes
.
c_oflag
&=
~
(
ONLCR
);
tty_attributes
.
c_iflag
&=
~
(
INLCR
|
ICRNL
);
/* Speed */
#if defined OS_LINUX
tty_attributes
.
c_cflag
&=
~
CBAUD
;
#endif
switch
(
op
->
Speed
)
{
case
300
:
tty_attributes
.
c_cflag
|=
B300
;
break
;
case
1200
:
tty_attributes
.
c_cflag
|=
B1200
;
break
;
case
2400
:
tty_attributes
.
c_cflag
|=
B2400
;
break
;
case
4800
:
tty_attributes
.
c_cflag
|=
B4800
;
break
;
case
9600
:
tty_attributes
.
c_cflag
|=
B9600
;
break
;
case
19200
:
tty_attributes
.
c_cflag
|=
B19200
;
break
;
default:
errh_Error
(
"Modbus RTU Master, unsupported speed, %s"
,
ap
->
Name
);
tty_attributes
.
c_cflag
|=
B9600
;
break
;
}
/* DataBits 5, 6, 7 or 8 */
tty_attributes
.
c_cflag
&=
~
CSIZE
;
switch
(
op
->
DataBits
)
{
case
pwr_eDataBitsEnum_5
:
tty_attributes
.
c_cflag
|=
CS5
;
break
;
case
pwr_eDataBitsEnum_6
:
tty_attributes
.
c_cflag
|=
CS6
;
break
;
case
pwr_eDataBitsEnum_7
:
tty_attributes
.
c_cflag
|=
CS7
;
break
;
case
pwr_eDataBitsEnum_8
:
tty_attributes
.
c_cflag
|=
CS8
;
break
;
default:
errh_Error
(
"Modbus RTU Master, unsupported DataBits, %s"
,
ap
->
Name
);
tty_attributes
.
c_cflag
|=
CS8
;
}
//tty_attributes.c_iflag |=ISTRIP;
/* Parity */
switch
(
op
->
Parity
)
{
case
pwr_eParityEnum_Odd
:
case
pwr_eParityEnum_Even
:
tty_attributes
.
c_cflag
|=
PARENB
;
tty_attributes
.
c_iflag
|=
IGNPAR
;
if
(
op
->
Parity
==
pwr_eParityEnum_Even
)
tty_attributes
.
c_cflag
&=
~
PARODD
;
else
tty_attributes
.
c_cflag
|=
PARODD
;
break
;
default:
tty_attributes
.
c_cflag
&=
~
PARENB
;
}
/* stopbitsval */
switch
(
op
->
StopBits
)
{
case
pwr_eStopBitsEnum_2
:
tty_attributes
.
c_cflag
|=
CSTOPB
;
break
;
case
pwr_eStopBitsEnum_1
:
tty_attributes
.
c_cflag
&=~
CSTOPB
;
break
;
case
pwr_eStopBitsEnum_0
:
errh_Error
(
"Modbus RTU Master, unsupported StopBits, %s"
,
ap
->
Name
);
tty_attributes
.
c_cflag
&=~
CSTOPB
;
break
;
}
tty_attributes
.
c_iflag
&=
~
IXON
;
//ingen XON/XOFF in
//tty_attributes.c_iflag &= (V_IGNCR);
//tty_attributes.c_iflag &= (IGNPAR | V_IGNCR);
//tty_attributes.c_iflag &= ~(BRKINT | IXON | V_INLCR | V_ICRNL);
//tty_attributes.c_cflag &= ~(CSIZE | CSTOPB | PARENB); //fippla om vrden lite granna
sts
=
tcsetattr
(
local
->
fd
,
TCSANOW
,
&
tty_attributes
);
if
(
sts
<
0
)
{
errh_Error
(
"Modbus RTU Master, set device attributes error, %s"
,
ap
->
Name
);
return
IO__ERRINIDEVICE
;
}
tcflush
(
local
->
fd
,
TCIOFLUSH
);
// Test
sleep
(
2
);
local
->
initialized
=
TRUE
;
return
IO__SUCCESS
;
}
static
void
generate_crc
(
unsigned
char
*
buf
,
int
size
,
unsigned
char
*
result
)
{
unsigned
short
int
crc
;
unsigned
short
int
gen_polynomial
=
0xA001
;
unsigned
short
int
flag_mask
=
0x0001
;
unsigned
short
int
flag
;
int
i
,
j
;
crc
=
0xFFFF
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
crc
=
crc
^
buf
[
i
];
for
(
j
=
0
;
j
<
8
;
j
++
)
{
flag
=
crc
&
flag_mask
;
crc
=
crc
>>
1
;
if
(
flag
)
crc
=
crc
^
gen_polynomial
;
}
}
result
[
0
]
=
(
unsigned
char
)
(
crc
&
0x00FF
);
result
[
1
]
=
(
unsigned
char
)
((
crc
>>
8
)
&
0x00FF
);
}
static
pwr_tStatus
rtu_send
(
io_sRack
*
rp
,
io_sAgentLocal
*
local_master
,
io_sRackLocal
*
local_slave
,
io_sCardLocalMsg
*
local_card
,
pwr_sClass_Modbus_RTU_Master
*
masterp
,
pwr_sClass_Modbus_RTU_Slave
*
slavep
,
pwr_sClass_Modbus_RTU_Module
*
modulep
,
unsigned
char
*
buf
,
int
buffer_size
)
{
int
sts
;
rec_buf
*
rb
;
unsigned
char
fc
;
int
data_size
=
0
;
unsigned
char
telegram
[
512
];
unsigned
char
crc
[
2
];
fd_set
read_fd
;
struct
timeval
tv
;
generate_crc
(
buf
,
buffer_size
,
&
buf
[
buffer_size
]);
if
(
masterp
->
Debug
)
{
int
i
;
pwr_tTime
current
;
char
timstr
[
40
];
time_GetTime
(
&
current
);
time_AtoAscii
(
&
current
,
time_eFormat_Time
,
timstr
,
sizeof
(
timstr
));
printf
(
"Snd: %s %2d "
,
timstr
,
buffer_size
+
2
);
for
(
i
=
0
;
i
<
buffer_size
+
2
;
i
++
)
printf
(
"%02d "
,
buf
[
i
]);
printf
(
"
\n
"
);
}
sts
=
write
(
local_master
->
fd
,
buf
,
buffer_size
+
2
);
if
(
sts
<=
0
)
{
slavep
->
ErrorCount
++
;
return
0
;
}
slavep
->
TX_packets
++
;
/* Receive answer */
sts
=
1
;
float_to_timeval
(
&
tv
,
masterp
->
ReceiveTimeout
);
FD_ZERO
(
&
read_fd
);
FD_SET
(
local_master
->
fd
,
&
read_fd
);
sts
=
select
(
local_master
->
fd
+
1
,
&
read_fd
,
NULL
,
NULL
,
&
tv
);
if
(
sts
==
0
)
return
0
;
sts
=
read
(
local_master
->
fd
,
telegram
,
1
);
if
(
sts
<=
0
)
{
if
(
masterp
->
Debug
)
printf
(
"Rcv: Nothing to read
\n
"
);
return
0
;
}
while
(
sts
>
0
)
{
data_size
++
;
float_to_timeval
(
&
tv
,
masterp
->
CharTimeout
);
FD_ZERO
(
&
read_fd
);
FD_SET
(
local_master
->
fd
,
&
read_fd
);
sts
=
select
(
local_master
->
fd
+
1
,
&
read_fd
,
NULL
,
NULL
,
&
tv
);
if
(
sts
==
0
)
{
break
;
}
sts
=
read
(
local_master
->
fd
,
telegram
+
data_size
,
1
);
}
if
(
data_size
<
2
)
{
if
(
masterp
->
Debug
)
printf
(
"Rcv: Data size < 2
\n
"
);
return
0
;
}
if
(
masterp
->
Debug
)
{
int
i
;
pwr_tTime
current
;
char
timstr
[
40
];
time_GetTime
(
&
current
);
time_AtoAscii
(
&
current
,
time_eFormat_Time
,
timstr
,
sizeof
(
timstr
));
printf
(
"Rcv: %s %2d "
,
timstr
,
data_size
);
for
(
i
=
0
;
i
<
data_size
;
i
++
)
printf
(
"%02d "
,
telegram
[
i
]);
printf
(
"
\n
"
);
}
generate_crc
(
telegram
,
data_size
-
2
,
crc
);
if
(
crc
[
0
]
!=
telegram
[
data_size
-
2
]
||
crc
[
1
]
!=
telegram
[
data_size
-
1
])
{
slavep
->
ErrorCount
++
;
return
0
;
}
slavep
->
RX_packets
++
;
rb
=
(
rec_buf
*
)
telegram
;
fc
=
rb
->
fc
;
if
(
fc
!=
modulep
->
FunctionCode
)
{
return
0
;
}
slavep
->
Status
=
MB__NORMAL
;
modulep
->
Status
=
pwr_eModbusModule_StatusEnum_OK
;
switch
(
fc
)
{
case
pwr_eModbus_FCEnum_ReadCoils
:
{
res_read
*
res_r
;
res_r
=
(
res_read
*
)
rb
;
memcpy
(
local_card
->
input_area
,
res_r
->
buf
,
MIN
(
res_r
->
bc
,
local_card
->
input_size
));
break
;
}
case
pwr_eModbus_FCEnum_ReadDiscreteInputs
:
{
res_read
*
res_r
;
res_r
=
(
res_read
*
)
rb
;
memcpy
(
local_card
->
input_area
,
res_r
->
buf
,
MIN
(
res_r
->
bc
,
local_card
->
input_size
));
break
;
}
case
pwr_eModbus_FCEnum_ReadHoldingRegisters
:
{
res_read
*
res_r
;
res_r
=
(
res_read
*
)
rb
;
memcpy
(
local_card
->
input_area
,
res_r
->
buf
,
MIN
(
res_r
->
bc
,
local_card
->
input_size
));
break
;
}
case
pwr_eModbus_FCEnum_ReadInputRegisters
:
{
res_read
*
res_r
;
res_r
=
(
res_read
*
)
rb
;
memcpy
(
local_card
->
input_area
,
res_r
->
buf
,
MIN
(
res_r
->
bc
,
local_card
->
input_size
));
break
;
}
case
pwr_eModbus_FCEnum_WriteMultipleCoils
:
case
pwr_eModbus_FCEnum_WriteMultipleRegisters
:
case
pwr_eModbus_FCEnum_WriteSingleRegister
:
// Nothing good to do here
break
;
}
return
IO__SUCCESS
;
}
static
pwr_tStatus
mb_rtu_send_data
(
io_sRack
*
rp
,
io_sAgentLocal
*
local_master
,
io_sRackLocal
*
local_slave
,
pwr_sClass_Modbus_RTU_Master
*
masterp
,
pwr_sClass_Modbus_RTU_Slave
*
slavep
,
mb_tSendMask
mask
)
{
io_sCardLocalMsg
*
local_card
;
io_sCard
*
cardp
;
pwr_sClass_Modbus_RTU_Module
*
modulep
;
pwr_tStatus
sts
;
pwr_tCid
cid
;
int
modules
;
int
i
;
int
send_error
;
struct
timespec
tf
;
/* Send messages to slave */
cardp
=
rp
->
cardlist
;
while
(
cardp
)
{
cid
=
cardp
->
Class
;
while
(
ODD
(
gdh_GetSuperClass
(
cid
,
&
cid
,
cardp
->
Objid
)))
;
switch
(
cid
)
{
case
pwr_cClass_Modbus_RTU_Module
:
modulep
=
(
pwr_sClass_Modbus_RTU_Module
*
)
cardp
->
op
;
modules
=
1
;
break
;
default:
modules
=
0
;
}
if
(
!
modules
)
{
cardp
=
cardp
->
next
;
continue
;
}
send_error
=
0
;
for
(
i
=
0
;
i
<
modules
;
i
++
)
{
sts
=
1
;
if
(
!
modulep
->
Continous
&&
!
modulep
->
SendOp
)
{
break
;
}
local_card
=
&
((
io_sCardLocal
*
)
cardp
->
Local
)
->
msg
[
i
];
if
(
modulep
->
ScanInterval
>
1
&&
local_card
->
interval_cnt
!=
0
)
{
modulep
++
;
continue
;
}
if
(
mask
&
mb_mSendMask_ReadReq
)
{
switch
(
modulep
->
FunctionCode
)
{
case
pwr_eModbus_FCEnum_ReadCoils
:
case
pwr_eModbus_FCEnum_ReadDiscreteInputs
:
{
read_req
rr
;
modulep
->
SendOp
=
FALSE
;
rr
.
unit_id
=
modulep
->
UnitId
;
rr
.
fc
=
modulep
->
FunctionCode
;
rr
.
addr
=
htons
(
modulep
->
Address
);
rr
.
quant
=
htons
(
local_card
->
no_di
);
// rr.quant = ntohs(local_card->input_size * 8);
sts
=
rtu_send
(
rp
,
local_master
,
local_slave
,
local_card
,
masterp
,
slavep
,
modulep
,
(
unsigned
char
*
)
&
rr
,
sizeof
(
read_req
)
-
2
);
if
(
EVEN
(
sts
))
{
slavep
->
Status
=
MB__CONNDOWN
;
slavep
->
ErrorCount
++
;
send_error
=
1
;
break
;
}
slavep
->
Status
=
MB__NORMAL
;
break
;
}
case
pwr_eModbus_FCEnum_ReadHoldingRegisters
:
case
pwr_eModbus_FCEnum_ReadInputRegisters
:
{
read_req
rr
;
modulep
->
SendOp
=
FALSE
;
rr
.
unit_id
=
modulep
->
UnitId
;
rr
.
fc
=
modulep
->
FunctionCode
;
rr
.
addr
=
htons
(
modulep
->
Address
);
rr
.
quant
=
ntohs
((
local_card
->
input_size
+
1
)
/
2
);
sts
=
rtu_send
(
rp
,
local_master
,
local_slave
,
local_card
,
masterp
,
slavep
,
modulep
,
(
unsigned
char
*
)
&
rr
,
sizeof
(
read_req
)
-
2
);
if
(
EVEN
(
sts
))
{
slavep
->
Status
=
MB__CONNDOWN
;
slavep
->
ErrorCount
++
;
send_error
=
1
;
break
;
}
slavep
->
Status
=
MB__NORMAL
;
break
;
}
}
/* End - switch FC ... */
}
if
(
mask
&
mb_mSendMask_WriteReq
)
{
switch
(
modulep
->
FunctionCode
)
{
case
pwr_eModbus_FCEnum_WriteSingleCoil
:
{
write_single_req
wsr
;
modulep
->
SendOp
=
FALSE
;
wsr
.
unit_id
=
modulep
->
UnitId
;
wsr
.
fc
=
modulep
->
FunctionCode
;
wsr
.
addr
=
htons
(
modulep
->
Address
);
if
(
local_card
->
output_size
==
4
)
{
if
(
*
(
int
*
)
local_card
->
output_area
)
wsr
.
value
=
ntohs
(
0xFF00
);
else
wsr
.
value
=
0
;
}
else
if
(
local_card
->
output_size
==
2
)
{
if
(
*
(
short
int
*
)
local_card
->
output_area
)
wsr
.
value
=
ntohs
(
0xFF00
);
else
wsr
.
value
=
0
;
}
else
if
(
local_card
->
output_size
==
1
)
{
if
(
*
(
char
*
)
local_card
->
output_area
)
wsr
.
value
=
ntohs
(
0xFF00
);
else
wsr
.
value
=
0
;
}
else
wsr
.
value
=
0
;
sts
=
rtu_send
(
rp
,
local_master
,
local_slave
,
local_card
,
masterp
,
slavep
,
modulep
,
(
unsigned
char
*
)
&
wsr
,
sizeof
(
wsr
)
-
2
);
if
(
EVEN
(
sts
))
{
slavep
->
Status
=
MB__CONNDOWN
;
slavep
->
ErrorCount
++
;
send_error
=
1
;
break
;
}
slavep
->
Status
=
MB__NORMAL
;
break
;
}
case
pwr_eModbus_FCEnum_WriteMultipleCoils
:
{
write_coils_req
wcr
;
modulep
->
SendOp
=
FALSE
;
wcr
.
unit_id
=
modulep
->
UnitId
;
wcr
.
fc
=
modulep
->
FunctionCode
;
wcr
.
addr
=
htons
(
modulep
->
Address
);
wcr
.
quant
=
htons
(
local_card
->
no_do
);
// wcr.quant = ntohs((local_card->output_size) * 8);
wcr
.
bc
=
local_card
->
output_size
;
memcpy
(
wcr
.
reg
,
local_card
->
output_area
,
local_card
->
output_size
);
sts
=
rtu_send
(
rp
,
local_master
,
local_slave
,
local_card
,
masterp
,
slavep
,
modulep
,
(
unsigned
char
*
)
&
wcr
,
sizeof
(
wcr
)
-
2
-
sizeof
(
wcr
.
reg
)
+
local_card
->
output_size
);
if
(
EVEN
(
sts
))
{
slavep
->
Status
=
MB__CONNDOWN
;
slavep
->
ErrorCount
++
;
send_error
=
1
;
break
;
}
slavep
->
Status
=
MB__NORMAL
;
break
;
}
case
pwr_eModbus_FCEnum_WriteMultipleRegisters
:
{
write_reg_req
wrr
;
modulep
->
SendOp
=
FALSE
;
wrr
.
unit_id
=
modulep
->
UnitId
;
wrr
.
fc
=
modulep
->
FunctionCode
;
wrr
.
addr
=
htons
(
modulep
->
Address
);
wrr
.
quant
=
ntohs
((
local_card
->
output_size
)
/
2
);
wrr
.
bc
=
local_card
->
output_size
;
memcpy
(
wrr
.
reg
,
local_card
->
output_area
,
local_card
->
output_size
);
sts
=
rtu_send
(
rp
,
local_master
,
local_slave
,
local_card
,
masterp
,
slavep
,
modulep
,
(
unsigned
char
*
)
&
wrr
,
sizeof
(
wrr
)
-
2
-
sizeof
(
wrr
.
reg
)
+
local_card
->
output_size
);
if
(
EVEN
(
sts
))
{
slavep
->
Status
=
MB__CONNDOWN
;
slavep
->
ErrorCount
++
;
send_error
=
1
;
break
;
}
slavep
->
Status
=
MB__NORMAL
;
break
;
}
case
pwr_eModbus_FCEnum_WriteSingleRegister
:
{
write_single_req
wrr
;
modulep
->
SendOp
=
FALSE
;
wrr
.
unit_id
=
modulep
->
UnitId
;
wrr
.
fc
=
modulep
->
FunctionCode
;
wrr
.
addr
=
htons
(
modulep
->
Address
);
memcpy
(
&
wrr
.
value
,
local_card
->
output_area
,
sizeof
(
wrr
.
value
));
sts
=
rtu_send
(
rp
,
local_master
,
local_slave
,
local_card
,
masterp
,
slavep
,
modulep
,
(
unsigned
char
*
)
&
wrr
,
sizeof
(
wrr
)
-
2
);
if
(
EVEN
(
sts
))
{
slavep
->
Status
=
MB__CONNDOWN
;
slavep
->
ErrorCount
++
;
send_error
=
1
;
break
;
}
slavep
->
Status
=
MB__NORMAL
;
break
;
}
}
/* End - switch FC ... */
}
if
(
send_error
&&
cardp
->
next
)
{
/* Time to next frame */
float_to_timespec
(
&
tf
,
masterp
->
FrameTimeout
-
masterp
->
CharTimeout
);
nanosleep
(
&
tf
,
NULL
);
break
;
}
if
(
!
(
i
==
modules
-
1
&&
!
cardp
->
next
))
{
float_to_timespec
(
&
tf
,
masterp
->
FrameTimeout
-
masterp
->
CharTimeout
);
nanosleep
(
&
tf
,
NULL
);
}
modulep
++
;
}
cardp
=
cardp
->
next
;
}
/* End - while cardp ... */
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Read method for the Modbus RTU Master agent
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoAgentRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
)
{
io_sAgentLocal
*
local
;
io_sRackLocal
*
local_rack
;
pwr_tUInt16
sts
;
io_sRack
*
rp
;
pwr_tCid
cid
;
pwr_sClass_Modbus_RTU_Slave
*
sp
;
pwr_sClass_Modbus_RTU_Master
*
op
=
(
pwr_sClass_Modbus_RTU_Master
*
)
ap
->
op
;
local
=
(
io_sAgentLocal
*
)
ap
->
Local
;
rp
=
ap
->
racklist
;
while
(
rp
)
{
cid
=
rp
->
Class
;
while
(
ODD
(
gdh_GetSuperClass
(
cid
,
&
cid
,
rp
->
Objid
)))
;
switch
(
cid
)
{
case
pwr_cClass_Modbus_RTU_Slave
:
sp
=
(
pwr_sClass_Modbus_RTU_Slave
*
)
rp
->
op
;
local_rack
=
rp
->
Local
;
/* Request new data */
if
(
/* sp->Status == MB__NORMAL && */
sp
->
DisableSlave
!=
1
)
{
sts
=
mb_rtu_send_data
(
rp
,
local
,
local_rack
,
op
,
sp
,
mb_mSendMask_ReadReq
);
if
(
sp
->
ErrorCount
>=
sp
->
ErrorLimit
)
{
switch
(
sp
->
StallAction
)
{
case
pwr_eStallActionEnum_EmergencyBreak
:
ctx
->
Node
->
EmergBreakTrue
=
1
;
break
;
case
pwr_eStallActionEnum_ResetInputs
:
memset
(
sp
->
Inputs
,
0
,
local_rack
->
input_size
);
local_rack
->
reset_inputs
=
1
;
break
;
default:
;
}
}
else
local_rack
->
reset_inputs
=
0
;
}
break
;
}
rp
=
rp
->
next
;
}
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Write method for the Modbus RTU Master agent
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoAgentWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
)
{
io_sAgentLocal
*
local
;
io_sRackLocal
*
local_rack
;
pwr_tUInt16
sts
;
io_sRack
*
rp
;
pwr_tCid
cid
;
pwr_sClass_Modbus_RTU_Slave
*
sp
;
pwr_sClass_Modbus_RTU_Master
*
op
=
(
pwr_sClass_Modbus_RTU_Master
*
)
ap
->
op
;
local
=
(
io_sAgentLocal
*
)
ap
->
Local
;
rp
=
ap
->
racklist
;
while
(
rp
)
{
cid
=
rp
->
Class
;
while
(
ODD
(
gdh_GetSuperClass
(
cid
,
&
cid
,
rp
->
Objid
)))
;
switch
(
cid
)
{
case
pwr_cClass_Modbus_RTU_Slave
:
sp
=
(
pwr_sClass_Modbus_RTU_Slave
*
)
rp
->
op
;
local_rack
=
rp
->
Local
;
/* Request new data */
if
(
/* sp->Status == MB__NORMAL && */
sp
->
DisableSlave
!=
1
)
{
sts
=
mb_rtu_send_data
(
rp
,
local
,
local_rack
,
op
,
sp
,
mb_mSendMask_WriteReq
);
}
break
;
}
rp
=
rp
->
next
;
}
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoAgentClose
(
io_tCtx
ctx
,
io_sAgent
*
ap
)
{
io_sAgentLocal
*
local
=
(
io_sAgentLocal
*
)
ap
->
Local
;
close
(
local
->
fd
);
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport
pwr_BindIoMethods
(
Modbus_RTU_Master
)
=
{
pwr_BindIoMethod
(
IoAgentInit
),
pwr_BindIoMethod
(
IoAgentRead
),
pwr_BindIoMethod
(
IoAgentWrite
),
pwr_BindIoMethod
(
IoAgentClose
),
pwr_NullMethod
};
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_module.c
0 → 100644
View file @
7c5b1249
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2011 SSAB Oxelosund AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include "pwr.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_io_bus.h"
#include "rt_mb_msg.h"
#include "rt_io_mb_rtu.h"
/*----------------------------------------------------------------------------*\
Init method for the Modbus module
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoCardInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sCardLocalMsg
*
local
;
pwr_sClass_Modbus_RTU_Module
*
op
;
int
i
;
op
=
(
pwr_sClass_Modbus_RTU_Module
*
)
cp
->
op
;
local
=
((
io_sCardLocal
*
)
cp
->
Local
)
->
msg
;
for
(
i
=
0
;
i
<
IO_MAXCHAN
;
i
++
)
{
local
->
scancount
[
i
]
=
0
;
}
op
->
Status
=
pwr_eModbusModule_StatusEnum_StatusUnknown
;
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Read method for the Modbus RTU module
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoCardRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sCardLocalMsg
*
local
;
io_sRackLocal
*
local_rack
=
(
io_sRackLocal
*
)
rp
->
Local
;
pwr_sClass_Modbus_RTU_Module
*
op
;
pwr_sClass_Modbus_RTU_Slave
*
slave
;
op
=
(
pwr_sClass_Modbus_RTU_Module
*
)
cp
->
op
;
local
=
((
io_sCardLocal
*
)
cp
->
Local
)
->
msg
;
slave
=
(
pwr_sClass_Modbus_RTU_Slave
*
)
rp
->
op
;
if
(
op
->
ScanInterval
>
1
)
{
local
->
has_read_method
=
1
;
if
(
local
->
interval_cnt
!=
0
)
{
local
->
interval_cnt
++
;
if
(
local
->
interval_cnt
>=
op
->
ScanInterval
)
local
->
interval_cnt
=
0
;
return
IO__SUCCESS
;
}
local
->
interval_cnt
++
;
}
if
(
slave
->
Status
==
MB__NORMAL
||
local_rack
->
reset_inputs
)
{
io_bus_card_read
(
ctx
,
rp
,
cp
,
slave
->
Inputs
,
NULL
,
pwr_eByteOrderingEnum_BigEndian
,
pwr_eFloatRepEnum_FloatIntel
);
}
// printf("Method Modbus_RTU_Module-IoCardRead\n");
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Write method for the Modbus RTU module
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoCardWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sCardLocalMsg
*
local
;
pwr_sClass_Modbus_RTU_Module
*
op
;
pwr_sClass_Modbus_RTU_Slave
*
slave
;
op
=
(
pwr_sClass_Modbus_RTU_Module
*
)
cp
->
op
;
local
=
((
io_sCardLocal
*
)
cp
->
Local
)
->
msg
;
slave
=
(
pwr_sClass_Modbus_RTU_Slave
*
)
rp
->
op
;
if
(
op
->
ScanInterval
>
1
)
{
if
(
!
local
->
has_read_method
)
{
if
(
local
->
interval_cnt
!=
0
)
{
local
->
interval_cnt
++
;
if
(
local
->
interval_cnt
>=
op
->
ScanInterval
)
local
->
interval_cnt
=
0
;
return
IO__SUCCESS
;
}
local
->
interval_cnt
++
;
}
else
if
(
local
->
interval_cnt
!=
1
)
return
IO__SUCCESS
;
}
if
(
slave
->
Status
==
MB__NORMAL
)
{
io_bus_card_write
(
ctx
,
cp
,
slave
->
Outputs
,
pwr_eByteOrderingEnum_BigEndian
,
pwr_eFloatRepEnum_FloatIntel
);
}
// printf("Method Modbus_RTU_Module-IoCardWrite\n");
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport
pwr_BindIoMethods
(
Modbus_RTU_Module
)
=
{
pwr_BindIoMethod
(
IoCardInit
),
pwr_BindIoMethod
(
IoCardRead
),
pwr_BindIoMethod
(
IoCardWrite
),
pwr_NullMethod
};
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_server.c
0 → 100644
View file @
7c5b1249
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2011 SSAB Oxelosund AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
/* rt_io_m_mb_rtu_server.c -- io methods for Modbus/RTU Server */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#if defined OS_LINUX
#include <termio.h>
#endif
#if defined OS_LINUX || defined OS_MACOS
#include <sgtty.h>
#endif
#include <sys/ioctl.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "pwr_version.h"
#include "rt_gdh.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "co_cdh.h"
#include "co_time.h"
#include "rt_mb_msg.h"
#include "rt_io_mb_rtu.h"
char
rcv_buffer
[
512
];
static
pwr_tStatus
mb_init_channels
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
);
static
void
mb_shift_write
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
);
static
void
mb_shift_read
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
);
typedef
struct
{
io_sRack
*
rp
;
}
mb_sCondata
;
static
void
float_to_timeval
(
struct
timeval
*
tv
,
float
t
)
{
tv
->
tv_sec
=
t
;
tv
->
tv_usec
=
(
t
-
(
float
)
tv
->
tv_sec
)
*
1000000
;
}
static
void
float_to_timespec
(
struct
timespec
*
tv
,
float
t
)
{
tv
->
tv_sec
=
t
;
tv
->
tv_nsec
=
(
t
-
(
float
)
tv
->
tv_sec
)
*
1000000000
;
}
static
void
generate_crc
(
unsigned
char
*
buf
,
int
size
,
unsigned
char
*
result
)
{
unsigned
short
int
crc
;
unsigned
short
int
gen_polynomial
=
0xA001
;
unsigned
short
int
flag_mask
=
0x0001
;
unsigned
short
int
flag
;
int
i
,
j
;
crc
=
0xFFFF
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
crc
=
crc
^
buf
[
i
];
for
(
j
=
0
;
j
<
8
;
j
++
)
{
flag
=
crc
&
flag_mask
;
crc
=
crc
>>
1
;
if
(
flag
)
crc
=
crc
^
gen_polynomial
;
}
}
result
[
0
]
=
(
unsigned
char
)
(
crc
&
0x00FF
);
result
[
1
]
=
(
unsigned
char
)
((
crc
>>
8
)
&
0x00FF
);
}
static
pwr_tStatus
rtu_send
(
io_sServerLocal
*
local_master
,
pwr_sClass_Modbus_RTU_Server
*
op
,
void
*
bufp
,
int
buffer_size
)
{
int
sts
;
unsigned
char
*
buf
=
(
unsigned
char
*
)
bufp
;
struct
timespec
tf
;
generate_crc
(
buf
,
buffer_size
,
&
buf
[
buffer_size
]);
if
(
op
->
Debug
)
{
int
i
;
pwr_tTime
current
;
char
timstr
[
40
];
time_GetTime
(
&
current
);
time_AtoAscii
(
&
current
,
time_eFormat_Time
,
timstr
,
sizeof
(
timstr
));
printf
(
"Snd: %s %2d "
,
timstr
,
buffer_size
+
2
);
for
(
i
=
0
;
i
<
buffer_size
+
2
;
i
++
)
printf
(
"%02d "
,
buf
[
i
]);
printf
(
"
\n
"
);
}
float_to_timespec
(
&
tf
,
op
->
FrameTimeout
);
nanosleep
(
&
tf
,
NULL
);
sts
=
write
(
local_master
->
fd
,
buf
,
buffer_size
+
2
);
if
(
sts
<=
0
)
{
op
->
ErrorCount
++
;
return
0
;
}
return
1
;
}
static
void
*
mb_receive
(
void
*
data
)
{
io_sRack
*
rp
=
((
mb_sCondata
*
)
data
)
->
rp
;
io_sServerLocal
*
local_master
=
rp
->
Local
;
pwr_sClass_Modbus_RTU_Server
*
op
=
(
pwr_sClass_Modbus_RTU_Server
*
)
rp
->
op
;
int
data_size
=
0
;
rec_buf
*
rb
;
unsigned
char
fc
;
unsigned
char
exception_code
;
ssize_t
ssts
;
struct
timeval
tv
=
{
0
,
0
};
int
sts
;
fd_set
read_fd
;
unsigned
char
crc
[
2
];
unsigned
char
telegram
[
512
];
free
(
data
);
tcflush
(
local_master
->
fd
,
TCIOFLUSH
);
while
(
1
)
{
sts
=
1
;
data_size
=
0
;
float_to_timeval
(
&
tv
,
op
->
CharTimeout
);
FD_ZERO
(
&
read_fd
);
FD_SET
(
local_master
->
fd
,
&
read_fd
);
sts
=
select
(
local_master
->
fd
+
1
,
&
read_fd
,
NULL
,
NULL
,
&
tv
);
if
(
sts
==
0
)
continue
;
sts
=
read
(
local_master
->
fd
,
telegram
,
1
);
if
(
sts
<=
0
)
{
op
->
Status
=
MB__CONNLOST
;
continue
;
}
while
(
sts
>
0
)
{
data_size
++
;
if
(
data_size
>
256
)
{
data_size
=
0
;
break
;
}
float_to_timeval
(
&
tv
,
op
->
CharTimeout
);
FD_ZERO
(
&
read_fd
);
FD_SET
(
local_master
->
fd
,
&
read_fd
);
sts
=
select
(
local_master
->
fd
+
1
,
&
read_fd
,
NULL
,
NULL
,
&
tv
);
if
(
sts
==
0
)
{
break
;
}
sts
=
read
(
local_master
->
fd
,
telegram
+
data_size
,
1
);
}
if
(
data_size
<
2
)
{
op
->
ErrorCount
++
;
continue
;
}
if
(
op
->
Debug
)
{
int
i
;
pwr_tTime
current
;
char
timstr
[
40
];
time_GetTime
(
&
current
);
time_AtoAscii
(
&
current
,
time_eFormat_Time
,
timstr
,
sizeof
(
timstr
));
printf
(
"Rcv: %s %2d "
,
timstr
,
data_size
);
for
(
i
=
0
;
i
<
data_size
;
i
++
)
printf
(
"%02d "
,
telegram
[
i
]);
printf
(
"
\n
"
);
}
generate_crc
(
telegram
,
data_size
-
2
,
crc
);
if
(
crc
[
0
]
!=
telegram
[
data_size
-
2
]
||
crc
[
1
]
!=
telegram
[
data_size
-
1
])
{
op
->
ErrorCount
++
;
continue
;
}
op
->
RX_packets
++
;
rb
=
(
rec_buf
*
)
telegram
;
fc
=
rb
->
fc
;
time_GetTime
(
&
local_master
->
last_req_time
);
exception_code
=
0
;
switch
(
fc
)
{
case
pwr_eModbus_FCEnum_ReadHoldingRegisters
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_RTU_ServerModule
*
mp
;
read_req
*
rmsg
=
(
read_req
*
)
rb
;
rsp_read
msg
;
int
found
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
addr
-=
mp
->
ReadAddress
;
if
(
addr
<
0
||
addr
+
quant
*
2
>
local_card
->
output_size
)
{
exception_code
=
2
;
break
;
}
msg
.
fc
=
fc
;
msg
.
bc
=
quant
*
2
;
msg
.
unit_id
=
rmsg
->
unit_id
;
thread_MutexLock
(
&
local_master
->
mutex
);
memcpy
(
msg
.
buf
,
(
char
*
)
local_card
->
output_area
+
addr
,
quant
*
2
);
thread_MutexUnlock
(
&
local_master
->
mutex
);
ssts
=
rtu_send
(
local_master
,
op
,
&
msg
,
sizeof
(
msg
)
-
sizeof
(
msg
.
buf
)
+
quant
*
2
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_ReadCoils
:
case
pwr_eModbus_FCEnum_ReadDiscreteInputs
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_RTU_ServerModule
*
mp
;
read_req
*
rmsg
=
(
read_req
*
)
rb
;
rsp_read
msg
;
int
found
;
unsigned
char
mask
;
unsigned
int
bytes
;
int
i
;
int
offs
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
offs
=
addr
/
8
;
bytes
=
(
addr
+
quant
)
/
8
+
(((
addr
+
quant
)
%
8
==
0
)
?
0
:
1
)
-
offs
;
if
(
addr
<
0
||
offs
+
bytes
+
local_card
->
do_offset
>
local_card
->
output_size
||
offs
+
bytes
>
local_card
->
do_size
)
{
exception_code
=
2
;
break
;
}
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
fc
=
fc
;
msg
.
bc
=
bytes
;
msg
.
unit_id
=
rmsg
->
unit_id
;
thread_MutexLock
(
&
local_master
->
mutex
);
if
(
addr
%
8
==
0
)
{
memcpy
(
msg
.
buf
,
(
char
*
)
local_card
->
output_area
+
local_card
->
do_offset
+
addr
/
8
,
bytes
);
mask
=
0
;
for
(
i
=
0
;
i
<
quant
%
8
;
i
++
)
mask
|=
1
<<
i
;
if
(
quant
%
8
!=
0
)
{
unsigned
char
*
b
=
(
unsigned
char
*
)
msg
.
buf
;
b
[
bytes
-
1
]
&=
mask
;
}
}
else
{
mb_shift_read
(
(
unsigned
char
*
)
local_card
->
output_area
+
local_card
->
do_offset
+
addr
/
8
,
(
unsigned
char
*
)
msg
.
buf
,
addr
%
8
,
quant
);
}
thread_MutexUnlock
(
&
local_master
->
mutex
);
ssts
=
rtu_send
(
local_master
,
op
,
&
msg
,
sizeof
(
msg
)
-
sizeof
(
msg
.
buf
)
+
bytes
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteSingleRegister
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_RTU_ServerModule
*
mp
;
write_single_req
*
rmsg
=
(
write_single_req
*
)
rb
;
rsp_single_write
msg
;
int
found
;
short
addr
=
ntohs
(
rmsg
->
addr
);
unsigned
char
unit_id
=
rmsg
->
unit_id
;
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
addr
-=
mp
->
WriteAddress
;
if
(
addr
<
0
||
addr
+
2
>
local_card
->
input_size
)
{
exception_code
=
2
;
break
;
}
thread_MutexLock
(
&
local_master
->
mutex
);
memcpy
(
(
char
*
)
local_card
->
input_area
+
addr
,
&
rmsg
->
value
,
2
);
thread_MutexUnlock
(
&
local_master
->
mutex
);
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
value
=
rmsg
->
value
;
msg
.
unit_id
=
rmsg
->
unit_id
;
ssts
=
rtu_send
(
local_master
,
op
,
&
msg
,
sizeof
(
msg
)
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteMultipleRegisters
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_RTU_ServerModule
*
mp
;
write_reg_req
*
rmsg
=
(
write_reg_req
*
)
rb
;
rsp_write
msg
;
int
found
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
addr
-=
mp
->
WriteAddress
;
if
(
addr
<
0
||
addr
+
quant
*
2
>
local_card
->
input_size
)
{
exception_code
=
2
;
break
;
}
thread_MutexLock
(
&
local_master
->
mutex
);
memcpy
(
(
char
*
)
local_card
->
input_area
+
addr
,
rmsg
->
reg
,
quant
*
2
);
thread_MutexUnlock
(
&
local_master
->
mutex
);
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
quant
=
rmsg
->
quant
;
msg
.
unit_id
=
rmsg
->
unit_id
;
ssts
=
rtu_send
(
local_master
,
op
,
&
msg
,
sizeof
(
msg
)
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteSingleCoil
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_RTU_ServerModule
*
mp
;
write_single_req
*
rmsg
=
(
write_single_req
*
)
rb
;
rsp_single_write
msg
;
int
found
;
unsigned
char
mask
;
int
offs
;
short
addr
=
ntohs
(
rmsg
->
addr
);
unsigned
short
value
=
ntohs
(
rmsg
->
value
);
unsigned
char
unit_id
=
rmsg
->
unit_id
;
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
offs
=
addr
/
8
;
if
(
addr
<
0
||
offs
+
local_card
->
di_offset
>=
local_card
->
input_size
||
offs
>=
local_card
->
di_size
)
{
exception_code
=
2
;
break
;
}
mask
=
1
<<
(
addr
%
8
);
if
(
value
==
0xFF00
||
value
==
0
)
{
thread_MutexLock
(
&
local_master
->
mutex
);
if
(
value
==
0xFF00
)
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
offs
)
|=
mask
;
else
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
offs
)
&=
~
mask
;
thread_MutexUnlock
(
&
local_master
->
mutex
);
}
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
value
=
rmsg
->
value
;
msg
.
unit_id
=
rmsg
->
unit_id
;
ssts
=
rtu_send
(
local_master
,
op
,
&
msg
,
sizeof
(
msg
)
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteMultipleCoils
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_RTU_ServerModule
*
mp
;
write_reg_req
*
rmsg
=
(
write_reg_req
*
)
rb
;
rsp_write
msg
;
int
found
;
unsigned
char
mask
;
unsigned
int
bytes
;
int
i
;
int
offs
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
thread_MutexLock
(
&
local_master
->
mutex
);
offs
=
addr
/
8
;
bytes
=
(
addr
+
quant
)
/
8
+
(((
addr
+
quant
)
%
8
==
0
)
?
0
:
1
)
-
offs
;
if
(
addr
<
0
||
offs
+
bytes
+
local_card
->
di_offset
>
local_card
->
input_size
||
offs
+
bytes
>
local_card
->
di_size
)
{
exception_code
=
2
;
break
;
}
if
(
addr
%
8
==
0
)
{
if
(
quant
%
8
!=
0
)
{
mask
=
0
;
for
(
i
=
0
;
i
<
quant
%
8
;
i
++
)
mask
|=
1
<<
i
;
memcpy
(
(
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
,
rmsg
->
reg
,
bytes
-
1
);
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
+
bytes
-
1
)
&=
~
mask
;
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
+
bytes
-
1
)
|=
*
((
char
*
)
rmsg
->
reg
+
bytes
-
1
)
&
mask
;
}
else
memcpy
(
(
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
,
rmsg
->
reg
,
bytes
);
}
else
{
mb_shift_write
(
(
unsigned
char
*
)
rmsg
->
reg
,
(
unsigned
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
,
addr
%
8
,
quant
);
}
thread_MutexUnlock
(
&
local_master
->
mutex
);
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
quant
=
rmsg
->
quant
;
msg
.
unit_id
=
rmsg
->
unit_id
;
ssts
=
rtu_send
(
local_master
,
op
,
&
msg
,
sizeof
(
msg
)
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
break
;
}
case
43
:
{
/* Encapsulated Interface Transport, Read Device Identification */
read_dev_id_req
*
rmsg
=
(
read_dev_id_req
*
)
rb
;
rsp_dev_id
msg
;
int
i
;
int
len
;
if
(
rmsg
->
mei_type
!=
0x2b
)
{
exception_code
=
1
;
break
;
}
if
(
rmsg
->
id_code
!=
1
)
{
exception_code
=
1
;
break
;
}
if
(
rmsg
->
object_id
!=
0
)
{
exception_code
=
1
;
break
;
}
msg
.
fc
=
rmsg
->
fc
;
msg
.
mei_type
=
rmsg
->
mei_type
;
msg
.
id_code
=
rmsg
->
id_code
;
msg
.
conformity_level
=
1
;
msg
.
more_follows
=
0
;
msg
.
next_object_id
=
0
;
msg
.
number_of_objects
=
3
;
i
=
0
;
/* Vendor name */
msg
.
list
[
i
++
]
=
0
;
len
=
strlen
(
"Proview"
);
msg
.
list
[
i
++
]
=
len
;
strncpy
(
(
char
*
)
&
msg
.
list
[
i
],
"Proview"
,
len
);
i
+=
len
;
/* Product code */
msg
.
list
[
i
++
]
=
0
;
len
=
strlen
(
"-"
);
msg
.
list
[
i
++
]
=
len
;
strncpy
(
(
char
*
)
&
msg
.
list
[
i
],
"-"
,
len
);
i
+=
len
;
/* Major Minor Revision */
msg
.
list
[
i
++
]
=
0
;
len
=
strlen
(
pwrv_cPwrVersionStr
);
msg
.
list
[
i
++
]
=
len
;
strncpy
(
(
char
*
)
&
msg
.
list
[
i
],
pwrv_cPwrVersionStr
,
len
);
i
+=
len
;
msg
.
unit_id
=
rmsg
->
unit_id
;
ssts
=
rtu_send
(
local_master
,
op
,
&
msg
,
sizeof
(
msg
)
-
sizeof
(
msg
.
list
)
+
1
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
break
;
}
default:
exception_code
=
1
;
}
if
(
exception_code
)
{
rsp_fault
rsp_f
;
rsp_f
.
fc
=
fc
+
0x80
;
rsp_f
.
ec
=
exception_code
;
rsp_f
.
unit_id
=
rb
->
unit_id
;
ssts
=
rtu_send
(
local_master
,
op
,
&
rsp_f
,
sizeof
(
rsp_f
)
-
2
);
if
(
ssts
<
0
)
{
op
->
Status
=
MB__CONNLOST
;
break
;
}
op
->
Status
=
MB__NORMAL
;
op
->
TX_packets
++
;
}
}
return
0
;
}
/*----------------------------------------------------------------------------*\
Init method for the Modbus/RTU server
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
struct
termios
tty_attributes
;
io_sServerLocal
*
local
;
pwr_tStatus
sts
;
pwr_sClass_Modbus_RTU_Server
*
op
;
pwr_tOName
name
;
mb_sCondata
*
condata
;
op
=
(
pwr_sClass_Modbus_RTU_Server
*
)
rp
->
op
;
sts
=
gdh_ObjidToName
(
rp
->
Objid
,
(
char
*
)
&
name
,
sizeof
(
name
),
cdh_mNName
);
errh_Info
(
"Init of Modbus RTU Server %s"
,
name
);
rp
->
Local
=
calloc
(
1
,
sizeof
(
io_sServerLocal
));
local
=
rp
->
Local
;
if
(
op
->
DisableServer
)
return
IO__SUCCESS
;
local
->
fd
=
open
(
op
->
Device
,
O_RDWR
|
O_NDELAY
|
O_NOCTTY
);
if
(
local
->
fd
==
-
1
)
{
errh_Error
(
"Modbus RTU Master, open device error, %s"
,
ap
->
Name
);
return
IO__ERRINIDEVICE
;
}
tcgetattr
(
local
->
fd
,
&
tty_attributes
);
tty_attributes
.
c_cc
[
VMIN
]
=
1
;
tty_attributes
.
c_cc
[
VTIME
]
=
0
;
tty_attributes
.
c_lflag
&=
~
(
ICANON
|
ISIG
|
ECHO
|
IEXTEN
);
tty_attributes
.
c_cflag
|=
(
CLOCAL
|
CREAD
);
tty_attributes
.
c_oflag
&=
~
(
OPOST
);
tty_attributes
.
c_oflag
&=
~
(
ONLCR
);
tty_attributes
.
c_iflag
&=
~
(
INLCR
|
ICRNL
);
/* Speed */
#if defined OS_LINUX
tty_attributes
.
c_cflag
&=
~
CBAUD
;
#endif
switch
(
op
->
Speed
)
{
case
300
:
tty_attributes
.
c_cflag
|=
B300
;
break
;
case
1200
:
tty_attributes
.
c_cflag
|=
B1200
;
break
;
case
2400
:
tty_attributes
.
c_cflag
|=
B2400
;
break
;
case
4800
:
tty_attributes
.
c_cflag
|=
B4800
;
break
;
case
9600
:
tty_attributes
.
c_cflag
|=
B9600
;
break
;
case
19200
:
tty_attributes
.
c_cflag
|=
B19200
;
break
;
default:
errh_Error
(
"Modbus RTU Master, unsupported speed, %s"
,
ap
->
Name
);
tty_attributes
.
c_cflag
|=
B9600
;
break
;
}
/* DataBits 5, 6, 7 or 8 */
tty_attributes
.
c_cflag
&=
~
CSIZE
;
switch
(
op
->
DataBits
)
{
case
pwr_eDataBitsEnum_5
:
tty_attributes
.
c_cflag
|=
CS5
;
break
;
case
pwr_eDataBitsEnum_6
:
tty_attributes
.
c_cflag
|=
CS6
;
break
;
case
pwr_eDataBitsEnum_7
:
tty_attributes
.
c_cflag
|=
CS7
;
break
;
case
pwr_eDataBitsEnum_8
:
tty_attributes
.
c_cflag
|=
CS8
;
break
;
default:
errh_Error
(
"Modbus RTU Master, unsupported DataBits, %s"
,
ap
->
Name
);
tty_attributes
.
c_cflag
|=
CS8
;
}
//tty_attributes.c_iflag |=ISTRIP;
/* Parity */
switch
(
op
->
Parity
)
{
case
pwr_eParityEnum_Odd
:
case
pwr_eParityEnum_Even
:
tty_attributes
.
c_cflag
|=
PARENB
;
tty_attributes
.
c_iflag
|=
IGNPAR
;
if
(
op
->
Parity
==
pwr_eParityEnum_Even
)
tty_attributes
.
c_cflag
&=
~
PARODD
;
else
tty_attributes
.
c_cflag
|=
PARODD
;
break
;
default:
tty_attributes
.
c_cflag
&=
~
PARENB
;
}
/* stopbitsval */
switch
(
op
->
StopBits
)
{
case
pwr_eStopBitsEnum_2
:
tty_attributes
.
c_cflag
|=
CSTOPB
;
break
;
case
pwr_eStopBitsEnum_1
:
tty_attributes
.
c_cflag
&=~
CSTOPB
;
break
;
case
pwr_eStopBitsEnum_0
:
errh_Error
(
"Modbus RTU Master, unsupported StopBits, %s"
,
ap
->
Name
);
tty_attributes
.
c_cflag
&=~
CSTOPB
;
break
;
}
tty_attributes
.
c_iflag
&=
~
IXON
;
//ingen XON/XOFF in
//tty_attributes.c_iflag &= (V_IGNCR);
//tty_attributes.c_iflag &= (IGNPAR | V_IGNCR);
//tty_attributes.c_iflag &= ~(BRKINT | IXON | V_INLCR | V_ICRNL);
//tty_attributes.c_cflag &= ~(CSIZE | CSTOPB | PARENB); //fippla om vrden lite granna
sts
=
tcsetattr
(
local
->
fd
,
TCSANOW
,
&
tty_attributes
);
if
(
sts
<
0
)
{
errh_Error
(
"Modbus RTU Master, set device attributes error, %s"
,
ap
->
Name
);
return
IO__ERRINIDEVICE
;
}
sts
=
mb_init_channels
(
ctx
,
ap
,
rp
);
if
(
EVEN
(
sts
))
return
sts
;
/* Create mutex */
sts
=
thread_MutexInit
(
&
local
->
mutex
);
if
(
EVEN
(
sts
))
{
errh_Error
(
"Error creating mutex IO modbus rtu server %s"
,
rp
->
Name
);
return
IO__ERRINIDEVICE
;
}
/* Create a thread for receive */
condata
=
(
mb_sCondata
*
)
malloc
(
sizeof
(
mb_sCondata
));
condata
->
rp
=
rp
;
sts
=
thread_Create
(
&
local
->
receive_thread
,
0
,
mb_receive
,
(
void
*
)
condata
);
if
(
EVEN
(
sts
))
{
errh_Error
(
"Error creating receive thread IO modbus rtu server %s"
,
rp
->
Name
);
free
(
condata
);
return
IO__ERRINIDEVICE
;
}
op
->
Status
=
MB__NORMAL
;
return
IO__SUCCESS
;
}
static
pwr_tStatus
mb_init_channels
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
io_sServerModuleLocal
*
local_card
;
io_sCard
*
cardp
;
io_sServerLocal
*
local
;
short
input_counter
;
short
output_counter
;
short
card_input_counter
;
short
card_output_counter
;
pwr_sClass_Modbus_RTU_Server
*
op
;
pwr_sClass_Modbus_RTU_ServerModule
*
mp
;
char
name
[
196
];
pwr_tStatus
sts
;
pwr_tCid
cid
;
io_sChannel
*
chanp
;
int
i
,
latent_input_counter
,
latent_output_counter
;
pwr_tInt32
chan_size
;
pwr_sClass_ChanDi
*
chan_di
;
pwr_sClass_ChanDo
*
chan_do
;
pwr_sClass_ChanAi
*
chan_ai
;
pwr_sClass_ChanAit
*
chan_ait
;
pwr_sClass_ChanIi
*
chan_ii
;
pwr_sClass_ChanAo
*
chan_ao
;
pwr_sClass_ChanIo
*
chan_io
;
sts
=
gdh_ObjidToName
(
rp
->
Objid
,
(
char
*
)
&
name
,
sizeof
(
name
),
cdh_mNName
);
op
=
(
pwr_sClass_Modbus_RTU_Server
*
)
rp
->
op
;
local
=
rp
->
Local
;
/* Create socket, store in local struct */
/* Do configuration check and initialize modules. */
cardp
=
rp
->
cardlist
;
input_counter
=
0
;
output_counter
=
0
;
card_input_counter
=
0
;
card_output_counter
=
0
;
latent_input_counter
=
0
;
latent_output_counter
=
0
;
while
(
cardp
)
{
local_card
=
calloc
(
1
,
sizeof
(
*
local_card
));
cardp
->
Local
=
local_card
;
input_counter
=
input_counter
+
card_input_counter
+
latent_input_counter
;
output_counter
=
output_counter
+
card_output_counter
+
latent_output_counter
;
local_card
->
input_area
=
(
void
*
)
&
(
op
->
Inputs
)
+
input_counter
;
local_card
->
output_area
=
(
void
*
)
&
(
op
->
Outputs
)
+
output_counter
;
card_input_counter
=
0
;
card_output_counter
=
0
;
latent_input_counter
=
0
;
latent_output_counter
=
0
;
/* From v4.1.3 we can have subclasses, find the super class */
cid
=
cardp
->
Class
;
while
(
ODD
(
gdh_GetSuperClass
(
cid
,
&
cid
,
cardp
->
Objid
)))
;
switch
(
cid
)
{
case
pwr_cClass_Modbus_RTU_ServerModule
:
mp
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cardp
->
op
;
mp
->
Status
=
pwr_eModbusModule_StatusEnum_StatusUnknown
;
for
(
i
=
0
;
i
<
cardp
->
ChanListSize
;
i
++
)
{
chanp
=
&
cardp
->
chanlist
[
i
];
if
(
is_diag
(
&
chanp
->
ChanAref
))
{
chanp
->
udata
|=
PB_UDATA_DIAG
;
switch
(
chanp
->
ChanClass
)
{
case
pwr_cClass_ChanIi
:
chanp
->
offset
=
((
pwr_sClass_ChanIi
*
)
chanp
->
cop
)
->
Number
;
chanp
->
size
=
GetChanSize
(
((
pwr_sClass_ChanIi
*
)
chanp
->
cop
)
->
Representation
);
break
;
default:
errh_Error
(
"Diagnostic channel class, card %s"
,
cardp
->
Name
);
}
continue
;
}
if
(
chanp
->
ChanClass
!=
pwr_cClass_ChanDi
)
{
card_input_counter
+=
latent_input_counter
;
latent_input_counter
=
0
;
}
if
(
chanp
->
ChanClass
!=
pwr_cClass_ChanDo
)
{
card_output_counter
+=
latent_output_counter
;
latent_output_counter
=
0
;
}
switch
(
chanp
->
ChanClass
)
{
case
pwr_cClass_ChanDi
:
chan_di
=
(
pwr_sClass_ChanDi
*
)
chanp
->
cop
;
if
(
chan_di
->
Number
==
0
)
{
card_input_counter
+=
latent_input_counter
;
latent_input_counter
=
0
;
}
chanp
->
offset
=
card_input_counter
;
chanp
->
mask
=
1
<<
chan_di
->
Number
;
if
(
chan_di
->
Representation
==
pwr_eDataRepEnum_Bit16
)
chanp
->
mask
=
swap16
(
chanp
->
mask
);
if
(
chan_di
->
Representation
==
pwr_eDataRepEnum_Bit32
)
chanp
->
mask
=
swap32
((
unsigned
short
)
chanp
->
mask
);
if
(
chan_di
->
Number
==
0
)
latent_input_counter
=
GetChanSize
(
chan_di
->
Representation
);
if
(
local_card
->
di_size
==
0
)
local_card
->
di_offset
=
chanp
->
offset
;
if
(
chan_di
->
Number
==
0
||
local_card
->
di_size
==
0
)
local_card
->
di_size
+=
GetChanSize
(
chan_di
->
Representation
);
// printf("Di channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_di->Number, chanp->offset);
break
;
case
pwr_cClass_ChanAi
:
chan_ai
=
(
pwr_sClass_ChanAi
*
)
chanp
->
cop
;
chanp
->
offset
=
card_input_counter
;
chan_size
=
GetChanSize
(
chan_ai
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_input_counter
+=
chan_size
;
io_AiRangeToCoef
(
chanp
);
// printf("Ai channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ai->Number, chanp->offset);
break
;
case
pwr_cClass_ChanAit
:
chan_ait
=
(
pwr_sClass_ChanAit
*
)
chanp
->
cop
;
chanp
->
offset
=
card_input_counter
;
chan_size
=
GetChanSize
(
chan_ait
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_input_counter
+=
chan_size
;
io_AiRangeToCoef
(
chanp
);
break
;
case
pwr_cClass_ChanIi
:
chan_ii
=
(
pwr_sClass_ChanIi
*
)
chanp
->
cop
;
chanp
->
offset
=
card_input_counter
;
chan_size
=
GetChanSize
(
chan_ii
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_input_counter
+=
chan_size
;
// printf("Ii channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ii->Number, chanp->offset);
break
;
case
pwr_cClass_ChanDo
:
chan_do
=
(
pwr_sClass_ChanDo
*
)
chanp
->
cop
;
if
(
chan_do
->
Number
==
0
)
{
card_output_counter
+=
latent_output_counter
;
latent_output_counter
=
0
;
}
chanp
->
offset
=
card_output_counter
;
chan_size
=
GetChanSize
(
chan_do
->
Representation
);
chanp
->
mask
=
1
<<
chan_do
->
Number
;
if
(
chan_do
->
Representation
==
pwr_eDataRepEnum_Bit16
)
chanp
->
mask
=
swap16
(
chanp
->
mask
);
if
(
chan_do
->
Representation
==
pwr_eDataRepEnum_Bit32
)
chanp
->
mask
=
swap32
((
unsigned
short
)
chanp
->
mask
);
if
(
chan_do
->
Number
==
0
)
latent_output_counter
=
GetChanSize
(
chan_do
->
Representation
);
if
(
local_card
->
do_size
==
0
)
local_card
->
do_offset
=
chanp
->
offset
;
if
(
chan_do
->
Number
==
0
||
local_card
->
do_size
==
0
)
local_card
->
do_size
+=
GetChanSize
(
chan_do
->
Representation
);
// printf("Do channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_do->Number, chanp->offset);
break
;
case
pwr_cClass_ChanAo
:
chan_ao
=
(
pwr_sClass_ChanAo
*
)
chanp
->
cop
;
chanp
->
offset
=
card_output_counter
;
chan_size
=
GetChanSize
(
chan_ao
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_output_counter
+=
chan_size
;
io_AoRangeToCoef
(
chanp
);
// printf("Ao channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ao->Number, chanp->offset);
break
;
case
pwr_cClass_ChanIo
:
chan_io
=
(
pwr_sClass_ChanIo
*
)
chanp
->
cop
;
chanp
->
offset
=
card_output_counter
;
chan_size
=
GetChanSize
(
chan_io
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_output_counter
+=
chan_size
;
// printf("Io channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_io->Number, chanp->offset);
break
;
}
}
/* End - for ... */
break
;
}
/* End - switch ... */
local_card
->
input_size
=
card_input_counter
+
latent_input_counter
;
local_card
->
output_size
=
card_output_counter
+
latent_output_counter
;
cardp
=
cardp
->
next
;
}
local
->
input_size
=
input_counter
+
card_input_counter
+
latent_input_counter
;
local
->
output_size
=
output_counter
+
card_output_counter
+
latent_output_counter
;
return
IO__SUCCESS
;
}
static
void
mb_shift_write
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
)
{
int
i
;
if
(
sh
+
quant
<=
8
)
{
unsigned
char
mask
=
0
;
for
(
i
=
sh
;
i
<
sh
+
quant
;
i
++
)
mask
|=
1
<<
i
;
out
[
0
]
&=
~
mask
;
out
[
0
]
|=
mask
&
(
in
[
0
]
<<
sh
);
return
;
}
for
(
i
=
0
;
i
<
(
quant
+
sh
)
/
8
;
i
++
)
{
if
(
i
==
0
)
{
unsigned
char
mask
=
~
0
<<
sh
;
out
[
0
]
&=
~
mask
;
out
[
0
]
|=
mask
&
(
in
[
0
]
<<
sh
);
}
else
{
out
[
i
]
=
in
[
i
]
<<
sh
;
out
[
i
]
|=
in
[
i
-
1
]
>>
(
8
-
sh
);
}
}
if
(
(
quant
+
sh
)
%
8
!=
0
)
{
unsigned
char
mask
=
~
0
<<
((
quant
+
sh
)
%
8
);
mask
=
~
mask
;
out
[
i
]
&=
~
mask
;
out
[
i
]
|=
mask
&
(
in
[
i
]
<<
sh
);
out
[
i
]
|=
mask
&
(
in
[
i
-
1
]
>>
(
8
-
sh
));
}
}
void
mb_shift_read
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
)
{
int
i
;
if
(
sh
+
quant
<=
8
)
{
unsigned
char
mask
=
~
0
;
mask
=
mask
>>
(
8
-
quant
);
out
[
0
]
=
mask
&
(
in
[
0
]
>>
sh
);
return
;
}
for
(
i
=
0
;
i
<
quant
/
8
;
i
++
)
{
out
[
i
]
=
in
[
i
]
>>
sh
;
out
[
i
]
|=
in
[
i
+
1
]
<<
(
8
-
sh
);
}
out
[
i
]
=
in
[
i
]
>>
sh
;
if
(
(
quant
+
sh
)
/
8
>
quant
/
8
)
out
[
i
]
|=
in
[
i
+
1
]
<<
(
8
-
sh
);
if
(
quant
%
8
!=
0
)
{
unsigned
char
mask
=
~
0
;
mask
=
mask
>>
(
8
-
(
quant
%
8
));
out
[
i
]
&=
mask
;
}
}
/*----------------------------------------------------------------------------*\
Read method for the Modbus RTU server
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Write method for the Modbus_RTU server
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackClose
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
io_sServerLocal
*
local
=
rp
->
Local
;
close
(
local
->
fd
);
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport
pwr_BindIoMethods
(
Modbus_RTU_Server
)
=
{
pwr_BindIoMethod
(
IoRackInit
),
pwr_BindIoMethod
(
IoRackRead
),
pwr_BindIoMethod
(
IoRackWrite
),
pwr_BindIoMethod
(
IoRackClose
),
pwr_NullMethod
};
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_servermodule.c
0 → 100644
View file @
7c5b1249
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2011 SSAB Oxelosund AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>
#include "pwr.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_io_bus.h"
#include "rt_mb_msg.h"
#include "rt_io_mb_rtu.h"
#include "co_time.h"
/*----------------------------------------------------------------------------*\
Init method for the Modbus server module
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoCardInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sServerModuleLocal
*
local
;
pwr_sClass_Modbus_RTU_ServerModule
*
op
;
int
i
;
op
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cp
->
op
;
local
=
(
io_sServerModuleLocal
*
)
cp
->
Local
;
for
(
i
=
0
;
i
<
IO_MAXCHAN
;
i
++
)
{
local
->
scancount
[
i
]
=
0
;
}
op
->
Status
=
pwr_eModbusModule_StatusEnum_StatusUnknown
;
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Read method for the Modbus RTU server module
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoCardRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sServerModuleLocal
*
local
;
io_sServerLocal
*
local_server
;
pwr_sClass_Modbus_RTU_ServerModule
*
op
;
pwr_sClass_Modbus_RTU_Server
*
server
;
op
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cp
->
op
;
local
=
(
io_sServerModuleLocal
*
)
cp
->
Local
;
server
=
(
pwr_sClass_Modbus_RTU_Server
*
)
rp
->
op
;
local_server
=
(
io_sServerLocal
*
)
rp
->
Local
;
if
(
server
->
DisableServer
||
!
local
)
return
IO__SUCCESS
;
if
(
server
->
Status
==
MB__NORMAL
)
{
thread_MutexLock
(
&
local_server
->
mutex
);
io_bus_card_read
(
ctx
,
rp
,
cp
,
local
->
input_area
,
NULL
,
pwr_eByteOrderingEnum_BigEndian
,
pwr_eFloatRepEnum_FloatIntel
);
thread_MutexUnlock
(
&
local_server
->
mutex
);
}
// printf("Method Modbus_Module-IoCardRead\n");
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Write method for the Modbus RTU server module
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoCardWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
,
io_sCard
*
cp
)
{
io_sServerModuleLocal
*
local
;
io_sServerLocal
*
local_server
;
pwr_sClass_Modbus_RTU_ServerModule
*
op
;
pwr_sClass_Modbus_RTU_Server
*
server
;
op
=
(
pwr_sClass_Modbus_RTU_ServerModule
*
)
cp
->
op
;
local
=
(
io_sServerModuleLocal
*
)
cp
->
Local
;
server
=
(
pwr_sClass_Modbus_RTU_Server
*
)
rp
->
op
;
local_server
=
(
io_sServerLocal
*
)
rp
->
Local
;
if
(
server
->
DisableServer
||
!
local
)
return
IO__SUCCESS
;
if
(
server
->
Status
==
MB__NORMAL
)
{
thread_MutexLock
(
&
local_server
->
mutex
);
io_bus_card_write
(
ctx
,
cp
,
local
->
output_area
,
pwr_eByteOrderingEnum_BigEndian
,
pwr_eFloatRepEnum_FloatIntel
);
thread_MutexUnlock
(
&
local_server
->
mutex
);
}
// printf("Method Modbus_Module-IoCardWrite\n");
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport
pwr_BindIoMethods
(
Modbus_RTU_ServerModule
)
=
{
pwr_BindIoMethod
(
IoCardInit
),
pwr_BindIoMethod
(
IoCardRead
),
pwr_BindIoMethod
(
IoCardWrite
),
pwr_NullMethod
};
otherio/lib/rt/src/os_linux/rt_io_m_mb_rtu_slave.c
0 → 100644
View file @
7c5b1249
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2011 SSAB Oxelosund AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
/* rt_io_m_mb_rtu_slave.c -- io methods for a Modbus RTU slave */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "rt_gdh.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "co_cdh.h"
#include "co_time.h"
#include "rt_mb_msg.h"
#include "rt_io_mb_rtu.h"
/*----------------------------------------------------------------------------*\
Init method for the Modbus_TCP slave
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
io_sCardLocal
*
local_card
;
io_sCard
*
cardp
;
io_sRackLocal
*
local
;
int
no_di
;
int
no_do
;
pwr_sClass_Modbus_RTU_Slave
*
op
;
char
name
[
196
];
pwr_tStatus
sts
;
pwr_tCid
cid
;
io_sChannel
*
chanp
;
int
i
;
sts
=
gdh_ObjidToName
(
rp
->
Objid
,
(
char
*
)
&
name
,
sizeof
(
name
),
cdh_mNName
);
errh_Info
(
"Init of Modbus TCP Slave and Modules %s"
,
name
);
op
=
(
pwr_sClass_Modbus_RTU_Slave
*
)
rp
->
op
;
rp
->
Local
=
calloc
(
1
,
sizeof
(
io_sRackLocal
));
local
=
rp
->
Local
;
op
->
Status
=
MB__NORMAL
;
/* Do configuration check and initialize modules. */
cardp
=
rp
->
cardlist
;
unsigned
int
prev_input_area_offset
=
0
;
unsigned
int
prev_output_area_offset
=
0
;
unsigned
int
input_area_offset
=
0
;
unsigned
int
output_area_offset
=
0
;
unsigned
int
input_area_chansize
=
0
;
unsigned
int
output_area_chansize
=
0
;
while
(
cardp
)
{
local_card
=
calloc
(
1
,
sizeof
(
*
local_card
));
cid
=
cardp
->
Class
;
/* Find the super class */
while
(
ODD
(
gdh_GetSuperClass
(
cid
,
&
cid
,
cardp
->
Objid
)))
;
switch
(
cid
)
{
case
pwr_cClass_Modbus_RTU_Module
:
{
pwr_sClass_Modbus_RTU_Module
*
modulep
;
cardp
->
Local
=
local_card
;
no_di
=
0
;
no_do
=
0
;
local_card
->
msg
[
0
].
input_area
=
(
void
*
)
&
(
op
->
Inputs
)
+
input_area_offset
+
input_area_chansize
;
local_card
->
msg
[
0
].
output_area
=
(
void
*
)
&
(
op
->
Outputs
)
+
output_area_offset
+
output_area_chansize
;
modulep
=
(
pwr_sClass_Modbus_RTU_Module
*
)
cardp
->
op
;
modulep
->
Status
=
pwr_eModbusModule_StatusEnum_StatusUnknown
;
io_bus_card_init
(
ctx
,
cardp
,
&
input_area_offset
,
&
input_area_chansize
,
&
output_area_offset
,
&
output_area_chansize
,
pwr_eByteOrderingEnum_BigEndian
);
/* Count number of di and do */
for
(
i
=
0
;
i
<
cardp
->
ChanListSize
;
i
++
)
{
chanp
=
&
cardp
->
chanlist
[
i
];
switch
(
chanp
->
ChanClass
)
{
case
pwr_cClass_ChanDi
:
no_di
++
;
break
;
case
pwr_cClass_ChanDo
:
no_do
++
;
break
;
}
}
local_card
->
msg
[
0
].
input_size
=
input_area_offset
+
input_area_chansize
-
prev_input_area_offset
;
local_card
->
msg
[
0
].
output_size
=
output_area_offset
+
output_area_chansize
-
prev_output_area_offset
;
local_card
->
msg
[
0
].
no_di
=
no_di
;
local_card
->
msg
[
0
].
no_do
=
no_do
;
break
;
}
}
/* End - switch ... */
prev_input_area_offset
=
input_area_offset
+
input_area_chansize
;
prev_output_area_offset
=
output_area_offset
+
output_area_chansize
;
cardp
=
cardp
->
next
;
}
local
->
input_size
=
input_area_offset
+
input_area_chansize
;
local
->
output_size
=
output_area_offset
+
output_area_chansize
;
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Read method for the Modbus_TCP slave
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
#if 0
io_sRackLocal *local;
pwr_sClass_Modbus_TCP_Slave *sp;
pwr_tStatus sts;
pwr_tTime now;
pwr_tDeltaTime dt;
local = rp->Local;
sp = (pwr_sClass_Modbus_TCP_Slave *) rp->op;
/* Receive data */
if ((sp->Status == MB__NORMAL) && !sp->SingleOp) {
sts = mb_recv_data(local, rp, sp);
}
if (sp->DisableSlave != 1) {
if (sp->Status == MB__NORMAL) {
sp->ErrorCount = 0;
}
else {
sp->ErrorCount++;
}
if (sp->ErrorCount > sp->ErrorLimit) {
memset(&sp->Inputs, 0, local->input_size);
}
}
else {
sp->ErrorCount = 0;
sp->Status = MB__DISABLED;
}
#endif
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Write method for the Modbus_TCP slave
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
#if 0
io_sRackLocal *local;
pwr_sClass_Modbus_TCP_Slave *sp;
pwr_tStatus sts;
local = rp->Local;
sp = (pwr_sClass_Modbus_TCP_Slave *) rp->op;
local->expected_msgs = 0;
if (sp->Status == MB__NORMAL && sp->DisableSlave != 1) {
sts = mb_send_data( rp, ap->Local, local, ap->op, sp, mb_mSendMask_WriteReq);
}
if (sp->DisableSlave == 1) sp->Status = MB__DISABLED;
#endif
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackClose
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport
pwr_BindIoMethods
(
Modbus_RTU_Slave
)
=
{
pwr_BindIoMethod
(
IoRackInit
),
pwr_BindIoMethod
(
IoRackRead
),
pwr_BindIoMethod
(
IoRackWrite
),
pwr_BindIoMethod
(
IoRackClose
),
pwr_NullMethod
};
otherio/lib/rt/src/os_linux/rt_io_mb_rtu.h
0 → 100644
View file @
7c5b1249
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2011 SSAB Oxelosund AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
#ifndef pwr_class_h
#include "pwr_class.h"
#endif
#define IO_MAXCHAN 96
#define MAX_MSGS_LOST 5
// These constants are obsolete from V4.1, except for the old style
// (Pb_Di, Pb_Do etc)
#define PB_MODULE_STATE_NOTINIT 0
#define PB_MODULE_STATE_OPERATE 1
#define PB_NUMREP_UNSIGNEDINT 0
#define PB_NUMREP_SIGNEDINT 1
#define PB_NUMREP_FLOATIEEE 2
#define PB_NUMREP_FLOATVAX 3
#define PB_NUMREP_FLOATINTEL 4
#define PB_ORIENTATION_BYTE 8
#define PB_ORIENTATION_WORD 16
#define PB_ORIENTATION_DWORD 32
#define PB_UDATA_DIAG 1
#define MB_MAX_CONNECTIONS 20
typedef
pwr_tMask
mb_tSendMask
;
typedef
enum
{
mb_mSendMask_ReadReq
=
1
,
mb_mSendMask_WriteReq
=
2
,
}
mb_mSendMask
;
typedef
struct
{
int
initialized
;
int
fd
;
}
io_sAgentLocal
;
typedef
struct
{
int
initialized
;
short
int
trans_id
;
int
input_size
;
int
output_size
;
int
msgs_lost
;
pwr_tTime
last_try_connect_time
;
int
reset_inputs
;
}
io_sRackLocal
;
typedef
struct
{
void
*
input_area
;
void
*
output_area
;
int
scancount
[
IO_MAXCHAN
];
int
trans_id
;
int
input_size
;
int
output_size
;
short
int
no_di
;
short
int
no_do
;
int
interval_cnt
;
int
has_read_method
;
}
io_sCardLocalMsg
;
typedef
struct
{
io_sCardLocalMsg
msg
[
2
];
}
io_sCardLocal
;
typedef
struct
{
int
initialized
;
int
fd
;
int
input_size
;
int
output_size
;
pwr_tTime
last_req_time
;
thread_sMutex
mutex
;
thread_s
receive_thread
;
}
io_sServerLocal
;
typedef
struct
{
void
*
input_area
;
void
*
output_area
;
int
scancount
[
IO_MAXCHAN
];
int
trans_id
;
int
input_size
;
int
output_size
;
int
no_di
;
int
no_do
;
int
di_offset
;
int
do_offset
;
int
di_size
;
int
do_size
;
}
io_sServerModuleLocal
;
#pragma pack(1)
typedef
struct
_read_req
{
unsigned
char
unit_id
;
unsigned
char
fc
;
short
int
addr
;
short
int
quant
;
short
int
crc
;
}
read_req
;
typedef
struct
_rec_buf
{
unsigned
char
unit_id
;
unsigned
char
fc
;
unsigned
char
buf
[
255
];
}
rec_buf
;
typedef
struct
_write_single_req
{
unsigned
char
unit_id
;
unsigned
char
fc
;
short
int
addr
;
short
int
value
;
short
int
crc
;
}
write_single_req
;
typedef
struct
_write_reg_req
{
unsigned
char
unit_id
;
unsigned
char
fc
;
short
int
addr
;
short
int
quant
;
unsigned
char
bc
;
short
int
reg
[
125
];
short
int
crc
;
}
write_reg_req
;
typedef
struct
_write_coils_req
{
unsigned
char
unit_id
;
unsigned
char
fc
;
short
int
addr
;
short
int
quant
;
unsigned
char
bc
;
unsigned
char
reg
[
247
];
short
int
crc
;
}
write_coils_req
;
typedef
struct
_read_dev_id_req
{
unsigned
char
unit_id
;
unsigned
char
fc
;
unsigned
char
mei_type
;
unsigned
char
id_code
;
unsigned
char
object_id
;
short
int
crc
;
}
read_dev_id_req
;
typedef
struct
_res_write
{
unsigned
char
unit_id
;
unsigned
char
fc
;
short
int
addr
;
short
int
quant
;
unsigned
char
buf
[
248
];
short
int
crc
;
}
res_write
;
typedef
struct
_res_read
{
unsigned
char
unit_id
;
unsigned
char
fc
;
unsigned
char
bc
;
unsigned
char
buf
[
251
];
short
int
crc
;
}
res_read
;
typedef
struct
_res_fault
{
unsigned
char
unit_id
;
unsigned
char
fc
;
unsigned
char
ec
;
short
int
crc
;
}
res_fault
;
typedef
struct
_rsp_fault
{
unsigned
char
unit_id
;
unsigned
char
fc
;
unsigned
char
ec
;
short
int
crc
;
}
rsp_fault
;
typedef
struct
_rsp_read
{
unsigned
char
unit_id
;
unsigned
char
fc
;
unsigned
char
bc
;
unsigned
char
buf
[
250
];
short
int
crc
;
}
rsp_read
;
typedef
struct
_rsp_write
{
unsigned
char
unit_id
;
unsigned
char
fc
;
short
int
addr
;
short
int
quant
;
short
int
crc
;
}
rsp_write
;
typedef
struct
_rsp_single_write
{
unsigned
char
unit_id
;
unsigned
char
fc
;
short
int
addr
;
short
int
value
;
short
int
crc
;
}
rsp_single_write
;
typedef
struct
_rsp_dev_id
{
unsigned
char
unit_id
;
unsigned
char
fc
;
unsigned
char
mei_type
;
unsigned
char
id_code
;
unsigned
char
conformity_level
;
unsigned
char
more_follows
;
unsigned
char
next_object_id
;
unsigned
char
number_of_objects
;
unsigned
char
list
[
80
];
short
int
crc
;
}
rsp_dev_id
;
#pragma pack(0)
pwr_tStatus
mb_recv_data
(
io_sRackLocal
*
local
,
io_sRack
*
rp
,
pwr_sClass_Modbus_TCP_Slave
*
sp
);
pwr_tStatus
mb_send_data
(
io_sRackLocal
*
local
,
io_sRack
*
rp
,
pwr_sClass_Modbus_TCP_Slave
*
sp
,
mb_tSendMask
mask
);
otherio/lib/rt/src/rt_io_otherio.meth
View file @
7c5b1249
...
...
@@ -6,6 +6,11 @@ Modbus_ModuleReadWrite
Modbus_Master
Modbus_TCP_Server
Modbus_TCP_ServerModule
Modbus_RTU_Slave
Modbus_RTU_Module
Modbus_RTU_Master
Modbus_RTU_Server
Modbus_RTU_ServerModule
Arduino_Uno
#if OS_LINUX
GPIO
...
...
otherio/wbl/mcomp/src/otherio.wb_load
View file @
7c5b1249
Volume OtherIO $ClassVolume 0.0.250.10
Body SysBody 01-JAN-1970 01:00:00.00
Attr NextOix = "_X2
67
"
Attr NextCix = "_X
29
"
Attr NextOix = "_X2
95
"
Attr NextCix = "_X
34
"
Attr NextTix[0] = "_X10"
EndBody
Object Type $TypeHier 1 15-NOV-2007 14:35:37.90
...
...
@@ -814,7 +814,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
Object RtBody $ObjBodyDef 1 08-FEB-2008 10:26:36.84
Body SysBody 08-FEB-2008 10:26:36.85
Attr StructName = "Modbus_TCP_Slave"
Attr NextAix = "_X2
0
"
Attr NextAix = "_X2
1
"
EndBody
!/**
! Description of slave
...
...
@@ -882,6 +882,10 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$String32"
EndBody
EndObject
!/**
! The default port for Modbus TCP is 502. If another port should be
! used it is specifiec here.
!*/
Object Port $Attribute 19 04-DEC-2009 17:22:45.73
Body SysBody 04-DEC-2009 17:23:01.72
Attr PgmName = "Port"
...
...
@@ -899,6 +903,19 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndBody
EndObject
!/**
! Specifies the action when the errorcounter has reached the error limit.
!
! No no action.
! Reset inputs the inputs for the slave are reset.
! Emergency break all I/O is stopped.
!*/
Object StallAction $Attribute 20 27-OCT-2011 08:54:41.57
Body SysBody 27-OCT-2011 08:54:45.34
Attr PgmName = "StallAction"
Attr TypeRef = "pwrb:Type-StallActionEnum"
EndBody
EndObject
!/**
! @Summary Error count of the slave.
! ErrorCount will increase every cycle if status is not MB__NORMAL.
! When ErrorCount reaches the ErrorLimit all inputs are reset to zero.
...
...
@@ -994,7 +1011,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndObject
!/**
! @Summary Input area.
! Area where all
a
input data is stored.
! Area where all input data is stored.
!*/
Object Inputs $Attribute 14 08-FEB-2008 10:59:26.76
Body SysBody 08-FEB-2008 11:00:29.99
...
...
@@ -1006,7 +1023,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndObject
!/**
! @Summary Output area.
! Area where all
a
output data is stored.
! Area where all output data is stored.
!*/
Object Outputs $Attribute 15 08-FEB-2008 11:00:48.44
Body SysBody 08-FEB-2008 11:00:44.86
...
...
@@ -1175,6 +1192,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Module status.
!*/
Object Status $Attribute 7 08-FEB-2008 11:20:34.93
Body SysBody 04-DEC-2009 17:15:47.85
Attr PgmName = "Status"
...
...
@@ -1401,11 +1421,12 @@ Volume OtherIO $ClassVolume 0.0.250.10
! @b See also
! @classlink Modbus_ModuleMsg otherio_modbus_modulemsg.html
! @classlink Modbus_Module otherio_modbus_module.html
!*/
Object Modbus_ModuleReadWrite $ClassDef 27 17-OCT-2011 07:54:13.97
Body SysBody 17-OCT-2011 07:54:45.40
Attr Editor = 0
Attr Method = 0
Attr Flags =
18512
Attr Flags =
51280
EndBody
Object RtBody $ObjBodyDef 1 17-OCT-2011 07:56:53.34
Body SysBody 17-OCT-2011 07:56:53.34
...
...
@@ -1753,7 +1774,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndObject
!/**
! @Summary Input area.
! Area where all
a
input data is stored.
! Area where all input data is stored.
!*/
Object Inputs $Attribute 36 27-NOV-2009 09:42:27.83
Body SysBody 27-NOV-2009 09:42:46.12
...
...
@@ -1765,7 +1786,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndObject
!/**
! @Summary Ouput area.
! Area where all
a
output data is stored.
! Area where all output data is stored.
!*/
Object Outputs $Attribute 37 27-NOV-2009 09:42:27.83
Body SysBody 27-NOV-2009 09:43:03.16
...
...
@@ -1813,7 +1834,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
!/**
! @Version 1.0
! @Group IO
! @Summary Server Modue object for Modbus TCP I/O.
! @Summary Server Modu
l
e object for Modbus TCP I/O.
! Server Module object for Modbus TCP I/O.
!
! The Module object is placed as a child to a Modbus_TCP_Server object
...
...
@@ -1875,7 +1896,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndObject
!/**
! @Summary Unit id.
! Identification of the modbus
unit to communicate with
. It is typically
! Identification of the modbus
server unit
. It is typically
! only used if communicating with a tpc gateway that is connected to a
! Modbus serial line with possibly several units. Usually this has no
! meaning and should be set to zero (0).
...
...
@@ -1951,6 +1972,1022 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Master object for Modbus RTU I/O.
! Master object for Modbus RTU I/O.
!
! @classlink Modbus_RTU_Module otherio_modbus_rtu_module.html
! @classlink Modbus_RTU_Slave otherio_modbus_rtu_slave.html
!*/
Object Modbus_RTU_Master $ClassDef 29 18-OCT-2011 11:07:34.64
Body SysBody 18-OCT-2011 11:07:05.53
Attr Editor = 0
Attr Method = 0
Attr Flags = 38992
EndBody
Object RtBody $ObjBodyDef 1 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:07:44.18
Attr StructName = "Modbus_RTU_Master"
Attr NextAix = "_X18"
EndBody
!/**
! Description of master.
!*/
Object Description $Attribute 5 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:07:05.53
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! If TRUE the master is disabled.
!*/
Object Disable $Attribute 6 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:07:05.53
Attr PgmName = "Disable"
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
!/**
! @Summary Process that handles the card. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the master.
!
! 1: The master is read by the plc process, and is handled by a specific
! thread in the plc, which is specified in the ThreadObject attribute.
! 2: The master is read by the rt_io_comm process.
! 4: The master is handled by an application program.
!*/
Object Process $Attribute 7 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:07:05.53
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the master.
! The PlcThread object of the plc thread that handles the master.
! The master is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 8 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:07:05.53
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! Device name of the serial port, e.g. /dev/ttyS0.
!*/
Object Device $Attribute 9 18-OCT-2011 11:08:23.34
Body SysBody 18-OCT-2011 11:08:38.79
Attr PgmName = "Device"
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
!/**
! Baud rate of the serial port.
!*/
Object Speed $Attribute 10 18-OCT-2011 11:09:05.07
Body SysBody 18-OCT-2011 11:09:12.39
Attr PgmName = "Speed"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Parity of the serial port.
!*/
Object Parity $Attribute 11 18-OCT-2011 11:09:38.47
Body SysBody 18-OCT-2011 11:10:12.61
Attr PgmName = "Parity"
Attr TypeRef = "pwrb:Type-ParityEnum"
EndBody
EndObject
!/**
! Stop bits of the serial port.
!*/
Object StopBits $Attribute 12 18-OCT-2011 11:10:26.72
Body SysBody 18-OCT-2011 11:10:34.59
Attr PgmName = "StopBits"
Attr TypeRef = "pwrb:Type-StopBitsEnum"
EndBody
EndObject
!/**
! Data bits of the serial port.
!*/
Object DataBits $Attribute 13 18-OCT-2011 11:10:46.95
Body SysBody 18-OCT-2011 11:10:53.17
Attr PgmName = "DataBits"
Attr TypeRef = "pwrb:Type-DataBitsEnum"
EndBody
EndObject
!/**
! Timeout for character read.
!*/
Object CharTimeout $Attribute 14 25-OCT-2011 13:26:58.49
Body SysBody 25-OCT-2011 13:27:00.56
Attr PgmName = "CharTimeout"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Time between frames.
!*/
Object FrameTimeout $Attribute 15 25-OCT-2011 13:27:08.81
Body SysBody 25-OCT-2011 13:27:09.97
Attr PgmName = "FrameTimeout"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Timeout slave response.
!*/
Object ReceiveTimeout $Attribute 16 26-OCT-2011 16:57:52.50
Body SysBody 26-OCT-2011 16:57:53.52
Attr PgmName = "ReceiveTimeout"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Print debug information.
!*/
Object Debug $Attribute 17 27-OCT-2011 08:55:53.85
Body SysBody 27-OCT-2011 08:58:09.11
Attr Flags = 25167872
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 268 18-OCT-2011 11:07:05.53
Object IoAgentInit $Method 269 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:13:04.50
Attr MethodName = "Modbus_RTU_Master-IoAgentInit"
EndBody
EndObject
Object IoAgentRead $Method 270 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:13:17.28
Attr MethodName = "Modbus_RTU_Master-IoAgentRead"
EndBody
EndObject
Object IoAgentWrite $Method 271 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:13:27.20
Attr MethodName = "Modbus_RTU_Master-IoAgentWrite"
EndBody
EndObject
Object IoAgentClose $Method 272 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:13:39.73
Attr MethodName = "Modbus_RTU_Master-IoAgentClose"
EndBody
EndObject
EndObject
Object PostCreate $DbCallBack 273 18-OCT-2011 11:07:05.53
Body SysBody 18-OCT-2011 11:07:05.53
Attr MethodName = "BaseIORack-PostCreate"
EndBody
EndObject
Object Template Modbus_RTU_Master 2155315200 01-JAN-1970 01:00:00.00
Body RtBody 26-OCT-2011 18:01:49.06
Attr Process = 1
Attr Device = "/dev/ttyS0"
Attr Speed = 9600
Attr StopBits = 2
Attr DataBits = 8
Attr CharTimeout = 2.000000e-02
Attr FrameTimeout = 1.000000e-02
Attr ReceiveTimeout = 5.000000e-01
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Slave object for Modbus RTU I/O.
! Slave object for Modbus RTU I/O.
!
! @classlink Modbus_RTU_Master otherio_modbus_rtu_master.html
! @classlink Modbus_RTU_Module otherio_modbus_rtu_module.html
!*/
Object Modbus_RTU_Slave $ClassDef 30 18-OCT-2011 11:14:28.26
Body SysBody 18-OCT-2011 11:14:17.41
Attr Editor = 0
Attr Method = 0
Attr Flags = 43088
EndBody
Object RtBody $ObjBodyDef 1 25-OCT-2011 13:28:38.46
Body SysBody 18-OCT-2011 11:14:34.02
Attr StructName = "Modbus_RTU_Slave"
Attr NextAix = "_X39"
EndBody
!/**
! Description of slave
!*/
Object Description $Attribute 20 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! @Summary Datasheet.
! Link to datasheet for the specific slave type.
!*/
Object DataSheet $Attribute 21 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "DataSheet"
Attr TypeRef = "pwrs:Type-$URL"
EndBody
EndObject
!/**
! @Summary Status of the slave.
! Status of the slave. Shows if tcp-link to slave is up or not.
!*/
Object Status $Attribute 22 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$Status"
EndBody
EndObject
!/**
! @Summary Process that handles the slave. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the card.
!
! 1: The slave is read by the plc process, and is handled by a specific
! thread in the plc, which is specified in the ThreadObject attribute.
! 2: The slave is read by the rt_io_comm process.
! 4: The slave is handled by an application program.
!*/
Object Process $Attribute 23 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the slave.
! The PlcThread object of the plc thread that handles the slave.
! The slave is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 24 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! Specifies the action when the errorcounter has reached the error limit.
!
! No no action.
! Reset inputs the inputs for the slave are reset.
! Emergency break all I/O is stopped.
!*/
Object StallAction $Attribute 38 27-OCT-2011 08:52:20.96
Body SysBody 27-OCT-2011 08:53:31.33
Attr PgmName = "StallAction"
Attr TypeRef = "pwrb:Type-StallActionEnum"
EndBody
EndObject
!/**
! @Summary Flag that disables the slave.
! Flag that disables the initialization of the slave, if initialized turns off i/o-handling.
!*/
Object DisableSlave $Attribute 27 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "DisableSlave"
Attr TypeRef = "pwrb:Type-YesNoEnum"
EndBody
EndObject
!/**
! @Summary Error count of the slave.
! ErrorCount will increase every cycle if status is not MB__NORMAL.
! When ErrorCount reaches the ErrorLimit the action in StallAction is executed.
!*/
Object ErrorCount $Attribute 28 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "ErrorCount"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! @Summary Error limit of the slave.
! ErrorCount will increase every cycle if status is not MB__NORMAL.
! When ErrorCount reaches the ErrorLimit the action in StallAction is exectued.
!*/
Object ErrorLimit $Attribute 29 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "ErrorLimit"
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! @Summary Received number of messages from slave.
! Received number of messages from slave.
!*/
Object RX_packets $Attribute 34 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "RX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Sent number of messages to slave.
! Sent number of messages to slave.
!*/
Object TX_packets $Attribute 35 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "TX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Input area.
! Area where all input data is stored.
!*/
Object Inputs $Attribute 36 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "Inputs"
Attr Flags = 3074
Attr Elements = 256
Attr TypeRef = "pwrs:Type-$UInt8"
EndBody
EndObject
!/**
! @Summary Output area.
! Area where all output data is stored.
!*/
Object Outputs $Attribute 37 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr PgmName = "Outputs"
Attr Flags = 3074
Attr Elements = 256
Attr TypeRef = "pwrs:Type-$UInt8"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 274 18-OCT-2011 11:14:17.41
Object IoRackInit $Method 275 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:16:56.30
Attr MethodName = "Modbus_RTU_Slave-IoRackInit"
EndBody
EndObject
Object IoRackClose $Method 276 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:17:02.69
Attr MethodName = "Modbus_RTU_Slave-IoRackClose"
EndBody
EndObject
Object IoRackRead $Method 277 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:17:08.79
Attr MethodName = "Modbus_RTU_Slave-IoRackRead"
EndBody
EndObject
Object IoRackWrite $Method 278 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:17:15.19
Attr MethodName = "Modbus_RTU_Slave-IoRackWrite"
EndBody
EndObject
EndObject
Object PostCreate $DbCallBack 279 18-OCT-2011 11:14:17.41
Body SysBody 18-OCT-2011 11:14:17.41
Attr MethodName = "BaseIORack-PostCreate"
EndBody
EndObject
Object Template Modbus_RTU_Slave 2155577344 01-JAN-1970 01:00:00.00
Body RtBody 25-OCT-2011 13:31:22.94
Attr Process = 1
Attr ErrorLimit = 100
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Module object for Modbus RTU I/O.
! Module object for Modbus RTU I/O.
! Defines the type of Modbus action that is to be performed and at which address on the slave.
! The action is defined by a function code which means either reading or writing data to
! the Modbus slave.
!
! The supported function codes are:
!
! @b ReadCoils (FC 1)
! This function code is used to read from 1 to 2000 contiguous status of coils in a remote device.
! Typically the input data area is defined by a number of ChanDi's which represent
! the number of coils you want to read. The represenation on the ChanDi should be set to Bit8.
!
! @b ReadDiscreteInputs (FC 2)
! This function code is used to read from 1 to 2000 contiguous status of discrete inputs
! in a remote device. Typically the input data area is defined by a number of ChanDi's
! which represent the number of coils you want to read.
! The represenation on the ChanDi should be set to Bit8.
!
! @b ReadHoldingRegisters (FC 3)
! This function code is used to read the contents of a contiguous block of holding registers
! in a remote device.
! Typically the input data area is defined by a number of ChanIi's which represent
! the number of registers you want to read. The represenation on the ChanIi should
! be set to UInt16 or Int16. ChanAi and ChanDi is also applicable. In case of ChanDi the
! representation should be set to Bit16.
!
! @b ReadInputRegisters (FC 4)
! This function code is used to read from 1 to 125 contiguous input registers
! in a remote device.
! Typically the input data area is defined by a number of ChanIi's which represent
! the number of registers you want to read. The represenation on the ChanIi should
! be set to UInt16 or Int16. ChanAi and ChanDi is also applicable. In case of ChanDi the
! representation should be set to Bit16.
!
! @b WriteSingleCoil (FC 5)
! This function code is used to write to one single coil.
! Typically the output data area is defined by one ChanDo's which represent
! the state of the coil to write to.
!
! @b WriteMultipleCoils (FC 15)
! This function code is used to force each coil in a sequence of coils to either ON or OFF
! in a remote Device.
! Typically the output data area is defined by a number of ChanDo's which represent
! the number of coils you want to write. The represenation on the ChanDo should
! be set to Bit8.
!
! @b WriteMultipleRegisters (FC 16)
! This function code is used to write a block of contiguous registers (1 to 123 registers)
! in a remote device.
! Typically the output data area is defined by a number of ChanIo's which represent
! the number of registers you want to write. The represenation on the ChanIo should
! be set to UInt16 or Int16. ChanAo and ChanDo is also applicable. In case of ChanDo the
! representation should be set to Bit16.
!
! @classlink Modbus_RTU_Master otherio_modbus_rtu_master.html
! @classlink Modbus_RTU_Slave otherio_modbus_rtu_slave.html
!*/
Object Modbus_RTU_Module $ClassDef 31 18-OCT-2011 11:18:19.61
Body SysBody 18-OCT-2011 11:18:07.74
Attr Editor = 0
Attr Method = 0
Attr Flags = 51280
EndBody
Object RtBody $ObjBodyDef 1 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:24.86
Attr StructName = "Modbus_RTU_Module"
Attr NextAix = "_X22"
EndBody
!/**
! Description of module
!*/
Object Description $Attribute 12 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! @Summary Modbus function code.
! The function code defines the action that is to be perfomed with the Modbus slave.
! The module is handled with the scantime of the thread.
! The supported function codes are:
!
! (FC 1) ReadCoils
! (FC 2) ReadDiscreteInputs
! (FC 3) ReadHoldingRegisters
! (FC 4) ReadInputRegisters
! (FC 5) WriteSingleCoil
! (FC 15) WriteMultipleCoils
! (FC 16) WriteMultipleRegisters
!*/
Object FunctionCode $Attribute 13 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "FunctionCode"
Attr TypeRef = "OtherIO:Type-Modbus_FCEnum"
EndBody
EndObject
!/**
! @Summary Address of data area on Modbus slave.
! Address of data area on Modbus slave.
!*/
Object Address $Attribute 14 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "Address"
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! @Summary Unit id.
! Identification of the modbus unit to communicate with.
!*/
Object UnitId $Attribute 15 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "UnitId"
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Module status.
!*/
Object Status $Attribute 16 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "OtherIO:Type-ModbusModule_StatusEnum"
EndBody
EndObject
!/**
! @Summary Continous operation of the module.
! If set to Yes the module is scanned cylically for each scan (read or write operation).
! If set to false the action defined by the FunctionCode-attribute will only be executed
! when the SendOp-attribute is set.
!*/
Object Continous $Attribute 17 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "Continous"
Attr TypeRef = "pwrb:Type-YesNoEnum"
EndBody
EndObject
!/**
! @Summary Request to execute action defined by FunctionCode-attribute once.
! This attribute is only valid if Contious-attribute is set to 'No'.
!*/
Object SendOp $Attribute 18 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "SendOp"
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
!/**
! Specifies, in relation to the scantime of the thread, how
! often the module is handled. If ScanInterval i 1, the module
! is handled every scan. If ScanInterval is for example 10, it
! is handled every 10'th scan, i.e. the scantime for the module
! will be ScanInterval times the scantime of the thread.
!*/
Object ScanInterval $Attribute 19 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "ScanInterval"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Process that handles the card. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the card.
!
! 1: The card is read by the plc process, and is handled by a specific
! thread in the plc, which is specified in the ThreadObject attribute.
! 2: The card is read by the rt_io_comm process.
! 4: The card is handled by an application program.
!*/
Object Process $Attribute 20 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the module.
! The PlcThread object of the plc thread that handles the module.
! The module is handled with the scantime of the thread.
!*/
Object ThreadObject $Attribute 21 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 280 18-OCT-2011 11:18:07.74
Object IoCardInit $Method 281 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:29:45.08
Attr MethodName = "Modbus_RTU_Module-IoCardInit"
EndBody
EndObject
Object IoCardRead $Method 282 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:29:52.02
Attr MethodName = "Modbus_RTU_Module-IoCardRead"
EndBody
EndObject
Object IoCardWrite $Method 283 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:29:58.27
Attr MethodName = "Modbus_RTU_Module-IoCardWrite"
EndBody
EndObject
EndObject
Object PostCreate $DbCallBack 284 18-OCT-2011 11:18:07.74
Body SysBody 18-OCT-2011 11:18:07.74
Attr MethodName = "BaseIOCard-PostCreate"
EndBody
EndObject
Object Template Modbus_RTU_Module 2155839488 01-JAN-1970 01:00:00.00
Body RtBody 18-OCT-2011 11:30:53.55
Attr Continous = 1
Attr ScanInterval = 1
Attr Process = 1
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Server object for Modbus RTU I/O.
! Server object for Modbus RTU I/O.
!
! The defines a Modbus/RTU server, i.e. makes it possible to act as a slave
! in the communication with a Modbus/RTU master.
!
! The Server object is placed in the node hierarchy under the node object.
!
! @classlink Modbus_RTU_ServerModule otherio_modbus_rtu_servermodule.html
!*/
Object Modbus_RTU_Server $ClassDef 32 24-OCT-2011 08:03:56.99
Body SysBody 24-OCT-2011 08:03:46.50
Attr Editor = 0
Attr Method = 0
Attr Flags = 43088
EndBody
Object RtBody $ObjBodyDef 1 27-OCT-2011 08:57:12.15
Body SysBody 24-OCT-2011 08:04:01.44
Attr StructName = "Modbus_RTU_Server"
Attr NextAix = "_X61"
EndBody
!/**
! Description of the object.
!*/
Object Description $Attribute 39 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! Datasheet URL.
!*/
Object DataSheet $Attribute 40 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "DataSheet"
Attr TypeRef = "pwrs:Type-$URL"
EndBody
EndObject
!/**
! Current status of the server.
!*/
Object Status $Attribute 41 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$Status"
EndBody
EndObject
!/**
! @Summary Process that handles the card. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the server.
!
! 1: The server is read by the plc process, and is handled by a specific
! thread in the plc, which is specified in the ThreadObject attribute.
! 2: The server is read by the rt_io_comm process.
! 4: The server is handled by an application program.
!*/
Object Process $Attribute 42 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the server.
! The PlcThread object of the plc thread that handles the server.
! The server is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 43 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! Device name of the serial port, e.g. /dev/ttyS0.
!*/
Object Device $Attribute 53 24-OCT-2011 08:07:11.01
Body SysBody 24-OCT-2011 08:07:11.01
Attr PgmName = "Device"
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
!/**
! Baud rate of the serial port.
!*/
Object Speed $Attribute 54 24-OCT-2011 08:07:11.01
Body SysBody 24-OCT-2011 08:07:11.01
Attr PgmName = "Speed"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Parity of the serial port.
!*/
Object Parity $Attribute 55 24-OCT-2011 08:07:11.01
Body SysBody 24-OCT-2011 08:07:11.01
Attr PgmName = "Parity"
Attr TypeRef = "pwrb:Type-ParityEnum"
EndBody
EndObject
!/**
! Stop bits of the serial port.
!*/
Object StopBits $Attribute 56 24-OCT-2011 08:07:11.01
Body SysBody 24-OCT-2011 08:07:11.01
Attr PgmName = "StopBits"
Attr TypeRef = "pwrb:Type-StopBitsEnum"
EndBody
EndObject
!/**
! Data bits of the serial port.
!*/
Object DataBits $Attribute 57 24-OCT-2011 08:07:11.01
Body SysBody 24-OCT-2011 08:07:11.01
Attr PgmName = "DataBits"
Attr TypeRef = "pwrb:Type-DataBitsEnum"
EndBody
EndObject
!/**
! If Yes, the server is disabled.
!*/
Object DisableServer $Attribute 45 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "DisableServer"
Attr TypeRef = "pwrb:Type-YesNoEnum"
EndBody
EndObject
!/**
! @Summary Error count of the server.
! ErrorCount will increase every cycle if status is not MB__NORMAL.
! When ErrorCount reaches the ErrorLimit all inputs are reset to zero.
!*/
Object ErrorCount $Attribute 46 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "ErrorCount"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! @Summary Error limit of the server.
! ErrorCount will increase every cycle if status is not MB__NORMAL.
! When ErrorCount reaches the ErrorLimit all inputs are reset to zero.
!*/
Object ErrorLimit $Attribute 47 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "ErrorLimit"
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Timeout for character read.
!*/
Object CharTimeout $Attribute 48 25-OCT-2011 13:28:00.42
Body SysBody 25-OCT-2011 13:30:14.63
Attr PgmName = "CharTimeout"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Not used.
!*/
Object FrameTimeout $Attribute 58 26-OCT-2011 16:59:58.07
Body SysBody 26-OCT-2011 16:59:59.48
Attr PgmName = "FrameTimeout"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Received number of messages for the server.
!*/
Object RX_packets $Attribute 49 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "RX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Sent number of messages from the server.
!*/
Object TX_packets $Attribute 50 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "TX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Input area.
! Area where all input data is stored.
!*/
Object Inputs $Attribute 51 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "Inputs"
Attr Flags = 3090
Attr Elements = 256
Attr TypeRef = "pwrs:Type-$UInt8"
EndBody
EndObject
!/**
! @Summary Ouput area.
! Area where all output data is stored.
!*/
Object Outputs $Attribute 52 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr PgmName = "Outputs"
Attr Flags = 3090
Attr Elements = 256
Attr TypeRef = "pwrs:Type-$UInt8"
EndBody
EndObject
!/**
! Print debug information.
!*/
Object Debug $Attribute 60 27-OCT-2011 08:57:19.86
Body SysBody 27-OCT-2011 08:57:53.68
Attr Flags = 25167872
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 285 24-OCT-2011 08:03:46.50
Object IoRackInit $Method 286 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:05:15.56
Attr MethodName = "Modbus_RTU_Server-IoRackInit"
EndBody
EndObject
Object IoRackClose $Method 287 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:05:21.95
Attr MethodName = "Modbus_RTU_Server-IoRackClose"
EndBody
EndObject
Object IoRackRead $Method 288 24-OCT-2011 08:05:26.11
Body SysBody 24-OCT-2011 08:05:30.33
Attr MethodName = "Modbus_RTU_Server-IoRackRead"
EndBody
EndObject
Object IoRackWrite $Method 289 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:05:36.10
Attr MethodName = "Modbus_RTU_Server-IoRackWrite"
EndBody
EndObject
EndObject
Object PostCreate $DbCallBack 290 24-OCT-2011 08:03:46.50
Body SysBody 24-OCT-2011 08:03:46.50
Attr MethodName = "BaseIORack-PostCreate"
EndBody
EndObject
Object Template Modbus_RTU_Server 2156101632 01-JAN-1970 01:00:00.00
Body RtBody 26-OCT-2011 18:00:51.72
Attr Process = 1
Attr Device = "/dev/ttyS0"
Attr Speed = 9600
Attr StopBits = 2
Attr DataBits = 8
Attr ErrorLimit = 100
Attr CharTimeout = 2.000000e-02
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Server Module object for Modbus RTU I/O.
! Server Module object for Modbus RTU I/O.
!
! The Module object is placed as a child to a Modbus_RTU_Server object
! and is the father of channel objects that define the input and
! output area for the module.
!
! @classlink Modbus_RTU_Server otherio_modbus_rtu_server.html
!*/
Object Modbus_RTU_ServerModule $ClassDef 33 24-OCT-2011 08:04:31.37
Body SysBody 24-OCT-2011 08:04:13.86
Attr Editor = 0
Attr Method = 0
Attr Flags = 51280
EndBody
Object RtBody $ObjBodyDef 1 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:37.00
Attr StructName = "Modbus_RTU_ServerModule"
Attr NextAix = "_X28"
EndBody
!/**
! Description of the object.
!*/
Object Description $Attribute 21 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! @Summary Address for reading registers.
! Address for reading with function code ReadHoldingRegisters.
! The value defines the starting address for the input channels
! of class ChanIi and ChanAi.
!
! Note that the address for ReadDiscreteInputs and ReadCoils are
! not affected by the ReadAddress.
!*/
Object ReadAddress $Attribute 22 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr PgmName = "ReadAddress"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Address for writing registers.
! Address for reading with function code WriteMultipleRegisters and
! WriteSingleRegister.
! The value defines the starting address for the output channels
! of class ChanIo and ChanAo.
!
! Note that the address for WriteSingleCoil and WriteMultipleCoils
! are not affected by the WriteAddress.
!*/
Object WriteAddress $Attribute 23 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr PgmName = "WriteAddress"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Unit id.
! Identification of the modbus server unit.
!*/
Object UnitId $Attribute 24 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr PgmName = "UnitId"
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Module status.
!*/
Object Status $Attribute 25 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "OtherIO:Type-ModbusSever_StatusEnum"
EndBody
EndObject
!/**
! @Summary Process that handles the module. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the module.
!
! 1: The module is read by the plc process, and is handled by a specific
! thread in the plc, which is specified in the ThreadObject attribute.
! 2: The module is read by the rt_io_comm process.
! 4: The module is handled by an application program.
!*/
Object Process $Attribute 26 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the module.
! The PlcThread object of the plc thread that handles the module.
! The master is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 27 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 291 24-OCT-2011 08:04:13.86
Object IoCardInit $Method 292 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:48.67
Attr MethodName = "Modbus_RTU_ServerModule-IoCardInit"
EndBody
EndObject
Object IoCardRead $Method 293 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:54.62
Attr MethodName = "Modbus_RTU_ServerModule-IoCardRead"
EndBody
EndObject
Object IoCardWrite $Method 294 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:05:01.41
Attr MethodName = "Modbus_RTU_ServerModule-IoCardWrite"
EndBody
EndObject
EndObject
Object PostCreate $DbCallBack 295 24-OCT-2011 08:04:13.86
Body SysBody 24-OCT-2011 08:04:13.86
Attr MethodName = "BaseIOCard-PostCreate"
EndBody
EndObject
Object Template Modbus_RTU_ServerModule 2156363776 01-JAN-1970 01:00:00.00
Body RtBody 24-OCT-2011 08:09:15.76
Attr Process = 1
EndBody
EndObject
EndObject
Object GPIO $ClassDef 8 15-APR-2010 21:46:30.11
Body SysBody 15-APR-2010 21:46:16.74
Attr Editor = 0
...
...
src/wbl/pwrb/src/pwrb_td_stallactionenum.wb_load
0 → 100644
View file @
7c5b1249
!
! Proview Open Source Process Control.
! Copyright (C) 2005-2011 SSAB Oxelosund AB.
!
! This file is part of Proview.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with Proview. If not, see <http://www.gnu.org/licenses/>
!
! Linking Proview statically or dynamically with other modules is
! making a combined work based on Proview. Thus, the terms and
! conditions of the GNU General Public License cover the whole
! combination.
!
! In addition, as a special exception, the copyright holders of
! Proview give you permission to, from the build function in the
! Proview Configurator, combine Proview with modules generated by the
! Proview PLC Editor to a PLC program, regardless of the license
! terms of these modules. You may copy and distribute the resulting
! combined work under the terms of your choice, provided that every
! copy of the combined work is accompanied by a complete copy of
! the source code of Proview (the version used to produce the
! combined work), being distributed under the terms of the GNU
! General Public License plus this exception.
!
! pwrb_td_stallactionenum.wb_load -- Defines the enum type StallAction
!
SObject pwrb:Type
!/**
! @Version 1.0
! @Group Types
! Enumeration for I/O stall action.
!*/
Object StallActionEnum $TypeDef 58
Body SysBody
Attr TypeRef = "pwrs:Type-$Enum"
Attr PgmName = "StallActionEnum"
EndBody
!/**
! No.
!*/
Object No $Value
Body SysBody
Attr PgmName = "No"
Attr Text = "No"
Attr Value = 0
EndBody
EndObject
!/**
! Reset inputs.
!*/
Object ResetInputs $Value
Body SysBody
Attr PgmName = "ResetInputs"
Attr Text = "Reset inputs"
Attr Value = 1
EndBody
EndObject
!/**
! Emergency break.
!*/
Object EmergencyBreak $Value
Body SysBody
Attr PgmName = "EmergencyBreak"
Attr Text = "Set emergency break"
Attr Value = 2
EndBody
EndObject
EndObject
EndSObject
wb/exp/wb/src/pwr_wb_palette.cnf
View file @
7c5b1249
...
...
@@ -307,6 +307,17 @@ palette NavigatorPalette
class Modbus_TCP_ServerModule
}
}
menu Modbus_RTU
{
class Modbus_RTU_Master
class Modbus_RTU_Slave
class Modbus_RTU_Module
menu Server
{
class Modbus_RTU_Server
class Modbus_RTU_ServerModule
}
}
menu Hilscher_cifX
{
class Hilscher_cifX_Master
...
...
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