User written acquisition software problem

Post Reply
bhb2048
Posts: 4
Joined: Fri May 19, 2017 8:16 pm

User written acquisition software problem

Post by bhb2048 » Tue May 23, 2017 5:44 pm

Hello,

I'm attempting to write a module for our current data acquisition system to use our BioSemi Mk2 system. It's set in mode 4 (282 chan). I'm using Linux. I got the Labview_DLL_Synctest example program to work (after adjusting for 282 chan). My program and Synctest both link with liblabview_dll.so. My program follows Synctest's liblabview_dll call order. One difference is the first call 'OPEN_DRIVER()' is done in my module's ctor. Then READ_MULTIPLE_SWEEPS() and USB_WRITE() are in my module's 'startAD()' function. Here's the code:

SubSysBS::SubSysBS()
{
// init _controlBuffer
for (int i=0; i<64; i++)
_controlBuffer = 0;
_lastSample = 0;

// get USB handle, do config
if ( ( _usbHandle = OPEN_DRIVER()) != NULL)
{
cout << "Device Ready" << endl;
_status = DAS_READY;
getConfig();
}
else
_status = DAS_AD_OPEN_ERR;
}

SubSysBS::startAD( int sg, int cb)
{
char *buf;
bool nStatus;

cout << "startAD status " << hex << _status << endl;
if ( _status & DAS_ERROR)
{
cerr << "startAD: DAS_ERROR" << endl;
return 1;
}

buf = _dataBuf + _circBuf[cb].offset;

nStatus = READ_MULTIPLE_SWEEPS( _usbHandle, buf, _circBufSize);
if ( nStatus == false)
{ // ERROR
_status |= DAS_ERROR;
alert ("READ_MULTIPLE_SWEEPS error: %s\n", strerror(errno));
return 1;
}

// start the flow of samples to the ring buffer

sleep(1); // 1 sec sleep

_controlBuffer[0] = char(-1);
nStatus = USB_WRITE( _usbHandle, &_controlBuffer[0]); // enable usb interface
if ( nStatus == false)
{ // ERROR
_status |= DAS_ERROR;
alert ("USB_WRITE-2 for enable handshake error: %s\n", strerror(errno));
return 1;
}
...

The problem is that 'USB_WRITE' returns an 'invalid argument' error (errno=22).
OPEN_DRIVER() and READ_MULTIPLE_SWEEPS() seem to work fine. I am at a loss to why USB_WRITE doesn't work and would appreciate any hints or suggestions on how to debug this.

Thanks,
Barry

pmac
Posts: 70
Joined: Thu Jan 21, 2010 2:51 pm
Location: Canada

Re: User written acquisition software problem

Post by pmac » Wed May 24, 2017 12:05 am

Hi Barry,

This does not look right:

// init _controlBuffer
for (int i=0; i<64; i++)
_controlBuffer = 0;


Isn't there a subscript missing?

Paul

bhb2048
Posts: 4
Joined: Fri May 19, 2017 8:16 pm

Re: User written acquisition software problem

Post by bhb2048 » Wed May 24, 2017 3:02 pm

You are right, apparently I needed to click 'Disable BBCode', the brackets were stripped. The ctor code actually is this:

SubSysBS::SubSysBS()
{
// init _controlBuffer
for (int i=0; i<64; i++)
_controlBuffer[i] = 0;
...

Any suggestions on debugging the main USB_WRITE error problem will be greatly appreciated.

Thanks,
Barry

pmac
Posts: 70
Joined: Thu Jan 21, 2010 2:51 pm
Location: Canada

Re: User written acquisition software problem

Post by pmac » Wed May 24, 2017 6:11 pm

Hi Barry,

As I understand things, here USB_WRITE expects as its 2nd argument the address of a 64 byte array
with all bits on in the first byte and the following 63 bytes all zeros.

The Synctest program is written in C and uses a "cast" to CHAR to set this first byte:

controlBuffer[0] = (CHAR)(-1);

Your C++ program seems to call a function called "char" to do this:

_controlBuffer[0] = char(-1);

I don't know this function. Does it return a byte with all bits set?

Why not just do it the way Synctest does it which you seem to have working.

Paul

bhb2048
Posts: 4
Joined: Fri May 19, 2017 8:16 pm

Re: User written acquisition software problem

Post by bhb2048 » Thu May 25, 2017 6:25 pm

Hi Paul,

In labview_dll.h (#included by Labview_DLL_Synctest) 'CHAR' is #defined as 'char'. So they're the same thing. 'char' casts -1 to byte size all 1's. And I've checked _controlBuffer[0] to verify that. That's why I'm mystified by this problem. If you could offer any debugging suggestions I'd be very thankful.

Barry

pmac
Posts: 70
Joined: Thu Jan 21, 2010 2:51 pm
Location: Canada

Re: User written acquisition software problem

Post by pmac » Thu May 25, 2017 8:46 pm

Hi Barry,

You're right, it doesn't seem to make sense. Perhaps you've stumbled on some subtle difference between
C and C++.

My suggestion ...

You have a C program that works - synctest. Try building your program from that, by first
stripping out what you don't need, testing at various stages that it still works, and then
slowly adding your changes, testing frequently.

Please let us know if you discover something we should know.

Paul

bhb2048
Posts: 4
Joined: Fri May 19, 2017 8:16 pm

Re: User written acquisition software problem

Post by bhb2048 » Fri May 26, 2017 6:10 pm

Hi Paul,

I found the problem. I ran my program in the Valgrind memory checker and found this error:
==15369== Syscall param ioctl(USBDEVFS_SUBMITURB).buffer points to unaddressable byte(s)
==15369== at 0x7870507: ioctl (in /usr/lib64/libc-2.17.so)
==15369== by 0x7B49B7E: submit_bulk_transfer (linux_usbfs.c:1396)
==15369== by 0x7B47C5B: libusb_submit_transfer (io.c:1236)
==15369== by 0x4E385F3: BSIF_USB_WRITE (in /usr/local/lib/liblabview_dll.so.0.0.1)
==15369== by 0x4E35BB7: USB_WRITE (in /usr/local/lib/liblabview_dll.so.0.0.1)

which led me to checking my databuffer creation. There was a bug so the prior call to READ_MULTIPLE_SWEEPS initializing the buffer was using a bad buffer address. It's fixed. Now USB_WRITE works.

Thanks for your help!
Barry

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest