Скачать презентацию Wir schaffen Wissen heute für morgen Paul Скачать презентацию Wir schaffen Wissen heute für morgen Paul

8d7c6b9d834174d678d24e5a50c7bd01.ppt

  • Количество слайдов: 29

Wir schaffen Wissen – heute für morgen Paul Scherrer Institut Dirk Zimoch Using the Wir schaffen Wissen – heute für morgen Paul Scherrer Institut Dirk Zimoch Using the Stream. Device Driver

What is Stream. Device? • A generic device driver for byte stream (string) based What is Stream. Device? • A generic device driver for byte stream (string) based I/O • One device support for many. . . – record types • ai, ao, bi, bo, mbbi, mbbo, stringin, stringout, waveform, … – devices with command string interface • oscilloscopes, frequency generators, temperature sensors, pumps, vacuum gauges, power supplies, motors, … – bus types • GPIB, serial (RS 232, RS 485), Ethernet (“telnet type”), … – protocols • ASCII text messages • Binary messages – format converters • standard printf / scanf like: %f %s %i • additional: %b %r %D %{…} • checksums

Stream. Device and asyn. Driver • Does Stream. Device replace asyn. Driver? – No. Stream. Device and asyn. Driver • Does Stream. Device replace asyn. Driver? – No. In fact it uses asyn. Driver to talk to the hardware. – To be exact: It uses the asyn. Octet interface. • But doesn’t asyn. Driver already come with device support? – Yes, but for string based devices only stringin, stringout and char waveform support. • Stream. Device does the string formatting and parsing and asyn. Driver does the hardware access. Example: ao 3. 1415 (double) Stream. Device “SET %. 2 frn” “SET 3. 14rn” (string) asyn. Driver GPIB

Stream. Device Architecture ai bo stringout . . . records waveformat converters record interfaces Stream. Device Architecture ai bo stringout . . . records waveformat converters record interfaces %f … %{…} Stream. Core Stream Protocol Parser Stream. Device %b asyn. Driver Interface %<…> protocol files %/…/ bus interfaces bus drivers asyn. Driver buses Modular design allows to plug in new functionality serial TCP GPIB

