Friday, April 12, 2024

Re: Determining number of dropped samples from USRP Sink in TX chain

Hi Adrian -

You wrote:
I'm wondering if there is any possibility to programmatically check how long an underrun event in a flowgraph that uses a USRP sink lasted.

I believe the usrp/uhd attempts to treat each underrun as a one-sample event, and report accordingly.  There's a cogent definition in the Ettus Driver Manual, see the section header "Underrun notes":


If we define dt = 1/samp_rate  ... then (ignoring buffering and queueing), one underrun event means:
     1. the usrp started waiting for a sample from your program at time t=t0,  but 
     2. no sample was provided after dt seconds had elapsed, and
     3. at time t=t0+dt the usrp issued a timestamped message (asynchronously) about the event. SO ...

 
I do get messages from the sink when and that an underrun happened, but I can't see if that was for 1 ms or 20 seconds.


NOTE: the 'event' is a point-in-time, rather than an interval of time.  It takes place at a time  t0 + 1/samp_rate  as described above,  and - although it's printed in a format that looks weird in trace output - you have all the info you need:

>    message_debug :warning: Message: (uhd_async_msg (channel . 0) (time_spec 1333 . 0.277859) (event_code underflow))
>    Umessage_debug :warning: Message: (uhd_async_msg (channel . 0) (time_spec 1333 . 0.280334) (event_code underflow)) 

What you're seeing above are two underruns being reported about 2ms apart ...   
      - the U on the second line is stderr - you'll always see one U for each underrrun (or a summary, depending on config)  
      - the Message:...  is because you're routing the message output of the USRP to a Message Debug block.    
      - the time_spec_t object tuple(int, double) contains whole seconds (1333) and fractional seconds (0.280334) since the USRP 'started'.
      - Rule of thumb re t=0: a B200/B210 finishes initializing (messages like '[INFO] [B200] Actually got clock rate 16.777216 MHz') at around (time_spec 2 , 0.1000).

What to do??
The event 'duration' of each underrun is 1/samp_rate, and those stamps should be accurate - time deltas to be computed between two time_spec_t objects.
You probably care most about the average time between events.
Pro tip: a better way to monitor those messages is to send them to a ZMQ Message Sink block and process them  in a separate flowgraph or python script that subscribes or pulls the messages.  You can then consume them as numbers at your leisure.  This adds minimal blocking / backpressure to your flowgraph.

Is there any way to query the USRP for further information on the event?

Yes there is:  
1. You're already getting the 'cue' of when to look by subscribing to the message source.
2. To dig into the details, have a look at the 'answer to my own question' posted under this subject earlier this week:
     Re: How to get UHD 'rx_time' / 'rx_freq' after 'tune'? (Python)

The post includes (poorly edited) code examples, I'm happy to answer questions (or to be corrected by those more knowledgeable :-)   

Cheers,

W .--



No comments:

Post a Comment