Experimental Physics and
| |||||||||||||||||
|
The return type of parse() defines the data type as seen by the record. This is not necessarily the type of the record, it is the type of the conversion. For example, %i is long_format and %f is a double_format in stream. Both can be used with an ai record. The long value from %i goes to the RVAL field and the double value from %f goes to the VAL field. Thus, it depends on the data type of the conversion, to which field the input is passed. Depending on the return value of parse, different versions of print and scan are used when actually processing in and out commands. By the way, parse can return different values for input and output. For example %c is a long output but a string input format. Note that stream uses long and double but but not short and float. In your case, you want to read/write a floating point value. Thus parse returns double_format and you have to implement bool printDouble(const StreamFormat& fmt, StreamBuffer& output, double value); int scanDouble(const StreamFormat& fmt, const char* input, double& value); Because the number is always coded in 4 bytes, scanDouble() always returns 4. You can handle endianess with flags. I usually assume big endian by default and use the # flag for little endian. To read several values, you can use a waveform or aai record. The converter reads/writes only one element at a time. It is called multiple times to handle arrays. There are no array converters. On output, your converter will be called NELM times any should write one value (4 bytes). On input, your converter will be called as long as there is input left, a maximum of NELM times, and until you return -1, whatever happens first. NORD will be set to the number of read elements. Reading at least one element is a success. You will write just set NELM of the record to 25 and use { in "%R"; } to read the complete array. The other possibility is to use redirected input %(otherrecord.VAL)R. Then, you have to specify 25 format conversions in the protocol as in your example below. Note the capital .VAL. Using .val will not work because the record has no .val field. You can use parametres like \$1 \$2 ... \$9 to keep the record names, or at least parts of the record names, out of the protocol file. But there are only 9 parameters. Thus you would use something like: in "%(\$1:status1.VAL)R%(\$1:status2.VAL)R...%(\$1:status24.VAL)R%R"; record(ai, "$(DEVICE):status1") { } ... record(ai, "$(DEVICE):status24") { } record(ai, "$(DEVICE):status25") { field (DTYP, "stream") field (INP, "@file getStatus($(DEVICE)) $(BUS)") } Unfortunately, you will find errors only in status25, because that's the record that processes the protocol. In either case, the converter does not know about arrays. It always handles one value at a time. Dirk Emmanuel Mayssat wrote: Dirk, others,
| ||||||||||||||||
ANJ, 10 Nov 2011 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |