SoapyHackRF - Osmocom - gnuradio

2,443 views
Skip to first unread message

Gavin Jacobs

unread,
Oct 30, 2016, 8:23:07 PM10/30/16
to Pothos Users
I'm looking for a way to use a Hackrf One in gnuradio, such that I can switch between transmit and receive. I saw some comments on the hackrf git site ( https://github.com/mossmann/hackrf/issues/195 ) which led me to the SoapyHackrf module, which can be linked into the gr-osmosdr block. Sounded like just what I need and so I downloaded and built all the pieces and now I have the following:
- Ubuntu
- gnuradio companion
- SoapySDR
- libhackrf
- gr-osmosdr c/w SoapyHackrf

I can see my hackrf using hackrf_info, and I can also see it using SoapySDRUtil. I put the osmocom source and sink blocks into a gnuradio flow graph, and I can see in the output that soapy finds the hackrf; in fact it ALMOST works like I hoped. There are two problems:
1) If I just enable the sink, run the flowgraph, it works fine; but if I stop and restart the flowgraph, it hangs. I have to reset the hackrf (using the push button) to get it working again. Same issue with source; i.e. have to reset the hackrf to get it to work again. Note: if I use the osmocom block with hackrf driver (as opposed to the soapy hackrf driver), then both source and sink work as expected, but only one or the other; i.e. no switching between transmit and receive.

2) Meanwhile, if I enable both source and sink, I see the tx LED flicker briefly, then the rx LED, then the tx LED comes on steady; I expected to see the tx LED for about 10 seconds, then the rx LED steady.

So first, is this the right place to ask for help? To me it looks like an issue with the implementation of hackrf in SoapyHackrf, and if that's correct, is there a place to file a bug report?

Also, I see a few examples using SoapyHackrf in Pothos; but I would love to see some examples in gnuradio & gr-osmosdr.

Also, any suggestions, or workarounds, or alternatives would be helpful.

Thanks,
Jake



Josh Blum

unread,
Nov 2, 2016, 2:55:33 AM11/2/16
to pothos...@googlegroups.com
Hey Jake,

Cool, glad you are looking into this. Replies inline:

On 10/30/2016 07:23 PM, Gavin Jacobs wrote:
> I'm looking for a way to use a Hackrf One in gnuradio, such that I can
> switch between transmit and receive. I saw some comments on the hackrf git
> site ( https://github.com/mossmann/hackrf/issues/195 ) which led me to the
> SoapyHackrf module, which can be linked into the gr-osmosdr block. Sounded
> like just what I need and so I downloaded and built all the pieces and now
> I have the following:
> - Ubuntu
> - gnuradio companion
> - SoapySDR
> - libhackrf
> - gr-osmosdr c/w SoapyHackrf
>
> I can see my hackrf using hackrf_info, and I can also see it using
> SoapySDRUtil. I put the osmocom source and sink blocks into a gnuradio flow
> graph, and I can see in the output that soapy finds the hackrf; in fact it
> ALMOST works like I hoped. There are two problems:

> 1) If I just enable the sink, run the flowgraph, it works fine; but if I
> stop and restart the flowgraph, it hangs. I have to reset the hackrf (using
> the push button) to get it working again. Same issue with source; i.e. have
> to reset the hackrf to get it to work again. Note: if I use the osmocom
> block with hackrf driver (as opposed to the soapy hackrf driver), then both
> source and sink work as expected, but only one or the other; i.e. no
> switching between transmit and receive.

I have personally caused the hackrf to lock-up while doing development
so that it needed a physical reset, but nothing consistent. It may be a
cleanup issue or perhaps there is a command to reset things to a good
state on open.

Is the flowgraph being stopped nicely or is this the "kill button" that
actually kill -9s the running flowgraph? That could be leaving things in
a bad state too.

I dont know off the top of my head the reason, but it looks like
something easy to reproduce when I get the chance (I'm away from my
hackrf now).

>
> 2) Meanwhile, if I enable both source and sink, I see the tx LED flicker
> briefly, then the rx LED, then the tx LED comes on steady; I expected to
> see the tx LED for about 10 seconds, then the rx LED steady.


Is there a stream of data going into the osmo sink block for just 10
seconds on init? It might be the case that since both rx and tx are
initially started that the tx stream takes precedence (maybe random
ordering of block setup). Then it switches back to rx since there is no
tx data. Then the tx data makes it way into the osmo sink and starts
transmit streaming again. Some printing in HackRF_Streaming.cpp
mentioned below might help to see whats going on.

>
> So first, is this the right place to ask for help? To me it looks like an
> issue with the implementation of hackrf in SoapyHackrf, and if that's
> correct, is there a place to file a bug report?

I saw the the issue on the hackrf github, but I sort of lost track.
Sorry about that. The mailing list if perfectly fine for this. I think
the https://github.com/pothosware/SoapyHackRF issue tracker may have a
few more relevant eyes on it too if that helps.

>
> Also, I see a few examples using SoapyHackrf in Pothos; but I would love to
> see some examples in gnuradio & gr-osmosdr.

