srsRAN——npdsch_ue.c代码梳理

1.程序使用

-g:设置接收端信息增益值;

-o:offset frequency correction (in Hz) for input file,输入文件的频率偏移校准

频率偏移:调频信号偏离载波频率的幅度。为了兼顾接收机的分辨度和节约频谱资源,往往   需要选取一个调制指数来确定原始信号和频率偏移之间的关系。

-O:offset samples for input file,输入文件的采样率偏移

-p:nof_prb for input file,number of PRBs(Physical Resource Block,物理资源块)

-P:nof_ports for input file,可能是设置物理层相关信息,默认是0

-r:RNTI in Hex,UE的标识

-l:n_id_ncell,发射段id

-R:Is R14 cell,bool类型

2.部分变量

srsran_nbiot_ue_dl_t定义

typedef struct SRSRAN_API {
  srsran_npdcch_t         npdcch;//承载MIB
  srsran_npdsch_t         npdsch;//承载SIB
  srsran_ofdm_t           fft;
  srsran_chest_dl_nbiot_t chest;

  srsran_cfo_t sfo_correct;

  srsran_softbuffer_rx_t softbuffer;
  srsran_nbiot_cell_t    cell;
  srsran_mib_nb_t        mib;
  bool                   mib_set;

  int    nof_re;     // Number of RE per subframe
  cf_t*  sf_symbols; // this buffer holds the symbols of the current subframe
  cf_t*  sf_buffer;  // this buffer holds multiple subframes
  cf_t*  ce[SRSRAN_MAX_PORTS];
  cf_t*  ce_buffer[SRSRAN_MAX_PORTS];
  float* llr; // Buffer to hold soft-bits for later combining repetitions

  uint32_t pkt_errors;
  uint32_t pkts_total;
  uint32_t pkts_ok;
  uint32_t nof_detected;
  uint32_t bits_total;

  // DL configuration for "normal" transmissions
  bool                has_dl_grant;
  srsran_npdsch_cfg_t npdsch_cfg;

  // DL configuration for SIB1 transmissions
  uint32_t                 sib1_sfn[4 * SIB1_NB_MAX_REP]; // there are 4 SIB1 TTIs in each hyper frame
  srsran_nbiot_si_params_t si_params[SRSRAN_NBIOT_SI_TYPE_NITEMS];
  bool                     si_tti[10240]; // We trade memory consumption for speed

  uint16_t              current_rnti;
  uint32_t              last_n_cce;
  srsran_dci_location_t last_location;

  float sample_offset;
} srsran_nbiot_ue_dl_t;
srsran_nbiot_ue_dl_t   ue_dl;//主要变量

srsran_npdsch_t定义如下:

typedef struct SRSRAN_API {
  srsran_nbiot_cell_t cell;
  uint32_t            max_re;
  bool                rnti_is_set;
  uint16_t            rnti;

  // buffers
  uint8_t data[SRSRAN_NPDSCH_MAX_TBS_CRC];
  uint8_t data_enc[SRSRAN_NPDSCH_MAX_TBS_ENC];
  float   rm_f[SRSRAN_NPDSCH_MAX_TBS_ENC];
  cf_t*   ce[SRSRAN_MAX_PORTS];
  cf_t*   symbols[SRSRAN_MAX_PORTS];
  cf_t*   sib_symbols[SRSRAN_MAX_PORTS]; // extra buffer for SIB1 symbols as they may be interleaved with other NPDSCH
  cf_t*   tx_syms[SRSRAN_MAX_PORTS];     // pointer to either symbols or sib1_symbols
  cf_t*   x[SRSRAN_MAX_PORTS];
  cf_t*   d;

  float*   llr;
  uint8_t* temp;
  uint8_t* rm_b;

  // tx & rx objects
  srsran_modem_table_t mod;
  srsran_viterbi_t     decoder;
  srsran_sequence_t    seq[SRSRAN_NPDSCH_NUM_SEQ];
  srsran_crc_t         crc;
  srsran_convcoder_t   encoder;
} srsran_npdsch_t;

srsran_npdcch_t定义:

typedef struct SRSRAN_API {
  srsran_nbiot_cell_t cell;
  uint32_t            nof_cce;
  uint32_t            ncce_bits;
  uint32_t            max_bits;
  uint32_t            i_n_start;      /// start of the first OFDM symbol (signalled through NB-SIB1)
  uint32_t            nof_nbiot_refs; /// number of NRS symbols per OFDM symbol
  uint32_t            nof_lte_refs;   /// number of CRS symbols per OFDM symbol
  uint32_t            num_decoded_symbols;

  /* buffers */
  cf_t*    ce[SRSRAN_MAX_PORTS];
  cf_t*    symbols[SRSRAN_MAX_PORTS];
  cf_t*    x[SRSRAN_MAX_PORTS];
  cf_t*    d;
  uint8_t* e;
  float    rm_f[3 * (SRSRAN_DCI_MAX_BITS + 16)];
  float*   llr[2]; // Two layers of LLRs for Format0 and Format1 NPDCCH

  /* tx & rx objects */
  srsran_modem_table_t mod;
  srsran_sequence_t    seq[SRSRAN_NOF_SF_X_FRAME];
  srsran_viterbi_t     decoder;
  srsran_crc_t         crc;

} srsran_npdcch_t;

信号数目的问题:

计算Channel Response - Magnitude(信道响应度)代码(计算相关系数同):

int numpoints = SRSRAN_NRE * 2;
      bzero(tmp_plot2, sizeof(float) * numpoints);
      int g = (numpoints - SRSRAN_NRE) / 2;
      for (int i = 0; i < 12 * ue_dl.cell.base.nof_prb; i++) {
        tmp_plot2[g + i] = 20 * log10(cabsf(ue_dl.ce[0][i]));
        if (isinf(tmp_plot2[g + i])) {
          tmp_plot2[g + i] = -80;
        }

      }
      plot_real_setNewData(&pce, tmp_plot2, numpoints);//Channel Response - Magnitude展示图窗

星座图打印函数:

if (ue_dl.npdsch_cfg.nbits.nof_re) {
      // plot NPDSCH
      plot_scatter_setNewData(&constellation_plot, ue_dl.npdsch.d, ue_dl.npdsch_cfg.nbits.nof_re);
      //for(int i=0;i<sizeof(ue_dl.npdsch.))
      //printf("test num:%d\n",ue_dl.npdsch_cfg.nbits.nof_re);
      /*
      struct timespec timestamp;
      clock_gettime(CLOCK_REALTIME,&timestamp);
      
      for(int i=0;i<ue_dl.npdsch_cfg.nbits.nof_re;i++){
        printf("%.12f:%f+%fi\n",timestamp.tv_sec+timestamp.tv_nsec*1e-9,
        creal(ue_dl.npdsch.d[i]),cimag(ue_dl.npdsch.d[i]));
      }
      printf("\n");*///打印星座图

    } else if (ue_dl.npdcch.num_decoded_symbols) {
      // plot NPDCCH
      plot_scatter_setNewData(&constellation_plot, ue_dl.npdcch.d, ue_dl.npdcch.num_decoded_symbols);

      //printf("test:ue_dl.npdcch.num_decoded_symbols\n");
    }

srsran_ue_mib_nbiot_t的定义:

typedef struct SRSRAN_API {
  srsran_sync_nbiot_t sfind;

  cf_t* sf_symbols;
  cf_t* ce[SRSRAN_MAX_PORTS];

  srsran_ofdm_t           fft;
  srsran_chest_dl_nbiot_t chest;
  srsran_npbch_t          npbch;//承载MIB信息

  uint8_t  last_bch_payload[SRSRAN_MIB_NB_LEN];
  uint32_t nof_tx_ports;
  uint32_t nof_rx_antennas;
  uint32_t sfn_offset;

  uint32_t frame_cnt;
} srsran_ue_mib_nbiot_t;

prog_args来源

prog_args的信息为接收端自己的信息,n_cell_id为接收端的id

 parse_args(&prog_args, argc, argv);

 ue_mib用于解码MIB,type为srsran_ue_mib_nbiot_t

srsran_ue_mib_nbiot_t的定义如下:

typedef struct SRSRAN_API {
  srsran_sync_nbiot_t sfind;

  cf_t* sf_symbols;
  cf_t* ce[SRSRAN_MAX_PORTS];

  srsran_ofdm_t           fft;
  srsran_chest_dl_nbiot_t chest;
  srsran_npbch_t          npbch;//用于承载MIB

  uint8_t  last_bch_payload[SRSRAN_MIB_NB_LEN];
  uint32_t nof_tx_ports;
  uint32_t nof_rx_antennas;
  uint32_t sfn_offset;

  uint32_t frame_cnt;
} srsran_ue_mib_nbiot_t;
//注明:cf_t 是Complex float类型

srsran_npdch_t定义如下:

typedef struct SRSRAN_API {
  srsran_nbiot_cell_t cell;

  uint32_t frame_idx;
  uint32_t nof_symbols;

  // buffers
  cf_t*    ce[SRSRAN_MAX_PORTS];
  cf_t*    symbols[SRSRAN_MAX_PORTS];
  cf_t*    x[SRSRAN_MAX_PORTS];
  cf_t*    d;
  float*   llr;
  float*   temp;
  float    rm_f[SRSRAN_MIB_NB_ENC_LEN];
  uint8_t* rm_b;
  uint8_t  data[SRSRAN_MIB_NB_CRC_LEN];
  uint8_t  data_enc[SRSRAN_MIB_NB_ENC_LEN];

  srsran_nbiot_mode_t op_mode;

  // tx & rx objects
  srsran_modem_table_t mod;
  srsran_sequence_t    seq;
  srsran_sequence_t    seq_r14[SRSRAN_NPBCH_NUM_BLOCKS];
  srsran_viterbi_t     decoder;
  srsran_crc_t         crc;
  srsran_convcoder_t   encoder;
  bool                 search_all_ports;
} srsran_npbch_t;

srsran_sync_nbiot定义如下:

srsran_ofdm_t定义如下:

