GNURadio中的错误及解决方发

本文汇总了GNU Radio开发中常见的六种错误及其解决方案,包括共享内存配置、模块导入失败、缓冲区请求不匹配等问题,并提供了详细的排查步骤及修复建议。

1、buffer相关的错误之一        

        错误信息:

gr::vmcircbuf_sysv_shm: shmget(1): 无效的参数
gr::vmcircbuf_sysv_shm: shmget(1): 无效的参数
gr::vmcircbuf_sysv_shm: shmget(1): 无效的参数
gr::buffer::allocate_buffer: failed to allocate buffer of size 30728 KB
gr::vmcircbuf_sysv_shm: shmget(1): 无效的参数
gr::vmcircbuf_sysv_shm: shmget(1): 无效的参数
gr::vmcircbuf_sysv_shm: shmget(1): 无效的参数
gr::buffer::allocate_buffer: failed to allocate buffer of size 30728 KB
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


参考解决方案:

首先在命令行中执行:

sysctl kernel.shmmax,来查看系统的共享缓存大小,
如果过小的话,执行:
sudo sysctl -w kernel.shmmax=2147483648
来增大系统的共享缓存
参考:https://www.ruby-forum.com/topic/4418749#new

2、ImportError  

完整错误信息:

Traceback (most recent call last):
  File "/home/abing/pro/test_ca.py", line 17, in <module>
    import lte_sat
  File "/usr/local/lib/python2.7/dist-packages/lte_sat/__init__.py", line 45, in <module>
    from lte_sat_swig import *
  File "/usr/local/lib/python2.7/dist-packages/lte_sat/lte_sat_swig.py", line 26, in <module>
    _lte_sat_swig = swig_import_helper()
  File "/usr/local/lib/python2.7/dist-packages/lte_sat/lte_sat_swig.py", line 22, in swig_import_helper
    _mod = imp.load_module('_lte_sat_swig', fp, pathname, description)
ImportError: /usr/local/lib/libgnuradio-lte_sat.so: undefined symbol: fftwf_execute

可能的错误原因:

我这里碰到的错误时我自己写的、并不是用gr_modtool工具添加的,头文件在include/目录下,c/c++文件在lib/目录下,同时在各自目录下的CmakeLists.txt中添加相应的文件名以便于make安装,原本以为这样就可以执行,其实不然,还需要在swig/目录下在**_swig.i文件中包含include目录下的头文件名,用于wrap  C 程序到Python中。


还有,检查总目录下的CmakeLists.txt文件中是否有:find_package(FFTW3f) ,如果没有,那么在make的过程中虽然不会报错,但编译并没有连接到fftw库,需要添加上,这一句尤为重要。

3、buffer相关的错误之二

完整错误信息:

sched: <block dl_baseband_sync (2)> is requesting more input data
  than we can provide.
  ninput_items_required = 20000
  max_possible_items_available = 10239
  If this is a filter, consider reducing the number of taps.

错误原因:

        自定义模块的输入与输出之间比例过大,但是并没有通知top_block或者相关的调度模块,关于输入或者输出一端所需数据量过大,因此系统按照默认配置的值分配的输入与输出buffer不能满足要求,如上面提示的,系统提供的最大输入缓存为10239,而实际所需的为20000,必然出现错误.

解决办法:

        GNURadio的top_block提供了接口函数:

void set_relative_rate(double rate)
可以调用设置,之后就可解决这个问题.

