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":

https://files.ettus.com/manual/page_general.html#:~:text=has space 
again.-,Underrun notes,mean the host machine can't keep up with the requested 
rates.,-Threading Notes 
<https://files.ettus.com/manual/page_general.html#:~:text=has%20space%20again.-,Underrun%20notes,mean%20the%20host%20machine%20can't%20keep%20up%20with%20the%20requested%20rates.,-Threading%20Notes>

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 .--



Reply via email to