GNU Radio代码框架简介

ccll2026-07-23 14:39:21
3 浏览 0 评论

1GNU Radio框架

图1 gnuradio框架

2GNU Radio系统层次结构图

图2 gnuradio系统层次结构

3GNU Radio软件架构

 

图3 gnuradio软件架构

4、代码阅读

4.1 block信号处理基类

 

图4 gnuradio信号处理类(C++)

4.2 block应用关系

 

图5 gnuradio block应用

上图中,箭头表示引用关系,如通过调用block::detail()可以得倒block_detail实例对象的指针。

block主要关注数据的处理、运算和生成;

block_detail主要关注block的输入、输出及连接关系等;

buffer主要关注buffer的分配、数据的写入及交换等;

buffer_reader主要关注buffer的读取。

每个block的输出可以连接到多个block的输入,两个block之间的连接(或者说是数据交换)是通过buffer类的对象完成的。

buffer的角度来看,每个buffer都与一个block的输出和多个block的输入相关联,可以看成是单写入多读取的环形缓冲区。

对于一个指向buffer对象的指针buf来说,通过buf->link()可以获得与之关联的上游block指针(该blockbuffer中写入);同时,该buffer还暴露出若干个buffer_reader对象指针,用于下游block的读取,每个buffer_reader各自通过link()成员函数与单个下游block相关联。通过调用全局函数buffer_add_reader可以为buffer绑定一个新的reader

4.3 block调度运行机制

一个系统由多个block连接而成,并形成一个top_block,通过调用top_blockrun()成员函数,gnuradio启动一系列的线程,并通过调度机制将来自于源的数据顺序经过各个block处理,最终送到sink

 

图6 gnuradio调度流程

   

top_block持有一个指向类top_block_impl的数据成员d_impl,进入top_block_impl类的start函数查看:

 

上述代码执行若干检查后,最后调用阴影部分的代码创建gnuradio的调度器,接着我们继续查看make_scheduler()函数:

 

 

代码可以看出,首先检查是否设置了linux的环境变量GR_SCHEDULER,如果没有则使用默认的TPBthread per block)调度器,否则根据环境变量使用所需要的调度器。

TPBdefault):multi-threaded scheduler

STS:single-threaded scheduler

默认情况下,调用scheduler_tpb::make来创建调度器。

该代码中,对flowgraph中的block进行排序,系统按照排列的结果,逐个block进行调度。最重要的是最后阴影部分的代码,thread_body_wrapper是一个仿函数类,该类用来封装线程的主体函数,其构造函数第一个参数为实际要执行的函数体。该部分代码中,这个参数是tpb_container的对象。

tpb_container类的定义如下:

 

对于每个block来说,线程的入口就在tpb_thread_body body(d_block, d_max_noutput_items);每个线程的工作步骤有以下几步:

1、每个block对应的线程都有一个while(1)循环

2、循环内处理各种消息并运行关键处理函数run_one_iteration()

3、run_one_iteration()检查是否有足够多的输入数据和足够的输出空间

4、如果是,调用general_work()函数完成block的功能

5、否则相应的返回BLKD_IN,BLKD_OUT

 

 

可以看出,run_one_iteration()是线程运行的主体,包含了模块的主要功能。

其主要流程如下:

 

      总的来说,该函数针对block的每个输出端口,检查各自对应的buffer的剩余空间,从而获得block可以输出的items数目。如果没有用于输出的足够的空间,则返回BLKD_OUT(输出阻塞);同时,根据前面计算出的输出items数目,计算出所需要的输入items数目(通过forecast函数),综合检查输入的items数目是否满足要求,不满足则返回BLKD_IN;如果输入的items足够,也有足够的空间存放输出的items,则执行block::general_work()完成模块的功能。

5、代码调试

5.1 日志

       block_executor.cc文件中,将#define ENABLE_LOGGING 0修改为#define ENABLE_LOGGING 1,即打开日志的使能开关,就可以看到各个block在运行中的各步骤打印信息。

5.2 blockGDB调试

       block的调试主要包含以下几个步骤:

1)编译模块代码 cmake的时候,按照以下命令执行

cmake .. -DCMAKE_BUILD_TYPE=Debug

2)在生成的py文件最前面加上

import os  

最后面的 if __name__ == '__main__':中,main前增加以下两行:        

print "pid=%d" %(os.getpid(),)

                raw_input()    

3)如果gdb中出现设置断点提示make breakpoint pending on future shared library? 则按照下面步骤操作:

打开文件:sudo文件:sudo gedit /etc/sysctl.d/10-prtace.conf

修改kernel.yama.ptrace_scope=0

然后执行service procps restart

4)在终端中执行python *.py 回车后显示pid,然后在新的终端中“gdb -p pid进入gdb设置断点后,在显示PID号的终端上再次回车启动流图运行,进入断点调试。

6、缩略语

简写全称
SWIG(Simplified Wrapper and Interface Generator)简化封装接口生成器
SDR(Software Defined Radio)软件无线电
USRP(Universal software Radio Peripheral)通用软件无线电外围设备
GPP(General-Purpose Processors)通用处理器
TPB(thread per block)每模块线程
STS(single-threaded scheduler)单线程调度


# GNU Radio

全部回复 (0)

0 / 1000
请遵守社区规范
暂无评论,快来抢沙发吧~
c

cll

社区创作者

帖子信息

所属板块GNU Radio
发布时间2026-07-23 14:39:21
3浏览
0点赞
0评论