![]() |
![]() ![]()
Experimental Physics and
| ||||||||||||||||
|
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
| ||||||||||||||||
ANJ, 02 Sep 2010 |
![]() · Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |