gnuradio之flowgraph和top_block

一般的gnuradio开发方式是底层的信号处理模块采用C++编写,这样可以提高处理效率;而模块之间的连接使用Python,这是因为Python提供了更方便的操作接口,使用起来更方便。然而分析gnuradio的源代码可以发现,gnuradio中的流图和顶层模块top_block都是通过C++编写的:

流图类:

/*!
   * \brief Class representing a directed, acyclic graph of basic blocks
   * \ingroup internal
   */
  class GR_RUNTIME_API flowgraph
  {
  public:
    friend GR_RUNTIME_API flowgraph_sptr make_flowgraph();

    /*!
     * \brief Destruct an arbitrary flowgraph
     */
    virtual ~flowgraph();

    /*!
     * \brief Connect two endpoints
     * \details
     * Checks the validity of both endpoints, and whether the
     * destination is unused so far, then adds the edge to the internal list of
     * edges.
     */
    void connect(const endpoint &src, const endpoint &dst);

    /*!
     * \brief Disconnect two endpoints
     */
    void disconnect(const endpoint &src, const endpoint &dst);

    /*!
     * \brief convenience wrapper; used to connect two endpoints
     */
    void connect(basic_block_sptr src_block, int src_port,
                 basic_block_sptr dst_block, int dst_port);

    /*!
     * \brief convenience wrapper; used to disconnect two endpoints
     */
    void disconnect(basic_block_sptr src_block, int src_port,
                    basic_block_sptr dst_block, int dst_port);

    /*!
     * \brief Connect two message endpoints
     * \details
     * Checks the validity of both endpoints, then adds the edge to the
     * internal list of edges.
     */
    void connect(const msg_endpoint &src, const msg_endpoint &dst);

    /*!
     * \brief Disconnect two message endpoints
     */
    void disconnect(const msg_endpoint &src, const msg_endpoint &dst);

    /*!
     * \brief Validate flow graph
     * \details
     * Gathers all used blocks, checks the contiguity of all connected in- and
     * outputs, and calls the check_topology method of each block.
     */
    void validate();

    /*!
     * \brief Clear existing flowgraph
     */
    void clear();

    /*!
     * \brief Get vector of edges
     */
    const edge_vector_t &edges() const { return d_edges; }

    /*!
     * \brief Get vector of message edges
     */
    const msg_edge_vector_t &msg_edges() const { return d_msg_edges; }

    /*!
     * \brief calculates all used blocks in a flow graph
     * \details
     * Iterates over all message edges and stream edges, noting both endpoints in a vector.
     *
     * \return a unique vector of used blocks
     */
    basic_block_vector_t calc_used_blocks();

    /*!
     * \brief topologically sort blocks
     * \details
     * Uses depth-first search to return a sorted vector of blocks
     *
     * \return toplogically sorted vector of blocks.  All the sources come first.
     */
    basic_block_vector_t topological_sort(basic_block_vector_t &blocks);

    /*!
     * \brief Calculate vector of disjoint graph partions
     * \return vector of disjoint vectors of topologically sorted blocks
     */
    std::vector<basic_block_vector_t> partition();

  protected:
    basic_block_vector_t d_blocks;
    edge_vector_t d_edges;
    msg_edge_vector_t d_msg_edges;

    flowgraph();
    std::vector<int> calc_used_ports(basic_block_sptr block, bool check_inputs);
    basic_block_vector_t calc_downstream_blocks(basic_block_sptr block, int port);
    edge_vector_t calc_upstream_edges(basic_block_sptr block);
    bool has_block_p(basic_block_sptr block);
    edge calc_upstream_edge(basic_block_sptr block, int port);

  private:
    void check_valid_port(gr::io_signature::sptr sig, int port);
    void check_valid_port(const msg_endpoint &e);
    void check_dst_not_used(const endpoint &dst);
    void check_type_match(const endpoint &src, const endpoint &dst);
    edge_vector_t calc_connections(basic_block_sptr block, bool check_inputs); // false=use outputs
    void check_contiguity(basic_block_sptr block, const std::vector<int> &used_ports, bool check_inputs);

    basic_block_vector_t calc_downstream_blocks(basic_block_sptr block);
    basic_block_vector_t calc_reachable_blocks(basic_block_sptr block, basic_block_vector_t &blocks);
    void reachable_dfs_visit(basic_block_sptr block, basic_block_vector_t &blocks);
    basic_block_vector_t calc_adjacent_blocks(basic_block_sptr block, basic_block_vector_t &blocks);
    basic_block_vector_t sort_sources_first(basic_block_vector_t &blocks);
    bool source_p(basic_block_sptr block);
    void topological_dfs_visit(basic_block_sptr block, basic_block_vector_t &output);
  };