Its funny, gr-osmosdr blocks in GRC was actually the first test case for
this. So I didnt expect there to be a problem.

>
> Also, any suggestions, or workarounds, or alternatives would be helpful.
>

I suspect the logic behind the switching. Could be a logic bug or just
something that could be implemented better especially in regards to the
second issue. It may be worthwhile just adding a few prints. The code is
literally just calling activateStream() and checking an internal
variable called _current_mode to do the switchover:
https://github.com/pothosware/SoapyHackRF/blob/master/HackRF_Streaming.cpp#L269

Hope that helps!
-josh

Gavin Jacobs

unread,
Nov 6, 2016, 9:58:08 PM11/6/16
to pothos...@googlegroups.com
Josh,
Thanks for those pointers. I was able to gather more info. See below.


I wait for the WAV file to finish transmitting (it's only about 10 seconds), then I kill the flowgraph with the red X. Also, I added some debug statements, so I know that the TX stream is deactivated once file is sent. Here is the output:
[DEBUG] Init
[DEBUG] Exit
[DEBUG] Init
[INFO] Opening HackRF device instance {device=HackRF One, driver=hackrf, part_id=a000cb3c005d475a, serial=0000000000000000909864c8343e0ecf, soapy=0, version=2015.07.2}...
[DEBUG] Using format CF32.
[DEBUG] Start TX
[DEBUG] Stop TX


Some curious things:
a) I don't know why it calls Init & Exit & then Init again
b) There is no closing Exit
I get the same output when it works, and subsequently when it doesn't work.


I dont know off the top of my head the reason, but it looks like
something easy to reproduce when I get the chance (I'm away from my
hackrf now).

>
> 2) Meanwhile, if I enable both source and sink, I see the tx LED flicker
> briefly, then the rx LED, then the tx LED comes on steady; I expected to
> see the tx LED for about 10 seconds, then the rx LED steady.


Is there a stream of data going into the osmo sink block for just 10
seconds on init? It might be the case that since both rx and tx are
initially started that the tx stream takes precedence (maybe random
ordering of block setup). Then it switches back to rx since there is no
tx data. Then the tx data makes it way into the osmo sink and starts
transmit streaming again. Some printing in HackRF_Streaming.cpp
mentioned below might help to see whats going on.

Yes, there is data to tx immediately; but even if there was some random switch on startup, the 10 second burst should still be heard but it isn't. Here is the debug output, which just confirms what the LEDs indicate,
[DEBUG] Init
[DEBUG] Exit
[DEBUG] Init
[INFO] Opening HackRF device instance {device=HackRF One, driver=hackrf, part_id=a000cb3c005d475a, serial=0000000000000000909864c8343e0ecf, soapy=0, version=2015.07.2}...
[DEBUG] setupStream RX
[DEBUG] Using format CF32.
gr-osmosdr v0.1.4-75-gae686c46 (0.1.5git) gnuradio 3.7.9
built-in sink types: hackrf soapy redpitaya file
[DEBUG] setupStream TX
[DEBUG] Using format CF32.
[DEBUG] activateStream RX
[DEBUG] Switch from RX to TX
[DEBUG] activateStream TX
[DEBUG] Switch from TX to RX
[DEBUG] activateStream RX
[DEBUG] Switch from RX to TX
[DEBUG] activateStream TX
[DEBUG] deactivateStream TX


>
> So first, is this the right place to ask for help? To me it looks like an
> issue with the implementation of hackrf in SoapyHackrf, and if that's
> correct, is there a place to file a bug report?

I saw the the issue on the hackrf github, but I sort of lost track.
Sorry about that. The mailing list if perfectly fine for this. I think
the https://github.com/pothosware/SoapyHackRF issue tracker may have a
few more relevant eyes on it too if that helps.

>
> Also, I see a few examples using SoapyHackrf in Pothos; but I would love to
> see some examples in gnuradio & gr-osmosdr.

Its funny, gr-osmosdr blocks in GRC was actually the first test case for
this. So I didnt expect there to be a problem.
 
If you still have the GRC file, perhaps you could send it to me and I'll see if I can get that to work.
 

>
> Also, any suggestions, or workarounds, or alternatives would be helpful.
>

I suspect the logic behind the switching. Could be a logic bug or just
something that could be implemented better especially in regards to the
second issue. It may be worthwhile just adding a few prints. The code is
literally just calling activateStream() and checking an internal
variable called _current_mode to do the switchover:
https://github.com/pothosware/SoapyHackRF/blob/master/HackRF_Streaming.cpp#L269

I used SoapySDR_logf rather than prints; but I can't figure out what triggers a switchover. The code that calls activateStream is either acquireReadBuffer or acquireWriteBuffer, and those are called from readStream or writeStream, but it isn't clear what controls those routines.
 
Hope that helps!
-josh

