View topic - Loop frequency enhancement

Loop frequency enhancement

anything that doesn't fit to other groups.

Loop frequency enhancement

Postby wallace » Mon Jan 23, 2012 9:08 am

I need advice.

I have a usb device, and I`ve written code to get data from the device.
The code:
do{
usbd_setup_isochronous(urb, URB_DIR_IN | URB_ISOCH_ASAP, 0 mem, max_packet_size );
usbd_io( urb, conn_pipe, cbf, NULL,USBD_TIME_DEFAULT);
pthread_mutex_lock(&io_mutex);
pthread_cond_wait(&io_cond, &io_mutex);
pthread_mutex_unlock(&io_mutex);
...
}while(...)

cbf is as follows:
void cbf(struct usbd_urb *, struct usbd_pipe *, void *){
pthread_mutex_lock(&io_mutex);
pthread_cond_signal(&io_cond);
pthread_mutex_unlock(&io_mutex);
}

My problem is that, loop frequency is about 90Hz. Pooling interval for isochronous devices is 1ms. Is there any way to make the loop to go faster? Without mutexes and condvar code speeds up significantly, it hangs up the usb stack, however.io_mutex);
pthread_cond_signal(
wallace
Active Member
 
Posts: 15
Joined: Tue Dec 20, 2011 11:11 pm

Re: Loop frequency enhancement

Postby Tim » Mon Jan 23, 2012 10:59 pm

Wallace,

The polling interval for USB may be 1 ms but that doesn't mean there is any data there to read in your CBF.

Without seeing more of your code its hard to guess. But are you signaling the condition (pthread_cond_signal) only when there is data read or every 1 ms? Normally you only want to signal when there is data. So are you sure you are missing data from the USB device or is the device only sending at a 90 Hz rate?

QNX mutex's and condvars are very fast. Much faster than 90 Hz I can assure you.

Tim
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Re: Loop frequency enhancement

Postby wallace » Tue Jan 24, 2012 12:27 am

Tim,

When you say "the device only sending at a 90 Hz rate?" what do you mean?

The device is usb audio codec (pcm2902B) with sinusoidal wave plugged to input channel, so I`m pretty sure there are data to receive every 1ms. What is more, when generated plots from gathered data they look like some frames are missing.

I believe that condvars and mutexes are much faster, but the frequency drops down when used. Without synchronization mechanism program is unstable (system stops responding).

The last thing I noticed is fact, that when IO code looks that way:

usbd_get_frame(device, &fnum, &flen);
usbd_setup_isochronous(urb, URB_DIR_IN | URB_ISOCH_ASAP, fnum, mem, flen);
usbd_io( urb, conn_pipe, cbf, NULL,USBD_TIME_DEFAULT);

It`s pretty fast, but flen is much bigger than max_packet_size, they are respectively 1024 and 98. And gathered data is a part of time-repeatable data (but it doesn`t even close to sin shape) and 0.
wallace
Active Member
 
Posts: 15
Joined: Tue Dec 20, 2011 11:11 pm

Re: Loop frequency enhancement

Postby Tim » Tue Jan 24, 2012 2:31 pm

Wallace,

wallace wrote:The device is usb audio codec (pcm2902B) with sinusoidal wave plugged to input channel, so I`m pretty sure there are data to receive every 1ms.


Ah, OK, good to know. I had no idea what USB device you were connecting. I wasn't sure if it was some kind of Digital/Analog I/O card that only sent data 10 or 100 times a second.

wallace wrote:usbd_get_frame(device, &fnum, &flen);
usbd_setup_isochronous(urb, URB_DIR_IN | URB_ISOCH_ASAP, fnum, mem, flen);
usbd_io( urb, conn_pipe, cbf, NULL,USBD_TIME_DEFAULT);

It`s pretty fast, but flen is much bigger than max_packet_size, they are respectively 1024 and 98.


Not sure where you get max_packet_size from (the doc's on the USB device?). I would use the code above. It's very possible (likely) that the transferred data from the USB device contains multiple packets of data (similar to how Ethernet packets can contain 1024 bytes and could contain 10 packets of 98 bytes).

When you use the above code, how much data is being transferred? If it's more than 98 bytes, are you handling the possibility that you are getting multiple packets in that data?

Tim
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Re: Loop frequency enhancement

Postby wallace » Thu Jan 26, 2012 6:12 pm

Tim,

Sorry for late response, but i`m suffering from lack of time. I`ve taken a closer look at the code (faster version), it appears not to work correctly. I`ve used usbd_urb_status. Returned value is always EBUSY, and completion status never equals to USBD_STATUS_CMP_ERR. I think, data I get using the faster code version is just rubbish.

max_packet_size is value I received from endpoint descriptor (it equals the value mentioned in devices datasheet).

I`m handling possibility that I`m getting multiple packets in data transmitted from device. Program just writes data from buffer (which data from device are transferred to) to file as short type, so every packet I get is saved in file. As I use write() function is not human-readable format. The another program reads the file, and save the data as column of numbers readable for human. This file is passed as data input for plot.
wallace
Active Member
 
Posts: 15
Joined: Tue Dec 20, 2011 11:11 pm

Re: Loop frequency enhancement

Postby Tim » Fri Jan 27, 2012 9:02 pm

Wallace,

I went back and re-read all your postings. You don't mention which version of QNX you are running. In the 6.4 Doc's for usbd_io() it says that the function parameter (where you are stuffing cbf) is not supported. Only synchronous transfers are allowed.

http://www.qnx.com/developers/docs/6.4. ... bd_io.html

So I just want to make sure you aren't going down the wrong path in 6.4. I do not know about the 6.5 DDK as I didn't see the doc's for it. It may well still be the same as 6.4.

I agree with you about the rubbish part when you don't have the Condvar. In those cases I expect you are just returning immediately and actually reading nothing from the USB stack. You could probably verify this if you wanted by setting the memory transfer block to something like 0xFF in every byte and seeing if you got that back. But I don't think you need to do that.

When you make your call to usbd_alloc (which you don't show), how much space are you allocating for the transfer data (your mem variable)? Is it 98 or 1024? Just curious to know if how big you've made this since you won't be able to get 1024 bytes unless you reserved that much space.

Tim
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Re: Loop frequency enhancement

Postby wallace » Thu Feb 02, 2012 1:34 pm

Tim,

I`ve tried usbd_alloc with allocating both, 98 and 1024 bytes.

The system version is 6.4.1, so I have to admit that, I did not read the usb ddk docs carefully enough.

Ok, so now i understand, that I have to use
usbd_setup_vendor - ddk docs does not mention how to set up synchronous mode.

and then,
usbd_io

If the callback must be set to NULL, how to signalize that usbd_io has finished?
wallace
Active Member
 
Posts: 15
Joined: Tue Dec 20, 2011 11:11 pm

Re: Loop frequency enhancement

Postby Tim » Thu Feb 02, 2012 4:41 pm

Wallace,

wallace wrote:If the callback must be set to NULL, how to signalize that usbd_io has finished?


When the call returns. With synchronous transfers the usbd_io call will block until data is returned (UDBD_TIME_INFINITY) OR UDBD_TIME_DEFAULT (not sure what that's set to but it's in case you don't want to wait forever for data and want to do some processing before returning to check again for data being available).

Just be sure to check the error code when usbd_io returns to make sure the USB device wasn't removed.

Tim
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am


Return to General Programming

Who is online

Users browsing this forum: No registered users and 2 guests