顶层模块top_block类:

/*!
   *\brief Top-level hierarchical block representing a flowgraph
   * \ingroup container_blk
   */
  class GR_RUNTIME_API top_block : public hier_block2
  {
  private:
    friend GR_RUNTIME_API top_block_sptr
      make_top_block(const std::string &name);

    top_block_impl *d_impl;

  protected:
    top_block(const std::string &name);

  public:
    ~top_block();

    /*!
     * \brief The simple interface to running a flowgraph.
     *
     * Calls start() then wait(). Used to run a flowgraph that will
     * stop on its own, or when another thread will call stop().
     *
     * \param max_noutput_items the maximum number of output items
     * allowed for any block in the flowgraph. This passes through to
     * the start function; see that function for more details.
     */
    void run(int max_noutput_items=100000000);

    /*!
     * Start the contained flowgraph. Creates one or more threads to
     * execute the flow graph. Returns to the caller once the threads
     * are created. Calling start() on a top_block that is already
     * started IS an error.
     *
     * \param max_noutput_items the maximum number of output items
     * allowed for any block in the flowgraph; the noutput_items can
     * always be less than this, but this will cap it as a
     * maximum. Use this to adjust the maximum latency a flowgraph can
     * exhibit.
     */
    void start(int max_noutput_items=100000000);

    /*!
     * Stop the running flowgraph. Notifies each thread created by the
     * scheduler to shutdown, then returns to caller. Calling stop()
     * on a top_block that is already stopped IS NOT an error.
     */
    void stop();

    /*!
     * Wait for a flowgraph to complete. Flowgraphs complete when
     * either (1) all blocks indicate that they are done (typically
     * only when using blocks.file_source, or blocks.head, or (2)
     * after stop() has been called to request shutdown. Calling wait
     * on a top_block that is not running IS NOT an error (wait
     * returns w/o blocking).
     */
    void wait();

    /*!
     * Lock a flowgraph in preparation for reconfiguration. When an
     * equal number of calls to lock() and unlock() have occurred, the
     * flowgraph will be reconfigured.
     *
     * N.B. lock() and unlock() may not be called from a flowgraph
     * thread (E.g., block::work method) or deadlock will occur
     * when reconfiguration happens.
     */
    virtual void lock();

    /*!
     * Unlock a flowgraph in preparation for reconfiguration. When an
     * equal number of calls to lock() and unlock() have occurred, the
     * flowgraph will be reconfigured.
     *
     * N.B. lock() and unlock() may not be called from a flowgraph thread
     * (E.g., block::work method) or deadlock will occur when
     * reconfiguration happens.
     */
    virtual void unlock();

    /*!
     * Returns a string that lists the edge connections in the
     * flattened flowgraph.
     */
    std::string edge_list();

    /*!
     * Returns a string that lists the msg edge connections in the
     * flattened flowgraph.
     */
    std::string msg_edge_list();

    /*!
     * Displays flattened flowgraph edges and block connectivity
     */
    void dump();

    //! Get the number of max noutput_items in the flowgraph
    int max_noutput_items();

    //! Set the maximum number of noutput_items in the flowgraph
    void set_max_noutput_items(int nmax);

    top_block_sptr to_top_block(); // Needed for Python type coercion

    void setup_rpc();
  };

可见C++的类中实现了比Python更多的功能,既然这些类都是通过C++编写的,虽然目前还没看到C++流图开发的例子,但理论上来说应该也可以通过C++开发流图。另一方面,由于Python并不能实现真正的多线程,使用C++开发可能也会得到更好地运行效果。

时间: 2024-07-30 09:00:47

gnuradio之flowgraph和top_block的相关文章