4、undefined reference to `uhd::device_addr_t::device_addr_t

完整错误信息:

libgnuradio-lte_sat.so: undefined reference to `gr::uhd::usrp_sink::make(uhd::device_addr_t const&, uhd::stream_args_t const&)'
libgnuradio-lte_sat.so: undefined reference to `uhd::time_spec_t::operator-=(uhd::time_spec_t const&)'
libgnuradio-lte_sat.so: undefined reference to `uhd::time_spec_t::time_spec_t(double)'
libgnuradio-lte_sat.so: undefined reference to `uhd::time_spec_t::get_system_time()'
libgnuradio-lte_sat.so: undefined reference to `uhd::time_spec_t::time_spec_t(long, double)'
libgnuradio-lte_sat.so: undefined reference to `uhd::device_addr_t::device_addr_t(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'

错误原因:

       这是连接(link)错误,首先能说明,头文件包含正确,因为已经能够完成编译,但是在链接(link)过程中没有找到相应的动态库,就是libuhd.so和libgnuradio-uhd.so,可能的原因有两个:

1)uhd或者gnuradio安装路径不是默认的,即其库文件没有在/usr/local/lib/目录下;

2)自己定义的功能模块的CMakelists.txt中没有指定连接到相应的库;

解决办法:

          对于原因1),要么手动修改路径,要么重新安装。

          对于2),要手动修改CMakelists.txt,在/lib/目录下的修改为:

include_directories(
    ${Boost_INCLUDE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${GR_UHD_INCLUDE_DIRS}
    ${GNURADIO_RUNTIME_INCLUDE_DIRS}
    ${UHD_INCLUDE_DIRS}
)

link_directories(
  ${UHD_LIBRARY_DIRS}
  ${GR_UHD_LIBRARY_DIRS}
)
          对于外面总的CMakelists.txt,

set(GR_REQUIRED_COMPONENTS RUNTIME FILTER UHD)
find_package(UHD)

5、RuntimeError: fifo ctrl timed out looking for acks

完整错误信息:

 File "/usr/local/lib/python2.7/dist-packages/gnuradio/uhd/__init__.py", line 116, in constructor_interceptor
   return old_constructor(*args)
 File "/usr/local/lib/python2.7/dist-packages/gnuradio/uhd/uhd_swig.py", line 2895, in usrp_sink
   return _uhd_swig.usrp_sink(*args)
RuntimeError: RuntimeError: fifo ctrl timed out looking for acks

硬件为USRP N210      

错误原因:

一般情况下是由于网络传输的丢包造成的;一般使用N210时候会用到千兆网卡,所以主机直接连到USRP不会有问题,而需要通过千兆交换机/路由器来访问USRP的时候一般会出现问题。至少我们用的是这种情况,由于USRP N210数据传输采用UDP协议,而UDP通过交换机时候在大量吞吐量时候难免会丢包,因此产生上述错误。


暂时未能在网上找到这种错误的解决办法,期待大牛能给出答案。


6、RuntimeError: port does not exist

完整错误信息:

Traceback (most recent call last):
  File "/home/abing/software/grc_work/new_test.py", line 96, in <module>
    tb = new_test()
  File "/home/abing/software/grc_work/new_test.py", line 38, in __init__
    self.lte_sat_dl_baseband_sync_0 = lte_sat.dl_baseband_sync(0.8)
  File "/usr/local/lib/python2.7/dist-packages/lte_sat/lte_sat_swig.py", line 10124, in make
    return _lte_sat_swig.dl_baseband_sync_make(*args, **kwargs)
RuntimeError: port does not exist

错误原因:

       首先找到了这句错误的打印位置:$/gnuradio-3.7.2.1/gnuradio-runtime/lib/basic_block.cc,函数

void basic_block::message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg)
执行过程中首先检测所要输出的消息id,就是message_port_register_*函数注册时候的参数,因为在注册时候系统将该string转换成可识别的类型,然后将该string与实际的消息端口一字典(dict)的形式映射到一起,在上面的函数中,首先检测所要发布消息的port_id在映射的字典中是否存在,不存在则说明在此之前的message_port_register_*函数必然出了问题,可以去查。





<think>好的,我现在需要帮助用户在GNU Radio中实现错误重传机制的解决方案或示例代码。首先,我需要了解用户的需求。错误重传机制通常用于通信系统中,当接收方检测到数据包错误时,会请求发送方重新传输。这涉及到ARQ(自动重传请求)协议,比如停等ARQ、后退N帧或者选择性重传。 接下来,我需要回忆GNU Radio的基本结构和组件。GNU Radio是一个基于流的信号处理框架,使用块(block)来构建流程图。用户通常通过Python编写流程图,并使用C++实现自定义块。因此,实现错误重传可能需要创建自定义块来处理重传逻辑。 用户可能需要示例代码,所以我得考虑如何构建发送和接收端的块。发送端需要能够缓存已发送的数据包,直到收到确认(ACK),而接收端需要检查数据包的正确性(比如通过CRC校验),并发送ACK或NACK。如果使用停等协议,发送方在发送一个数据包后需要等待确认,超时则重传。 我需要参考GNU Radio中现有的块,比如CRC添加和校验块,以及如何与自定义块集成。例如,发送端可能使用Packet Encoder块添加CRC,然后通过自定义块管理重传。接收端使用CRC Check块验证数据包,并通过反馈信道发送ACK/NACK。 另外,GNU Radio中的消息传递机制可能用于实现ACK/NACK的反馈。例如,使用消息队列和异步消息处理,在接收端检测到错误后发送消息到发送端的消息队列,触发重传。 可能遇到的问题包括时序同步、反馈延迟的处理、缓冲区管理等。例如,发送端需要维护一个缓冲区来存储未确认的数据包,并处理可能的超时重传。接收端需要正确处理重复的数据包,避免重复处理。 我需要确保示例代码的结构清晰,包括发送端和接收端的流程图,以及自定义块的实现。可能需要使用Python块或嵌入C++代码。考虑到用户可能需要具体的代码片段,比如如何在块中实现状态机处理重传逻辑,如何通过消息端口发送ACK/NACK。 还需要考虑如何测试这个机制,比如使用模拟信道引入错误,观察重传是否触发。可能需要使用GNU Radio的频道模型块来模拟噪声或丢包。 最后,总结实现步骤,包括设计协议、创建自定义块、集成CRC校验、实现反馈机制和测试验证。同时,提供相关的优化建议,比如动态调整超时时间,使用选择性重传提高效率等。</think>在GNU Radio中实现错误重传机制需要结合协议设计与信号处理流程。以下是分步实现方案和示例代码框架: ### 一、核心实现原理 1. 基于停等ARQ协议实现基础重传机制 2. 使用CRC校验检测数据完整性 3. 通过消息传递实现ACK/NACK反馈[^2] 4. 发送端设置超时重传定时器 ### 二、系统架构设计 ```text [发送端] -> 数据分帧 -> CRC添加 -> 发送缓存 -> 调制发射                   ↑            │                   └──ACK/NACK─┘ [接收端] -> 接收解调 -> CRC校验 -> 反馈ACK/NACK                             │                             └─> 数据重组 ``` ### 三、关键代码实现 #### 1. 自定义发送块(Python Block) ```python class arq_sender(gr.sync_block): def __init__(self): gr.sync_block.__init__(self, name="ARQ_Sender", in_sig=[np.byte], out_sig=[np.byte]) self.retry_buffer = [] self.timer_active = False self.seq_num = 0 self.message_port_register_in(pmt.intern("ack")) self.set_msg_handler(pmt.intern("ack"), self.handle_ack) def handle_ack(self, msg): ack = pmt.to_python(msg) if ack['status'] == 'NACK': self.retransmit_packet(ack['seq']) def retransmit_packet(self, seq): if seq in self.retry_buffer: self._post(pmt.to_pmt(self.retry_buffer[seq])) def work(self, input_items, output_items): # 数据分帧处理 frame = self.create_frame(input_items[0][:1500]) self.retry_buffer[self.seq_num] = frame output_items[0][:] = frame self.seq_num += 1 return len(output_items[0]) ``` #### 2. 自定义接收块(C++实现节选) ```cpp class arq_receiver : public gr::block { public: arq_receiver() : gr::block("ARQ_Receiver") { message_port_register_out(pmt::mp("ack")); } int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { // CRC校验实现 if(check_crc(frame)) { send_ack(frame.seq, "ACK"); produce(0, frame.data); } else { send_ack(frame.seq, "NACK"); } return WORK_CALLED_PRODUCE; } }; ``` ### 四、完整流程图配置 ```python def main(): tb = gr.top_block() # 发送链路 src = blocks.vector_source_b() arq_tx = arq_sender() crc_add = digital.crc_append(0x11021, 16, 0xFFFF) # 接收链路 arq_rx = arq_receiver() crc_check = digital.crc_check(0x11021, 16, 0xFFFF) sink = blocks.vector_sink_b() # 反馈通道 feedback = blocks.message_strobe(pmt.intern("ACK"), 1000) tb.connect(src, crc_add, arq_tx) tb.msg_connect(arq_rx, "ack", arq_tx, "ack") tb.connect(arq_tx, (channel_model, 0)) tb.connect((channel_model, 0), arq_rx, crc_check, sink) tb.run() ``` ### 五、关键优化措施 1. **动态超时调整**:根据RTT时间自动调整重传超时阈值 $$ timeout = \alpha \times RTT_{avg} + \beta \times RTT_{var} $$ 2. **选择性重传**:使用位图记录丢失包序号 3. **前向纠错**:结合RS码提升首次传输成功率[^2] 4. **窗口机制**:实现滑动窗口协议提升吞吐量 ### 六、测试验证方案 1. 使用`channel_model`模块添加误码 2. 通过`ber_tools`模块统计误码率 3. 观察重传触发次数与吞吐量变化关系
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值