gnss-sdr代码解读(3)
作者微信公众号:小卫星
操作系统: Windows 10
这篇是接着上一篇的,但是没有必然联系,上一篇地址:
https://mp.youkuaiyun.com/postedit/80905880
1、top_block
在所有的信号处理模块(如gnss-sdr/src/algorithms/signal_source/adapters/osmosdr_signal_source.h)中,都有个继承自GNSSBlockInterface的连接函数:
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
它接受一个gr::top_block_sptr的智能指针参数,adapters中的文件都是这样使用的。
这个gr::top_block_sptr是个啥东西呢,在gnuradio中进行了定义:
它是一个指向top_block的智能指针。值得注意的是,同时还定义了一个指向flowgraph的智能指针。
connect函数在对应的cc文件中进行了实现:
void OsmosdrSignalSource::connect(gr::top_block_sptr top_block)
{
if (samples_ != 0)
{
top_block->connect(osmosdr_source_, 0, valve_, 0);
DLOG(INFO) << "connected osmosdr source to valve";
if (dump_)
{
top_block->connect(valve_, 0, file_sink_, 0);
DLOG(INFO) << "connected valve to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(osmosdr_source_, 0, file_sink_, 0);
DLOG(INFO) << "connected osmosdr source to file sink";
}
}
}
这个里面干了个啥事呢,就是调用top_block的connect函数(这本来是在python里干的事情,这里用C++实现)。
这里连接的参数都是个啥东西呢,在osmosdr_signal_source.h里定义了:
osmosdr::source::sptr osmosdr_source_;
boost::shared_ptr<gr::block> valve_;
gr::blocks::file_sink::sptr file_sink_;
其实都是智能指针。这个valve_是个啥呢?
valve_ = gnss_sdr_make_valve(item_size_, samples_, queue_);
在gnss-sdr/src/algorithms/libs/gnss_sdr_valve.cc中
boost::shared_ptr<gr::block> gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue)
{
boost::shared_ptr<gnss_sdr_valve> valve_(new gnss_sdr_valve(sizeof_stream_item, nitems, queue));
return valve_;
}
gnss_sdr_valve::gnss_sdr_valve(size_t sizeof_stream_item,
unsigned long long nitems,
gr::msg_queue::sptr queue) : gr::sync_block("valve",
gr::io_signature::make(1, 1, sizeof_stream_item),
gr::io_signature::make(1, 1, sizeof_stream_item)),
d_nitems(nitems),
d_ncopied_items(0),
d_queue(queue)
{
}
看样子是个同步模块。
事实上我找了半天,在gnuradio/gnuradio-runtime/lib/top_block.cc中也没有找到top->connect这个函数的实现。好吧,还有
class GR_RUNTIME_API top_block : public hier_block2
hier_block2里面gnuradio/gnuradio-runtime/lib/hier_block2.cc有
void
hier_block2::connect(basic_block_sptr block)
{
d_detail->connect(block);
}
void
hier_block2::connect(basic_block_sptr src, int src_port,
basic_block_sptr dst, int dst_port)
{
d_detail->connect(src, src_port, dst, dst_port);
}
有四个参数的时候调用第二个,在gnuradio/gnuradio-runtime/include/gnuradio/hier_block2.h中定义了
class hier_block2_detail;
hier_block2_detail *d_detail;
在gnuradio/gnuradio-runtime/lib/hier_block2_detail.cc中
void
hier_block2_detail::connect(basic_block_sptr src, int src_port,
basic_block_sptr dst, int dst_port)
{
std::stringstream msg;
hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
if(src_block && src.get() != d_owner) {
src_block->d_detail->d_parent_detail = this;
}
if(dst_block && dst.get() != d_owner) {
dst_block->d_detail->d_parent_detail = this;
}
// Connections to block inputs or outputs
int max_port;
if(src.get() == d_owner) {
max_port = src->input_signature()->max_streams();
return connect_input(src_port, dst_port, dst);
}
if(dst.get() == d_owner) {
max_port = dst->output_signature()->max_streams();
return connect_output(dst_port, src_port, src);
}
// Internal connections
d_fg->connect(src, src_port, dst, dst_port);
}
这个实在是比较复杂,因此不往下追溯了,总之就是端口号要对应,与输入输出的signature有关系。
2、GNSSFlowgraph
这个connect在哪里用了呢,就是这个
void GNSSFlowgraph::connect()
sig_source_.at(i)->connect(top_block_);
sig_conditioner_.at(i)->connect(top_block_);
channels_.at(i)->connect(top_block_);
observables_->connect(top_block_);
pvt_->connect(top_block_);
还有
top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j);
top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
top_block_->connect(channels_.at(i)->get_right_block(), 0,
observables_->get_left_block(), i);
top_block_->connect(observables_->get_right_block(), i, pvt_->get_left_block(), i);
这两步,一个是将模块和同步模块接起来,一个是将输入输出连接起来。