--
You received this message because you are subscribed to a topic in the Google Groups "Pothos Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pothos-users/Zj8l-Wf4rcU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pothos-users+unsubscribe@googlegroups.com.
To post to this group, send email to pothos...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pothos-users/bee67a81-7f5b-2b0c-7a27-3f27d4fd2daf%40joshknows.com.
For more options, visit https://groups.google.com/d/optout.

Josh Blum

unread,
Nov 9, 2016, 3:51:07 PM11/9/16
to pothos...@googlegroups.com

>>
> I wait for the WAV file to finish transmitting (it's only about 10
> seconds), then I kill the flowgraph with the red X. Also, I added some
> debug statements, so I know that the TX stream is deactivated once file is
> sent. Here is the output:
> [DEBUG] Init
> [DEBUG] Exit
> [DEBUG] Init
> [INFO] Opening HackRF device instance {device=HackRF One, driver=hackrf,
> part_id=a000cb3c005d475a, serial=0000000000000000909864c8343e0ecf, soapy=0,
> version=2015.07.2}...
> [DEBUG] Using format CF32.
> [DEBUG] Start TX
> [DEBUG] Stop TX
>
> Some curious things:
> a) I don't know why it calls Init & Exit & then Init again

Its probably the discovery routine finding the available devices first.
The hackrf init/exit is also called for finding the device.

https://github.com/pothosware/SoapyHackRF/blob/master/HackRF_Registation.cpp#L29

And then once again in the actual device instance:
https://github.com/pothosware/SoapyHackRF/blob/master/SoapyHackRF.hpp#L379


> b) There is no closing Exit

So the kill "with the red X" is killing the process, so it has no chance
to properly shutdown.

Are you able to close the gui or command like app nicely with the close
button? Or does it hang?
I think I see whats happening. So the code really only got tested with
transmitting once single burst from the sink side. It doesnt stay in
continuous tx when more data shows up:

It seems the way it works is that aquireWriteBuffer() calls
activateStream(tx) when the hackrf is currently in receive mode. There
is this _tx_stream->burst_end variable floating around that is used in
the tx thread to block exiting back to the rx'ing state.

more on that below

>
>>
>>> So first, is this the right place to ask for help? To me it looks like an
>>> issue with the implementation of hackrf in SoapyHackrf, and if that's
>>> correct, is there a place to file a bug report?
>>
>> I saw the the issue on the hackrf github, but I sort of lost track.
>> Sorry about that. The mailing list if perfectly fine for this. I think
>> the https://github.com/pothosware/SoapyHackRF issue tracker may have a
>> few more relevant eyes on it too if that helps.
>>
>>>
>>> Also, I see a few examples using SoapyHackrf in Pothos; but I would love
>> to
>>> see some examples in gnuradio & gr-osmosdr.
>>
>> Its funny, gr-osmosdr blocks in GRC was actually the first test case for
>> this. So I didnt expect there to be a problem.
>>
>
> If you still have the GRC file, perhaps you could send it to me and I'll
> see if I can get that to work.
>

It wasnt my work, sorry I cant find it.

>
>>
>>>
>>> Also, any suggestions, or workarounds, or alternatives would be helpful.
>>>
>>
>> I suspect the logic behind the switching. Could be a logic bug or just
>> something that could be implemented better especially in regards to the
>> second issue. It may be worthwhile just adding a few prints. The code is
>> literally just calling activateStream() and checking an internal
>> variable called _current_mode to do the switchover:
>> https://github.com/pothosware/SoapyHackRF/blob/master/HackRF
>> _Streaming.cpp#L269
>>
>> I used SoapySDR_logf rather than prints; but I can't figure out what
> triggers a switchover. The code that calls activateStream is either
> acquireReadBuffer or acquireWriteBuffer, and those are called from
> readStream or writeStream, but it isn't clear what controls those routines.


readStream and writeStream get called by the scheduler (gr-osmosdr work
function). Internally readStream calls acquire/releaseReadBuffer() and
writeStream calls acquire/releaseWriteBuffer(). Technically an API user
could directly use the acquire/release calls to get direct access to the
ring buffer -- depends which API fits best.

The activateStream(tx and rx) call typically gets called once when the
gr-osmosdr blocks get the start() hook called. However, the acquire
implementations will also call activateStream() when the current
transmit/receive mode does not match the function that was just called.
And then activateStream() handles the thread switchover.

I think that the right pieces are there but that the metric for
switching isnt quite right. I think that rx acquire should wait to
switch with a timeout on a condition variable triggered by the tx
callback underflowing. A tx underflow would mean that we switched into
tx mode but drained all of the data available from the caller.

This is where rx should wait properly before switching:
https://github.com/pothosware/SoapyHackRF/blob/master/HackRF_Streaming.cpp#L692

And where the tx callback could underflow and notify the condition
variable:
https://github.com/pothosware/SoapyHackRF/blob/master/HackRF_Streaming.cpp#L60

In this case, Im thinking that underflow would clear the
_tx_stream->burst_end variable. The use of _tx_stream->burst_samps as
sort of a sample count down doesnt work here since its not being set to
any particular number of samples anyway.

-josh
Reply all
Reply to author
Forward
0 new messages