我是靠谱客的博主 健忘自行车,最近开发中收集的这篇文章主要介绍OAI NR nr-softmodem初步解析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

编译和仿真命令

基于版本:OAI_develop_210827。对nr-softmodem,也就是 gnb进行解析。

下载后编译 先用git init命令,然后chmod 777 -R把文件夹内权限设置一下。

develop的编译:

sudo ./build_oai -w USRP --eNB --nrUE --gNB -g -G  -V -x -P --ue-trace --ue-timing   --build-lib telnetsrv  --build-lib all

NR_UE_SA的编译:

sudo ./build_oai -w USRP --eNB --nrUE --gNB -g -G -P --build-lib all

​      分别用-P和取消-P分别编译一次。

gdb 调试和仿真:

ue端:
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path ./ -d
server端: (在ubuntu终端中输入export RFSIMULATOR=server,并用env命令查看)
sudo cgdb --args ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --rfsim --phy-test -d   --command set enviroment RFSIMULATOR=server --rfsimulator.options saviq

读取配置

调试命令:

对NR_SSB的一些配置(读取nr_init_frame_parms()运行后的fp结构体):

{freq_range = nr_FR1, N_RB_DL = 106, N_RB_UL = 106, N_RBG = 0 '00', N_RBGS = 0 '00',
nr_band = 78, dl_CarrierFreq = 3619080000, ul_CarrierFreq = 3619080000, att_tx = 0, att_rx
= 0, frame_type = TDD, tdd_config = 0 '00', Nid_cell = 0, subcarrier_spacing = 30000,
threequarter_fs = 0 '00', ofdm_symbol_size= 2048, nb_prefix_samples = 144,
nb_prefix_samples0 = 176, first_carrier_offset = 1412, symbols_per_slot = 14,
slots_per_subframe = 2, slots_per_frame = 20, samples_per_subframe = 61440,
samples_per_slot0 = 30720, samples_per_slotN0 = 30688, samples_per_frame = 614400,
samples_per_subframe_wCP = 57344, samples_per_slot_wCP = 28672, samples_per_frame_wCP =
573440, numerology_index = 1 '01', nb_antennas_tx = 1 '01', nb_antennas_rx = 1 '01',
nb_antenna_ports_gNB = 0 '00', Ncp = NORMAL, symbol_rotation = {{0 <repeats 448 times>},
{0 <repeats 448 times>}}, nushift = 0 '00', srs_nr = {active_srs_Resource_Set = 0 '00',
number_srs_Resource_Set = 0 '00', p_SRS_ResourceSetList = {0x0}}, ss_PBCH_BlockPower = 0,
p_tdd_UL_DL_Configuration = 0x0, p_tdd_UL_DL_ConfigurationCommon2 = 0x0,
p_TDD_UL_DL_ConfigDedicated = 0x0, tdd_uplink_nr = {0 <repeats 320 times>}, half_frame_bit
= 0 '00', ssb_start_subcarrier = 0, ssb_type = nr_ssb_type_C, Lmax = 8 'b', L_ssb =
9223372036854775808, N_ssb = 1 '01', ssb_index = 0 '00', pbch_polar_params = {idx = 0,
nextPtr = 0x0, n_max = 0 '00', i_il = 0 '00', i_seg = 0 '00', n_pc = 0 '00',
n_pc_wm = 0 '00', i_bil = 0 '00', payloadBits = 0, encoderLength = 0, crcParityBits = 0
'00', crcCorrectionBits = 0 '00', K = 0, N = 0, n = 0 '00', crcBit = 0,
interleaving_pattern = 0x0, deinterleaving_pattern = 0x0, rate_matching_pattern = 0x0,
Q_0_Nminus1 = 0x0, Q_I_N = 0x0, Q_F_N = 0x0, Q_PC_N = 0x0, information_bit_pattern = 0x0,
channel_interleaver_pattern = 0x0, crc_generator_matrix = 0x0, G_N = 0x0, G_N_tab = 0x0,
groupsize = 0, rm_tab = 0x0, cprime_tab0 = {{0 <repeats 256 times>} <repeats 32 times>},
cprime_tab1 = {{0 <repeats 256 times>} <repeats 32 times>}, B_tab0 = {{0 <repeats 256
times>} <repeats 32 times>}, B_tab1 = {{0 <repeats 256 times>} <repeats 32 times>},
extended_crc_generator_matrix = 0x0, nr_polar_crc = 0x0, nr_polar_aPrime = 0x0,
nr_polar_APrime = 0x0, nr_polar_D = 0x0, nr_polar_E = 0x0, nr_polar_A = 0x0, nr_polar_CPrime = 0x0, nr_polar_B = 0x0, nr_polar_U = 0x0, tree = {root = 0x0, num_nodes =
0}}}


 数据发送:

​       按slot来发送。一个子帧是2个,所以大多数情况是0.5ms发送一次。

​       tx_rf()中ru->rfdevice.trx_write_func()进行发送。这个函数指针在usrp发送指向trx_usrp_write()。在RFSIMULATOR=server仿真下,指向  rfsimulator_write_internal()进行的数据发送。

​      发送的数据长度为nsamps,地址为txp,   如下进行赋值: 

txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension];

​       在rx_func()末尾,如果满足下面的条件,则启动tx_func()。

 tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT

发送函数作用解释:

- tx_func():  生成bit帧(dci、csi,旋转等),主要调用phy_procedures_gNB_TX()。在rx_func()末尾可以启动。  在Tpool0_1  ~ Tpool7_-1共8个线程中来承载运行;
- ru_tx_func() :   射频前端、OFDM调制,调用ru->fh_south_out()函数指针,指向tx_rf(),以通过射频usrp或者仿真网口发出去。ru_tx_func()在tx_func()末尾启动。 ofdm调制调用Tpoll线程的nr_feptx_prec来实现。 在Tpool0_1  ~ Tpool7_-1共8个线程中承载运行;

- nr_feptx_prec() :OFDM调试、波束预编码。由线程"feptx"承载运行。 由线程Tpool0_1  ~ Tpool7_-1里面的tx_func(),通过nr_feptx_ofdm_2thread()调用。

读取发送保存的文件

​     运行时添加参数    --rfsimulator.options saviq。默认保存位置为tmp/rfsimulator.iqs

​     matlab读取的对应代码为:
 


clear;clc;close all;
format LONGG;
fid = fopen('Z:workdatarfsimulator.iqs','r');
skip = 0;  % by bytes
Nframe = 100;
for i = 1:Nframe
    header = fread(fid,8,'uint32');
    frame.header.magic = header(1) * 2^32 +  header(2);
    frame.header.size = header(3);
    frame.header.nbAnt = header(4);
    frame.header.timestamp = header(5) * 2^32 + header(6);
    frame.header.option_value = header(7);
    frame.header.option_flag = header(8); 
    
    skip = skip + 32;
    fseek(fid,skip,1);  % by bytes
    size = frame.header.size;
    data = fread(fid,size*2,'int16');
    frame.real=data(1:2:end-1);
    frame.img =data(2:2:end);
    frame.cmx = frame.real + 1j * frame.img;    
    skip = skip + size * 4;  
    fseek(fid,skip,1);  % by bytes
    FrameS(i) = frame;
end
fclose(fid);

# 线程池及调用

​       发送和接收的主要函数是ru_thread(),通过thread_FH线程承载。这个线程又调用函数tx_func()和ru_tx_func()。这两个函数都是通过Tpool0_1  ~ Tpool7_-1线程池承载。tx_func里面的OFDM调制又通过调用nr_feptx_prec()里面的nr_feptx_ofdm_2thread()来实现。而nr_feptx_prec是通过线程feptx来承载。

​      ru_thread()里面也把接收的数据发给scope,用于显示;

​     函数通过 pushTpool()如   pushTpool (gNB->threadPool, res)调用函数。如读取 res内容可以看到线程运行的函数 ru_tx_func():

(gdb) p *res
$39 = {next = 0x0, key = 3, reponseFifo = 0x39c2c40, processingFunc = 0x6b0633 <ru_tx_func>, malloced = true, creationTime = 0, startProcessingTime = 0, endProcessingTime = 0, returnTime = 0, msgData = 0x7fffe001e6c0}

​       该线程池的详解见:“线程池Code详解"   作者 从善若水。

​        pullTpool() : 返回可用的线程;pushTpool()运行线程。里面有线程上一个处理函数和下一个处理函数

​        如tx_func()里面语句:

res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);

​      在此处断点,打印

p *gNB->resp_RU_tx->outF
p *gNB->resp_RU_tx->inF

最后

以上就是健忘自行车为你收集整理的OAI NR nr-softmodem初步解析的全部内容,希望文章能够帮你解决OAI NR nr-softmodem初步解析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部