Programming Stream. Device • Usually no C programming needed to support new devices • Programming Stream. Device • Usually no C programming needed to support new devices • Description of all I/O in plain text “protocol file” Example: Read Kelvin temperature 1 from a Lake. Shore 218 – Command: “KRDG? 1” CR LF – Reply: “+273. 15” CR LF startup script drv. Asyn. Serial. Port. Configure "Lake. Shore 1", "/dev/tty. S 0" asyn. Set. Option "Lake. Shore 1", 0, "baud", "9600" asyn. Set. Option "Lake. Shore 1", 0, … record field } asyn port (and address) (ai, "$(DEVICE): TEMP 1") { (DTYP, "stream") (INP, "@LS 218. prot temp_K_1 Lake. Shore 1") (EGU, "K") (PREC, "2") protocol file name protocol name File: LS 218. prot Terminator = CR LF; temp_K_1 { out "KRDG? 1"; protocol in "%f"; } protocol file

Protocol Files • One file for each device type • Global configuration of communication Protocol Files • One file for each device type • Global configuration of communication properties • One protocol for each function of device • out and in commands send and receive messages from device • Strings can contain format converters like %f. • Format converters work on implicit variables, typically VAL or RVAL fields. comment: # until end of line #Lake. Shore 218 configuration variables protocol: needs unique name within file write a constant string read and parse input string if used by an ai record %f sets. VAL Terminator = CR LF; Reply. Timeout = 1000; Read. Timeout = 100; all times are milliseconds reset { out "*RST"; #no reply } # read in Kelvin temp_K_1 { out "KRDG? 1"; in "%f"; } # read in Celsius temp_C_1 { out "CRDG? 1"; in "%f"; }

Strings in Stream. Device • Strings can be single or double quoted. – Strings in Stream. Device • Strings can be single or double quoted. – "That's a string" – 'This one too' Only difference: no need to escape the other quote type • Strings can be written in chunks, with or without comma – "This is", ' one' " big" ' string' This is the way to break long strings into multiple lines. • Non-printable characters can be written in many ways: hex, oct, or dec number, escape sequence, symbolic name – 0 x 0 a 012 10 "x 0 a" "12" "10" "n" LF For a list of symbolic names – 0 x 00 0 "x 00" "" NUL • Alternatives can be freely mixed – 0 x 1 b "00", 'PR 3' CR and escape sequence s see the documentation.

Format Converters as Known From printf and scanf • Standard formats – – %f, Format Converters as Known From printf and scanf • Standard formats – – %f, %e, %E, %g, %G, %d, %i, %x, %o, %s, %c, %[…] standard flags %0 -+# to modify format and %* to skip input new flags %? for optional input and %= for input comparison but no type modifiers like %hi or %lf • Additional formats and features – – – %b (bit strings like "10010001") %r (raw machine format numbers) %{…|…|…} (enumerations) %<…> (checksums) %/…/ (regular expressions) These are just some examples. More formats can be added. • Variable is implicit, usually VAL or RVAL field – Depends on converter type and record type – But can be redirected like %(EGU)s or %(record)f "redirection" is explained later

Protocol Parameters • Passing parameters from record to protocol can save typing. Example: Lake. Protocol Parameters • Passing parameters from record to protocol can save typing. Example: Lake. Shore 218 has 8 temperatures Terminator=CR temp_K_1 {out temp_K_2 {out temp_K_3 {out temp_K_4 {out temp_K_5 {out temp_K_6 {out temp_K_7 {out temp_K_8 {out LF; "KRDG? "KRDG? 1"; 2"; 3"; 4"; 5"; 6"; 7"; 8"; in in many almost identical protocols "%f"; } "%f"; } or record field } Terminator=CR LF; temp_K {out "KRDG? $1"; in "%f"; } use parameter instead: "$1" is 1 st parameter pass value for 1 st parameter (ai, "$(DEVICE): TEMP 2") { (DTYP, "stream") (INP, "@LS 218. prot temp(2) $(BUS)") (EGU, "K") (PREC, "2") Up to 9 paramet are possible. ers

Redirections • Normally format converters choose field automatically – ai. RVAL, ai. VAL, ao. Redirections • Normally format converters choose field automatically – ai. RVAL, ai. VAL, ao. RVAL, ao. VAL, … – Scaling (ASLO, AOFF) and smoothing (SMOO) supported • Sometimes other fields or even other records needed – E. g. when one message contains more than one value. Examples: Write value and units: Read status and value: out "%f %(EGU)s"; in "%(otherrecord)d, %f"; • Other records must be on the same IOC. If no field is given. VAL is assumed • Use parameters to avoid record names in protocols. – Like "%($1)d" or "%($1: STATUS)d" pass full record name as parameter pass only part of record name as parameter

Redirection Example: “position” request gives reply with 6 coordinates. Redirection Example: “position” request gives reply with 6 coordinates. "position( 1. 2 , 2. 1234, 23. 12 , -2. 312 , -12. 33 spaces , 24. 4321)" around numbers: record (ai, "$(DEV): POS-X") { %f accepts leading w field (DTYP, "stream") hitespace any amount of trailin g whitespace field (INP, "@XXX. prot POS($(DEV)) $(BUS)") is consumed by _ field (EGU, "mm") field (PREC, "2") POS { out "position"; field (SCAN, "5 second") When FLNK is processed, in "position(%f_, " field (FLNK, "…") the other records have "%($1: POS-Y)f_, " already got their values. } "%($1: POS-Z)f_, " record (ai, $(DEV): POS-Y) { "%($1: POS-RX)f_, " field (EGU, "mm") "%($1: POS-RY)f_, " field (PREC, "2") "%($1: POS-RZ)f_)"; } } Redirects to other re … cords do a db. Put. Field() These records have record (ai, $(DEV): POS-RZ) { and thus process the SCAN="Passive" and target field (EGU, "deg") if the field (here. VA DTYP="Soft Channel" L) is PP field (PREC, "3") When redirecting } to. RVAL use "Raw Soft Channel"

Complex Protocol Example: Pfeiffer Maxi. Gauge 1. Address device (on RS 485): ESC (0 Complex Protocol Example: Pfeiffer Maxi. Gauge 1. Address device (on RS 485): ESC (0 x 1 b) "aa" – aa is address 00, 01, … 2. Pressure read command: "PRn" CR – n is sensor number 1… 6 3. Each command is acknowledged with ACK (0 x 06) CR LF record field ENQ (0 x 05) } record 5. Receive status field and pressure: field "0, 1. 234 E-5" CR LF field … } 4. After acknowledge request value with In. Terminator=CR LF; # no Out. Terminator because of ENQ pressure { address out ESC "0$1" "PR$2" CR; in ACK; sensor out ENQ; in "%($3: STATUS)d, %f"; } redirect status to other record pass address, sensor and device name as 3 parameters (ai, "$(D): PRESSURE") { (DTYP, "stream") (INP, "@Maxi. prot pressure($(A), $(S), $(D)) $(B)") (mbbi, "$(D): STATUS") { (ZRST, "OK") (ONST, "Unterrange") (TWST, "Overrange") No spaces allowed in or around parameters And parameter values cannot contain , or )

Enum Format: %{…|…|…} • Translates integer to enumeration string and back Example 1: Device Enum Format: %{…|…|…} • Translates integer to enumeration string and back Example 1: Device can be switched with "STOP" and "GO". Example 2: Device may run forward or backward with different speeds (e. g. 1 or 5 mm/s) and reports this as "<<", "=", ">", or ">>". record field field } 0 = "STOP" 1 = "GO" # allows assignments: (bo, "$(DEV): SWITCH") { switch { "<<" = -5 (DTYP, "stream") "<" = -1 out "%{STOP|GO}"; "=" = 0 (OUT, "@XXX. proto switch $(BUS)") } ">" = 1 (ZNAM, "off") ">>" = 5 speed { (ONAM, "on") out "DIR? "; in "DIR=%#{<<=-5|<=-1|=|>>=5|>=1}" } (ai, "$(DEV): SPEED") { (DTYP, "stream") escape any literal (INP, "@XXX. proto speed $(BUS)") | or } or = ">>" before ">" to (EGU, "mm/s") in enum strings as avoid wrong match Input that does not m atch any of the choices is a format error and caus es an INVALID/CALC alar m | or } or =

Binary protocols Example: Send 5 byte telegram: – address, command, 2 byte value (little Binary protocols Example: Send 5 byte telegram: – address, command, 2 byte value (little endian), xor-checksum – confirmation is the same with bit 8 set in command byte • Use %r to send integers in "raw" machine code format Protocol does not use terminators but has fixed size set_value { messages and Max. Input=5; checksums. out $1 0 x 04 "%#. 2 r%"; Terminator=""; pass address as parameter 1 (no outside quotes) local configurations per protocol (overwrite globals) in $1 0 x 84 "%=#. 2 r%"; } check reply value get_value { Max. Input=5; out $1 0 x 44 0 x 00 "%"; in $1 0 xc 4 "%2 r%"; } • Use %R for raw float or doubles details see next slide checksum added checksum tested

Raw values: %r • Output format: %<flag><width>. <precision>r – flag #: little endian (default Raw values: %r • Output format: %. r – flag #: little endian (default is big endian) – width: number of bytes printed (sign extended) – precision: number of bytes taken from variable Example: value = 0 xdeadbeef pi byte out "%2 r"; 0 xff 0 xef 1 tfall sign extended to 2 out "%. 2 r"; 0 xbe 0 xef 2 bytes out "%#. 4 r"; 0 xef 0 xbe 0 xad 0 xde 4 bytes little endian out "%#4. 2 r"; 0 xef 0 xbe 0 xff 2 bytes sign extended to 4 • Input format: %r sorry for the mismatch out "%. 2 r" versus in "%2 r" – width: number of bytes to read – flag #: little endian – flag 0: zero extend to long (default is sign extend)

Checksums: %<…> • Many types of checksums supported – sum, xor, crc (8, 16, Checksums: %<…> • Many types of checksums supported – sum, xor, crc (8, 16, 32 bit), adler 32, … • Output: checksum is appended to output • Input: checksum is compared with input • Range selection: %. – start: number of bytes to skip from beginning of string – end: number of bytes to skip just before %<. . . > – both default to 0 Example: out "Example string%3. 2"; • Flag %0<…> switches to hex digits instead of raw bytes • Flag %#<…> switches to little endian for multi-byte checksums

Regular expressions: %/…/ • Regular expressions allow very powerful string parsing. – either to Regular expressions: %/…/ • Regular expressions allow very powerful string parsing. – either to read the string itself – or to find data that comes after some string Example: read title of a web-page. drv. Asyn. IPPort. Configure "web", "epics. web. psi. ch: 80" %/…/ ignores all input before the match if the expression does not start with ^ . 1: get 1 st sub expression, here: (. *? ) Out. Terminator = LF; Extra. Input = ignore; don't complain that we don't parse the whole page title { out "GET http: //$1"; in "%. 1/(? im)(. *? )/"; disconnect; escape the / } web server disconnects after sending a page and so do we (? im): case insensitive multi-line match. These are perl compatible regular expressions (PCRE) which are more powerful than GNU regexp. record (stringin, "$(DEV): TITLE") { field (DTYP, "stream") field (INP, "@web. prot title(epics. web. psi. ch/) web") }

Asynchronous input: I/O Intr • Some devices send unsolicited data Example: Temperature sensor sends Asynchronous input: I/O Intr • Some devices send unsolicited data Example: Temperature sensor sends periodically: "+27. 3 C" CR LF Terminator = CR LF; temperature { in "%f C"; } record field field } (ai, "$(DEVICE): TEMP") { (DTYP, "stream") (INP, "@XXX. prot temperature $(BUS)") (EGU, "C") (PREC, "1") (SCAN, "I/O Intr") • Asynchronous records have SCAN="I/O Intr" • Asynchronous protocols typically start with in command. • Any input from that device is checked. – Including input going to other protocols – Record is processed whenever matching input is found. – Non-matching input is ignored.

I/O Intr vs. Redirection Example: Read input line with two values x and y I/O Intr vs. Redirection Example: Read input line with two values x and y every second record field field } (ai, "$(D): x") { (SCAN, "1 second") (DTYP, "stream") (INP, "@XY. prot x $(BUS)") y is processe d (ai, "$(D): y") { when anyone (SCAN, "I/O Intr") receives input that matches (DTYP, "stream") (INP, "@XY. prot y $(BUS)") x { out "xy? "; in "%f %*f"; } Ignore first value (ai, "$(D): x") { (SCAN, "1 second") (DTYP, "stream") (INP, "@XY. prot x($(D)) $(BUS)") y is processe d (ai, "$(D): y") { when x writes (SCAN, "Passive") value to it (DTYP, "Soft Channel") x { out "xy? "; in "%f %($1: y)f"; } second value y { in "%*f %f"; } record field } record field } Be careful: Any input with two numbers matches. redirect second value Redirection is more selective. Only input from x goes to y.

Error Handling • All errors set SEVR to INVALID – STAT depends on error Error Handling • All errors set SEVR to INVALID – STAT depends on error type • • • Reply timeout: device does not reply (TIMEOUT) Read timeout: device stops sending unexpectedly (READ) Write timeout: writing is not possible (WRITE) Lock timeout: bus is blocked by other records (TIMEOUT) Mismatch: input does not match format string (CALC) • Errors abort the protocol – but may trigger exception handlers See next slide • Errors are not propagated along redirections – Redirects before mismatch are processed normally – Redirects after mismatch are not processed at all – Only active record gets error status • Mismatch in I/O Intr records is silently ignored

Exception handlers • Jump to different protocol if something goes wrong – @mismatch, @reply. Exception handlers • Jump to different protocol if something goes wrong – @mismatch, @reply. Timeout, @read. Timeout, @write. Timeout Example: Device replies with value or error message @mismatch { in "%($1: Error. String)39 c"; } read. Value { out "value? "; in "%f"; } Exception handlers can be defined before or inside normal protocol. if input does not match "%f" jump to @mismatch record field } record } reparse input and redirect error string If input does not mat ch and the @mismatch handler starts with in , then the same input is parsed a second time. (ai, "$(DEVICE): Value") { (DTYP, "stream") (INP, "@XXX. prot read. Value($(DEVICE)) $(BUS)") (stringin, "$(DEVICE): Error. String") {

Record Initialization • Output records can be initialized from hardware – Initialization is formally Record Initialization • Output records can be initialized from hardware – Initialization is formally handled as an exception: @init get. Volt { out "VOLT? "; in "VOLT %f"; } record field } set. Volt { record out "VOLT %. 2 f"; field @init {get. Volt; } field reference other } protocol to insert all } its commands get. Freq { record out "FREQ? "; in "FREQ %f MHZ"; field } set. Freq { record out "FREQ %. 6 f MHZ"; field @init {get. Freq; } field @init is executed } in ioc. Init before } scans are started (ai, "$(D): Read. Voltage") { (DTYP, "stream") (INP, "@X. prot get. Volt $(BUS)") (ao, $(D): Set. Voltage") { (DTYP, "stream") (OUT, "@X. prot set. Volt $(BUS)") (ai, "$(D): Read. Frequency") { (DTYP, "stream") (INP, "@X. prot get. Freq $(BUS)") (ao, $(D): Set. Frequency") { (DTYP, "stream") (OUT, "@X. prot set. Freq $(BUS)")

Arrays • For arrays the format is repeated for each element with optional separator Arrays • For arrays the format is repeated for each element with optional separator string in between. Example: "{10. 2, 345. 3, 23. 3, 10. 0}" read. Array { Separator = ", "; in "{%f}"; } record field } (aai, "$(DEVICE): Array") { (FTVL, "FLOAT") (NELM, "100") (DTYP, "stream") (INP, "@XXX. prot read. Array $(BUS)") • Input – reads max NELM elements – at least one element must be found – sets NORD to number of elements found • Output – writes NORD elements

Sending E-Mail do not auto-connect drv. Asyn. IPPort. Configure mail, mail. epics. org: 25, Sending E-Mail do not auto-connect drv. Asyn. IPPort. Configure mail, mail. epics. org: 25, 0, 1 Terminator = CR LF; Extra. Input = Ignore; Reply. Timeout = 1000; @mismatch { out "QUIT"; disconnect; } mail_start { connect 10000; in "220"; out "HELO"; in "250"; out "MAIL FROM: $1"; in "250"; out "RCPT TO: $2[email protected] org"; in "250"; out "DATA"; in "354"; out "From: $1"; out "To: [email protected] org"; out "Subject: Report from $1"; out ""; } don't care what text comes after those numbers allow a long connect time mail_end { out ". "; in "250"; out "QUIT"; disconnect; } disconnect when done mailstring { mail_start; out "The problem is: %s"; mail_end; } You may need a valid sender address to be accepted by your mail server. include common header and trailer by reference Better don't process this record periodically record (stringout, "$(DEVICE): Mail") { field (DTYP, "stream") field (OUT, "@sendmail. proto mailstring($(DEVICE), controls) mail") }

Parsing XML • Use regular expression to find a string, then read data Example: Parsing XML • Use regular expression to find a string, then read data Example: read food price from XML menu XML example taken from w 3 schools. com Belgian Waffles $5. 95 two of our famous Belgian Waffles with plenty of real maple syrup 650 Strawberry Belgian Waffles $7. 95 light Belgian waffles covered with strawberries and whipped cream 900 find the next Strawberry. Waffles. Price { out "GET http: //www. w 3 schools. com/xml/simple. xml"; in "%*/(? m)Strawberry Belgian Waffles. *? /$%f"; disconnect; Why this is not a real } XML *: discard the regexp match just find the string then continue parser: Input is parsed only on ce. %*/…/ discards non-m atching start of file. Reading multiple valu es is difficult when order is unknown. now read the price

Changing the Baud Rate of an Active Connection Example: Device switches to low baud Changing the Baud Rate of an Active Connection Example: Device switches to low baud rate when reset. drv. Asyn. Serial. Port. Configure serial 1, /dev/tty. S 0 start IOC with "normal" high # normal baud rate is 115200 baud rate asyn. Set. Option serial 1, 0, baud, 115200 @reply. Timeout { # device switches to 9600 baud when reset # switch serial line to 9600 baud exec "asyn. Set. Option serial 1, 0, 9600"; exec sends a command to iocsh # switch device to 115200 baud out "set baud 115200"; # switch serial line back to 115200 baud exec "asyn. Set. Option serial 1, 0, 115200"; } if device was reset it does not reply on high baud rate try to reset baud rate to high speed

Debugging • Read the device documentation carefully but don't trust it! • Look for Debugging • Read the device documentation carefully but don't trust it! • Look for error messages in the ioc shell. • Switch on stream debugging: var stream. Debug 1 – Output will be huge! – Disable all other records but the one you are debugging. – At the moment not switchable per record or per device • Switch on asyn. Driver debugging. • RS 232 serial line: – Put a serial analyzer in the line – Try to connect with minicom, hyperterm or other terminal program • Network TCP: – Try to connect with telnet

Debugging • A generic command record is very helpful record (stringout, Debugging • A generic command record is very helpful record (stringout, "$(DEV): command") { field (DTYP, "stream") field (OUT, "@XXX. proto command $(BUS)") } command { Extra. Input = ignore; out "%s"; in "%39 c"; First 39 chars of reply will replace the } co mmand string after processing. Use a caput with process callback (not in base ) • For medm or other GUI using two records is better record (stringout, "$(DEV): command") { command { field (DTYP, "stream") Extra. Input = ignore; field (OUT, "@XXX. proto command($(DEV)) $(BUS)") out "%s"; ' } in "%($1: reply)39 c"; } Reply is sent to othe r record (stringin, "$(DEV): reply") { } record.

Debugging • Spying the input can help record (stringin, Debugging • Spying the input can help record (stringin, "$(DEV): spy") { field (DTYP, "stream") field (INP, "@XXX. proto spy $(BUS)") field (SCAN, "I/O Intr") } spy { Extra. Input = ignore; in "%39 c"; } record (waveform, "$(DEV): spybin) { field (DTYP, "stream") field (INP, "@xxx. proto spybin $(BUS)") field (FTVL, "CHAR") field (NELM, "1000") field (SCAN, "I/O Intr") } spybin { Extra. Input = ignore; In. Terminator = ""; Read. Timeout = 1; in "%r"; } • If in doubt about the In. Terminator try to set it to empty string and check what you get in the input.