gutelfuldead
gutelfuldead

Reputation: 602

gnuradio source only outputting zeros

I made a custom source block that is reading switch values on a zedboard. It is accessing them via a proc driver that I wrote. The /var/log/kern.log is reporting proper output. The debug printf in the source block is reporting proper output.

However pushing the data to a filesink as well as a GUI number sink is only reading zeros. Did I not set up the block properly?

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "switches_impl.h"
#include <stdio.h>
#include <stdlib.h>
#include <uinstd.h>

namespace gr {
  namespace zedboard {

    switches::sptr
    switches::make()
    {
      return gnuradio::get_initial_sptr
        (new switches_impl());
    }

    /*
     * The private constructor
     */
    switches_impl::switches_impl()
      : gr::block("switches",
             gr::io_signature::make(0,0,0),
              gr::io_signature::make(1, 1, sizeof(unsigned int *)))
    {}

    /*
     * Our virtual destructor.
     */
    switches_impl::~switches_impl()
    {
    }

    void
    switches_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
    {
      /* <+forecast+> e.g. ninput_items_required[0] = noutput_items */
    }

    int
    switches_impl::general_work (int noutput_items,
                       gr_vector_int &ninput_items,
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
    {
      //const <+ITYPE+> *in = (const <+ITYPE+> *) input_items[0];
      unsigned int *out = (unsigned int *) output_items[0];

      // Do <+signal processing+>
      // Tell runtime system how many input items we consumed on
      // each input stream.

        char buffer[5];
        size_t size = 1;
        size_t nitems = 5;
        FILE* fp;

        fp = fopen("/proc/zedSwitches","r");
        if (fp == NULL)
        {
            printf("Cannot open for read\n");
            return -1;
        }
        /*
        Expect return format:
        0x00
        */
        fread(buffer, size, nitems, fp);
        fclose(fp);
        out=(unsigned int *)strtoul(buffer,NULL,0);
        printf("read: 0x%02x",out);

      consume_each (noutput_items);

      // Tell runtime system how many output items we produced.
      return noutput_items;
    }

  } /* namespace zedboard */
} /* namespace gr */

Upvotes: 0

Views: 514

Answers (1)

Marcus M&#252;ller
Marcus M&#252;ller

Reputation: 36442

A pointer is a pointer to data, usually:

  unsigned int *out = (unsigned int *) output_items[0];

out refers to the buffer for your output.

But you overwrite that pointer with another pointer:

    out=(unsigned int *)strtoul(buffer,NULL,0);

which just bends around your copy of that pointer, and doesn't affect the content of that buffer at all. Basic C!

You probably meant to say something like:

    out[0]= strtoul(buffer,NULL,0);

That will put your value into the first element of the buffer.

However, you tell GNU Radio that you not only produced a single item (the line above), but noutput_items:

  return noutput_items;

That must read

  return 1;

when you're only producing a single item, or you must actually produce as many items as you return.

Your consume_each call is nonsensical – GNU Radio Sources are typically instances of gr::sync_block, which means that you'd write a work() instead of a general_work() method as you did.

From the fact alone that this is a general_work and not a work I'd say you haven't used gr_modtool (with block type set to source!) to generate the stub for this block – you really should. Again, I'd like to point you to the Guided Tutorials which should really quickly explain usage of gr_modtool as well as the underlying GNU Radio concepts.

Upvotes: 0

Related Questions