Hi everyone, I'm currently updating Thomas Schmid's old 802.15.4 demodulation code. It has been tested and works with at least revision 7596 of the gnuradio trunk. I've been trying to update the code to work with the latest release of Gnuradio (3.1). I've looked at examples converting from hier_block to hier_block2 and flow_graph to top_block. I've implemented those changes but still run into this error:
python: /usr/include/boost/shared_ptr.hpp:375: T* boost::shared_ptr<T>::operator->() const [with T = gr_basic_block]: Assertion `px != 0' failed. Searches for this error on the list did not turn up much. I was wondering if there was anything else that I missed. I've been banging my head on the wall about this trying to figure out a fix. I jumped into gdb and found that the code was crashing when trying to flatten the flow_graph. I turned on debugging messages for gr_hier_block2_detail.cc and here is the result of that: connecting: ieee802_15_4_demod(3):0 -> sos_packet_sink(8):0 connect: src is hierarchical, setting parent to 0x89e3d00 connecting: usrp1_source_c(1):0 -> pwr_squelch_cc(9):0 connecting: pwr_squelch_cc(9):0 -> ieee802_15_4_demod_pkts(2):0 connect: dst is hierarchical, setting parent to 0x88bc270 start: entered flattening top_block Flattening edge usrp1_source_c(1):0->pwr_squelch_cc(9):0 Flattening edge pwr_squelch_cc(9):0->ieee802_15_4_demod_pkts(2):0 Resolving endpoint ieee802_15_4_demod_pkts(2):0 as an input, recursing Resolving port 0 as an input of ieee802_15_4_demod_pkts python: /usr/include/boost/shared_ptr.hpp:375: T* boost::shared_ptr<T>::operator->() const [with T = gr_basic_block]: Assertion `px != 0' failed. Aborted I have attached a patch for anyone who wants to look further. If you'd like to see all the code you can follow these steps to try it out yourself: svn checkout svn://acert.ir.bbn.com/svn/gr-ucla cd gr-ucla/trunk (copy changes.diff to this directory) patch -p0 -i changes.diff Then build it all: ./bootstrap && ./configure && make sudo make install then: cd src/examples ./cc2420_rxtest.py If you have any comments or leads on something else that I should look into I would really appreciate hearing it. Thanks for all your help! -Leslie Choong
Index: src/python/ieee802_15_4.py =================================================================== --- src/python/ieee802_15_4.py (revision 64) +++ src/python/ieee802_15_4.py (working copy) @@ -31,20 +31,22 @@ from gnuradio import gr, ucla from math import pi -class ieee802_15_4_mod(gr.hier_block): +class ieee802_15_4_mod(gr.hier_block2): - def __init__(self, fg, spb = 2): + def __init__(self, spb = 2): """ Hierarchical block for cc1k FSK modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. - @param fg: flow graph - @type fg: flow graph @param spb: samples per baud >= 2 @type spb: integer """ + gr.hier_block2.__init__(self, "ieee802_15_4_mod", + gr.io_signature(0, 0, 0), # Input + gr.io_signature(0, 0, 0)) # Output + if not isinstance(spb, int) or spb < 2: raise TypeError, "sbp must be an integer >= 2" self.spb = spb @@ -58,15 +60,11 @@ # Connect - fg.connect(self.symbolsToChips, self.chipsToSymbols, + self.connect(self.symbolsToChips, self.chipsToSymbols, self.symbolsToConstellation, self.pskmod, self.delay) - # Initialize base class - gr.hier_block.__init__(self, fg, self.symbolsToChips, self.delay) - - -class ieee802_15_4_demod(gr.hier_block): - def __init__(self, fg, sps = 2, symbol_rate = 2000000): +class ieee802_15_4_demod(gr.hier_block2): + def __init__(self, *args, **kwargs): """ Hierarchical block for O-QPSK demodulation. @@ -80,25 +78,34 @@ @param symbol_rate: symbols per second @type symbol_rate: float """ + try: + self.sps = kwargs.pop('sps') + self.symbol_rate = kwargs.pop('symbol_rate') + except KeyError: + pass + + gr.hier_block2.__init__(self, "ieee802_15_4_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input + gr.io_signature(1, 1, gr.sizeof_float)) # Output # Demodulate FM - sensitivity = (pi / 2) / sps + sensitivity = (pi / 2) / self.sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset - alpha = 0.0008/sps + alpha = 0.0008/self.sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() - fg.connect(self.fmdemod, (self.sub, 0)) - fg.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) + self.connect(self.fmdemod, (self.sub, 0)) + self.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock - omega = sps + omega = self.sps gain_mu=0.03 mu=0.5 omega_relative_limit=0.0002 @@ -109,9 +116,5 @@ omega_relative_limit) # Connect - fg.connect(self.sub, self.clock_recovery) + self.connect(self.sub, self.clock_recovery) - # Initialize base class - gr.hier_block.__init__(self, fg, self.fmdemod, self.clock_recovery) - - Index: src/python/ieee802_15_4_pkt.py =================================================================== --- src/python/ieee802_15_4_pkt.py (revision 64) +++ src/python/ieee802_15_4_pkt.py (working copy) @@ -34,6 +34,8 @@ import ieee802_15_4 import struct +#import pdb + MAX_PKT_SIZE = 128 def make_ieee802_15_4_packet(FCF, seqNr, addressInfo, payload, pad_for_usrp=True, preambleLength=4, SFD=0xA7): @@ -136,34 +138,34 @@ + (sourceAddressingMode << 14)) -class ieee802_15_4_mod_pkts(gr.hier_block): +class ieee802_15_4_mod_pkts(gr.hier_block2): """ IEEE 802.15.4 modulator that is a GNU Radio source. Send packets by calling send_pkt """ - def __init__(self, fg, msgq_limit=2, pad_for_usrp=True, *args, **kwargs): + def __init__(self, msgq_limit=2, pad_for_usrp=True, *args, **kwargs): """ Hierarchical block for the 802_15_4 O-QPSK modulation. Packets to be sent are enqueued by calling send_pkt. The output is the complex modulated signal at baseband. - @param fg: flow graph - @type fg: flow graph @param msgq_limit: maximum number of messages in message queue @type msgq_limit: int @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples See 802_15_4_mod for remaining parameters """ + gr.hier_block2.__init__(self, "ieee802_15_4_mod_pkts", + gr.io_signature(0, 0, 0), # Input + gr.io_signature(0, 0, 0)) # Output self.pad_for_usrp = pad_for_usrp # accepts messages from the outside world self.pkt_input = gr.message_source(gr.sizeof_char, msgq_limit) - self.ieee802_15_4_mod = ieee802_15_4.ieee802_15_4_mod(fg, *args, **kwargs) - fg.connect(self.pkt_input, self.ieee802_15_4_mod) - gr.hier_block.__init__(self, fg, None, self.ieee802_15_4_mod) + self.ieee802_15_4_mod = ieee802_15_4.ieee802_15_4_mod(self, *args, **kwargs) + self.connect(self.pkt_input, self.ieee802_15_4_mod) def send_pkt(self, seqNr, addressInfo, payload='', eof=False): """ @@ -192,7 +194,7 @@ self.pkt_input.msgq().insert_tail(msg) -class ieee802_15_4_demod_pkts(gr.hier_block): +class ieee802_15_4_demod_pkts(gr.hier_block2): """ 802_15_4 demodulator that is a GNU Radio sink. @@ -200,15 +202,13 @@ app via the callback. """ - def __init__(self, fg, callback=None, threshold=-1, *args, **kwargs): + def __init__(self, *args, **kwargs): """ Hierarchical block for O-QPSK demodulation. The input is the complex modulated signal at baseband. Demodulated packets are sent to the handler. - @param fg: flow graph - @type fg: flow graph @param callback: function of two args: ok, payload @type callback: ok: bool; payload: string @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default) @@ -216,15 +216,24 @@ See ieee802_15_4_demod for remaining parameters. """ + try: + self.callback = kwargs.pop('callback') + self.threshold = kwargs.pop('threshold') + except KeyError: + pass + gr.hier_block2.__init__(self, "ieee802_15_4_demod_pkts", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input + gr.io_signature(0, 0, 0)) # Output + self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY - self.ieee802_15_4_demod = ieee802_15_4.ieee802_15_4_demod(fg, *args, **kwargs) - self._packet_sink = ucla.ieee802_15_4_packet_sink(self._rcvd_pktq, threshold) - - fg.connect(self.ieee802_15_4_demod, self._packet_sink) + self.ieee802_15_4_demod = ieee802_15_4.ieee802_15_4_demod(self, *args, **kwargs) + self._packet_sink = ucla.ieee802_15_4_packet_sink(self._rcvd_pktq, self.threshold) + + #pdb.set_trace() + self.connect(self.ieee802_15_4_demod, self._packet_sink) - gr.hier_block.__init__(self, fg, self.ieee802_15_4_demod, None) - self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) + self._watcher = _queue_watcher_thread(self._rcvd_pktq, self.callback) def carrier_sensed(self): """ Index: src/lib/ucla_ieee802_15_4_packet_sink.cc =================================================================== --- src/lib/ucla_ieee802_15_4_packet_sink.cc (revision 64) +++ src/lib/ucla_ieee802_15_4_packet_sink.cc (working copy) @@ -41,9 +41,9 @@ #include <gr_count_bits.h> // very verbose output for almost each sample -#define VERBOSE 0 +#define VERBOSE 1 // less verbose output for higher level debugging -#define VERBOSE2 0 +#define VERBOSE2 1 static const int DEFAULT_THRESHOLD = 10; // detect access code with up to DEFAULT_THRESHOLD bits wrong @@ -147,7 +147,7 @@ d_processed = 0; if ( VERBOSE ) - fprintf(stderr, "syncvec: %x, threshold: %d\n", d_sync_vector, d_threshold),fflush(stderr); + fprintf(stderr, "syncvec: %x, threshold: %d, sizeof(Float): %d\n", d_sync_vector, d_threshold, sizeof(float)),fflush(stderr); enter_search(); } Index: src/lib/ucla_sos_packet_sink.cc =================================================================== --- src/lib/ucla_sos_packet_sink.cc (revision 64) +++ src/lib/ucla_sos_packet_sink.cc (working copy) @@ -40,7 +40,7 @@ #include <stdexcept> #include <gr_count_bits.h> -#define VERBOSE 0 +#define VERBOSE 1 static const int DEFAULT_THRESHOLD = 0; // detect access code with up to DEFAULT_THRESHOLD bits wrong Index: src/examples/cc2420_rxtest.py =================================================================== --- src/examples/cc2420_rxtest.py (revision 64) +++ src/examples/cc2420_rxtest.py (working copy) @@ -33,9 +33,9 @@ self.nright = 0 -class oqpsk_rx_graph (gr.flow_graph): +class oqpsk_rx_graph (gr.top_block): def __init__(self, options, rx_callback): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) print "cordic_freq = %s" % (eng_notation.num_to_str (options.cordic_freq)) @@ -106,15 +106,15 @@ st = stats() - fg = oqpsk_rx_graph(options, rx_callback) - fg.start() + tb = oqpsk_rx_graph(options, rx_callback) + tb.start() - fg.wait() + tb.wait() if __name__ == '__main__': # insert this in your test code... - #import os - #print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),) - #raw_input ('Press Enter to continue: ') + import os + print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),) + raw_input ('Press Enter to continue: ') main ()
_______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio