USRP发送接收程序/boost库的安装与使用

一、  下载所需要的BOOST版本,本博文提供boost1.58以及最新boost1.63的下载文件

BOOST_1.58链接:http://pan.baidu.com/s/1eSIDpi6

BOOST_16.3链接:http://pan.baidu.com/s/1jHCPln4

二、  安装步骤:

cd boost_1_58_0               ##进入boost解压的文件夹

              ./bootstrap.sh –prefix=/usr           ##设置boost默认安装路径,如果该项缺省,其安装路径默认为/usr/local中的include文件夹和lib文件夹。因为有些代码默认的搜索路径在/usr目录下的文件及,所以笔者在此处就已经更改默认文件夹

              ./b2                         ##此过程相当于编译

              sudo ./b2 install            ##安装

至此boost就已安装完毕

 

三、  USRP_N210发送接收程序编译验证

本例程为UHD提供的example,并在USRP_N210设备上验证成功。

发送源码;

#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <boost/program_options.hpp>
#include <boost/thread/thread.hpp>
#include <boost/format.hpp>
#include <iostream>
#include <complex>

namespace po = boost::program_options;

int UHD_SAFE_MAIN(int argc, char *argv[]){
    uhd::set_thread_priority_safe();

    //variables to be set by po
    std::string args;
    std::string wire;
    double seconds_in_future;
    size_t total_num_samps;
    double rate;
    float ampl;

    //setup the program options
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "help message")
        ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")
        ("wire", po::value<std::string>(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc")
        ("secs", po::value<double>(&seconds_in_future)->default_value(1.5), "number of seconds in the future to transmit")
        ("nsamps", po::value<size_t>(&total_num_samps)->default_value(10000), "total number of samples to transmit")
        ("rate", po::value<double>(&rate)->default_value(100e6/16), "rate of outgoing samples")
        ("ampl", po::value<float>(&l)->default_value(float(0.3)), "amplitude of each sample")
        ("dilv", "specify to disable inner-loop verbose")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    //print the help message
    if (vm.count("help")){
        std::cout << boost::format("UHD TX Timed Samples %s") % desc << std::endl;
        return ~0;
    }

    bool verbose = vm.count("dilv") == 0;

    //create a usrp device
    std::cout << std::endl;
    std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
    std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl;

    //set the tx sample rate
    std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl;
    usrp->set_tx_rate(rate);
    std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl;

    std::cout << boost::format("Setting device timestamp to 0...") << std::endl;
    usrp->set_time_now(uhd::time_spec_t(0.0));

    //create a transmit streamer
    uhd::stream_args_t stream_args("fc32", wire); //complex floats
    uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);

    //allocate buffer with data to send
    std::vector<std::complex<float> > buff(tx_stream->get_max_num_samps(), std::complex<float>(ampl, ampl));

    //setup metadata for the first packet
    uhd::tx_metadata_t md;
    md.start_of_burst = false;
    md.end_of_burst = false;
    md.has_time_spec = true;
    md.time_spec = uhd::time_spec_t(seconds_in_future);

    //the first call to send() will block this many seconds before sending:
    const double timeout = seconds_in_future + 0.1; //timeout (delay before transmit + padding)

    size_t num_acc_samps = 0; //number of accumulated samples
    while(num_acc_samps < total_num_samps){
        size_t samps_to_send = std::min(total_num_samps - num_acc_samps, buff.size());

        //send a single packet
        size_t num_tx_samps = tx_stream->send(
            &buff.front(), samps_to_send, md, timeout
        );

        //do not use time spec for subsequent packets
        md.has_time_spec = false;

        if (num_tx_samps < samps_to_send) std::cerr << "Send timeout..." << std::endl;
        if(verbose) std::cout << boost::format("Sent packet: %u samples") % num_tx_samps << std::endl;

        num_acc_samps += num_tx_samps;
    }

    //send a mini EOB packet
    md.end_of_burst   = true;
    tx_stream->send("", 0, md);

    std::cout << std::endl << "Waiting for async burst ACK... " << std::flush;
    uhd::async_metadata_t async_md;
    bool got_async_burst_ack = false;
    //loop through all messages for the ACK packet (may have underflow messages in queue)
    while (not got_async_burst_ack and tx_stream->recv_async_msg(async_md, timeout)){
        got_async_burst_ack = (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK);
    }
    std::cout << (got_async_burst_ack? "success" : "fail") << std::endl;

    //finished
    std::cout << std::endl << "Done!" << std::endl << std::endl;

    return EXIT_SUCCESS;
}


在终端中输入:g++ qiu_tx.cpp –o tx –luhd –lboost_system –lboost_progrma_options

 

接收源码:


#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <complex>

namespace po = boost::program_options;

int UHD_SAFE_MAIN(int argc, char *argv[]){
    uhd::set_thread_priority_safe();

    //variables to be set by po
    std::string args;
    std::string wire;
    double seconds_in_future;
    size_t total_num_samps;
    double rate;
    std::string channel_list;

    //setup the program options
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "help message")
        ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")
        ("wire", po::value<std::string>(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc")
        ("secs", po::value<double>(&seconds_in_future)->default_value(1.5), "number of seconds in the future to receive")
        ("nsamps", po::value<size_t>(&total_num_samps)->default_value(10000), "total number of samples to receive")
        ("rate", po::value<double>(&rate)->default_value(100e6/16), "rate of incoming samples")
        ("dilv", "specify to disable inner-loop verbose")
        ("channels", po::value<std::string>(&channel_list)->default_value("0"), "which channel(s) to use (specify \"0\", \"1\", \"0,1\", etc)")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    //print the help message
    if (vm.count("help")){
        std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl;
        return ~0;
    }

    bool verbose = vm.count("dilv") == 0;

    //create a usrp device
    std::cout << std::endl;
    std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
    std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl;

   //detect which channels to use
    std::vector<std::string> channel_strings;
    std::vector<size_t> channel_nums;
    boost::split(channel_strings, channel_list, boost::is_any_of("\"',"));
    for(size_t ch = 0; ch < channel_strings.size(); ch++){
        size_t chan = boost::lexical_cast<int>(channel_strings[ch]);
        if(chan >= usrp->get_tx_num_channels() or chan >= usrp->get_rx_num_channels()){
            throw std::runtime_error("Invalid channel(s) specified.");
        }
        else channel_nums.push_back(boost::lexical_cast<int>(channel_strings[ch]));
    }

    //set the rx sample rate
    std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl;
    usrp->set_rx_rate(rate);
    std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl;

    std::cout << boost::format("Setting device timestamp to 0...") << std::endl;
    usrp->set_time_now(uhd::time_spec_t(0.0));

    //create a receive streamer
    uhd::stream_args_t stream_args("fc32", wire); //complex floats
    stream_args.channels = channel_nums;
    uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);

    //setup streaming
    std::cout << std::endl;
    std::cout << boost::format(
        "Begin streaming %u samples, %f seconds in the future..."
    ) % total_num_samps % seconds_in_future << std::endl;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    stream_cmd.num_samps = total_num_samps;
    stream_cmd.stream_now = false;
    stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future);
    rx_stream->issue_stream_cmd(stream_cmd);

    //meta-data will be filled in by recv()
    uhd::rx_metadata_t md;

    //allocate buffer to receive with samples
    std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps());
    std::vector<void *> buffs;
    for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++)
        buffs.push_back(&buff.front()); //same buffer for each channel

    //the first call to recv() will block this many seconds before receiving
    double timeout = seconds_in_future + 0.1; //timeout (delay before receive + padding)

    size_t num_acc_samps = 0; //number of accumulated samples
    while(num_acc_samps < total_num_samps){
        //receive a single packet
        size_t num_rx_samps = rx_stream->recv(
            buffs, buff.size(), md, timeout, true
        );

        //use a small timeout for subsequent packets
        timeout = 0.1;

        //handle the error code
        if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) break;
        if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
            throw std::runtime_error(str(boost::format(
                "Receiver error %s"
            ) % md.strerror()));
        }

        if(verbose) std::cout << boost::format(
            "Received packet: %u samples, %u full secs, %f frac secs"
        ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl;

        num_acc_samps += num_rx_samps;
    }

    if (num_acc_samps < total_num_samps) std::cerr << "Receive timeout before all samples received..." << std::endl;

    //finished
    std::cout << std::endl << "Done!" << std::endl << std::endl;

    return EXIT_SUCCESS;
}


在终端中输入:g++ qiu_rx.cpp –o rx –luhd –lboost_system –lboost_progrma_options

注:本源码由于用的progrma_option文件,在安装1.63版本的boost时候却提示找不到该文件,所以又同时安装了1.58版本的boost编译成功。

编译完成后将生成tx、rx两个执行文件,使用./tx和./rx运行

四、  USRP_B200发送接收程序编译验证

该源码出处:http://blog.csdn.net/jxwxg/article/details/53142911

发送程序:

#include<uhd/usrp/multi_usrp.hpp>
#include<signal.h>
 
#defineSAMPLE_PER_BUFF 2000
 
intstop_signal_called = 0;
void sig_int_handle(int)
{
    stop_signal_called = 1;
    printf("stop tx.........\n");
    exit(0);
}
 
int main()
{
    std::stringaddr_args = " ";
    uhd::usrp::multi_usrp::sptr usrp =uhd::usrp::multi_usrp::make(addr_args);
    printf("Create a usrp......\n");
 
    // set the ref and clock rate
    std::stringref = "internal";
    usrp->set_clock_source(ref);
 
    float clock_rate = 40e6;
    usrp->set_master_clock_rate(clock_rate);
    printf("set the  clock rate %0.2f\n",usrp->get_master_clock_rate() );
 
    // set the sample rate
    float samp_rate = 20e6;
    usrp->set_tx_rate(samp_rate);
    printf("set the tx sample rate to %0.2f \n", usrp->get_tx_rate());
 
    // set the center frequency
    float center_freq = 2.412e9;
    usrp->set_tx_freq(center_freq);
    printf("set the tx center freq to %0.2f \n", usrp->get_tx_freq());
 
    // set the rf gain
    float tx_gain = 90;
    usrp->set_tx_gain(tx_gain);
    printf("set the tx gain to %0.2f \n", usrp->get_tx_gain());
 
 
    // create a tx stream
    std::stringcpu_format = "fc32";
    std::stringwire_format = "sc16";
    uhd::stream_args_t stream_args(cpu_format,wire_format);
    uhd::tx_streamer::sptr tx_stream =usrp->get_tx_stream(stream_args);
 
    uhd::tx_metadata_t md;
 
    // catch the INT signal
    signal(SIGINT, sig_int_handle);
    float read_buff[SAMPLE_PER_BUFF * 2] = {0};
 
    while(!stop_signal_called)
    {
        FILE *fp = fopen("802.11a_BUPT41.seg", "rb");
        md.start_of_burst = false;
        md.end_of_burst = false;
 
 
        while( (!md.end_of_burst) &&(!stop_signal_called) )
        {
            int read_length = 0;
            if( (read_length = fread(read_buff, sizeof(uint32_t),SAMPLE_PER_BUFF * 2,fp) ) == (SAMPLE_PER_BUFF * 2) )
            {
                //int index;
                //for(index = 0; index <SAMPLE_PER_BUFF * 2; index++)
                //   printf("%0.2f ", read_buff[index]);
                //puts("");
 
                //md.start_of_burst = true;
                tx_stream->send(read_buff,SAMPLE_PER_BUFF, md);
                //md.start_of_burst = false;
                //sleep(1);
            }
            elseif(read_length >= 0)
            {
                md.end_of_burst = true;
            }
        }
 
        fclose(fp);
    }
 
 
    return0;
}

编译  
g++ 编译时需要链接uhd库,系统需提前安装UHD驱动。具体过程参见之前博客。 Ubuntu14.04 源码安装 UHD3.8.0  
g++ tx.cpp -o tx -luhd

接收程序:

 

#include<uhd/usrp/multi_usrp.hpp>
#include <csignal>
 
#define SAMPLE_PER_BUFF 2000
 
int stop_signal_called = false;
void sig_int_handle()
{
    stop_signal_called = true;
}
 
int main()
{
    std::string addr_args = "";
    uhd::usrp::multi_usrp::sptr usrp= uhd::usrp::multi_usrp::make(addr_args);
 
    // set the clock source andclock rate
    std::string ref ="internal";
    usrp->set_clock_source(ref);
 
    float clock_rate = 40e6;
    usrp->set_master_clock_rate(clock_rate);
    printf("set the  clock rate %0.2f \n",usrp->get_master_clock_rate() );
 
    // set the sample rate
    float samp_rate = 20e6;
    usrp->set_rx_rate(samp_rate);
    printf("set the tx samplerate to %0.2f \n", usrp->get_rx_rate());
 
    // set the center frequency
    float center_freq = 2.412e9;
   usrp->set_rx_freq(center_freq);
    printf("set the tx centerfreq to %0.2f \n", usrp->get_rx_freq());
 
    // set the rf gain
    float rx_gain = 80;
    usrp->set_rx_gain(rx_gain);
    printf("set the tx gain to%0.2f \n", usrp->get_rx_gain());
 
    std::string cpu_format ="fc32";
    std::string wire_format ="sc16";
    uhd::stream_args_tstream_args(cpu_format, wire_format);
    uhd::rx_streamer::sptr rx_stream= usrp->get_rx_stream(stream_args);
 
    uhd::rx_metadata_t md;
 
    //uhd::stream_cmd_tstream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    uhd::stream_cmd_tstream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
    stream_cmd.num_samps =SAMPLE_PER_BUFF;
    stream_cmd.stream_now = true;
    //stream_cmd.time_spec =uhd::time_spec_t();
    stream_cmd.time_spec =usrp->get_time_now();
   rx_stream->issue_stream_cmd(stream_cmd);
 
    uint32_t buff[SAMPLE_PER_BUFF*2]= {0};
    unsigned long longnum_total_samps = 0;
 
    while(!stop_signal_called)
    {
        //int num_rx_samps =rx_stream->recv(buff, SAMPLE_PER_BUFF, md);
        memset(buff, 0,SAMPLE_PER_BUFF * sizeof(uint32_t));
        int num_rx_samps =rx_stream->recv(buff, SAMPLE_PER_BUFF, md, 3.0, false);
        if(md.error_code ==uhd::rx_metadata_t::ERROR_CODE_TIMEOUT)
        {
            printf("Timeoutwhile streaming......\n");
            break;
        }
        if(md.error_code ==uhd::rx_metadata_t::ERROR_CODE_OVERFLOW)
        {
            printf("Overflowingwhile stream......\n");
            continue;
        }
        if(md.error_code !=uhd::rx_metadata_t::ERROR_CODE_NONE)
        {
            //printf("Receiveerror: %s \n", md.strerror());
            continue;
        }
 
    //rintf("num_rx_samps = %d\n",num_rx_samps);
        num_total_samps +=num_rx_samps;
 
    }
    printf("num_total_samps =%d \n", num_total_samps);
 
    stream_cmd.stream_mode =uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
   rx_stream->issue_stream_cmd(stream_cmd);
 
    return 0;
}
编译  
g++ 编译时需要链接uhd库,系统需提前安装UHD驱动。具体过程参见之前博客。 Ubuntu14.04 源码安装 UHD3.8.0  
g++ rx.cpp -o rx -luhd

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值