typedef struct SRSRAN_API {
  srsran_ofdm_cfg_t cfg;
  srsran_dft_plan_t fft_plan;
  srsran_dft_plan_t fft_plan_sf[2];
  uint32_t          max_prb;
  uint32_t          nof_symbols;
  uint32_t          nof_guards;
  uint32_t          nof_re;
  uint32_t          slot_sz;
  uint32_t          sf_sz;
  cf_t*             tmp; // for removing zero padding
  bool              mbsfn_subframe;
  uint32_t          mbsfn_guard_len;
  uint32_t          nof_symbols_mbsfn;
  uint8_t           non_mbsfn_region;
  uint32_t          window_offset_n;
  cf_t*             shift_buffer;
  cf_t*             window_offset_buffer;
  cf_t              phase_compensation[SRSRAN_MAX_NSYMB * SRSRAN_NOF_SLOTS_PER_SF];
  srsran_cfr_t      tx_cfr; ///< Tx CFR object
} srsran_ofdm_t;

srsran_chest_dl_nbiot_t的定义如下:

typedef struct {
  srsran_nbiot_cell_t         cell;
  srsran_refsignal_dl_nbiot_t nrs_signal;

  cf_t* pilot_estimates;
  cf_t* pilot_estimates_average;
  cf_t* pilot_recv_signal;
  cf_t* tmp_noise;

  uint32_t smooth_filter_len;
  float    smooth_filter[SRSRAN_CHEST_MAX_SMOOTH_FIL_LEN];

  srsran_interp_linsrsran_vec_t srsran_interp_linvec;
  srsran_interp_lin_t           srsran_interp_lin;

  float rssi[SRSRAN_MAX_PORTS];
  float rsrp[SRSRAN_MAX_PORTS];
  float noise_estimate[SRSRAN_MAX_PORTS];

  srsran_chest_dl_noise_alg_t noise_alg;

} srsran_chest_dl_nbiot_t;

3.部分函数

信号接受入口

int main((int argc, char** argv){
....
 // Set initial CFO for ue_sync
  srsran_ue_sync_nbiot_set_cfo(&ue_sync, cfo);

  srsran_npbch_decode_reset(&ue_mib.npbch);

  INFO("\nEntering main loop...");
  while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
ret = srsran_ue_sync_nbiot_zerocopy_multi(&ue_sync, buff_ptrs);
...
//printf("state:%d,decode mib:%d,decode sib:%d,decode npdsch:%d\n",state,DECODE_MIB,DECODE_SIB,DECODE_NPDSCH);
    /*state:未收到信号或者异常为0,
    *        正常收到信号为1,
    *DECODE MIB=0;
    *DECODE SIB=1;
    *DECODE NPDSCH=2;
    */
    // srsran_ue_sync_nbiot_zerocopy_multi() returns 1 if successfully read 1 aligned subframe
    if (ret == 1) {
      switch (state) {
...
case DECODE_SIB:
  if (!have_sib1) {
            //printf("test run?\n");
            /*
            *have_sib1:false下表示未收到信号,受到信号后更新为true
            */
            int dec_ret = srsran_nbiot_ue_dl_decode_npdsch(&ue_dl,
                                                           &buff_ptrs[0][prog_args.time_offset],
                                                           rx_tb,
                                                           system_frame_number,
                                                           srsran_ue_sync_nbiot_get_sfidx(&ue_sync),
                                                           SRSRAN_SIRNTI);
            if (dec_ret == SRSRAN_SUCCESS) {
              printf("SIB1 received\n");
              srsran_sys_info_block_type_1_nb_t sib = {};
              srsran_npdsch_sib1_unpack(rx_tb, &sib);
              hyper_frame_number = sib.hyper_sfn;

              have_sib1 = true;
...
}else if (!have_sib2 && !srsran_nbiot_ue_dl_is_sib1_sf(
                                       &ue_dl, system_frame_number, srsran_ue_sync_nbiot_get_sfidx(&ue_sync))) {
            //printf("test run?\n");
            // SIB2 is transmitted over multiple subframes, so this needs to be called more than once ..
            int dec_ret = srsran_nbiot_ue_dl_decode_npdsch(&ue_dl,
                                                           &buff_ptrs[0][prog_args.time_offset],
                                                           rx_tb,
                                                           system_frame_number,
                                                           srsran_ue_sync_nbiot_get_sfidx(&ue_sync),
                                                           SRSRAN_SIRNTI);

...
}

}

GUI部分获得星座图代码

//printf("test num:%d\n",ue_dl.npdsch_cfg.nbits.nof_re);
      /*
      struct timespec timestamp;
      clock_gettime(CLOCK_REALTIME,&timestamp);
      
      for(int i=0;i<ue_dl.npdsch_cfg.nbits.nof_re;i++){
        printf("%.12f:%f+%fi\n",timestamp.tv_sec+timestamp.tv_nsec*1e-9,
        creal(ue_dl.npdsch.d[i]),cimag(ue_dl.npdsch.d[i]));
      }
      printf("\n");*///打印星座图

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_ZhouTao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值