[Gambas-user] Help binding to /dev/usbtmc0?

Tobias Boege taboege at ...626...
Mon Jul 1 17:11:21 CEST 2013


On Mon, 01 Jul 2013, dr.diesel wrote:
> Thanks again, I believe this is what is causing my problems with
> "/dev/usbtmc0"
> 
> read(2) and fread(2)
> Here's another aspect you need to be aware of. The kernel offers two sets of
> system calls for file I/O, and their behavior is slightly different,
> especially when it comes to reading data. The read(2) system call requests a
> given maximum number of bytes from the file (instrument), but it is happy if
> the call returns less than the maximum number. The fread(2) system call, on
> the other hand, has the habit of retrying until the total number requested
> bytes is reached (or until the call returns 0 bytes, which indicates the end
> of the file). This works well for real files, but it doesn't work well for
> instruments because the second read transaction will usually cause a
> timeout.
> If you use C or another language that gives you the choice, it is
> recommended to use read(2) etc. instead of fread(2) etc. However, if you use
> echo/cat and shell output redirection, the shell will use fread(2). In order
> to avoid the issues associated with automatic retries, the driver simply
> ignores every second call to its read entry point (assuming that call is a
> retry) unless the first call returned the maximum number of bytes requested
> (in which case there is no retry).
> It is important to note that if you are using read(2) ??? which is recommended
> ??? you need to deactivate the driver's default behavior of ignoring every
> second call to its read entry point! This can be done by setting a driver
> attribute through a call to the driver's ioctl entry point:
> int my_inst;
> struct usbtmc_attribute attr;
> my_inst=open(???/dev/usbtmc1???,O_RDWR);
> attr.attribute=USBTMC_ATTRIB_READ_MODE;
> attr.value=USBTMC_ATTRIB_VAL_READ; // using read, not fread
> ioctl(my_inst,USBTMC_IOCTL_SET_ATTRIBUTE,&attr);
> 
> Source of the above:
> 
> http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.html?&cc=US&lc=eng
> 

The author certainly meant fread(3) because fread(2) is non-existent.

> I suspect CAT and Gambas are using fread(2), causing the timeouts.  Is there
> any method to use read(2) from Gabmas?
> 

If I was a nitpicker, I'd say "no, you need assembly to call a system call
on Linux". Fortunately, I did my daily nitpicking just above, so I'd say
"yes, you can use your C library's wrapper" for read(2):

---
Extern SysRead(iFd as Integer, hBuf As Pointer, iSize As Integer) As Integer In "libc:6" Exec "read"

Public Sub btnOpen_Click()
  Dim hFile As File

  hFile = Open "/dev/usbtmc0" For Read Write Watch
End

Public Sub File_Read()
  Dim hBuf As Pointer
  Dim sRead As String

  hBuf = Alloc(128)
  If SysRead(Last.Handle, hBuf, 128) = -1 Then
    Error.Raise(("read(2) error"))
    Return
  Endif
  sRead = Str@(hBuf)
  Free(hBuf)

  ' Do something with sRead
End
---

You should read about Extern functions[0][1][2]. The documentation is
impressively extensive about this :-)

Above is the read() method. You could alternatively do the ioctl() method
likewise.

Regards,
Tobi

[0] http://gambasdoc.org/help/lang/extdecl?v3
[1] http://gambasdoc.org/help/cat/externfunc?v3
[2] http://gambasdoc.org/help/howto/extern?v3




More information about the User mailing list