From b23be658cc2efdd84f290164360871037fb38d70 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 13 Nov 2017 10:14:11 +0100 Subject: [PATCH 1/3] Added PDSCH decoder maximum bitrate (from DSP execution time) --- lib/examples/pdsch_ue.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index bf4414f08..681b75566 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -326,7 +326,8 @@ srslte_netsink_t net_sink, net_sink_signal; #define PRINT_LINE_ADVANCE_CURSOR() printf("\033[%dB", prev_nof_lines + 1) int main(int argc, char **argv) { - int ret; + struct timeval t[3]; + int ret; int decimate = 1; srslte_cell_t cell; int64_t sf_cnt; @@ -559,7 +560,7 @@ int main(int argc, char **argv) { // Variables for measurements uint32_t nframes=0; uint8_t ri = 0, pmi = 0; - float rsrp0=0.0, rsrp1=0.0, rsrq=0.0, noise=0.0, enodebrate = 0.0, uerate = 0.0, + float rsrp0=0.0, rsrp1=0.0, rsrq=0.0, noise=0.0, enodebrate = 0.0, uerate = 0.0, procrate = 0.0, sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS], cn = 0.0; bool decode_pdsch = false; @@ -655,6 +656,7 @@ int main(int argc, char **argv) { decode_pdsch = false; } } + gettimeofday(&t[1], NULL); if (decode_pdsch) { if(sfidx != 1 || prog_args.mbsfn_area_id < 0){ // Not an MBSFN subframe if (cell.nof_ports == 1) { @@ -690,6 +692,8 @@ int main(int argc, char **argv) { INFO("mbsfn PDU size is %d\n", n); } } + gettimeofday(&t[2], NULL); + get_time_interval(t); if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); } else if (n > 0) { @@ -723,16 +727,19 @@ int main(int argc, char **argv) { } - nof_trials++; - - + nof_trials++; + + uint32_t nof_bits = ((acks[0]?ue_dl.pdsch_cfg.grant.mcs[0].tbs:0) + (acks[1]?ue_dl.pdsch_cfg.grant.mcs[1].tbs:0)); rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1f); rsrp0 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 0), rsrp0, 0.05f); rsrp1 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 1), rsrp1, 0.05f); noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05f); - enodebrate = SRSLTE_VEC_EMA((ue_dl.pdsch_cfg.grant.mcs[0].tbs + ue_dl.pdsch_cfg.grant.mcs[1].tbs)/1000.0f, enodebrate, 0.05f); - uerate = SRSLTE_VEC_EMA(((acks[0]?ue_dl.pdsch_cfg.grant.mcs[0].tbs:0) + (acks[1]?ue_dl.pdsch_cfg.grant.mcs[1].tbs:0))/1000.0f, uerate, 0.01f); - + enodebrate = SRSLTE_VEC_EMA(nof_bits/1000.0f, enodebrate, 0.05f); + uerate = SRSLTE_VEC_EMA(nof_bits/1000.0f, uerate, 0.001f); + float elapsed = (float) t[0].tv_usec + t[0].tv_sec*1.0e+6f; + if (elapsed != 0.0f) { + procrate = SRSLTE_VEC_EMA(nof_bits/elapsed, procrate, 0.01f); + } nframes++; if (isnan(rsrq)) { @@ -769,7 +776,7 @@ int main(int argc, char **argv) { PRINT_LINE("nof codewords: %d", SRSLTE_RA_DL_GRANT_NOF_TB(&ue_dl.pdsch_cfg.grant)); PRINT_LINE(" CFO: %+5.2f kHz", srslte_ue_sync_get_cfo(&ue_sync) / 1000); PRINT_LINE(" SNR: %+5.1f dB | %+5.1f dB", 10 * log10(rsrp0 / noise), 10 * log10(rsrp1 / noise)); - PRINT_LINE(" Rb: %6.2f / %6.2f Mbps (net/maximum)", uerate, enodebrate); + PRINT_LINE(" Rb: %6.2f / %6.2f / %6.2f Mbps (net/maximum/processing)", uerate, enodebrate, procrate); PRINT_LINE(" PDCCH-Miss: %5.2f%%", 100 * (1 - (float) ue_dl.nof_detected / nof_trials)); PRINT_LINE(" PDSCH-BLER: %5.2f%%", (float) 100 * ue_dl.pdsch_pkt_errors / ue_dl.pdsch_pkts_total); if(prog_args.mbsfn_area_id > -1){ From ca07f0064dcf3d7cde67a8bfb1be722a9aeeac03 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 13 Nov 2017 10:47:02 +0100 Subject: [PATCH 2/3] Remove otw_format=sc12/sc16 from device args, also commas. --- lib/src/phy/rf/rf_uhd_imp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 29aec5b44..cfe8418b8 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -291,6 +291,13 @@ int rf_uhd_open(char *args, void **h) return rf_uhd_open_multi(args, h, 1); } +#define REMOVE_SUBSTRING_WITHCOMAS(S, TOREMOVE) \ + remove_substring(args, TOREMOVE ",");\ + remove_substring(args, TOREMOVE ", ");\ + remove_substring(args, "," TOREMOVE);\ + remove_substring(args, ", " TOREMOVE);\ + remove_substring(args, TOREMOVE); + static void remove_substring(char *s,const char *toremove) { while((s=strstr(s,toremove))) { @@ -336,11 +343,11 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) // Check external clock argument enum {DEFAULT, EXTERNAL, GPSDO} clock_src; if (strstr(args, "clock=external")) { - remove_substring(args, "clock=external"); + REMOVE_SUBSTRING_WITHCOMAS(args, "clock=external"); clock_src = EXTERNAL; } else if (strstr(args, "clock=gpsdo")) { printf("Using GPSDO clock\n"); - remove_substring(args, "clock=gpsdo"); + REMOVE_SUBSTRING_WITHCOMAS(args, "clock=gpsdo"); clock_src = GPSDO; } else { clock_src = DEFAULT; @@ -349,8 +356,10 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) // Set over the wire format char *otw_format = "sc16"; if (strstr(args, "otw_format=sc12")) { + REMOVE_SUBSTRING_WITHCOMAS(args, "otw_format=sc12"); otw_format = "sc12"; } else if (strstr(args, "otw_format=sc16")) { + REMOVE_SUBSTRING_WITHCOMAS(args, "otw_format=sc16"); /* Do nothing */ } else if (strstr(args, "otw_format=")) { fprintf(stderr, "Wrong over the wire format. Valid formats: sc12, sc16\n"); From 861d65b070454c532a95310f636937d335710035 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 13 Nov 2017 16:01:01 +0100 Subject: [PATCH 3/3] Added subdev RF arguments. It fixes #95 --- lib/src/phy/rf/rf_uhd_imp.c | 65 +++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index cfe8418b8..729d96e11 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -292,11 +292,11 @@ int rf_uhd_open(char *args, void **h) } #define REMOVE_SUBSTRING_WITHCOMAS(S, TOREMOVE) \ - remove_substring(args, TOREMOVE ",");\ - remove_substring(args, TOREMOVE ", ");\ - remove_substring(args, "," TOREMOVE);\ - remove_substring(args, ", " TOREMOVE);\ - remove_substring(args, TOREMOVE); + remove_substring(S, TOREMOVE ",");\ + remove_substring(S, TOREMOVE ", ");\ + remove_substring(S, "," TOREMOVE);\ + remove_substring(S, ", " TOREMOVE);\ + remove_substring(S, TOREMOVE) static void remove_substring(char *s,const char *toremove) { @@ -305,6 +305,17 @@ static void remove_substring(char *s,const char *toremove) } } +static void copy_subdev_string(char *dst, char *src) { + int n = 0; + size_t len = strlen(src); + /* Copy until end of string or comma */ + while (n < len && src != '\0' && src[n] != ',') { + dst[n] = src[n]; + n++; + } + dst[n] = '\0'; +} + int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) { if (h) { @@ -366,6 +377,26 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) return -1; } + // Set transmitter subdevice spec string + const char tx_subdev_arg[] = "tx_subdev_spec="; + char tx_subdev_str[64] = {0}; + char *tx_subdev_ptr = strstr(args, tx_subdev_arg); + if (tx_subdev_ptr) { + copy_subdev_string(tx_subdev_str, tx_subdev_ptr + strlen(tx_subdev_arg)); + remove_substring(args, tx_subdev_arg); + remove_substring(args, tx_subdev_str); + } + + // Set receiver subdevice spec string + const char rx_subdev_arg[] = "rx_subdev_spec="; + char rx_subdev_str[64] = {0}; + char *rx_subdev_ptr = strstr(args, rx_subdev_arg); + if (rx_subdev_ptr) { + copy_subdev_string(rx_subdev_str, rx_subdev_ptr + strlen(rx_subdev_arg)); + remove_substring(args, rx_subdev_arg); + remove_substring(args, rx_subdev_str); + } + /* If device type or name not given in args, choose a B200 */ if (args[0]=='\0') { if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { @@ -405,7 +436,29 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) fprintf(stderr, "Error opening UHD: code %d\n", error); return -1; } - + + /* Set transmitter subdev spec if specified */ + if (strlen(tx_subdev_str)) { + uhd_subdev_spec_handle subdev_spec_handle = {0}; + + printf("Setting tx_subdev_spec to '%s'\n", tx_subdev_str); + + uhd_subdev_spec_make(&subdev_spec_handle, tx_subdev_str); + uhd_usrp_set_tx_subdev_spec(handler->usrp, subdev_spec_handle, 0); + uhd_subdev_spec_free(&subdev_spec_handle); + } + + /* Set receiver subdev spec if specified */ + if (strlen(rx_subdev_str)) { + uhd_subdev_spec_handle subdev_spec_handle = {0}; + + printf("Setting rx_subdev_spec to '%s'\n", rx_subdev_str); + + uhd_subdev_spec_make(&subdev_spec_handle, rx_subdev_str); + uhd_usrp_set_rx_subdev_spec(handler->usrp, subdev_spec_handle, 0); + uhd_subdev_spec_free(&subdev_spec_handle); + } + if (!handler->devname) { char dev_str[1024]; uhd_usrp_get_mboard_name(handler->usrp, 0, dev_str, 1024);