gnuradio学习之qa_tag_file_sink.py

#!/usr/bin/env python #A file sink that uses tags to save files. #        The sink uses a tag with the key 'burst' to trigger the saving of the burst data to a new file. # If the value of this tag is True, it will open a new file and start writing al

gnuradio中读取vector_sink数据

#!/usr/bin/env python from gnuradio import blocks from gnuradio import gr tb = gr.top_block() src = blocks.vector_source_f([1,2,3,4,5,6]) snk = blocks.vector_sink_f() tb.connect(src, snk) tb.run() print(snk.data())

gnuradio调试方法

How to debug GNU Radio applications Once you've started creating GNU Radio applications, you will probably stumble upon some errors sooner or later. Here is some advice on how to tackle those problems. How to debug GNU Radio applications Simple debug

gnuradio中接收端的信道滤波

在benchmark_rx中在接收端使用了FFT低通滤波器来得到感兴趣的频段,以滤除带外噪声,然而机器运行benchmark_rx时总是出现"段错误",究其原因就是使用了信道滤波,当把信道滤波去掉之后运行起来就没有什么问题了.然而滤除带外噪声也是有必要的,所以对信道滤波部分进行了研究. 在软件无线电中,信道滤波实际就是低通滤波器,在benchmark_rx中是这样使用的:在filter.firdes.low_pass()中设定了滤波器的抽头系数,然后使用fft_filter()实现滤波

在深入学习gnuradio之前你需要知道的

原文网站:http://radioware.nd.edu 在深入学习gnuradio之前你需要知道的 学习GNU Radio需要有一定电脑基础和深入的通信与信号处理知识,本文列举了一些有用的资源,包括教程.网页链接和一些在线教程.本教程的目的是帮助GNU Radio爱好者们为这个令人兴奋的工具做一些准备.  目录 1.对gnuradio有一个清楚的认识 2.为gnuradio编写程序 3.数字信号处理(DSP) 4.通信系统 5.准备好了吗? 相信你已经发现gnuradio中的乐趣,并且已经开始

通过gr-modtool在gnuradio中编写自己的C++模块

虽然gnuradio给我们提供了近百种常用的功能模块block,但是在我们自己的系统设计中,需要不同的模块完成特定的功能,这样就需要我们自己来编写C++源代码,生成新的block以供系统调用.如果源代码.编译文件都要自己编写,需要很强的专业知识.利用模板写模块gnuradio3.7用的都是gr_modtool 在终端进入主文件夹,输入: $gr_modtool newmod howto(这里以howto为例),主文件夹下就生成一个gr-howto文件夹 接下来就是添加要编写的模块.先进入刚才生成

【转载】第一个GNURadio应用程序心得

原文地址:我的第一个GNURadio应用程序心得作者:YEYE 目录: 前言 一.准备学习 二.针对性逐行研究代码 三.构建自己的应用流图,编写程序,调试通过 四.small tips     前言:学习背景:电子通信专业,相关专业课程都有学习,没学过python(大多数都没有学过)C++学习过,只学过C的话最好对面向对象编程的类,封装,重构有所了解,学习,有助于学习python编程.   一.           准备学习 步骤:入门中文文档--> 登陆gnuradio/wiki网站查看入门英

gnuradio中把file_sink的二进制文件转换成文本文件

http://www.swigerco.com/gnuradio/plotting.html Plotting Signals Here are a few simple utilities to convert raw datafiles into a format you can read and plot w/ gnuplot. raw2num.c - converts a file of 16 bit shorts into a numerical human readable file

gnuradio软件usrp设备的同时收发问题

问题描述 gnuradio软件usrp设备的同时收发问题 用的是gnuradio3.7.7.1软件自带的UHD:USRP Sink和UHD:USRP Source模块,设备是N210,实验收发一个简单的450MHz载频的正弦信号,实验过程中收.发程序能够单独工作,但不能同时工作,求解决办法 解决方案 把收发程序放到一个grc文件里,就可实现同时收发.根据设备指示灯就可以看出来设备的工作情况. 再问:接收程序收到的信号不正确,而且从USRP source模块出来接滤波器的话程序不能整运行,请教怎么