NR UE: introduce support to define multiple RUs

This commit is contained in:
Thomas Schlichter
2026-01-27 10:23:01 +01:00
parent 256a54ce6c
commit 90ad9fac1a
7 changed files with 341 additions and 95 deletions
+1
View File
@@ -1872,6 +1872,7 @@ add_executable(nr-uesoftmodem
${OPENAIR_DIR}/executables/nr-uesoftmodem.c
${OPENAIR_DIR}/executables/position_interface.c
${OPENAIR_DIR}/executables/nr-ue.c
${OPENAIR_DIR}/executables/nr-ue-ru.c
${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR_DIR}/radio/COMMON/common_lib.c
${OPENAIR_DIR}/radio/COMMON/record_player.c
@@ -14,6 +14,21 @@ position0 = {
thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
RUs = (
{
nb_tx = 1;
nb_rx = 1;
att_tx = 0;
att_rx = 0;
max_rxgain = 114;
sdr_addrs = "type=x300";
clock_src = "internal";
time_src = "internal";
# if_freq = 3700000000L;
# if_offset = 1000000;
}
);
#/* configuration for channel modelisation */
#/* To be included in main config file when */
#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
+248
View File
@@ -0,0 +1,248 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nr-ue-ru.h"
#include "nr-uesoftmodem.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
/* NR UE RU configuration section name */
#define CONFIG_STRING_NRUE_RU_LIST "RUs"
#define NRUE_RU_NB_TX "nb_tx"
#define NRUE_RU_NB_RX "nb_rx"
#define NRUE_RU_ATT_TX "att_tx"
#define NRUE_RU_ATT_RX "att_rx"
#define NRUE_RU_MAX_RXGAIN "max_rxgain"
#define NRUE_RU_SDR_ADDRS "sdr_addrs"
#define NRUE_RU_TX_SUBDEV "tx_subdev"
#define NRUE_RU_RX_SUBDEV "rx_subdev"
#define NRUE_RU_CLOCK_SRC "clock_src"
#define NRUE_RU_TIME_SRC "time_src"
#define NRUE_RU_TUNE_OFFSET "tune_offset"
#define NRUE_RU_IF_FREQUENCY "if_freq"
#define NRUE_RU_IF_FREQ_OFFSET "if_offset"
#define NRUE_RU_SRC_CHECK \
&(checkedparam_t) \
{ \
.s3a = { config_checkstr_assign_integer, {"internal", "external", "gpsdo"}, {internal, external, gpsdo}, 3 } \
}
/*------------------------------------------------------------------------------------------------------------------------------------------------*/
/* NR UE RU configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt chkPptr */
/*------------------------------------------------------------------------------------------------------------------------------------------------*/
// clang-format off
#define NRUE_RU_PARAMS_DESC { \
{NRUE_RU_NB_TX, CONFIG_HLP_UENANTT, 0, .uptr=NULL, .defuintval=1, TYPE_UINT, 0, NULL }, \
{NRUE_RU_NB_RX, CONFIG_HLP_UENANTR, 0, .uptr=NULL, .defuintval=1, TYPE_UINT, 0, NULL }, \
{NRUE_RU_ATT_TX, NULL, 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0, NULL }, \
{NRUE_RU_ATT_RX, NULL, 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0, NULL }, \
{NRUE_RU_MAX_RXGAIN, NULL, 0, .iptr=NULL, .defintval=120, TYPE_INT, 0, NULL }, \
{NRUE_RU_SDR_ADDRS, CONFIG_HLP_USRP_ARGS, 0, .strptr=NULL, .defstrval="type=b200", TYPE_STRING, 0, NULL }, \
{NRUE_RU_TX_SUBDEV, CONFIG_HLP_TX_SUBDEV, 0, .strptr=NULL, .defstrval="", TYPE_STRING, 0, NULL }, \
{NRUE_RU_RX_SUBDEV, CONFIG_HLP_RX_SUBDEV, 0, .strptr=NULL, .defstrval="", TYPE_STRING, 0, NULL }, \
{NRUE_RU_CLOCK_SRC, NULL, 0, .strptr=NULL, .defstrval="internal", TYPE_STRING, 0, NRUE_RU_SRC_CHECK }, \
{NRUE_RU_TIME_SRC, NULL, 0, .strptr=NULL, .defstrval="internal", TYPE_STRING, 0, NRUE_RU_SRC_CHECK }, \
{NRUE_RU_TUNE_OFFSET, CONFIG_HLP_TUNE_OFFSET, 0, .dblptr=NULL, .defdblval=0.0, TYPE_DOUBLE, 0, NULL }, \
{NRUE_RU_IF_FREQUENCY, CONFIG_HLP_IF_FREQ, 0, .u64ptr=NULL, .defint64val=0, TYPE_UINT64, 0, NULL }, \
{NRUE_RU_IF_FREQ_OFFSET, CONFIG_HLP_IF_FREQ_OFF, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0, NULL }, \
}
// clang-format on
static int nrue_ru_count;
static nrUE_RU_params_t *nrue_rus;
openair0_config_t openair0_cfg[MAX_CARDS];
openair0_device_t openair0_dev[MAX_CARDS];
int nrue_get_ru_count(void)
{
return nrue_ru_count;
}
const nrUE_RU_params_t *nrue_get_ru(int ru_id)
{
AssertFatal(ru_id >= 0 && ru_id < nrue_ru_count, "Invalid RU ID %d! RU count = %d\n", ru_id, nrue_ru_count);
return &nrue_rus[ru_id];
}
void nrue_set_ru_params(configmodule_interface_t *cfg)
{
paramdef_t RUParams[] = NRUE_RU_PARAMS_DESC;
paramlist_def_t RUParamList = {CONFIG_STRING_NRUE_RU_LIST, NULL, 0};
config_getlist(cfg, &RUParamList, RUParams, sizeofArray(RUParams), NULL);
if (RUParamList.numelt <= 0) {
nrue_ru_count = 1;
nrue_rus = calloc_or_fail(nrue_ru_count, sizeof(nrUE_RU_params_t));
nrue_rus[0] = (nrUE_RU_params_t){.nb_tx = get_nrUE_params()->nb_antennas_tx,
.nb_rx = get_nrUE_params()->nb_antennas_rx,
.att_tx = get_nrUE_params()->tx_gain,
.att_rx = 0,
.max_rxgain = get_nrUE_params()->rx_gain,
.sdr_addrs = get_nrUE_params()->usrp_args,
.tx_subdev = get_nrUE_params()->tx_subdev,
.rx_subdev = get_nrUE_params()->rx_subdev,
.clock_source = get_softmodem_params()->clock_source,
.time_source = get_softmodem_params()->timing_source,
.tune_offset = get_softmodem_params()->tune_offset,
.if_frequency = get_nrUE_params()->if_freq,
.if_freq_offset = get_nrUE_params()->if_freq_off};
return;
}
nrue_ru_count = RUParamList.numelt;
nrue_rus = calloc_or_fail(nrue_ru_count, sizeof(nrUE_RU_params_t));
LOG_W(NR_PHY, "Ignoring command line RU parameters, using the following instead:\n");
for (int ru_id = 0; ru_id < nrue_ru_count; ru_id++) {
nrue_rus[ru_id].nb_tx = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_NB_TX)->uptr);
nrue_rus[ru_id].nb_rx = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_NB_RX)->uptr);
nrue_rus[ru_id].att_tx = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_ATT_TX)->uptr);
nrue_rus[ru_id].att_rx = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_ATT_RX)->uptr);
nrue_rus[ru_id].max_rxgain = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_MAX_RXGAIN)->iptr);
nrue_rus[ru_id].tune_offset = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_TUNE_OFFSET)->dblptr);
nrue_rus[ru_id].if_frequency = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_IF_FREQUENCY)->u64ptr);
nrue_rus[ru_id].if_freq_offset = *(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_IF_FREQ_OFFSET)->iptr);
nrue_rus[ru_id].sdr_addrs = strdup(*(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_SDR_ADDRS)->strptr));
nrue_rus[ru_id].tx_subdev = strdup(*(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_TX_SUBDEV)->strptr));
nrue_rus[ru_id].rx_subdev = strdup(*(gpd(RUParamList.paramarray[ru_id], sizeofArray(RUParams), NRUE_RU_RX_SUBDEV)->strptr));
int clock_src_idx = config_paramidx_fromname(RUParams, sizeofArray(RUParams), NRUE_RU_CLOCK_SRC);
AssertFatal(clock_src_idx >= 0, "Index for clock_src config option not found!\n");
nrue_rus[ru_id].clock_source = config_get_processedint(cfg, &RUParamList.paramarray[ru_id][clock_src_idx]);
int time_src_idx = config_paramidx_fromname(RUParams, sizeofArray(RUParams), NRUE_RU_TIME_SRC);
AssertFatal(time_src_idx >= 0, "Index for time_src config option not found!\n");
nrue_rus[ru_id].time_source = config_get_processedint(cfg, &RUParamList.paramarray[ru_id][time_src_idx]);
LOG_I(NR_PHY,
"RU %d: nb_tx %d, nb_rx %d, att_tx %d, att_rx %d, max_rxgain %d, tune_offset %f, if_frequency %lu, if_freq_offset %d, "
"sdr_addrs \"%s\", tx_subdev \"%s\", rx_subdev \"%s\", clock_source %d, time_source %d\n",
ru_id,
nrue_rus[ru_id].nb_tx,
nrue_rus[ru_id].nb_rx,
nrue_rus[ru_id].att_tx,
nrue_rus[ru_id].att_rx,
nrue_rus[ru_id].max_rxgain,
nrue_rus[ru_id].tune_offset,
nrue_rus[ru_id].if_frequency,
nrue_rus[ru_id].if_freq_offset,
nrue_rus[ru_id].sdr_addrs,
nrue_rus[ru_id].tx_subdev,
nrue_rus[ru_id].rx_subdev,
nrue_rus[ru_id].clock_source,
nrue_rus[ru_id].time_source);
}
}
void nrue_init_openair0(const PHY_VARS_NR_UE *ue)
{
int freq_off = 0;
bool is_sidelink = (get_softmodem_params()->sl_mode) ? true : false;
memset(openair0_cfg, 0, sizeof(openair0_config_t) * MAX_CARDS);
memset(openair0_dev, 0, sizeof(openair0_device_t) * MAX_CARDS);
AssertFatal(MAX_CARDS >= nrue_ru_count,
"Too many RUs allocated (%d)! Maybe increase MAX_CARDS (%d).\n",
nrue_ru_count,
MAX_CARDS);
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
if (is_sidelink)
frame_parms = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
for (int ru_id = 0; ru_id < nrue_ru_count; ru_id++) {
openair0_config_t *cfg = &openair0_cfg[ru_id];
cfg->configFilename = NULL;
cfg->sample_rate = frame_parms->samples_per_subframe * 1e3;
cfg->samples_per_frame = frame_parms->samples_per_frame;
if (frame_parms->frame_type == TDD)
cfg->duplex_mode = duplex_mode_TDD;
else
cfg->duplex_mode = duplex_mode_FDD;
cfg->Mod_id = 0;
cfg->num_rb_dl = frame_parms->N_RB_DL;
cfg->tx_num_channels = min(4, frame_parms->nb_antennas_tx);
cfg->rx_num_channels = min(4, frame_parms->nb_antennas_rx);
LOG_I(PHY,
"HW: Configuring ru_id %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
ru_id,
cfg->sample_rate,
cfg->tx_num_channels,
cfg->rx_num_channels,
duplex_mode_txt[cfg->duplex_mode]);
uint64_t dl_carrier, ul_carrier;
if (is_sidelink || nrue_rus[ru_id].if_frequency == 0) {
dl_carrier = frame_parms->dl_CarrierFreq;
ul_carrier = frame_parms->ul_CarrierFreq;
} else {
dl_carrier = nrue_rus[ru_id].if_frequency;
ul_carrier = nrue_rus[ru_id].if_frequency + nrue_rus[ru_id].if_freq_offset;
}
nr_rf_card_config_freq(cfg, ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_gain(cfg);
cfg->configFilename = get_softmodem_params()->rf_config_file;
cfg->sdr_addrs = nrue_rus[ru_id].sdr_addrs;
cfg->tx_subdev = nrue_rus[ru_id].tx_subdev;
cfg->rx_subdev = nrue_rus[ru_id].rx_subdev;
cfg->clock_source = nrue_rus[ru_id].clock_source;
cfg->time_source = nrue_rus[ru_id].time_source;
cfg->tune_offset = nrue_rus[ru_id].tune_offset;
}
}
void nrue_ru_start(void)
{
for (int ru_id = 0; ru_id < nrue_ru_count; ru_id++) {
openair0_config_t *cfg0 = &openair0_cfg[ru_id];
openair0_device_t *dev0 = &openair0_dev[ru_id];
dev0->host_type = RAU_HOST;
int tmp = openair0_device_load(dev0, cfg0);
AssertFatal(tmp == 0, "Could not load the device %d\n", ru_id);
int tmp2 = dev0->trx_start_func(dev0);
AssertFatal(tmp2 == 0, "Could not start the device %d\n", ru_id);
if (usrp_tx_thread == 1)
dev0->trx_write_init(dev0);
}
}
void nrue_ru_end(void)
{
for (int ru_id = 0; ru_id < nrue_ru_count; ru_id++) {
if (openair0_dev[ru_id].trx_get_stats_func)
openair0_dev[ru_id].trx_get_stats_func(&openair0_dev[ru_id]);
if (openair0_dev[ru_id].trx_end_func)
openair0_dev[ru_id].trx_end_func(&openair0_dev[ru_id]);
}
}
+37
View File
@@ -0,0 +1,37 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef NR_UE_RU_H
#define NR_UE_RU_H
#include "PHY/defs_nr_UE.h"
#include "radio/COMMON/common_lib.h"
int nrue_get_ru_count(void);
const nrUE_RU_params_t *nrue_get_ru(int ru_id);
void nrue_set_ru_params(configmodule_interface_t *cfg);
void nrue_init_openair0(const PHY_VARS_NR_UE *ue);
void nrue_ru_start(void);
void nrue_ru_end(void);
#endif
-8
View File
@@ -767,8 +767,6 @@ void *UE_thread(void *arg)
void *rxp[NB_ANTENNAS_RX];
enum stream_status_e stream_status = STREAM_STATUS_UNSYNC;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tmp = openair0_device_load(dev0, cfg0);
AssertFatal(tmp == 0, "Could not load the device\n");
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
sl_nr_phy_config_request_t *sl_cfg = NULL;
if (UE->sl_mode == 2) {
@@ -776,13 +774,7 @@ void *UE_thread(void *arg)
sl_cfg = &UE->SL_UE_PHY_PARAMS.sl_config;
}
dev0->host_type = RAU_HOST;
UE->is_synchronized = 0;
int tmp2 = dev0->trx_start_func(dev0);
AssertFatal(tmp2 == 0, "Could not start the device\n");
if (usrp_tx_thread == 1)
dev0->trx_write_init(dev0);
InitSinLUT();
notifiedFIFO_t nf;
+24 -87
View File
@@ -81,6 +81,7 @@ unsigned short config_frames[4] = {2,9,11,13};
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
#include "PHY/TOOLS/phy_scope_interface.h"
#include "PHY/TOOLS/nr_phy_scope.h"
#include "executables/nr-ue-ru.h"
#include <executables/nr-uesoftmodem.h>
#include "executables/softmodem-common.h"
#include "executables/thread-common.h"
@@ -107,8 +108,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
// UE and OAI config variables
openair0_config_t openair0_cfg[MAX_CARDS];
openair0_device_t openair0_dev[MAX_CARDS];
double cpuf;
int create_tasks_nrue(uint32_t ue_nb) {
@@ -140,14 +139,7 @@ void exit_function(const char *file, const char *function, const int line, const
oai_exit = 1;
for (int card = 0; card < MAX_CARDS; card++) {
if (openair0_dev[card].trx_end_func) {
if (openair0_dev[card].trx_get_stats_func) {
openair0_dev[card].trx_get_stats_func(&openair0_dev[card]);
}
openair0_dev[card].trx_end_func(&openair0_dev[card]);
}
}
nrue_ru_end();
if (assert) {
abort();
@@ -183,20 +175,23 @@ static void get_options(configmodule_interface_t *cfg)
}
// set PHY vars from command line
void set_options(int CC_id, PHY_VARS_NR_UE *UE){
static void set_options(int CC_id, PHY_VARS_NR_UE *UE, int ru_id)
{
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
const nrUE_RU_params_t *RU = nrue_get_ru(ru_id);
// Set UE variables
UE->rx_total_gain_dB = (int)nrUE_params.rx_gain;
UE->tx_total_gain_dB = (int)nrUE_params.tx_gain;
UE->rx_total_gain_dB = RU->max_rxgain - RU->att_rx;
UE->tx_total_gain_dB = RU->att_tx;
UE->if_freq = RU->if_frequency;
UE->if_freq_off = RU->if_freq_offset;
UE->rf_map.card = ru_id;
UE->rf_map.chain = CC_id;
UE->tx_power_max_dBm = nrUE_params.tx_max_power;
UE->rf_map.card = 0;
UE->rf_map.chain = CC_id + 0;
UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations;
UE->UE_scan_carrier = nrUE_params.UE_scan_carrier;
UE->UE_fo_compensation = nrUE_params.UE_fo_compensation;
UE->if_freq = nrUE_params.if_freq;
UE->if_freq_off = nrUE_params.if_freq_off;
UE->chest_freq = nrUE_params.chest_freq;
UE->chest_time = nrUE_params.chest_time;
UE->no_timing_correction = nrUE_params.no_timing_correction;
@@ -207,71 +202,15 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq, UE->chest_time);
// Set FP variables
fp->nb_antennas_rx = RU->nb_rx;
fp->nb_antennas_tx = RU->nb_tx;
fp->nb_antennas_rx = nrUE_params.nb_antennas_rx;
fp->nb_antennas_tx = nrUE_params.nb_antennas_tx;
fp->threequarter_fs = get_softmodem_params()->threequarter_fs;
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
fp->threequarter_fs = get_softmodem_params()->threequarter_fs;
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ofdm_offset_divisor %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ofdm_offset_divisor);
}
void init_openair0(PHY_VARS_NR_UE *ue)
{
int freq_off = 0;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
bool is_sidelink = (get_softmodem_params()->sl_mode) ? true : false;
if (is_sidelink)
frame_parms = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
for (int card = 0; card < MAX_CARDS; card++) {
openair0_config_t *cfg = &openair0_cfg[card];
uint64_t dl_carrier, ul_carrier;
cfg->configFilename = NULL;
cfg->sample_rate = frame_parms->samples_per_subframe * 1e3;
cfg->samples_per_frame = frame_parms->samples_per_frame;
if (frame_parms->frame_type==TDD)
cfg->duplex_mode = duplex_mode_TDD;
else
cfg->duplex_mode = duplex_mode_FDD;
cfg->Mod_id = 0;
cfg->num_rb_dl = frame_parms->N_RB_DL;
cfg->clock_source = get_softmodem_params()->clock_source;
cfg->time_source = get_softmodem_params()->timing_source;
cfg->tune_offset = get_softmodem_params()->tune_offset;
cfg->tx_num_channels = min(4, frame_parms->nb_antennas_tx);
cfg->rx_num_channels = min(4, frame_parms->nb_antennas_rx);
LOG_I(PHY,
"HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
card,
cfg->sample_rate,
cfg->tx_num_channels,
cfg->rx_num_channels,
duplex_mode_txt[cfg->duplex_mode]);
if (is_sidelink) {
dl_carrier = frame_parms->dl_CarrierFreq;
ul_carrier = frame_parms->ul_CarrierFreq;
} else
nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier);
nr_rf_card_config_freq(cfg, ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_gain(cfg);
cfg->configFilename = get_softmodem_params()->rf_config_file;
if (get_nrUE_params()->usrp_args)
cfg->sdr_addrs = get_nrUE_params()->usrp_args;
if (get_nrUE_params()->tx_subdev)
cfg->tx_subdev = get_nrUE_params()->tx_subdev;
if (get_nrUE_params()->rx_subdev)
cfg->rx_subdev = get_nrUE_params()->rx_subdev;
}
}
// Stupid function addition because UE itti messages queues definition is common with eNB
void *rrc_enb_process_msg(void *notUsed) {
return NULL;
@@ -314,8 +253,6 @@ int main(int argc, char **argv)
}
//set_softmodem_sighandler();
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
memset(openair0_cfg, 0, sizeof(openair0_config_t) * MAX_CARDS);
memset(openair0_dev, 0, sizeof(openair0_device_t) * MAX_CARDS);
// initialize logging
logInit();
// get options and fill parameters from configuration file
@@ -387,11 +324,14 @@ int main(int argc, char **argv)
IS_SOFTMODEM_RFSIM ? TIME_SOURCE_IQ_SAMPLES
: TIME_SOURCE_REALTIME);
nrue_set_ru_params(uniqCfg);
int ru_id = 0; // initialize all UEs to RU 0 for now
for (int inst = 0; inst < NB_UE_INST; inst++) {
PHY_VARS_NR_UE *UE[MAX_NUM_CCs];
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
UE[CC_id] = PHY_vars_UE_g[inst][CC_id];
set_options(CC_id, UE[CC_id]);
set_options(CC_id, UE[CC_id], ru_id);
NR_UE_MAC_INST_t *mac = get_mac_inst(inst);
init_nr_ue_phy_cpu_stats(&UE[CC_id]->phy_cpu_stats);
// set frame config to initial values from command line and assume that the SSB is centered on the grid
@@ -449,7 +389,7 @@ int main(int argc, char **argv)
get_nrUE_params()->ofdm_offset_divisor);
sl_ue_phy_init(UE[CC_id]);
}
init_openair0(UE[CC_id]);
nrue_init_openair0(UE[CC_id]);
}
}
@@ -467,6 +407,8 @@ int main(int argc, char **argv)
load_module_shlib("imscope_record", NULL, 0, PHY_vars_UE_g[0][0]);
}
nrue_ru_start();
for (int inst = 0; inst < NB_UE_INST; inst++) {
LOG_I(PHY,"Intializing UE Threads for instance %d ...\n", inst);
init_NR_UE_threads(PHY_vars_UE_g[inst][0]);
@@ -511,12 +453,7 @@ int main(int argc, char **argv)
}
}
for (int card = 0; card < MAX_CARDS; card++) {
if (openair0_dev[card].trx_get_stats_func)
openair0_dev[card].trx_get_stats_func(&openair0_dev[card]);
if (openair0_dev[card].trx_end_func)
openair0_dev[card].trx_end_func(&openair0_dev[card]);
}
nrue_ru_end();
free_nrLDPC_coding_interface(&nrLDPC_coding_interface);
+16
View File
@@ -342,6 +342,22 @@ typedef struct UE_NR_SCAN_INFO_s {
int32_t freq_offset_Hz[3][10];
} UE_NR_SCAN_INFO_t;
typedef struct {
unsigned int nb_tx;
unsigned int nb_rx;
unsigned int att_tx;
unsigned int att_rx;
int max_rxgain;
char *sdr_addrs;
char *tx_subdev;
char *rx_subdev;
clock_source_t clock_source;
clock_source_t time_source;
double tune_offset;
uint64_t if_frequency;
int if_freq_offset;
} nrUE_RU_params_t;
/// Top-level PHY Data Structure for UE
typedef struct PHY_VARS_NR_UE_s {
/// \brief Module ID indicator for this instance