Experimental Physics and Industrial Control System
Hi Alan,
Stream Device supports that, but I don't call it hex, I call it "raw".
Hex is %x as in printf and you get an ASCII string, e.g. "C6B5"
Raw is %r and is used for data like 0xc6 0xb5 (2 bytes)
What StreamDevice cannot do is to calculate <length> or use a <length>
information it finds in the message. But if you know length in advance,
it is still possible to use StreamDevice.
StreamDevice can calculate a 16 bit crc CRC with %<crc16> (other
checksums are supported, too).
In your case, the additional difficulty is that you get multiple data in
one message (error, standard, version, revision).
You may want to accept only error=0x00 and read standard,version,
revision as single 4 byte long integer or redirect pieces of information
into other records. I will show you both.
> Client: EE0000000001201310
> Server: 06
[no message from the client here, like enq = 0x05 ?]
> Server: EE00000000050000020000C6B5
> Client: 06
read_std_ver_rev {
out 0xEE 0x00 0x00 0x00 0x00 0x01 0x20 0x13 0x10;
in 0x06;
# out 0x05;
in 0xEE 0x00 0x00 0x00 0x00 0x05 0x00 "%4r%<crc16>";
# alternative: in "\xee\x00\x00\x00\x00\x05\x00%4r%<crc16>";
}
If error is not 0x00, the record will stop parsing the input and go into
INVALID alarm state.
StreamDevice understands ACK and NAK and some other codes. So you can
write in ACK; or in ack; instead of in 0x06; or in "\x06"; if you like.
now with redirection:
read_version {
out 0xEE 0x00 0x00 0x00 0x00 0x01 0x20 "%<crc16>";
in ACK;
# out ENQ;
in 0xEE 0x00 0x00 0x00 0x00 0x05
"%(\1:error.RVAL)r" # put 1 byte into *:error record, e.g. mbbi
"%(\1:standard.VAL)r" # put 1 byte into *:standard record
"%2r"; # read 2 bytes version/revision
}
The %(record.field) is the redirection and works like a link writing
into the record. However, the record must be local on the same IOC and
you must specify the field, even if it's VAL.
"\$1" (or $1 outside quotes) is a way to pass a parameter to the
protocol, like a function parameter. This avoids to hardcode record
names in the protocol.
record (longin,"$(DEV):version") {
field (DTYP, "stream")
# pass the device part to the prococol as "\$1":
field (INP, "@protocol.file read_version($(DEV)) $(ASYN_PORT)")
}
record (mbbi,"$(DEV):error") {
field (DTYP,"Raw Soft Channel")
field (ZRST,"OK")
field (ONVL,"<error code 1>")
field (ONST,"<error string 1>")
...
}
record (longin,"$(DEV):standard") {
field (DTYP,"Soft Channel")
}
Note that the *:error and *:standard records are "Passive" and "Soft
Channel" or "Raw Soft Channel" (when writing to VAL or RVAL,
respectively). The *:version record writes to them. And processes them
if the written field has the PP attribute (see record reference manual).
You can split version and revision into two records if you like.
You can also assemble output from several records the same way.
Dirk
Barker, Alan M. wrote:
Hi Tech-talk, I am trying to build a softIOC to support the ANSI C12.22
communications protocol. C12.22 supports TCP/IP Server/Client messaging
where messages are hex streams of the format
<packet> ::= <stp><identity><ctrl><seq-nbr><length><data><crc>
<ack> ::= 0x06
<nak> ::= 0x15
where <stp>,<identity>,<ctrl>,<seq-nbr> are always bytes, <length> and
<crc> are always 2 bytes, and how many bytes of <data> is defined by
<length>.
Messages are typically sent in Request/Response pairs, i.e. the client
will ask the server for something, and the server will respond.
The first byte in a request's <data> indicates the message "type", such as
read or write data to a device. The first byte in a response's <data> is
0x00 for OK, or various other error codes.
Here is an example identification request (0x20) and response to the
request (values shown are hex). You learn from the server its standard is
0x00, version is 0x02, and revision is 0x00.
Client: EE0000000001201310
Server: 06
Server: EE00000000050000020000C6B5
Client: 06
I am new to EPICS, but have seen that StreamDevice with Asyn can send and
receive hex values. Most of the examples I have seen are for simple ASCII
commands like requesting "VOLTAGE?" and receiving "VOLTAGE=120".
In the context of EPICS, where do I parse the incoming hex stream? Where
do I assemble the outgoing hex string? Where do I do my processing (like calculating the CRC)? In a
genSub? Calc record? State Notion Language? Link to a c file?
Are there any examples out there of sending and processing hex streams?
Thanks,
Alan Barker, ORNL
RHEL 5.5, EPICS R3.14.11, asynDriver R4-14, StreamDevice-2
- References:
- hex stream processing with StreamDevice? Barker, Alan M.
- Navigate by Date:
- Prev:
agenda for the October meeting is updated (you may be scheduled to give a ttalk ; ) ) Dalesio, Leo
- Next:
Re: CA gateway dies without error message Andrew Johnson
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
<2010>
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
- Navigate by Thread:
- Prev:
RE: hex stream processing with StreamDevice? Mark Rivers
- Next:
synApps/vme-2-7/vmeApp/src for RTEMS (using EPICS libCom/osi Library) required Heinz Junkes
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
<2010>
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025