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 | 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 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: Reading scope waveforms with StreamDevice + asyn |
From: | Dirk Zimoch <[email protected]> |
To: | Rod Nussbaumer <[email protected]> |
Cc: | epics Techtalk <[email protected]> |
Date: | Mon, 16 Jan 2012 11:56:34 +0100 |
Hi Rod,Not specifying any terminator means: Do not touch the terminator settings. That means use whatever is specified by asynDriver with asynOctetSetInputEos and asynOctetSetOutputEos in the startup script. If neither is used, the default is empty string for both. Setting the terminator to "" or any other string overwrites the asynDriver setting.
I had a look at drvLinuxGpib.c and found:* It never sets eomReason. Thus StreamDevice (or any other asynUser) has no chance to find EOI.
* Under some circumstances it sets EOS to '\0' instead of nothing. Dirk Rod Nussbaumer wrote:
Thanks, Dirk.I have observed the 64-byte reads often in the past, and wondered whether there was a way to increase that amount, for purposes of efficiency. In this case, I do know the size of the array I expect to read, as it is a fixed size, and each binary word is the same, plus some accompanying header data, also of fixed length and makeup.I am reading/matching the trailing LF. I wasn't sure whether setting InTerminator = ""is the same as not setting it explicitly at all, or whether it might cause it to take on some new meaning. I do know that each protocol can have specific terminator settings, and I've been trying to use that in various combinations. What is the expected behavior if no Terminator or InTerminator is specified, neither globally within the protocol file, nor in the specific protocol? What I'm seeing in that case appears that any NULL byte terminates a read. This causes a huge number of short reads per waveform.2012/01/13 08:50:10.847 GPIB0 addr 10 gpibRead 2012/01/13 08:50:10.847 GPIB0 addr 10 gpibPortRead $ 24 00 2012/01/13 08:50:10.857 GPIB0 addr 10 gpibRead 2012/01/13 08:50:10.857 GPIB0 addr 10 gpibPortRead 00 2012/01/13 08:50:10.868 GPIB0 addr 10 gpibRead 2012/01/13 08:50:10.868 GPIB0 addr 10 gpibPortRead 00 2012/01/13 08:50:10.878 GPIB0 addr 10 gpibRead 2012/01/13 08:50:10.878 GPIB0 addr 10 gpibPortRead P 50 00 2012/01/13 08:50:10.888 GPIB0 addr 10 gpibRead 2012/01/13 08:50:10.889 GPIB0 addr 10 gpibPortRead 00 2012/01/13 08:50:10.899 GPIB0 addr 10 gpibRead 2012/01/13 08:50:10.899 GPIB0 addr 10 gpibPortRead 0a 2012/01/13 08:50:10.909 GPIB0 addr 10 gpibRead 2012/01/13 08:50:10.929 GPIB0 addr 10 : device timed out. epics>If I set InTerminator="" in the protocol, the same thing happens, but I also get, at the end of the record processing:00 2012/01/13 08:54:42.269 GPIB0 addr 10 gpibRead 2012/01/13 08:54:42.269 GPIB0 addr 10 gpibPortRead 0a 2012/01/13 08:54:42.279 GPIB0 addr 10 gpibRead 2012/01/13 08:54:42.299 GPIB0 addr 10 : device timed out. 2012/01/13 08:54:42.299 GPIB0 addr 10 setEos eoslen 0Note the reference to EOS in the last asyn message. I sense that this is germane to the problem.I am a bit curious about *how* terminators are used/implemented in streamDevice. Does the recognition of terminators get used only within streamDevice, or does it get passed down to asyn in some way? To me, there are different purposes to the terminators, especially in the case of GPIB, where the low level drivers have their own behaviors for message termination. It seems that there may be some interplay that is hidden.So far I think I've determined (from code inspections in the asyn linux GPIB port driver) that the behavior of asyn plus the asynSetOptions() I'm using should be mimicking my own test/diagnostic C code. I wonder whether streamDevice is asserting some communication options through its use of asyn? I will start looking into the streamDevice code, but if anyone knows for sure, I would be happy to hear.Mark, I haven't tried the asyn record tests yet, as I'm not really familiar with how to implement and use it, but now is looking like a good time learn.Thanks. --- rod. Dirk Zimoch wrote:Hi Rod, If everything works correctly in asyn, it sees the EOI and tells StreamDevice that this is the end of the message via the (eomReason & ASYN_EOM_END) bit (in opposite to the ASYN_EOM_EOS bit when a terminator is found). So it should work with an empty terminator. I guess you know that you can set the terminators individually for each protocol. So ASCII protocols can use LF and binary protocols "". In order to get rid of the LF at the end of the message, you have to read it in the protocol after reading the array. The waveform record reads data until either NELM elements are read or the message ends. If the array has variable size, you need to set NELM large enough. When trying to read the next 4-byte word, StreamDevice will find at some point that only one byte is left and stop reading. That byte (LF) will stay in the input and you have to read it explicitly. However, StreamDevice has one problem with GPIB but I don't know if it affects you: The asynGpib implementation (at least for vxi11, the only one I can test) does not allow to read the message in chunks. One has to know in advance how long the message is and need to provide a sufficiently large buffer. Therefore, StreamDevice starts with a 64 byte buffer for GPIB devices. This is enough for most messages but not for arrays. If the buffer is too small and the message cannot be read in chunks, asyn should return a asynOverflow error. In that case, StreamDevice increases the buffer size by doubling it. But this transmission fails. One of the next transmissions may succeed as soon as the buffer is sufficiently large. This problem may be fixed in a future version of asyn or may even have been fixed without me noticing it. One workaround would be to add a variable to StreamDevice to specify the initial buffer size. I have no idea how linux-gpib behaves. I can only test vxi11. Gruss Dirk Rod Nussbaumer wrote:Hi all. I've been trying to read waveforms from a Tektronix TDS8000 scope using R3.14.11 + StreamDevice (2.4) + asyn (4.13) + linux-gpib using a NI PCI GPIB interface on an x86 PC platform. I cannot seem to find the right message termination to satisfy all of the various components. The scope documentation says it does not use end-of-line terminator characters, but rather sets EOI on the GPIB to signal end of messages. Nevertheless, there are LF characters appended to each message, even binary formatted waveform data. I'm trying to use RIB encoded (Intel-endian binary) waveform data, 4-byte words. I'm hoping to read 10 waveforms per second on a periodic scan of an EPICS waveform record, (500 integer data points). A simple bit of C code is able to read waveforms at about 80 waveforms per second in a tight loop. In there, I have used the 'ibeos()' function to cause my C code to not terminate reads on any character delimiters, and this seems to have the desired effect. In the gpib.conf file, I've include the setting: set-reos = no There is also the setting... eos = ___ ... which I've set to 0x0, commented out completely, and set to 0x0a, none of which seems to change anything, and which is in accordance with my expectation. Most/some of the settings in gpib.conf seem to correspond to the capabilities of the asynSetOption() function which I've also used in the EPICS startup script. There, it does seem to make a difference. If I set... asynSetOption("GPIB0",10,0x0c,0) ...then asynTrace shows me that it does two things: 1. terminates its sequential reads on each binary zero byte 2. times out at the end of the read (and sees/reads the trailing LF) I seem to be stuck between a rock and a hard place: either I use an end-of-line terminator, which will eventually show up in the binary data and prematurely terminate the read, or if I try to use the option to not use end-of-message characters, it will wait until the read times out, which seems to have the effect of invalidating the record, and slowing things down a lot. Any hints on how to proceed, tests to make or requests for further info are welcomed. Thanks. Rod Nussbaumer ISAC Controls, TRIUMF Vancouver, Canada.