From cedde4ad1ff3a37372ffbd8df821b8d6a7f870e1 Mon Sep 17 00:00:00 2001 From: laurent Date: Mon, 26 Dec 2016 21:19:26 +0100 Subject: [PATCH 01/13] realtime for UE --- common/utils/itti/assertions.h | 2 +- openair1/PHY/defs.h | 3 + openair2/COMMON/platform_types.h | 2 +- openair2/UTIL/LOG/log.h | 20 + targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 929 +++---- targets/RT/USER/lte-ue.c | 2385 +++++++----------- 6 files changed, 1295 insertions(+), 2046 deletions(-) diff --git a/common/utils/itti/assertions.h b/common/utils/itti/assertions.h index df8251d105..a411bd5397 100644 --- a/common/utils/itti/assertions.h +++ b/common/utils/itti/assertions.h @@ -65,7 +65,7 @@ _Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX " (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3) #define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \ -_Assert_(cOND, _Assert_Exit_, #vALUE1": %"PRIdMAX"\n"#vALUE2": %"PRIdMAX"\n"#vALUE3": %"PRIdMAX"\n"#vALUE4": %"PRIdMAX"\n\n", \ +_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \ (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4) #define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3) diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index daf560a736..9c72bc433e 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -371,6 +371,9 @@ typedef struct { pthread_mutex_t mutex_rxtx; /// scheduling parameters for RXn-TXnp4 thread struct sched_param sched_param_rxtx; + int sub_frame_start; + int sub_frame_step; + unsigned long long gotIQs; } UE_rxtx_proc_t; /// Context data structure for eNB subframe processing diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 327523f1d0..256ed45b5d 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -255,7 +255,7 @@ typedef struct protocol_ctxt_s { (Ctxt_Pp)->subframe = sUBfRAME; \ PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp) -#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %"PRIx16"]" +#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %" PRIx16 "]" #define PROTOCOL_CTXT_ARGS(CTXT_Pp) \ (CTXT_Pp)->frame, \ ((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \ diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 6a6569c1a5..171f74da41 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -53,6 +53,26 @@ extern "C" { #endif + extern double cpuf; + static inline unsigned long long rdtsc(void) { + unsigned long long a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; + } + static inline unsigned long long checkT(int timeout, char * file, int line) { + static unsigned long long __thread last=0; + unsigned long long cur=rdtsc(); + int microCycles=(int)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) + printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, + duration, timeout); + last=cur; + return cur; + } + +#define check(a) checkT(a,__FILE__,__LINE__) + /** @defgroup _LOG LOG Generator * @{*/ /* @}*/ diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 0161761d97..3185b97226 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -40,10 +40,12 @@ #include #include "UTIL/LOG/log_extern.h" #include "common_lib.h" +#include "assertions.h" + #ifdef __SSE4_1__ # include #endif - + #ifdef __AVX2__ # include #endif @@ -56,16 +58,14 @@ * @{ */ -/*! \brief USRP Configuration */ -typedef struct -{ +/*! \brief USRP Configuration */ +typedef struct { - // -------------------------------- - // variables for USRP configuration - // -------------------------------- - //! USRP device pointer - uhd::usrp::multi_usrp::sptr usrp; - //uhd::usrp::multi_usrp::sptr rx_usrp; + // -------------------------------- + // variables for USRP configuration + // -------------------------------- + //! USRP device pointer + uhd::usrp::multi_usrp::sptr usrp; //create a send streamer and a receive streamer //! USRP TX Stream @@ -78,141 +78,93 @@ typedef struct //! USRP RX Metadata uhd::rx_metadata_t rx_md; - //! USRP Timestamp Information - uhd::time_spec_t tm_spec; + //! Sampling rate + double sample_rate; - //setup variables and allocate buffer - //! USRP Metadata - uhd::async_metadata_t async_md; + //! TX forward samples. We use usrp_time_offset to get this value + int tx_forward_nsamps; //166 for 20Mhz - //! Sampling rate - double sample_rate; - - //! time offset between transmiter timestamp and receiver timestamp; - double tdiff; - - //! TX forward samples. We use usrp_time_offset to get this value - int tx_forward_nsamps; //166 for 20Mhz - - - // -------------------------------- - // Debug and output control - // -------------------------------- - //! Number of underflows - int num_underflows; - //! Number of overflows - int num_overflows; - - //! Number of sequential errors - int num_seq_errors; - //! tx count - int64_t tx_count; - //! rx count - int64_t rx_count; - //! timestamp of RX packet - openair0_timestamp rx_timestamp; + // -------------------------------- + // Debug and output control + // -------------------------------- + int num_underflows; + int num_overflows; + int num_seq_errors; + int64_t tx_count; + int64_t rx_count; + //! timestamp of RX packet + openair0_timestamp rx_timestamp; } usrp_state_t; + + /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target */ -static int trx_usrp_start(openair0_device *device) -{ - usrp_state_t *s = (usrp_state_t*)device->priv; +static int trx_usrp_start(openair0_device *device) { - // init recv and send streaming - uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); - cmd.stream_now = false; // start at constant delay - s->rx_stream->issue_stream_cmd(cmd); + usrp_state_t *s = (usrp_state_t*)device->priv; - s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); - s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; + // init recv and send streaming + uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); + cmd.stream_now = true; + s->rx_stream->issue_stream_cmd(cmd); + s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); + s->tx_md.has_time_spec = true; + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; - s->rx_count = 0; - s->tx_count = 0; - s->rx_timestamp = 0; - - return 0; + s->rx_count = 0; + s->tx_count = 0; + s->rx_timestamp = 0; + return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ -static void trx_usrp_end(openair0_device *device) -{ - usrp_state_t *s = (usrp_state_t*)device->priv; +static void trx_usrp_end(openair0_device *device) { + usrp_state_t *s = (usrp_state_t*)device->priv; - s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + //send a mini EOB packet + s->tx_md.end_of_burst = true; + s->tx_stream->send("", 0, s->tx_md); + s->tx_md.end_of_burst = false; - //send a mini EOB packet - s->tx_md.end_of_burst = true; - s->tx_stream->send("", 0, s->tx_md); - s->tx_md.end_of_burst = false; - } /*! \brief Called to send samples to the USRP RF target @param device pointer to the device structure specific to the RF hardware target - @param timestamp The timestamp at whicch the first sample MUST be sent + @param timestamp The timestamp at whicch the first sample MUST be sent @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas @param flags flags must be set to TRUE if timestamp parameter needs to be applied -*/ -static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) -{ - static long long int loop=0; - static long time_min=0, time_max=0, time_avg=0; - struct timespec tp_start, tp_end; - long time_diff; - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start); +*/ +static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + int ret=0; + usrp_state_t *s = (usrp_state_t*)device->priv; - int ret=0, ret_i=0; - usrp_state_t *s = (usrp_state_t*)device->priv; + s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + s->tx_md.has_time_spec = flags; - s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + if (cc>1) { + std::vector buff_ptrs; + for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); + } else + ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); - - if(flags) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; - - if (cc>1) { - std::vector buff_ptrs; - for (int i=0;itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); - } - else - ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); + s->tx_md.start_of_burst = false; - s->tx_md.start_of_burst = false; + if (ret != nsamps) + LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); - if (ret != nsamps) { - printf("[xmit] tx samples %d != %d\n",ret,nsamps); - } - - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_end); - time_diff = (tp_end.tv_sec - tp_start.tv_sec) *1E09 + (tp_end.tv_nsec - tp_start.tv_nsec); - if (time_min==0 ||loop==1 || time_min > time_diff) - time_min=time_diff; - if (time_max==0 ||loop==1 || time_max < time_diff) - time_max=time_diff; - if (time_avg ==0 ||loop==1) - time_avg= time_diff; - else - time_avg=(time_diff+time_avg) /2.0; - - /* //prints statics of uhd every 10 seconds - if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0) - LOG_I(HW,"usrp_write: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg); - */ - loop++; - return ret; + return ret; } /*! \brief Receive samples from hardware. @@ -226,45 +178,42 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, * \param antenna_id Index of antenna for which to receive samples * \returns the number of sample read */ -static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) -{ - static long long int loop=0; - static long time_min=0, time_max=0, time_avg=0; - struct timespec tp_start, tp_end; - long time_diff; - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start); - usrp_state_t *s = (usrp_state_t*)device->priv; - int samples_received=0,i,j; - int nsamps2; // aligned to upper 32 or 16 byte boundary +static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + usrp_state_t *s = (usrp_state_t*)device->priv; + int samples_received=0,i,j; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+7)>>3; + __m256i buff_tmp[2][nsamps2]; #else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + __m128i buff_tmp[2][nsamps2]; #endif #elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tmp[2][nsamps2]; #endif - - if (device->type == USRP_B200_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; - - for (int i=0;irx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff_tmp[0], nsamps, s->rx_md); - } - - // bring RX data into 12 LSBs for softmodem RX - for (int i=0;itype == USRP_B200_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; + for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received=0; + while (samples_received != nsamps) { + samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + nsamps-samples_received, s->rx_md); + if (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE) + break; + } + } + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; irx_stream->recv(buff[0], nsamps, s->rx_md); } } + if (samples_received < nsamps) + LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); - if (samples_received < nsamps) { - printf("[recv] received %d samples out of %d\n",samples_received,nsamps); - - } + if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) + LOG_E(PHY,s->rx_md.to_pp_string(true).c_str()); - //handle the error code - switch(s->rx_md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_NONE: - break; - case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: - printf("[recv] USRP RX OVERFLOW!\n"); - s->num_overflows++; - break; - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - printf("[recv] USRP RX TIMEOUT!\n"); - break; - default: - printf("[recv] Unexpected error on RX, Error code: 0x%x\n",s->rx_md.error_code); - break; - } - s->rx_count += nsamps; - s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); - *ptimestamp = s->rx_timestamp; - - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_end); - time_diff = (tp_end.tv_sec - tp_start.tv_sec) *1E09 + (tp_end.tv_nsec - tp_start.tv_nsec); - if (time_min==0 ||loop==1 || time_min > time_diff) - time_min=time_diff; - if (time_max==0 ||loop==1 || time_max < time_diff) - time_max=time_diff; - if (time_avg ==0 ||loop==1) - time_avg= time_diff; - else - time_avg=(time_diff+time_avg) /2.0; - /* - //prints statics of uhd every 10 seconds - if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0) - LOG_I(HW,"usrp_read: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg); - - loop++;*/ - return samples_received; + s->rx_count += nsamps; + s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); + *ptimestamp = s->rx_timestamp; +#ifdef DEBUG_USRP + check(50); +#endif + return samples_received; } -/*! \brief Get current timestamp of USRP - * \param device the hardware to use -*/ -openair0_timestamp get_usrp_time(openair0_device *device) -{ - - usrp_state_t *s = (usrp_state_t*)device->priv; - - return s->usrp->get_time_now().to_ticks(s->sample_rate); -} - /*! \brief Compares two variables within precision * \param a first variable * \param b second variable */ -static bool is_equal(double a, double b) -{ +static bool is_equal(double a, double b) { return std::fabs(a-b) < std::numeric_limits::epsilon(); } @@ -360,59 +268,60 @@ static bool is_equal(double a, double b) */ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) { - usrp_state_t *s = (usrp_state_t*)device->priv; + usrp_state_t *s = (usrp_state_t*)device->priv; - printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[0]); + LOG_I(PHY,"Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); + s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[0]); + + return(0); - return(0); - } -/*! \brief Set RX frequencies +/*! \brief Set RX frequencies * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg) { - usrp_state_t *s = (usrp_state_t*)device->priv; - static int first_call=1; - static double rf_freq,diff; + usrp_state_t *s = (usrp_state_t*)device->priv; + static int first_call=1; + static double rf_freq,diff; - uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); + uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); - rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; - rf_freq=openair0_cfg[0].rx_freq[0]; - s->usrp->set_rx_freq(rx_tune_req); + rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; + rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; + rf_freq=openair0_cfg[0].rx_freq[0]; + s->usrp->set_rx_freq(rx_tune_req); + + return(0); - return(0); - } /*! \brief Set Gains (TX/RX) * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ -int trx_usrp_set_gains(openair0_device* device, - openair0_config_t *openair0_cfg) { +int trx_usrp_set_gains(openair0_device* device, + openair0_config_t *openair0_cfg) { - usrp_state_t *s = (usrp_state_t*)device->priv; + usrp_state_t *s = (usrp_state_t*)device->priv; - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[0]); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { - - printf("RX Gain 0 too high, reduce by %f dB\n", - openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); - printf("Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0],openair0_cfg[0].rx_gain[0],gain_range.stop()); + s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[0]); + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); + // limit to maximum gain + if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { + LOG_E(PHY,"RX Gain 0 too high, reduce by %f dB\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); + exit(-1); + } + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); + LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], + openair0_cfg[0].rx_gain[0],gain_range.stop()); return(0); } @@ -426,376 +335,310 @@ int trx_usrp_stop(openair0_device* device) { /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210[] = { - {3500000000.0,44.0}, - {2660000000.0,49.0}, - {2300000000.0,50.0}, - {1880000000.0,53.0}, - {816000000.0,58.0}, - {-1,0}}; + {3500000000.0,44.0}, + {2660000000.0,49.0}, + {2300000000.0,50.0}, + {1880000000.0,53.0}, + {816000000.0,58.0}, + {-1,0} +}; /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210_38[] = { - {3500000000.0,44.0}, - {2660000000.0,49.8}, - {2300000000.0,51.0}, - {1880000000.0,53.0}, - {816000000.0,57.0}, - {-1,0}}; + {3500000000.0,44.0}, + {2660000000.0,49.8}, + {2300000000.0,51.0}, + {1880000000.0,53.0}, + {816000000.0,57.0}, + {-1,0} +}; /*! \brief USRPx310 RX calibration table */ rx_gain_calib_table_t calib_table_x310[] = { - {3500000000.0,77.0}, - {2660000000.0,81.0}, - {2300000000.0,81.0}, - {1880000000.0,82.0}, - {816000000.0,85.0}, - {-1,0}}; + {3500000000.0,77.0}, + {2660000000.0,81.0}, + {2300000000.0,81.0}, + {1880000000.0,82.0}, + {816000000.0,85.0}, + {-1,0} +}; -/*! \brief Set RX gain offset +/*! \brief Set RX gain offset * \param openair0_cfg RF frontend parameters set by application * \param chain_index RF chain to apply settings to - * \returns 0 in success + * \returns 0 in success */ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { - int i=0; - // loop through calibration table to find best adjustment factor for RX frequency - double min_diff = 6e9,diff,gain_adj=0.0; - if (bw_gain_adjust==1) { - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - break; - case 23040000: - gain_adj=1.25; - break; - case 15360000: - gain_adj=3.0; - break; - case 7680000: - gain_adj=6.0; - break; - case 3840000: - gain_adj=9.0; - break; - case 1920000: - gain_adj=12.0; - break; - default: - printf("unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); - exit(-1); - break; + int i=0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9,diff,gain_adj=0.0; + if (bw_gain_adjust==1) { + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + break; + case 23040000: + gain_adj=1.25; + break; + case 15360000: + gain_adj=3.0; + break; + case 7680000: + gain_adj=6.0; + break; + case 3840000: + gain_adj=9.0; + break; + case 1920000: + gain_adj=12.0; + break; + default: + LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); + exit(-1); + break; + } } - } - while (openair0_cfg->rx_gain_calib_table[i].freq>0) { - diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); - printf("cal %d: freq %f, offset %f, diff %f\n", - i, - openair0_cfg->rx_gain_calib_table[i].freq, + while (openair0_cfg->rx_gain_calib_table[i].freq>0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, openair0_cfg->rx_gain_calib_table[i].offset,diff); if (min_diff > diff) { min_diff = diff; openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; } i++; - } - + } } -/*! \brief print the USRP statistics +/*! \brief print the USRP statistics * \param device the hardware to use * \returns 0 on success */ int trx_usrp_get_stats(openair0_device* device) { - - return(0); - + return(0); } -/*! \brief Reset the USRP statistics -* \param device the hardware to use -* \returns 0 on success -*/ +/*! \brief Reset the USRP statistics + * \param device the hardware to use + * \returns 0 on success + */ int trx_usrp_reset_stats(openair0_device* device) { - - return(0); - + return(0); } - - extern "C" { -/*! \brief Initialize Openair USRP target. It returns 0 if OK -* \param device the hardware to use -* \param openair0_cfg RF frontend parameters set by application -*/ - int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { - - uhd::set_thread_priority_safe(1.0); - usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t)); - memset(s, 0, sizeof(usrp_state_t)); - - // Initialize USRP device + /*! \brief Initialize Openair USRP target. It returns 0 if OK + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + */ + int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { + //uhd::set_thread_priority_safe(1.0); + usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); + // Initialize USRP device + device->openair0_cfg = openair0_cfg; - device->openair0_cfg = openair0_cfg; + std::string args = "type=b200"; + uhd::device_addrs_t device_adds = uhd::device::find(args); - std::string args = "type=b200"; + int vers=0,subvers=0,subsubvers=0; + int bw_gain_adjust=0; + sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); + LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", + uhd::get_version_string().c_str(),vers,subvers,subsubvers); - uhd::device_addrs_t device_adds = uhd::device::find(args); - size_t i; - - int vers=0,subvers=0,subsubvers=0; - int bw_gain_adjust=0; + if(device_adds.size() == 0) { + double usrp_master_clock = 184.32e6; + std::string args = "type=x300"; - sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); - - printf("Checking for USRPs : UHD %s (%d.%d.%d)\n",uhd::get_version_string().c_str(),vers,subvers,subsubvers); - - if(device_adds.size() == 0) - { - double usrp_master_clock = 184.32e6; - - std::string args = "type=x300"; - // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - -// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - - uhd::device_addrs_t device_adds = uhd::device::find(args); - if(device_adds.size() == 0) - { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; + uhd::device_addrs_t device_adds = uhd::device::find(args); - } + if(device_adds.size() == 0) { + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } + LOG_I(PHY,"Found USRP X300\n"); + s->usrp = uhd::usrp::multi_usrp::make(args); + // lock mboard clocks + s->usrp->set_clock_source("internal"); + //Setting device type to USRP X300/X310 + device->type=USRP_X300_DEV; - printf("Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); + // this is not working yet, master clock has to be set via constructor + // set master clock rate and sample rate for tx & rx for streaming + //s->usrp->set_master_clock_rate(usrp_master_clock); - // lock mboard clocks - s->usrp->set_clock_source("internal"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + // from usrp_time_offset + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + case 7680000: + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + case 1920000: + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 1.25e6; + openair0_cfg[0].rx_bw = 1.25e6; + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + } else { + LOG_I(PHY,"Found USRP B200\n"); + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + s->usrp = uhd::usrp::multi_usrp::make(args); + device->type = USRP_B200_DEV; + if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210; + bw_gain_adjust=0; + } else { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + } - } else { - printf("Found USRP B200"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + s->usrp->set_master_clock_rate(30.72e6); + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 23040000: + s->usrp->set_master_clock_rate(23.04e6); //to be checked + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + s->usrp->set_master_clock_rate(30.72e06); + openair0_cfg[0].tx_sample_advance = 103; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 7680000: + s->usrp->set_master_clock_rate(30.72e6); + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 1920000: + s->usrp->set_master_clock_rate(30.72e6); + openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + openair0_cfg[0].iq_txshift = 4;//shift + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // do not explicitly set the clock to "internal", because this will disable the gpsdo - // // lock mboard clocks - // s->usrp->set_clock_source("internal"); - // set master clock rate and sample rate for tx & rx for streaming + for(int i=0; iusrp->get_rx_num_channels(); i++) { + if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); + set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); - device->type = USRP_B200_DEV; + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); + // limit to maximum gain + AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(), + "RX Gain too high, lower by %f dB\n", + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); + LOG_I(PHY,"RX Gain %d %f (%f) => %f (max %f)\n",i, + openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); + } + } + for(int i=0; iusrp->get_tx_num_channels(); i++) { + if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); + s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); + } + } + //s->usrp->set_clock_source("external"); + //s->usrp->set_time_source("external"); - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - } - else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - } + // display USRP settings + LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } + // create tx & rx streamer + uhd::stream_args_t stream_args_rx("sc16", "sc16"); + int samples=openair0_cfg[0].sample_rate; + //while ( samples > s->rx_stream->get_max_num_samps()) + samples/=24000; + stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); + LOG_I(PHY,"rx_max_num_samps %u\n",s->rx_stream->get_max_num_samps()); - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - //printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); + uhd::stream_args_t stream_args_tx("sc16", "sc16"); + for (int i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] > gain_range.stop()) { - - printf("RX Gain %lu too high, lower by %f dB\n",i,openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); - printf("RX Gain %lu %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); - } - } - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - //printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); - } - } + /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ + for(int i=0; iusrp->get_tx_num_channels() && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); + for(int i=0; iusrp->get_rx_num_channels() && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - // display USRP settings - std::cout << boost::format("Actual master clock: %fMHz...") % (s->usrp->get_master_clock_rate()/1e6) << std::endl; - - sleep(1); + s->usrp->set_time_now(uhd::time_spec_t(0.0)); - // create tx & rx streamer - uhd::stream_args_t stream_args_rx("sc16", "sc16"); - //stream_args_rx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].rx_num_channels*openair0_cfg[0].samples_per_packet)); - for (i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - std::cout << boost::format("rx_max_num_samps %u") % (s->rx_stream->get_max_num_samps()) << std::endl; - //openair0_cfg[0].samples_per_packet = s->rx_stream->get_max_num_samps(); + for (int i=0; iusrp->get_rx_rate(i)/1e6); + LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); + LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); + LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); + LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); + } - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - //stream_args_tx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].tx_num_channels*openair0_cfg[0].samples_per_packet)); - for (i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - std::cout << boost::format("tx_max_num_samps %u") % (s->tx_stream->get_max_num_samps()) << std::endl; + for (int i=0; iusrp->get_tx_rate(i)/1e6); + LOG_I(PHY," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); + LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); + LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); + LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); + } + LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); - /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - } - } - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - } - } - - s->usrp->set_time_now(uhd::time_spec_t(0.0)); - - - for (i=0;iusrp->get_rx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX frequency: %fGHz...") % (s->usrp->get_rx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual RX gain: %f...") % (s->usrp->get_rx_gain(i)) << std::endl; - std::cout << boost::format("Actual RX bandwidth: %fM...") % (s->usrp->get_rx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX antenna: %s...") % (s->usrp->get_rx_antenna(i)) << std::endl; - } - } - - for (i=0;iusrp->get_tx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX frequency: %fGHz...") % (s->usrp->get_tx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual TX gain: %f...") % (s->usrp->get_tx_gain(i)) << std::endl; - std::cout << boost::format("Actual TX bandwidth: %fM...") % (s->usrp->get_tx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX antenna: %s...") % (s->usrp->get_tx_antenna(i)) << std::endl; - } - } - - std::cout << boost::format("Device timestamp: %f...") % (s->usrp->get_time_now().get_real_secs()) << std::endl; - - device->priv = s; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; + device->priv = s; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; device->trx_get_stats_func = trx_usrp_get_stats; device->trx_reset_stats_func = trx_usrp_reset_stats; device->trx_end_func = trx_usrp_end; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5ab6b7cddf..6e588f7f3c 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -75,15 +75,113 @@ #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" + +#define DEBUG_REALTIME 1 +#if DEBUG_REALTIME + +typedef struct latency_stat { + uint64_t counter; + uint64_t stat1100; + uint64_t stat1200; + uint64_t stat1500; + uint64_t stat2000; + uint64_t stat3000; +} latency_stat_t; + +static inline void saif_meas(int frame_rx) { + static latency_stat_t __thread latency_stat; + static struct timespec __thread last= {0}; + struct timespec now; + clock_gettime(CLOCK_MONOTONIC_RAW, &now); + if ( last.tv_sec ) { + uint64_t diffTime = ((uint64_t)now.tv_sec *1000 *1000 *1000 + now.tv_nsec) - + ((uint64_t)last.tv_sec *1000 *1000 *1000 + last.tv_nsec); + diffTime/=1000; + latency_stat.counter++; + if ( diffTime >= 1100 ) { + if (diffTime < 1200 ) + latency_stat.stat1100++; + else if ( diffTime < 1500 ) + latency_stat.stat1200++; + else if ( diffTime < 2000 ) + latency_stat.stat1500++; + else if ( diffTime < 3000 ) + latency_stat.stat2000++; + else + latency_stat.stat3000++; + } + if ( diffTime>=1100 || latency_stat.counter%20000==0 ) { + time_t current=time(NULL); + LOG_W(HW, + "%.2f delay=%llu Period stats %2.6f%% below 100µs\ncumul of events: 1100=%ld 1200=%ld 1500=%ld 2000=%ld >3000=%ld - (frame_rx=%d) - %s", + now.tv_sec+(double)now.tv_nsec/1e9, + diffTime, + (latency_stat.counter-latency_stat.stat1100-latency_stat.stat1200- + latency_stat.stat1500-latency_stat.stat2000-latency_stat.stat3000)/ + (float)latency_stat.counter *100, + latency_stat.stat1100, latency_stat.stat1200, + latency_stat.stat1500, latency_stat.stat2000, + latency_stat.stat3000, + frame_rx, ctime(¤t)); + fflush(stdout); + } + + } + last=now; +} + +typedef struct m { + unsigned long long iterations; + unsigned long long sum; + unsigned long long maxArray[11]; +} Meas; + + +void printMeas(char * txt, Meas *M, int period) { + if (M->iterations%period == 0 ) { + char txt2[512]; + sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", + txt, M->sum/M->iterations,M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], + M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); + LOG_W(PHY,txt2); + } +} + +int cmpint(const void* a, const void* b) { + unsigned long long* aa=(unsigned long long*)a; + unsigned long long* bb=(unsigned long long*)b; + return (int)(*aa-*bb); +} + +void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { + unsigned long long end=rdtsc(); + long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); + printMeas(txt,M,period); +} + +#else +#define check(a) do {} while (0) +#define saif_meas(a) do {} while (0) +#define update_max_times(a,b) do {} while (0) +#define print_meas(a,b) do {} while (0) +#endif +/* End of Changed by SYRTEM */ + #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL typedef enum { - pss=0, - pbch=1, - si=2 + pss=0, + pbch=1, + si=2 } sync_mode_t; + void init_UE_threads(int nb_inst); void *UE_thread(void *arg); void init_UE(int nb_inst); @@ -92,7 +190,6 @@ extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; - extern openair0_config_t openair0_cfg[MAX_CARDS]; extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -114,96 +211,122 @@ extern void exit_fun(const char* s); #define MHz (1000 * KHz) typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; } eutra_band_t; typedef struct band_info_s { - int nbands; - eutra_band_t band_info[100]; + int nbands; + eutra_band_t band_info[100]; } band_info_t; band_info_t bands_to_scan; static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, }; pthread_t main_ue_thread; pthread_attr_t attr_UE_thread; struct sched_param sched_param_UE_thread; +void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { + +#ifdef DEADLINE_SCHEDULER + if (sched_runtime!=0) { + struct sched_attr attr= {0}; + attr.size = sizeof(attr); + // This creates a .5 ms reservation + attr.sched_policy = SCHED_DEADLINE; + attr.sched_runtime = sched_runtime; + attr.sched_deadline = sched_deadline; + attr.sched_period = 0; + AssertFatal(sched_setattr(0, &attr, 0) == 0, + "[SCHED] main eNB thread: sched_setattr failed %s \n",perror(errno)); + LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", + (unsigned long)gettid(), sched_getcpu()); + } + +#else + if (cpuset!=NULL) + AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); + struct sched_param sp; + sp.sched_priority = sched_fifo; + AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, + "Can't set thread priority, Are you root?\n"); +#endif + + // Lock memory from swapping. This is a process wide call (not constraint to this thread). + mlockall(MCL_CURRENT | MCL_FUTURE); + pthread_setname_np( pthread_self(), name ); + + // LTS: this sync stuff should be wrong + printf("waiting for sync (%s)\n",name); + pthread_mutex_lock(&sync_mutex); + printf("Locked sync_mutex, waiting (%s)\n",name); + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + pthread_mutex_unlock(&sync_mutex); + printf("starting %s\n",name); +} + void init_UE(int nb_inst) { - int error_code; - int inst; - PHY_VARS_UE *UE; - int ret; + PHY_VARS_UE *UE; - for (inst=0;instrfdevice), &openair0_cfg[0]); - if (ret !=0){ - exit_fun("Error loading device library"); + AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); + + UE->rfdevice.host_type = BBU_HOST; + // UE->rfdevice.type = NONE_DEV; + AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL), ""); + pthread_setname_np( UE->proc.pthread_ue, "main UE" ); } - UE->rfdevice.host_type = BBU_HOST; - // UE->rfdevice.type = NONE_DEV; - error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL); - - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); - return; - } else { - LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); - pthread_setname_np( UE->proc.pthread_ue, "main UE" ); - } - } - printf("UE threads created\n"); + printf("UE threads created\n"); #ifdef USE_MME - - while (start_UE == 0) { - sleep(1); - } - + while (start_UE == 0) { + sleep(1); + } #endif - + } /*! @@ -212,388 +335,374 @@ void init_UE(int nb_inst) { * \param arg is a pointer to a \ref PHY_VARS_UE structure. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *UE_thread_synch(void *arg) -{ - static int UE_thread_synch_retval; - int i, hw_slot_offset; - PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; - int current_band = 0; - int current_offset = 0; - sync_mode_t sync_mode = pbch; - int CC_id = UE->CC_id; - int ind; - int found; - int freq_offset=0; +static void *UE_thread_synch(void *arg) { + static int __thread UE_thread_synch_retval; + int i, hw_slot_offset; + PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; + int current_band = 0; + int current_offset = 0; + sync_mode_t sync_mode = pbch; + int CC_id = UE->CC_id; + int ind; + int found; + int freq_offset=0; - UE->is_synchronized = 0; - printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); - printf("waiting for sync (UE_thread_synch) \n"); + UE->is_synchronized = 0; + printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); + printf("waiting for sync (UE_thread_synch) \n"); #ifndef DEADLINE_SCHEDULER - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; + int policy, s, j; + struct sched_param sparam; + char cpu_affinity[1024]; + cpu_set_t cpuset; - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ - CPU_ZERO(&cpuset); + /* Set affinity mask to include CPUs 1 to MAX_CPUS */ + /* CPU 0 is reserved for UHD threads */ + CPU_ZERO(&cpuset); - #ifdef CPU_AFFINITY - if (get_nprocs() >2) - { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); +#ifdef CPU_AFFINITY + if (get_nprocs() >2) { + for (j = 1; j < get_nprocs(); j++) + CPU_SET(j, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } } - } - #endif +#endif - /* Check the actual affinity mask assigned to the thread */ + /* Check the actual affinity mask assigned to the thread */ - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_getaffinity_np"); + exit_fun("Error getting processor affinity "); + } + memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + for (j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET(j, &cpuset)) { + char temp[1024]; + sprintf(temp, " CPU_%d ", j); + strcat(cpu_affinity, temp); + } - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) - { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) - { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); + memset(&sparam, 0 , sizeof (sparam)); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; + policy = SCHED_FIFO ; - } + s = pthread_setschedparam(pthread_self(), policy, &sparam); + if (s != 0) { + perror("pthread_setschedparam : "); + exit_fun("Error setting thread priority"); + } + s = pthread_getschedparam(pthread_self(), &policy, &sparam); + if (s != 0) { + perror("pthread_getschedparam : "); + exit_fun("Error getting thread priority"); - LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); + } + + LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), + (policy == SCHED_FIFO) ? "SCHED_FIFO" : + (policy == SCHED_RR) ? "SCHED_RR" : + (policy == SCHED_OTHER) ? "SCHED_OTHER" : + "???", + (int) sparam.sched_priority, cpu_affinity); #endif + printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); + ind = 0; + found = 0; + if (UE->UE_scan == 0) { + do { + current_band = eutra_bands[ind].band; + printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); - printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); - ind = 0; - found = 0; + if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) { + for (i=0; i<4; i++) + uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; + found = 1; + break; + } - if (UE->UE_scan == 0) { - do { - current_band = eutra_bands[ind].band; - printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); + ind++; + } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) { - for (i=0; i<4; i++) - uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; - - found = 1; - break; - } - - ind++; - } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - - if (found == 0) { - exit_fun("Can't find EUTRA band for frequency"); - return &UE_thread_synch_retval; - } + if (found == 0) { + exit_fun("Can't find EUTRA band for frequency"); + return &UE_thread_synch_retval; + } - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels); + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels); - for (i=0;irf_map.card].rx_num_channels;i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - if (uplink_frequency_offset[CC_id][i] != 0) // - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; - else //FDD - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; - } + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + if (uplink_frequency_offset[CC_id][i] != 0) // + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; + else //FDD + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + } - sync_mode = pbch; + sync_mode = pbch; - } else if (UE->UE_scan == 1) { - current_band=0; - - for (i=0; irf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; - - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - } - } - - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_sync_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); - - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } - - while (oai_exit==0) { - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } - - - while (UE->proc.instance_cnt_synch < 0) { - // the thread waits here most of the time - pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); - } - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_synch_retval; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 ); - - switch (sync_mode) { - case pss: - LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - current_offset += 20000000; // increase by 20 MHz - - if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { - current_band++; - current_offset=0; - } - - if (current_band==bands_to_scan.nbands) { + } else if (UE->UE_scan == 1) { current_band=0; + + for (i=0; irf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; + + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + } + } + + + pthread_mutex_lock(&sync_mutex); + printf("Locked sync_mutex, waiting (UE_sync_thread)\n"); + + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + + pthread_mutex_unlock(&sync_mutex); + printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); + + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); oai_exit=1; - } - - for (i=0; irf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; - - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - if (UE->UE_scan_carrier) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - - } - - break; - - case pbch: - - LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - if (initial_sync( UE, UE->mode ) == 0) { - - hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; - LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", - hw_slot_offset, - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, - UE->UE_scan_carrier ); - - if (UE->UE_scan_carrier == 1) { - - UE->UE_scan_carrier = 0; - // rerun with new cell parameters and frequency-offset - for (i=0;irf_map.card].rx_num_channels;i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; - downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; - freq_offset=0; - } - - // reconfigure for potentially different bandwidth - switch(UE->frame_parms.N_RB_DL) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; - // openair0_cfg[0].rx_gain[0] -= 0; - break; - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); - UE->rfdevice.trx_stop_func(&UE->rfdevice); - sleep(1); - init_frame_parms(&UE->frame_parms,1); - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } - } - else { - UE->is_synchronized = 1; - - if( UE->mode == rx_dump_frame ){ - FILE *fd; - if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present - if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - else { - LOG_E(PHY,"Cannot open file for writing\n"); - exit(0); - } - } - else { - UE->is_synchronized = 0; - } - } - } - } else { - // initial sync failed - // calculate new offset and try again - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) { - freq_offset += 100; - freq_offset *= -1; - } else { - freq_offset *= -1; - } - - if (abs(freq_offset) > 7500) { - LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); - FILE *fd; - if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - mac_xface->macphy_exit("No cell synchronization found, abandoning"); - return &UE_thread_synch_retval; // not reached - } - } - else { - - } - LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); - - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - - if (UE->UE_scan_carrier==1) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - - }// initial_sync=0 - - break; - - case si: - default: - break; } + while (oai_exit==0) { - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); + exit_fun("noting to add"); + return &UE_thread_synch_retval; + } - // indicate readiness - UE->proc.instance_cnt_synch--; - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + while (UE->proc.instance_cnt_synch < 0) { + // the thread waits here most of the time + pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); + } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); - } // while !oai_exit + if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" ); + exit_fun("nothing to add"); + return &UE_thread_synch_retval; + } - return &UE_thread_synch_retval; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 ); + + switch (sync_mode) { + case pss: + LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + current_offset += 20000000; // increase by 20 MHz + + if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { + current_band++; + current_offset=0; + } + + if (current_band==bands_to_scan.nbands) { + current_band=0; + oai_exit=1; + } + + for (i=0; irf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + if (UE->UE_scan_carrier) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + + } + + break; + + case pbch: + + LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + if (initial_sync( UE, UE->mode ) == 0) { + + hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; + LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", + hw_slot_offset, + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, + UE->UE_scan_carrier ); + + if (UE->UE_scan_carrier == 1) { + + UE->UE_scan_carrier = 0; + // rerun with new cell parameters and frequency-offset + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; + freq_offset=0; + } + + // reconfigure for potentially different bandwidth + switch(UE->frame_parms.N_RB_DL) { + case 6: + openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; + openair0_cfg[UE->rf_map.card].rx_bw =.96e6; + openair0_cfg[UE->rf_map.card].tx_bw =.96e6; + // openair0_cfg[0].rx_gain[0] -= 12; + break; + case 25: + openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; + openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; + openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; + // openair0_cfg[0].rx_gain[0] -= 6; + break; + case 50: + openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; + openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; + openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; + // openair0_cfg[0].rx_gain[0] -= 3; + break; + case 100: + openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; + openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; + openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; + // openair0_cfg[0].rx_gain[0] -= 0; + break; + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + UE->rfdevice.trx_stop_func(&UE->rfdevice); + sleep(1); + init_frame_parms(&UE->frame_parms,1); + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + } + } else { + UE->is_synchronized = 1; + + if( UE->mode == rx_dump_frame ) { + FILE *fd; + if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } else { + LOG_E(PHY,"Cannot open file for writing\n"); + exit(0); + } + } else { + UE->is_synchronized = 0; + } + } + } + } else { + // initial sync failed + // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) { + freq_offset += 100; + freq_offset *= -1; + } else { + freq_offset *= -1; + } + + if (abs(freq_offset) > 7500) { + LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); + FILE *fd; + if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } + mac_xface->macphy_exit("No cell synchronization found, abandoning"); + return &UE_thread_synch_retval; // not reached + } + } else { + + } + LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; + + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + if (UE->UE_scan_carrier==1) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + + }// initial_sync=0 + + break; + + case si: + default: + break; + } + + + if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" ); + exit_fun("noting to add"); + return &UE_thread_synch_retval; + } + + // indicate readiness + UE->proc.instance_cnt_synch--; + + if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" ); + exit_fun("noting to add"); + return &UE_thread_synch_retval; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); + } // while !oai_exit + + return &UE_thread_synch_retval; } @@ -601,259 +710,116 @@ static void *UE_thread_synch(void *arg) /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. * This thread performs the phy_procedures_UE_RX() on every received slot. - * then, if TX is enabled it performs TX for n+4. + * then, if TX is enabled it performs TX for n+4. * \param arg is a pointer to a \ref PHY_VARS_UE structure. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *UE_thread_rxn_txnp4(void *arg) -{ - static int UE_thread_rxtx_retval; - UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; - int ret; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; - proc->instance_cnt_rxtx=-1; +static void *UE_thread_rxn_txnp4(void *arg) { + static __thread int UE_thread_rxtx_retval; + UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; + int ret; + PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; + + static long long __thread instance_cnt_rxtx=-1; + proc->subframe_rx=proc->sub_frame_start; + + char threadName[256]= {0}; + sprintf(threadName,"UE_thread_rxn_txnp4_%d",proc->sub_frame_start); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(proc->sub_frame_start+1, &cpuset); + init_thread(900000,1000000 , 40, &cpuset,//sched_get_priority_max(SCHED_FIFO)-1, + threadName); + + while (!oai_exit) { + // Wait Rx data to process are available + AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + if ( (instance_cnt_rxtx+proc->sub_frame_step)%10 != proc->subframe_rx && instance_cnt_rxtx!=-1 ) + LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %d, got %d\n", + (instance_cnt_rxtx+proc->sub_frame_step)%10, proc->subframe_rx); + instance_cnt_rxtx=proc->subframe_rx; + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + + static __thread Meas t2= {0}, t3= {0}; + unsigned long long current=rdtsc(); + updateTimes(proc->gotIQs, &t2, 10000, "saif: Delay to wake up UE_Thread_Rx (case 2)"); + + // Process Rx data for one sub-frame + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadName, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadName, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } + phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); + } + + if (UE->mac_enabled==1) { + + ret = mac_xface->ue_scheduler(UE->Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + if ( ret != CONNECTION_OK) { + char *txt; + switch (ret) { + case CONNECTION_LOST: + txt="RRC Connection lost, returning to PRACH"; + break; + case PHY_RESYNCH: + txt="RRC Connection lost, trying to resynch"; + break; + case RESYNCH: + txt="return to PRACH and perform a contention-free access"; + break; + default: + txt="UNKNOWN RETURN CODE"; + }; + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); + } + } + // Prepare the future Tx data + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) + phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); -#ifdef DEADLINE_SCHEDULER + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && + (UE->frame_parms.frame_type == TDD)) + if (UE->mode != loop_through_memory) + phy_procedures_UE_S_TX(UE,0,0,no_relay); + updateTimes(current, &t3, 10000, "saif: Delay to process sub-frame (case 3)"); - struct sched_attr attr; - unsigned int flags = 0; + } - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - // This creates a .5ms reservation every 1ms period - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 900000; // each rx thread requires 1ms to finish its job - attr.sched_deadline = 1000000; // each rx thread will finish within 1ms - attr.sched_period = 1000000; // each rx thread has a period of 1ms from the starting point - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] UE_thread_rxtx : sched_setattr failed\n"); +// thread finished return &UE_thread_rxtx_retval; - } - -#else - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; - - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ - CPU_ZERO(&cpuset); - - #ifdef CPU_AFFINITY - if (get_nprocs() >2) - { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - } - #endif - - /* Check the actual affinity mask assigned to the thread */ - - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) - { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) - { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - - } - - LOG_I( HW, "[SCHED][UE] Started UE RX thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); - - -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread_rxn_txnp4)\n"); - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread_rxn_txnp4)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - -#define THREAD_NAME_LEN 16 - char threadname[THREAD_NAME_LEN]; - ret = pthread_getname_np(proc->pthread_rxtx, threadname, THREAD_NAME_LEN); - if (ret != 0) - { - perror("pthread_getname_np : "); - exit_fun("Error getting thread name"); - } - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread_rxtx)\n"); - - printf("Starting UE RXN_TXNP4 thread (%s)\n", threadname); - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->subframe_rx&1), 1 ); - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("nothing to add"); - return &UE_thread_rxtx_retval; - } - - while (proc->instance_cnt_rxtx < 0) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->subframe_rx&1), 1 ); - // most of the time, the thread is waiting here - pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->subframe_rx&1), 0 ); - - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - return &UE_thread_rxtx_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->subframe_rx&1), 0 ); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->subframe_rx&1), 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_UE+(proc->subframe_rx&1), proc->subframe_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_UE+(proc->subframe_tx&1), proc->subframe_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE+(proc->subframe_rx&1), proc->frame_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE+(proc->subframe_tx&1), proc->frame_tx ); - - lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { - - if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", - threadname, - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } else { - LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", - threadname, - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } - phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); - } - - if (UE->mac_enabled==1) { - - ret = mac_xface->ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); - - if (ret == CONNECTION_LOST) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, returning to PRACH\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = PRACH; - } else if (ret == PHY_RESYNCH) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, trying to resynch\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = RESYNCH; - } else if (ret == PHY_HO_PRACH) { - LOG_I( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u, return to PRACH and perform a contention-free access\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = PRACH; - } - } - - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) { - - if (UE->mode != loop_through_memory) { - phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); - } - } - - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && - (UE->frame_parms.frame_type == TDD)) { - - if (UE->mode != loop_through_memory) { - phy_procedures_UE_S_TX(UE,0,0,no_relay); - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->subframe_rx&1), 0 ); - - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->subframe_rx&1), 1 ); - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - return &UE_thread_rxtx_retval; - } - - proc->instance_cnt_rxtx--; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, proc->instance_cnt_rxtx); - - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - return &UE_thread_rxtx_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->subframe_rx&1), 0 ); - } - - // thread finished - return &UE_thread_rxtx_retval; } - - - - #define RX_OFF_MAX 10 #define RX_OFF_MIN 5 #define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2) @@ -870,764 +836,208 @@ static void *UE_thread_rxn_txnp4(void *arg) void *UE_thread(void *arg) { - static int UE_thread_retval; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; - // int tx_enabled = 0; - unsigned int rxs,txs; - int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); - openair0_timestamp timestamp,timestamp1; - void* rxp[2], *txp[2]; + PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; + // int tx_enabled = 0; + int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); + openair0_timestamp timestamp,timestamp1; + void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + int start_rx_stream = 0; + int i; + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(3, &cpuset); + init_thread(100000, 500000, 40, &cpuset, //sched_get_priority_max(SCHED_FIFO), + "main UE"); #ifdef NAS_UE - MessageDef *message_p; + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); #endif - int start_rx_stream = 0; - int rx_off_diff = 0; - int rx_correction_timer = 0; - int i; - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE); - - // This creates a .5 ms reservation - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 100000; - attr.sched_deadline = 500000; - attr.sched_period = 500000; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] main eNB thread: sched_setattr failed\n"); - exit_fun("Nothing to add"); - return &UE_thread_retval; - } - LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", - (unsigned long)gettid(), sched_getcpu()); - -#else - struct sched_param sp; - sp.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread)\n"); - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread)\n"); - - printf("starting UE thread\n"); - -#ifdef NAS_UE - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); -#endif - - while (!oai_exit) { - - if (UE->is_synchronized == 0) { - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] verror locking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - int instance_cnt_synch = UE->proc.instance_cnt_synch; - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - if (instance_cnt_synch < 0) { // we can invoke the synch - // grab 10 ms of signal and wakeup synch thread - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&rxdata[i][0]; - - if (UE->mode != loop_through_memory) { - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx); - - - if (rxs!=UE->frame_parms.samples_per_tti*10) { - LOG_E(PHY, "problem in rx 1! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti*10, rxs); - exit_fun("problem in rx 1"); - return &UE_thread_retval; - } - } - - instance_cnt_synch = ++UE->proc.instance_cnt_synch; - if (instance_cnt_synch == 0) { - if (pthread_cond_signal(&UE->proc.cond_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } // - else { - // grab 10 ms of signal into dummy buffer - - if (UE->mode != loop_through_memory) { - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0;sf<10;sf++) { - // printf("Reading dummy sf %d\n",sf); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - - if (rxs!=UE->frame_parms.samples_per_tti){ - LOG_E(PHY, "problem in rx 2! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs); - exit_fun("problem in rx 2"); - return &UE_thread_retval; - } - - } - } - } - - } // UE->is_synchronized==0 - else { - if (start_rx_stream==0) { - start_rx_stream=1; - if (UE->mode != loop_through_memory) { - - if (UE->no_timing_correction==0) { - LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx); - if (rxs != UE->rx_offset) { - LOG_E(PHY, "problem in rx 3! want #samples=%d but got only %d!\n", UE->rx_offset, rxs); - exit_fun("problem in rx 3!"); - return &UE_thread_retval; - } - } - UE->rx_offset=0; - UE->proc.proc_rxtx[0].frame_rx++; - UE->proc.proc_rxtx[1].frame_rx++; - - // read in first symbol - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)rxdata, - UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); - if (rxs != (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0)) { - LOG_E(PHY, "problem in rx 4! want #samples=%d but got only %d!\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, rxs); - exit_fun("problem in rx 4!"); - return &UE_thread_retval; - } - slot_fep(UE, - 0, - 0, - 0, - 0, - 0); - if (rxs != UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - } //UE->mode != loop_through_memory - else - rt_sleep_ns(1000000); - - }// start_rx_stream==0 - else { - //UE->proc.proc_rxtx[0].frame_rx++; - //UE->proc.proc_rxtx[1].frame_rx++; - - for (int sf=0;sf<10;sf++) { - for (i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&rxdata[i][UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti)]; - // grab signal for subframe - if (UE->mode != loop_through_memory) { - if (sf<9) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - if (rxs != UE->frame_parms.samples_per_tti) { - LOG_E(PHY, "problem in rx 5! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs); - exit_fun("problem in rx 5!"); - return &UE_thread_retval; - } - - // prepare tx buffer pointers - for (i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - txs = UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_tx, - 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, rxs ); - if (txs != UE->frame_parms.samples_per_tti) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti); - exit_fun( "problem transmitting samples" ); - } - } - - else { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 ); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - if (rxs != (UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0)) { - LOG_E(PHY, "problem in rx 6! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, rxs); - exit_fun("problem in rx 6!"); - return &UE_thread_retval; - } - - // prepare tx buffer pointers - for (i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 1 ); - txs = UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - UE->frame_parms.samples_per_tti - rx_off_diff, - UE->frame_parms.nb_antennas_tx, - 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, rxs ); - if (txs != UE->frame_parms.samples_per_tti - rx_off_diff) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti-rx_off_diff); - exit_fun( "problem transmitting samples" ); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 ); - // read in first symbol of next frame and adjust for timing drift - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp1, - (void**)rxdata, - UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 - rx_off_diff, - UE->frame_parms.nb_antennas_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - if (rxs != (UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 - rx_off_diff)) { - LOG_E(PHY, "problem in rx 7! want #samples=%d but got only %d! rx_off_diff=%d\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 - rx_off_diff, rxs, rx_off_diff); - exit_fun("problem in rx 7!"); - return &UE_thread_retval; - } - rx_off_diff = 0; - } - } - // operate on thread sf mod 2 - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sf&1]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+(proc->subframe_rx&1), 1 ); - // lock mutex - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - // increment instance count and change proc subframe/frame variables - int instance_cnt_rxtx = ++proc->instance_cnt_rxtx; - if(sf == 0) - { - UE->proc.proc_rxtx[0].frame_rx++; - UE->proc.proc_rxtx[1].frame_rx++; - } - proc->subframe_rx=sf; - proc->subframe_tx=(sf+4)%10; - proc->frame_tx = proc->frame_rx + ((proc->subframe_rx>5)?1:0); - proc->timestamp_tx = timestamp+(4*UE->frame_parms.samples_per_tti)-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; - - /* - if (sf != (timestamp/UE->frame_parms.samples_per_tti)%10) { - LOG_E(PHY,"steady-state UE_thread error : frame_rx %d, subframe_rx %d, frame_tx %d, subframe_tx %d, rx subframe %d\n",proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,(timestamp/UE->frame_parms.samples_per_tti)%10); - exit(-1); - } - */ - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+(proc->subframe_rx&1), 0 ); - - - if (instance_cnt_rxtx == 0) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX, 1 ); - if (pthread_cond_signal(&proc->cond_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - LOG_D(PHY, "firing up rxtx_thread[%d] at subframe %d\n", sf&1, sf); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX, 0 ); - - } else { - LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rxtx); - if (instance_cnt_rxtx > 2) { - sleep(1); - exit_fun("instance_cnt_rxtx > 2"); - return &UE_thread_retval; - } - } - if (UE->mode == loop_through_memory) { - printf("Processing subframe %d",proc->subframe_rx); - getchar(); - } - }// for sf=0..10 - if ((UE->rx_offset<(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset > RX_OFF_MIN) && - (rx_correction_timer == 0)) { - rx_off_diff = -UE->rx_offset + RX_OFF_MIN; - LOG_D(PHY,"UE->rx_offset %d > %d, diff %d\n",UE->rx_offset,RX_OFF_MIN,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset < ((10*UE->frame_parms.samples_per_tti)-RX_OFF_MIN)) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = 10*UE->frame_parms.samples_per_tti - RX_OFF_MIN - UE->rx_offset; - LOG_D(PHY,"UE->rx_offset %d < %d, diff %d\n",UE->rx_offset,10*UE->frame_parms.samples_per_tti-RX_OFF_MIN,rx_off_diff); - - rx_correction_timer = 5; - } - - if (rx_correction_timer>0) - rx_correction_timer--; - } // start_rx_stream==1 - } // UE->is_synchronized==1 - - } // while !oai_exit - return NULL; -} // UE_thread - -/* -void *UE_thread_old(void *arg) -{ - UNUSED(arg) - static int UE_thread_retval; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; - int spp = openair0_cfg[0].samples_per_packet; - int slot=1, frame=0, hw_subframe=0, rxpos=0, txpos=openair0_cfg[0].tx_scheduling_advance; -#ifdef __AVX2__ - int dummy[2][spp] __attribute__((aligned(32))); -#else - int dummy[2][spp] __attribute__((aligned(16))); -#endif - int dummy_dump = 0; - int tx_enabled = 0; - int start_rx_stream = 0; - int rx_off_diff = 0; - int rx_correction_timer = 0; - int first_rx = 0; - RTIME T0; - unsigned int rxs; - void* rxp[2]; - - openair0_timestamp timestamp; - -#ifdef NAS_UE - MessageDef *message_p; -#endif - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE); - - // This creates a .5 ms reservation - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 100000; - attr.sched_deadline = 500000; - attr.sched_period = 500000; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] main eNB thread: sched_setattr failed\n"); - exit_fun("Nothing to add"); - return &UE_thread_retval; - } - LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", - (unsigned long)gettid(), sched_getcpu()); - -#else - struct sched_param sp; - sp.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread)\n"); - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread)\n"); - - printf("starting UE thread\n"); - -#ifdef NAS_UE - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); -#endif - - T0 = rt_get_time_ns(); - first_rx = 1; - rxpos=0; - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP, dummy_dump ); - - - while (rxpos < (1+hw_subframe)*UE->frame_parms.samples_per_tti) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - -#ifndef USRP_DEBUG - - DevAssert( UE->frame_parms.nb_antennas_rx <= 2 ); - void* rxp[2]; - - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rxpos] : (void*)dummy[i]; - - - if (UE->mode != loop_through_memory) { - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - spp - ((first_rx==1) ? rx_off_diff : 0), - UE->frame_parms.nb_antennas_rx); - - if (rxs != (spp- ((first_rx==1) ? rx_off_diff : 0))) { - printf("rx error: asked %d got %d ",spp - ((first_rx==1) ? rx_off_diff : 0),rxs); - if (UE->is_synchronized == 1) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - } - } - - if (rx_off_diff !=0) - LOG_D(PHY,"frame %d, rx_offset %d, rx_off_diff %d\n",UE->frame_rx,UE->rx_offset,rx_off_diff); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - // Transmit TX buffer based on timestamp from RX - if ((tx_enabled==1) && (UE->mode!=loop_through_memory)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - - DevAssert( UE->frame_parms.nb_antennas_tx <= 2 ); - void* txp[2]; - - for (int i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void*)&txdata[i][txpos]; - - UE->rfdevice.trx_write_func(&openair0, - (timestamp+openair0_cfg[0].tx_scheduling_advance-openair0_cfg[0].tx_sample_advance), - txp, - spp - ((first_rx==1) ? rx_off_diff : 0), - UE->frame_parms.nb_antennas_tx, - 1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - } - else if (UE->mode == loop_through_memory) - rt_sleep_ns(1000000); -#else - // define USRP_DEBUG is active - rt_sleep_ns(1000000); -#endif - - rx_off_diff = 0; - first_rx = 0; - - rxpos += spp; - txpos += spp; - - if (txpos >= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti) - txpos -= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti; - } - - if (rxpos >= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti) - rxpos -= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti; - - if (UE->is_synchronized == 1) { - LOG_D( HW, "UE_thread: hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - - if (start_rx_stream == 1) { - LOG_D(PHY,"Locking mutex_rx (IC %d)\n",UE->instance_cnt_rx); - if (pthread_mutex_lock(&UE->mutex_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - int instance_cnt_rx = ++UE->instance_cnt_rx; - - LOG_D(PHY,"Unlocking mutex_rx (IC %d)\n",instance_cnt_rx); - if (pthread_mutex_unlock(&UE->mutex_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, instance_cnt_rx); - - - if (instance_cnt_rx == 0) { - LOG_D(HW,"signalling rx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - if (pthread_cond_signal(&UE->proc.cond_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - LOG_D(HW,"signalled rx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - if (UE->mode == loop_through_memory) { - printf("Processing subframe %d",UE->slot_rx>>1); - getchar(); - } - - if (UE->mode == rx_calib_ue) { - if (frame == 10) { - LOG_D(PHY, - "[SCHED][UE] Found cell with N_RB_DL %"PRIu8", PHICH CONFIG (%d,%d), Nid_cell %"PRIu16", NB_ANTENNAS_TX %"PRIu8", frequency offset "PRIi32" Hz, RSSI (digital) %hu dB, measured Gain %d dB, total_rx_gain %"PRIu32" dB, USRP rx gain %f dB\n", - UE->frame_parms.N_RB_DL, - UE->frame_parms.phich_config_common.phich_duration, - UE->frame_parms.phich_config_common.phich_resource, - UE->frame_parms.Nid_cell, - UE->frame_parms.nb_antennas_tx_eNB, - UE->common_vars.freq_offset, - UE->measurements.rx_power_avg_dB[0], - UE->measurements.rx_power_avg_dB[0] - rx_input_level_dBm, - UE->rx_total_gain_dB, - openair0_cfg[0].rx_gain[0] - ); - exit_fun("[HW][UE] UE in RX calibration mode, exiting"); - return &UE_thread_retval; + int sub_frame=-1; + int cumulated_shift=0; + while (!oai_exit) { + + if (UE->is_synchronized == 0) { + + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + int instance_cnt_synch = UE->proc.instance_cnt_synch; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + if (instance_cnt_synch < 0) { // we can invoke the synch + // grab 10 ms of signal and wakeup synch thread + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&rxdata[i][0]; + + if (UE->mode != loop_through_memory) + AssertFatal( UE->frame_parms.samples_per_tti*10 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx), ""); + instance_cnt_synch = ++UE->proc.instance_cnt_synch; + if (instance_cnt_synch == 0) { + AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); + } else { + LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); + exit_fun("nothing to add"); + } + } // + else { + // grab 10 ms of signal into dummy buffer + + if (UE->mode != loop_through_memory) { + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&dummy_rx[i][0]; + for (int sf=0; sf<10; sf++) { + // printf("Reading dummy sf %d\n",sf); + AssertFatal ( UE->frame_parms.samples_per_tti == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx), ""); + + } + } } - } - } else { - LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rx); - if (instance_cnt_rx > 2) { - exit_fun("instance_cnt_rx > 1"); - return &UE_thread_retval; - } - } - - if ((tx_enabled==1)&&(UE->mode != loop_through_memory)) { + } // UE->is_synchronized==0 + else { + if (start_rx_stream==0) { + start_rx_stream=1; + if (UE->mode != loop_through_memory) { + if (UE->no_timing_correction==0) { + LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); + AssertFatal(UE->rx_offset == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)rxdata, + UE->rx_offset, + UE->frame_parms.nb_antennas_rx),""); + } + UE->rx_offset=0; + UE->proc.proc_rxtx[0].frame_rx++; + UE->proc.proc_rxtx[1].frame_rx++; - if (pthread_mutex_lock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } + // read in first symbol + AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)rxdata, + UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx),""); + slot_fep(UE,0, 0, 0, 0, 0); + } //UE->mode != loop_through_memory + else + rt_sleep_ns(1000*1000); + } else { + sub_frame++; + sub_frame%=10; + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame&1]; - int instance_cnt_tx = ++UE->instance_cnt_tx; + if (UE->mode != loop_through_memory) { + for (i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&rxdata[i][UE->frame_parms.ofdm_symbol_size+ + UE->frame_parms.nb_prefix_samples0+ + sub_frame*UE->frame_parms.samples_per_tti]; + for (i=0; iframe_parms.nb_antennas_tx; i++) + txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti]; - if (pthread_mutex_unlock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX, instance_cnt_tx); + int readBlockSize, writeBlockSize; + if (sub_frame<9) { + readBlockSize=UE->frame_parms.samples_per_tti; + writeBlockSize=UE->frame_parms.samples_per_tti; + } else { + int rx_off_diff; + if ( UE->rx_offset< 5*UE->frame_parms.samples_per_tti ) + rx_off_diff = -UE->rx_offset; + else // moving to the left so drop rx_off_diff samples + rx_off_diff = 10*UE->frame_parms.samples_per_tti - RX_OFF_MIN - UE->rx_offset; + cumulated_shift+=rx_off_diff; + if ( rx_off_diff > 10 ) + LOG_E (PHY,"HUGE shift %d, cumul %d\n", rx_off_diff, cumulated_shift); + static __thread int printed_cumul=0; + if ( abs(cumulated_shift/1000) > printed_cumul ) { + LOG_W(PHY,"Shifted for 1000 samples: cumul %d\n", cumulated_shift); + printed_cumul=abs(cumulated_shift/1000); + } + readBlockSize=UE->frame_parms.samples_per_tti- + UE->frame_parms.ofdm_symbol_size- + UE->frame_parms.nb_prefix_samples0; + writeBlockSize=UE->frame_parms.samples_per_tti - rx_off_diff; + } - if (instance_cnt_tx == 0) { - if (pthread_cond_signal(&UE->cond_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - LOG_D(HW,"signalled tx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); + AssertFatal(readBlockSize == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + readBlockSize, + UE->frame_parms.nb_antennas_rx),""); + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + (2*UE->frame_parms.samples_per_tti) - + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - + openair0_cfg[0].tx_sample_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1),""); + if( sub_frame==9) { + // read in first symbol of next frame and adjust for timing drift + int first_symbols=writeBlockSize-readBlockSize; + if ( first_symbols > 0 ) + AssertFatal(first_symbols == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp1, + (void**)rxdata, + first_symbols, + UE->frame_parms.nb_antennas_rx),""); + if ( first_symbols <0 ) + LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); + } + unsigned long long gotIQs=rdtsc(); + // operate on thread sf mod 2 + AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + if(sub_frame == 0) { + UE->proc.proc_rxtx[0].frame_rx++; + UE->proc.proc_rxtx[1].frame_rx++; + } + UE->proc.proc_rxtx[0].gotIQs=gotIQs; + UE->proc.proc_rxtx[1].gotIQs=gotIQs; + proc->subframe_rx=sub_frame; + proc->subframe_tx=(sub_frame+4)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + proc->timestamp_tx = timestamp+ + (4*UE->frame_parms.samples_per_tti)- + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; - } else { - LOG_E( PHY, "[SCHED][UE] UE TX thread busy (IC %d)!!\n" ); - if (instance_cnt_tx>2) { - exit_fun("instance_cnt_tx > 1"); - return &UE_thread_retval; - } - } - } + AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + static __thread Meas t1= {0}; + static unsigned long long lastTime=0; + if ( lastTime != 0 ) + updateTimes(lastTime, &t1, 20000, "saif: Delay between two IQ acquisitions (case 1)"); + lastTime=rdtsc(); + saif_meas(proc->frame_rx); - } - } else { - // we are not yet synchronized - if ((hw_subframe == 9) && (dummy_dump == 0)) { - // Wake up initial synch thread - if (pthread_mutex_lock(&UE->mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } + } else { + printf("Processing subframe %d",proc->subframe_rx); + getchar(); + } + } // start_rx_stream==1 + } // UE->is_synchronized==1 - int instance_cnt_synch = ++UE->instance_cnt_synch; - - if (pthread_mutex_unlock(&UE->mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - dummy_dump = 1; - - if (instance_cnt_synch == 0) { - if (pthread_cond_signal(&UE->cond_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } - } - - hw_subframe++; - slot+=2; - - if (hw_subframe==10) { - hw_subframe = 0; - first_rx = 1; - frame++; - slot = 1; - - int fail = pthread_mutex_lock(&UE->mutex_synch); - int instance_cnt_synch = UE->instance_cnt_synch; - fail = fail || pthread_mutex_unlock(&UE->mutex_synch); - - if (fail) { - LOG_E( PHY, "[SCHED][UE] error (un-)locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_retval; - } - - if (instance_cnt_synch < 0) { - // the UE_thread_synch is ready - if (UE->is_synchronized == 1) { - rx_off_diff = 0; - LTE_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; // for macro FRAME_LENGTH_COMPLEX_SAMPLES - - // LOG_I(PHY,"UE->rx_offset %d\n",UE->rx_offset); - if ((UE->rx_offset > RX_OFF_MAX) && (start_rx_stream == 0)) { - start_rx_stream=1; - frame=0; - // dump ahead in time to start of frame - -#ifndef USRP_DEBUG - if (UE->mode != loop_through_memory) { - LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx); - if (rxs != UE->rx_offset) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - UE->rx_offset=0; - tx_enabled = 1; - } - else - rt_sleep_ns(1000000); -#else - rt_sleep_ns(10000000); -#endif - - } else if ((UE->rx_offset<(FRAME_LENGTH_COMPLEX_SAMPLES/2)) && - (UE->rx_offset > RX_OFF_MIN) && - (start_rx_stream==1) && - (rx_correction_timer == 0)) { - rx_off_diff = -UE->rx_offset + RX_OFF_MIN; - LOG_D(PHY,"UE->rx_offset %d > %d, diff %d\n",UE->rx_offset,RX_OFF_MIN,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(FRAME_LENGTH_COMPLEX_SAMPLES/2)) && - (UE->rx_offset < (FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MIN)) && - (start_rx_stream==1) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = FRAME_LENGTH_COMPLEX_SAMPLES - RX_OFF_MIN - UE->rx_offset; - LOG_D(PHY,"UE->rx_offset %d < %d, diff %d\n",UE->rx_offset,FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MIN,rx_off_diff); - - rx_correction_timer = 5; - } - - if (rx_correction_timer>0) - rx_correction_timer--; - } - - dummy_dump=0; - } - } - -#if defined(ENABLE_ITTI) - itti_update_lte_time(frame, slot); -#endif - } - - return &UE_thread_retval; + } // while !oai_exit + return NULL; } -*/ - /*! * \brief Initialize the UE theads. * Creates the UE threads: @@ -1636,124 +1046,97 @@ void *UE_thread_old(void *arg) * - UE_thread_synch * and the locking between them. */ -void init_UE_threads(int inst) -{ - PHY_VARS_UE *UE; - - UE = PHY_vars_UE_g[inst][0]; +void init_UE_threads(int inst) { + PHY_VARS_UE *UE; - pthread_attr_init (&UE->proc.attr_ue); - pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - -#ifndef LOWLATENCY - UE->proc.sched_param_ue.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&UE->proc.attr_ue,&sched_param_UE_thread); -#endif + UE = PHY_vars_UE_g[inst][0]; + + pthread_attr_init (&UE->proc.attr_ue); + pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); + + + // the threads are not yet active, therefore access is allowed without locking + int nb_threads=2; + for (int i=0; iproc.proc_rxtx[i].mutex_rxtx,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].sub_frame_start=i; + UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[i]); + } + pthread_mutex_init(&UE->proc.mutex_synch,NULL); + pthread_cond_init(&UE->proc.cond_synch,NULL); + pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - // the threads are not yet active, therefore access is allowed without locking - UE->proc.proc_rxtx[0].instance_cnt_rxtx = -1; - UE->proc.proc_rxtx[1].instance_cnt_rxtx = -1; - UE->proc.instance_cnt_synch = -1; - pthread_mutex_init(&UE->proc.proc_rxtx[0].mutex_rxtx,NULL); - pthread_mutex_init(&UE->proc.proc_rxtx[1].mutex_rxtx,NULL); - pthread_mutex_init(&UE->proc.mutex_synch,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[0].cond_rxtx,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[1].cond_rxtx,NULL); - pthread_cond_init(&UE->proc.cond_synch,NULL); - pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[0]); - pthread_setname_np( UE->proc.proc_rxtx[0].pthread_rxtx, "UE_thread_rxn_txnp4_even" ); - pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[1]); - pthread_setname_np( UE->proc.proc_rxtx[1].pthread_rxtx, "UE_thread_rxn_txnp4_odd" ); - pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - pthread_setname_np( UE->proc.pthread_synch, "UE_thread_synch" ); } #ifdef OPENAIR2 -void fill_ue_band_info(void) -{ +void fill_ue_band_info(void) { - UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; - int i,j; + UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; + int i,j; - bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; + bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; - for (i=0; irf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { - memcpy(&bands_to_scan.band_info[i], - &eutra_bands[j], - sizeof(eutra_band_t)); + for (j=0; jrf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { + memcpy(&bands_to_scan.band_info[i], + &eutra_bands[j], + sizeof(eutra_band_t)); - printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", - bands_to_scan.band_info[i].band, - UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, - bands_to_scan.band_info[i].dl_min, - bands_to_scan.band_info[i].dl_max, - bands_to_scan.band_info[i].ul_min, - bands_to_scan.band_info[i].ul_max, - (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); - break; - } - } + printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", + bands_to_scan.band_info[i].band, + UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, + bands_to_scan.band_info[i].dl_min, + bands_to_scan.band_info[i].dl_max, + bands_to_scan.band_info[i].ul_min, + bands_to_scan.band_info[i].ul_max, + (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); + break; + } + } } #endif -int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) -{ +int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) { - int i, CC_id; - LTE_DL_FRAME_PARMS *frame_parms; - openair0_rf_map *rf_map; + int i, CC_id; + LTE_DL_FRAME_PARMS *frame_parms; + openair0_rf_map *rf_map; - for (CC_id=0; CC_idrf_map; - - if (phy_vars_ue[CC_id]) { - frame_parms = &(phy_vars_ue[CC_id]->frame_parms); - } else { - printf("phy_vars_UE[%d] not initialized\n", CC_id); - return(-1); - } - - /* - if (frame_parms->frame_type == TDD) { - if (frame_parms->N_RB_DL == 100) - N_TA_offset = 624; - else if (frame_parms->N_RB_DL == 50) - N_TA_offset = 624/2; - else if (frame_parms->N_RB_DL == 25) - N_TA_offset = 624/4; - } - */ - - // replace RX signal buffers with mmaped HW versions - rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); - txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); - - for (i=0; inb_antennas_rx; i++) { - printf( "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); - rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD - printf("rxdata[%d] : %p\n",i,rxdata[i]); - } - - for (i=0; inb_antennas_tx; i++) { - printf( "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); - txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; - printf("txdata[%d] : %p\n",i,txdata[i]); - } - - // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] - // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] - // be careful when releasing memory! - // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) - - } + for (CC_id=0; CC_idrf_map; - return 0; + AssertFatal( phy_vars_ue[CC_id] !=0, ""); + frame_parms = &(phy_vars_ue[CC_id]->frame_parms); + + // replace RX signal buffers with mmaped HW versions + rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); + txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); + + for (i=0; inb_antennas_rx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); + rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD + } + + for (i=0; inb_antennas_tx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); + txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; + } + + // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] + // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] + // be careful when releasing memory! + // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) + } + return 0; } From 3b44919d0b03f8f0a1033ac2d4b89f51c1718a63 Mon Sep 17 00:00:00 2001 From: laurent Date: Tue, 27 Dec 2016 15:48:56 +0100 Subject: [PATCH 02/13] better performance measurements --- openair2/UTIL/LOG/log.h | 433 +++++++++++++++++++++---------------- openair2/UTIL/LOG/log_if.h | 59 +---- targets/RT/USER/lte-ue.c | 120 +--------- 3 files changed, 257 insertions(+), 355 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 171f74da41..b15f7064ac 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -53,26 +53,6 @@ extern "C" { #endif - extern double cpuf; - static inline unsigned long long rdtsc(void) { - unsigned long long a, d; - __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); - return (d<<32) | a; - } - static inline unsigned long long checkT(int timeout, char * file, int line) { - static unsigned long long __thread last=0; - unsigned long long cur=rdtsc(); - int microCycles=(int)(cpuf*1000); - int duration=(int)((cur-last)/microCycles); - if ( last!=0 && duration > timeout ) - printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, - duration, timeout); - last=cur; - return cur; - } - -#define check(a) checkT(a,__FILE__,__LINE__) - /** @defgroup _LOG LOG Generator * @{*/ /* @}*/ @@ -96,41 +76,197 @@ extern "C" { * @ingroup _macro * @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8 * @{*/ -#ifndef LOG_EMERG # define LOG_EMERG 0 /*!< \brief system is unusable */ -#endif -#ifndef LOG_ALERT # define LOG_ALERT 1 /*!< \brief action must be taken immediately */ -#endif -#ifndef LOG_CRIT # define LOG_CRIT 2 /*!< \brief critical conditions */ -#endif -#ifndef LOG_ERR # define LOG_ERR 3 /*!< \brief error conditions */ -#endif -#ifndef LOG_WARNING # define LOG_WARNING 4 /*!< \brief warning conditions */ -#endif -#ifndef LOG_NOTICE # define LOG_NOTICE 5 /*!< \brief normal but significant condition */ -#endif -#ifndef LOG_INFO # define LOG_INFO 6 /*!< \brief informational */ -#endif -#ifndef LOG_DEBUG # define LOG_DEBUG 7 /*!< \brief debug-level messages */ -#endif -#ifndef LOG_FILE # define LOG_FILE 8 /*!< \brief message sequence chart -level */ -#endif -#ifndef LOG_TRACE # define LOG_TRACE 9 /*!< \brief trace-level messages */ -#endif - #define NUM_LOG_LEVEL 10 /*!< \brief the number of message levels users have with LOG */ /* @}*/ +/** @defgroup _log_format Defined log format + * @ingroup _macro + * @brief Macro of log formats defined by LOG + * @{*/ + +/* .log_format = 0x13 uncolored standard messages + * .log_format = 0x93 colored standard messages */ + +#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */ +#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */ +#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */ +#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */ +#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */ +#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */ +/* @}*/ + + +/** @defgroup _syslog_conf Macros for write in syslog.conf + * @ingroup _macro + * @brief Macros used to write lines (local/remote) in syslog.conf + * @{*/ +#define LOG_LOCAL 0x01 +#define LOG_REMOTE 0x02 + +#define FLAG_COLOR 0x001 /*!< \brief defaults */ +#define FLAG_PID 0x002 /*!< \brief defaults */ +#define FLAG_COMP 0x004 +#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */ +#define FLAG_LEVEL 0x010 +#define FLAG_FUNCT 0x020 +#define FLAG_FILE_LINE 0x040 +#define FLAG_TIME 0x100 + +#define LOG_NONE 0x00 +#define LOG_LOW 0x5 +#define LOG_MED 0x15 +#define LOG_HIGH 0x35 +#define LOG_FULL 0x75 + +#define OAI_OK 0 /*!< \brief all ok */ +#define OAI_ERR 1 /*!< \brief generic error */ +#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */ +#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */ +/* @}*/ + + +//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */ + +//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ + +typedef enum { + MIN_LOG_COMPONENTS = 0, + PHY = MIN_LOG_COMPONENTS, + MAC, + EMU, + OCG, + OMG, + OPT, + OTG, + OTG_LATENCY, + OTG_LATENCY_BG, + OTG_GP, + OTG_GP_BG, + OTG_JITTER, + RLC, + PDCP, + RRC, + NAS, + PERF, + OIP, + CLI, + MSC, + OCM, + UDP_, + GTPU, + SPGW, + S1AP, + SCTP, + HW, + OSA, + RAL_ENB, + RAL_UE, + ENB_APP, + FLEXRAN_AGENT, + TMR, + USIM, + LOCALIZE, + RRH, + X2AP, + MAX_LOG_COMPONENTS, +} +comp_name_t; + +//#define msg printf + +typedef struct { + char *name; /*!< \brief string name of item */ + int value; /*!< \brief integer value of mapping */ +} mapping; + + +typedef struct { + const char *name; + int level; + int flag; + int interval; + int fd; + int filelog; + char *filelog_name; + + /* SR: make the log buffer component relative */ + char log_buffer[MAX_LOG_TOTAL]; +} log_component_t; + +typedef struct { + unsigned int remote_ip; + unsigned int audit_ip; + int remote_level; + int facility; + int audit_facility; + int format; +} log_config_t; + + +typedef struct { + log_component_t log_component[MAX_LOG_COMPONENTS]; + log_config_t config; + char* level2string[NUM_LOG_LEVEL]; + int level; + int onlinelog; + int flag; + int syslog; + int filelog; + char* filelog_name; +} log_t; + +typedef struct LOG_params { + const char *file; + const char *func; + int line; + int comp; + int level; + const char *format; + char l_buff_info [MAX_LOG_INFO]; + int len; +} LOG_params; + +#if defined(ENABLE_ITTI) +typedef enum log_instance_type_e { + LOG_INSTANCE_UNKNOWN, + LOG_INSTANCE_ENB, + LOG_INSTANCE_UE, +} log_instance_type_t; + +void log_set_instance_type (log_instance_type_t instance); +#endif + + +/*--- INCLUDES ---------------------------------------------------------------*/ +# include "log_if.h" +/*----------------------------------------------------------------------------*/ +int logInit (void); +void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...); +void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...); +int set_comp_log(int component, int level, int verbosity, int interval); +int set_log(int component, int level, int interval); +void set_glog(int level, int verbosity); +void set_log_syslog(int enable); +void set_log_onlinelog(int enable); +void set_log_filelog(int enable); +void set_component_filelog(int comp); +int map_str_to_int(mapping *map, const char *str); +char *map_int_to_str(mapping *map, int val); +void logClean (void); +int is_newline( char *str, int size); +void *log_thread_function(void * list); + /** @defgroup _logIt logIt function * @ingroup _macro * @brief Macro used to call tr_log_full_ex with file, function and line information @@ -206,169 +342,82 @@ extern "C" { #define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */ /* @}*/ - -/** @defgroup _log_format Defined log format - * @ingroup _macro - * @brief Macro of log formats defined by LOG - * @{*/ - -/* .log_format = 0x13 uncolored standard messages - * .log_format = 0x93 colored standard messages */ - -#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */ -#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */ -#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */ -#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */ -#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */ -#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */ -/* @}*/ - - -/** @defgroup _syslog_conf Macros for write in syslog.conf - * @ingroup _macro - * @brief Macros used to write lines (local/remote) in syslog.conf - * @{*/ -#define LOG_LOCAL 0x01 -#define LOG_REMOTE 0x02 - -#define FLAG_COLOR 0x001 /*!< \brief defaults */ -#define FLAG_PID 0x002 /*!< \brief defaults */ -#define FLAG_COMP 0x004 -#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */ -#define FLAG_LEVEL 0x010 -#define FLAG_FUNCT 0x020 -#define FLAG_FILE_LINE 0x040 -#define FLAG_TIME 0x100 - -#define LOG_NONE 0x00 -#define LOG_LOW 0x5 -#define LOG_MED 0x15 -#define LOG_HIGH 0x35 -#define LOG_FULL 0x75 - -#define OAI_OK 0 /*!< \brief all ok */ -#define OAI_ERR 1 /*!< \brief generic error */ -#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */ -#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */ -/* @}*/ - - -//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */ - -//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ - -typedef enum { - MIN_LOG_COMPONENTS = 0, - PHY = MIN_LOG_COMPONENTS, - MAC, - EMU, - OCG, - OMG, - OPT, - OTG, - OTG_LATENCY, - OTG_LATENCY_BG, - OTG_GP, - OTG_GP_BG, - OTG_JITTER, - RLC, - PDCP, - RRC, - NAS, - PERF, - OIP, - CLI, - MSC, - OCM, - UDP_, - GTPU, - SPGW, - S1AP, - SCTP, - HW, - OSA, - RAL_ENB, - RAL_UE, - ENB_APP, - FLEXRAN_AGENT, - TMR, - USIM, - LOCALIZE, - RRH, - X2AP, - MAX_LOG_COMPONENTS, +static inline unsigned long long rdtsc(void) { + unsigned long long a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; } -comp_name_t; -//#define msg printf +#define DEBUG_REALTIME 1 +#if DEBUG_REALTIME -typedef struct { - char *name; /*!< \brief string name of item */ - int value; /*!< \brief integer value of mapping */ -} mapping; +extern double cpuf; +static inline unsigned long long checkT(int timeout, char * file, int line) { + static unsigned long long __thread last=0; + unsigned long long cur=rdtsc(); + int microCycles=(int)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) + printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, + duration, timeout); + last=cur; + return cur; +} -typedef struct { - const char *name; - int level; - int flag; - int interval; - int fd; - int filelog; - char *filelog_name; +typedef struct m { + unsigned long long iterations; + unsigned long long sum; + unsigned long long maxArray[11]; +} Meas; - /* SR: make the log buffer component relative */ - char log_buffer[MAX_LOG_TOTAL]; -} log_component_t; +static inline void printMeas(char * txt, Meas *M, int period) { + if (M->iterations%period == 0 ) { + char txt2[512]; + sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", + txt, M->sum/M->iterations,M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], + M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); + LOG_W(PHY,txt2); + } +} -typedef struct { - unsigned int remote_ip; - unsigned int audit_ip; - int remote_level; - int facility; - int audit_facility; - int format; -} log_config_t; +static inline int cmpint(const void* a, const void* b) { + unsigned long long* aa=(unsigned long long*)a; + unsigned long long* bb=(unsigned long long*)b; + return (int)(*aa-*bb); +} +static inline void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { + if (start!=0) { + unsigned long long end=rdtsc(); + long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); + printMeas(txt,M,period); + } +} -typedef struct { - log_component_t log_component[MAX_LOG_COMPONENTS]; - log_config_t config; - char* level2string[NUM_LOG_LEVEL]; - int level; - int onlinelog; - int flag; - int syslog; - int filelog; - char* filelog_name; -} log_t; +#define check(a) checkT(a,__FILE__,__LINE__) +#define initRefTimes(a) static __thread Meas a= {0} +#define pickTime(a) unsigned long long a=rdtsc() +#define readTime(a) a +#define initStaticTime(a) static __thread unsigned long long a={0} +#define pickStaticTime(a) a=rdtsc() -typedef struct LOG_params { - const char *file; - const char *func; - int line; - int comp; - int level; - const char *format; - char l_buff_info [MAX_LOG_INFO]; - int len; -} LOG_params; - - -#if defined(ENABLE_ITTI) -typedef enum log_instance_type_e { - LOG_INSTANCE_UNKNOWN, - LOG_INSTANCE_ENB, - LOG_INSTANCE_UE, -} log_instance_type_t; - -void log_set_instance_type (log_instance_type_t instance); +#else +#define check(a) do {} while (0) +#define initRefTimes(a) do {} while (0) +#define initStaticTime(a) do {} while (0) +#define pickTime(a) do {} while (0) +#define readTime(a) 0 +#define pickStaticTime(a) do {} while (0) +#define updateTimes(a,b,c,d) do {} while (0) +#define printMeas(a,b,c) do {} while (0) #endif -int logInit (void); -/*--- INCLUDES ---------------------------------------------------------------*/ -# include "log_if.h" -/*----------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif diff --git a/openair2/UTIL/LOG/log_if.h b/openair2/UTIL/LOG/log_if.h index 1b447a7f60..6338fab829 100644 --- a/openair2/UTIL/LOG/log_if.h +++ b/openair2/UTIL/LOG/log_if.h @@ -27,59 +27,8 @@ * \warning This component can be runned only in user-space * @ingroup routing */ -#ifndef __LOG_IF_H__ -# define __LOG_IF_H__ - - -/*--- INCLUDES ---------------------------------------------------------------*/ -# include "log.h" -/*----------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef COMPONENT_LOG -# ifdef COMPONENT_LOG_IF -# define private_log_if(x) x -# define friend_log_if(x) x -# define public_log_if(x) x -# else -# define private_log_if(x) -# define friend_log_if(x) extern x -# define public_log_if(x) extern x -# endif -# else -# define private_log_if(x) -# define friend_log_if(x) -# define public_log_if(x) extern x -# endif - -/** @defgroup _log_if Interfaces of LOG - * @{*/ - -//public_log_if( log_t *g_log;) - -public_log_if( int logInit (void);) -public_log_if( void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...);) -public_log_if( void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...);) -public_log_if( int set_comp_log(int component, int level, int verbosity, int interval);) -public_log_if( int set_log(int component, int level, int interval);) -public_log_if( void set_glog(int level, int verbosity);) -public_log_if( void set_log_syslog(int enable);) -public_log_if( void set_log_onlinelog(int enable);) -public_log_if( void set_log_filelog(int enable);) -public_log_if( void set_component_filelog(int comp);) -public_log_if( int map_str_to_int(mapping *map, const char *str);) -public_log_if( char *map_int_to_str(mapping *map, int val);) -public_log_if( void logClean (void); ) -public_log_if( int is_newline( char *str, int size);) -public_log_if( void *log_thread_function(void * list);) - -/* @}*/ - -#ifdef __cplusplus -} -#endif - -#endif +// LTS: kept this file for compatibility +// this file was probably a trial to separate internal functions and external ones +// but it has never been finished, most source code include directly log.h (not log_if.h) +#include "log.h" diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 6e588f7f3c..b398d5127e 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -75,101 +75,6 @@ #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" - -#define DEBUG_REALTIME 1 -#if DEBUG_REALTIME - -typedef struct latency_stat { - uint64_t counter; - uint64_t stat1100; - uint64_t stat1200; - uint64_t stat1500; - uint64_t stat2000; - uint64_t stat3000; -} latency_stat_t; - -static inline void saif_meas(int frame_rx) { - static latency_stat_t __thread latency_stat; - static struct timespec __thread last= {0}; - struct timespec now; - clock_gettime(CLOCK_MONOTONIC_RAW, &now); - if ( last.tv_sec ) { - uint64_t diffTime = ((uint64_t)now.tv_sec *1000 *1000 *1000 + now.tv_nsec) - - ((uint64_t)last.tv_sec *1000 *1000 *1000 + last.tv_nsec); - diffTime/=1000; - latency_stat.counter++; - if ( diffTime >= 1100 ) { - if (diffTime < 1200 ) - latency_stat.stat1100++; - else if ( diffTime < 1500 ) - latency_stat.stat1200++; - else if ( diffTime < 2000 ) - latency_stat.stat1500++; - else if ( diffTime < 3000 ) - latency_stat.stat2000++; - else - latency_stat.stat3000++; - } - if ( diffTime>=1100 || latency_stat.counter%20000==0 ) { - time_t current=time(NULL); - LOG_W(HW, - "%.2f delay=%llu Period stats %2.6f%% below 100µs\ncumul of events: 1100=%ld 1200=%ld 1500=%ld 2000=%ld >3000=%ld - (frame_rx=%d) - %s", - now.tv_sec+(double)now.tv_nsec/1e9, - diffTime, - (latency_stat.counter-latency_stat.stat1100-latency_stat.stat1200- - latency_stat.stat1500-latency_stat.stat2000-latency_stat.stat3000)/ - (float)latency_stat.counter *100, - latency_stat.stat1100, latency_stat.stat1200, - latency_stat.stat1500, latency_stat.stat2000, - latency_stat.stat3000, - frame_rx, ctime(¤t)); - fflush(stdout); - } - - } - last=now; -} - -typedef struct m { - unsigned long long iterations; - unsigned long long sum; - unsigned long long maxArray[11]; -} Meas; - - -void printMeas(char * txt, Meas *M, int period) { - if (M->iterations%period == 0 ) { - char txt2[512]; - sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", - txt, M->sum/M->iterations,M->iterations, - M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], - M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); - LOG_W(PHY,txt2); - } -} - -int cmpint(const void* a, const void* b) { - unsigned long long* aa=(unsigned long long*)a; - unsigned long long* bb=(unsigned long long*)b; - return (int)(*aa-*bb); -} - -void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { - unsigned long long end=rdtsc(); - long long diff=(end-start)/(cpuf*1000); - M->maxArray[0]=diff; - M->sum+=diff; - M->iterations++; - qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); - printMeas(txt,M,period); -} - -#else -#define check(a) do {} while (0) -#define saif_meas(a) do {} while (0) -#define update_max_times(a,b) do {} while (0) -#define print_meas(a,b) do {} while (0) -#endif /* End of Changed by SYRTEM */ #define FRAME_PERIOD 100000000ULL @@ -742,9 +647,10 @@ static void *UE_thread_rxn_txnp4(void *arg) { instance_cnt_rxtx=proc->subframe_rx; AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); - static __thread Meas t2= {0}, t3= {0}; - unsigned long long current=rdtsc(); - updateTimes(proc->gotIQs, &t2, 10000, "saif: Delay to wake up UE_Thread_Rx (case 2)"); + initRefTimes(t2); + initRefTimes(t3); + pickTime(current); + updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); @@ -812,7 +718,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { (UE->frame_parms.frame_type == TDD)) if (UE->mode != loop_through_memory) phy_procedures_UE_S_TX(UE,0,0,no_relay); - updateTimes(current, &t3, 10000, "saif: Delay to process sub-frame (case 3)"); + updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); } @@ -1002,15 +908,15 @@ void *UE_thread(void *arg) { if ( first_symbols <0 ) LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); } - unsigned long long gotIQs=rdtsc(); + pickTime(gotIQs); // operate on thread sf mod 2 AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); if(sub_frame == 0) { UE->proc.proc_rxtx[0].frame_rx++; UE->proc.proc_rxtx[1].frame_rx++; } - UE->proc.proc_rxtx[0].gotIQs=gotIQs; - UE->proc.proc_rxtx[1].gotIQs=gotIQs; + UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); + UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); proc->subframe_rx=sub_frame; proc->subframe_tx=(sub_frame+4)%10; proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); @@ -1020,12 +926,10 @@ void *UE_thread(void *arg) { AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); - static __thread Meas t1= {0}; - static unsigned long long lastTime=0; - if ( lastTime != 0 ) - updateTimes(lastTime, &t1, 20000, "saif: Delay between two IQ acquisitions (case 1)"); - lastTime=rdtsc(); - saif_meas(proc->frame_rx); + initRefTimes(t1); + initStaticTime(lastTime); + updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); + pickStaticTime(lastTime); } else { printf("Processing subframe %d",proc->subframe_rx); From 2612df9ef24a1cc5240f9d3aa08d85b2736bd69a Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 29 Dec 2016 10:09:13 +0100 Subject: [PATCH 03/13] after tests --- openair2/UTIL/LOG/log.h | 68 +++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index b15f7064ac..9a7dac4de5 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -43,6 +43,9 @@ #include #include #include +#include +#include +#include #else #include "rtai_fifos.h" #endif @@ -342,10 +345,10 @@ void *log_thread_function(void * list); #define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */ /* @}*/ -static inline unsigned long long rdtsc(void) { - unsigned long long a, d; - __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); - return (d<<32) | a; +static __inline__ uint64_t rdtsc(void) { + uint64_t a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; } #define DEBUG_REALTIME 1 @@ -353,6 +356,26 @@ static inline unsigned long long rdtsc(void) { extern double cpuf; +static inline uint64_t checkTCPU(int timeout, char * file, int line) { + static uint64_t __thread lastCPUTime=0; + static uint64_t __thread last=0; + uint64_t cur=rdtsc(); + struct timespec CPUt; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt); + uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000; + double microCycles=(double)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%.3f %s:%d lte-ue delay %d (exceed %d), CPU for this period: %.2f\n", ts.tv_sec+ts.tv_nsec/(1000*1000*1000.0), file, line, + duration, timeout, (CPUTime-lastCPUTime)/1000.0 ); + } + last=cur; + lastCPUTime=CPUTime; + return cur; +} + static inline unsigned long long checkT(int timeout, char * file, int line) { static unsigned long long __thread last=0; unsigned long long cur=rdtsc(); @@ -366,49 +389,54 @@ static inline unsigned long long checkT(int timeout, char * file, int line) { } typedef struct m { - unsigned long long iterations; - unsigned long long sum; - unsigned long long maxArray[11]; + uint64_t iterations; + uint64_t sum; + uint64_t maxArray[11]; } Meas; static inline void printMeas(char * txt, Meas *M, int period) { if (M->iterations%period == 0 ) { char txt2[512]; - sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", - txt, M->sum/M->iterations,M->iterations, - M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], - M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); + sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%" + PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", + txt, + M->sum/M->iterations, + M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], + M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); LOG_W(PHY,txt2); } } static inline int cmpint(const void* a, const void* b) { - unsigned long long* aa=(unsigned long long*)a; - unsigned long long* bb=(unsigned long long*)b; + uint64_t* aa=(uint64_t*)a; + uint64_t* bb=(uint64_t*)b; return (int)(*aa-*bb); } -static inline void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { +static inline void updateTimes(uint64_t start, Meas *M, int period, char * txt) { if (start!=0) { - unsigned long long end=rdtsc(); + uint64_t end=rdtsc(); long long diff=(end-start)/(cpuf*1000); M->maxArray[0]=diff; M->sum+=diff; M->iterations++; - qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); + qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); printMeas(txt,M,period); } } -#define check(a) checkT(a,__FILE__,__LINE__) +#define check(a) do { checkT(a,__FILE__,__LINE__); } while (0) +#define checkcpu(a) do { checkTCPU(a,__FILE__,__LINE__); } while (0) #define initRefTimes(a) static __thread Meas a= {0} -#define pickTime(a) unsigned long long a=rdtsc() +#define pickTime(a) uint64_t a=rdtsc() #define readTime(a) a -#define initStaticTime(a) static __thread unsigned long long a={0} -#define pickStaticTime(a) a=rdtsc() +#define initStaticTime(a) static __thread uint64_t a={0} +#define pickStaticTime(a) do { a=rdtsc(); } while (0) #else #define check(a) do {} while (0) +#define checkcpu(a) do {} while (0) #define initRefTimes(a) do {} while (0) #define initStaticTime(a) do {} while (0) #define pickTime(a) do {} while (0) From 59d0cf1c5477bb6cc5d2b2d9094e52e60b3bc8d9 Mon Sep 17 00:00:00 2001 From: LTS Date: Tue, 3 Jan 2017 14:26:17 +0100 Subject: [PATCH 04/13] fix T macro calls --- common/utils/T/T.h | 12 ------------ targets/RT/USER/lte-ue.c | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 819615131e..bd090ac221 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -188,12 +188,6 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ - if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ - printf("%s:%d:%s: " \ - "bad use of T, pass a message ID as first parameter\n", \ - __FILE__, __LINE__, __FUNCTION__); \ - abort(); \ - } \ struct timespec T_HEADER_time; \ if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \ memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \ @@ -205,12 +199,6 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ - if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ - printf("%s:%d:%s: " \ - "bad use of T, pass a message ID as first parameter\n", \ - __FILE__, __LINE__, __FUNCTION__); \ - abort(); \ - } \ T_PUT_int(1, (int)(uintptr_t)(x)); \ } while (0) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index b398d5127e..cfd4296755 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -642,7 +642,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); if ( (instance_cnt_rxtx+proc->sub_frame_step)%10 != proc->subframe_rx && instance_cnt_rxtx!=-1 ) - LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %d, got %d\n", + LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %lld, got %d\n", (instance_cnt_rxtx+proc->sub_frame_step)%10, proc->subframe_rx); instance_cnt_rxtx=proc->subframe_rx; AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); From d31634c358f35548f14daf1645268a741d21b371 Mon Sep 17 00:00:00 2001 From: laurent Date: Sat, 7 Jan 2017 08:23:50 +0100 Subject: [PATCH 05/13] fix nettle --- cmake_targets/CMakeLists.txt | 12 ------------ openair2/UTIL/OSA/osa_stream_eea.c | 3 ++- openair3/SECU/nas_stream_eea2.c | 3 ++- openair3/TEST/test_aes128_ctr_decrypt.c | 3 ++- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 81ddf37503..4f40486801 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1669,18 +1669,6 @@ endif() message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - pkg_search_module(XPM xpm) if(NOT ${XPM_FOUND}) message("PACKAGE xpm not found: some targets will fail") diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c index 6aef6d2588..9e8a3a88b3 100644 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ b/openair2/UTIL/OSA/osa_stream_eea.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "UTIL/LOG/log.h" @@ -191,7 +192,7 @@ int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) } #endif -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index 37f2e298fb..e9f2e7c41a 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "assertions.h" #include "conversions.h" @@ -78,7 +79,7 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) } #endif -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/TEST/test_aes128_ctr_decrypt.c b/openair3/TEST/test_aes128_ctr_decrypt.c index a30dc6c2f2..98987a8d97 100644 --- a/openair3/TEST/test_aes128_ctr_decrypt.c +++ b/openair3/TEST/test_aes128_ctr_decrypt.c @@ -31,6 +31,7 @@ #include #include #include +#include static void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, @@ -41,7 +42,7 @@ void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, uint8_t *data = malloc(length); uint8_t *ctr = malloc(cipher->block_size); -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 cipher->set_encrypt_key(ctx, key_length, key); #else cipher->set_encrypt_key(ctx, key); From 00ebfbb0bc9179a015eb7e7a54d7705e1ee2fdb3 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 1 Feb 2017 15:00:01 +0100 Subject: [PATCH 06/13] fix merge compilation --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 297 +++---------------- 1 file changed, 44 insertions(+), 253 deletions(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 2f2e0088fa..c12cc50ead 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -312,6 +312,7 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); } + return(0); } @@ -495,39 +496,33 @@ extern "C" { // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - uhd::device_addrs_t device_adds = uhd::device::find(args); + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; + uhd::device_addrs_t device_adds = uhd::device::find(args); - if(device_adds.size() == 0) - { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; - - } - - - printf("Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // lock mboard clocks + if(device_adds.size() == 0) { + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } + LOG_I(PHY,"Found USRP X300\n"); + s->usrp = uhd::usrp::multi_usrp::make(args); + // lock mboard clocks if (openair0_cfg[0].clock_source == internal) s->usrp->set_clock_source("internal"); else s->usrp->set_clock_source("external"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); + //Setting device type to USRP X300/X310 + device->type=USRP_X300_DEV; - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: + // this is not working yet, master clock has to be set via constructor + // set master clock rate and sample rate for tx & rx for streaming + //s->usrp->set_master_clock_rate(usrp_master_clock); + + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; openair0_cfg[0].tx_sample_advance = 15; @@ -551,17 +546,17 @@ extern "C" { openair0_cfg[0].tx_sample_advance = 50; openair0_cfg[0].tx_bw = 1.25e6; openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } - } else { - printf("Found USRP B200"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); + } else { + LOG_I(PHY,"Found USRP B200\n"); + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + s->usrp = uhd::usrp::multi_usrp::make(args); // s->usrp->set_rx_subdev_spec(rx_subdev); // s->usrp->set_tx_subdev_spec(tx_subdev); @@ -577,17 +572,14 @@ extern "C" { else s->usrp->set_clock_source("external"); - device->type = USRP_B200_DEV; - - - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - } - else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - } + device->type = USRP_B200_DEV; + if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210; + bw_gain_adjust=0; + } else { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + } switch ((int)openair0_cfg[0].sample_rate) { case 30720000: @@ -626,217 +618,15 @@ extern "C" { openair0_cfg[0].rx_bw = 20e6; break; default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } - - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - //printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); - - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] > gain_range.stop()) { - - printf("RX Gain %lu too high, lower by %f dB\n",i,openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); - printf("RX Gain %lu %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); - } - } - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - //printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); - } - } - - - // display USRP settings - std::cout << boost::format("Actual master clock: %fMHz...") % (s->usrp->get_master_clock_rate()/1e6) << std::endl; - - sleep(1); - - // create tx & rx streamer - uhd::stream_args_t stream_args_rx("sc16", "sc16"); - int samples=openair0_cfg[0].sample_rate; - samples/=24000; - // stream_args_rx.args["spp"] = str(boost::format("%d") % samples); - - for (i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - std::cout << boost::format("rx_max_num_samps %u") % (s->rx_stream->get_max_num_samps()) << std::endl; - //openair0_cfg[0].samples_per_packet = s->rx_stream->get_max_num_samps(); - - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - //stream_args_tx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].tx_num_channels*openair0_cfg[0].samples_per_packet)); - for (i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - std::cout << boost::format("tx_max_num_samps %u") % (s->tx_stream->get_max_num_samps()) << std::endl; - - - /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - } - } - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - } - } - - s->usrp->set_time_now(uhd::time_spec_t(0.0)); - - - for (i=0;iusrp->get_rx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX frequency: %fGHz...") % (s->usrp->get_rx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual RX gain: %f...") % (s->usrp->get_rx_gain(i)) << std::endl; - std::cout << boost::format("Actual RX bandwidth: %fM...") % (s->usrp->get_rx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX antenna: %s...") % (s->usrp->get_rx_antenna(i)) << std::endl; - } - } - - for (i=0;iusrp->get_tx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX frequency: %fGHz...") % (s->usrp->get_tx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual TX gain: %f...") % (s->usrp->get_tx_gain(i)) << std::endl; - std::cout << boost::format("Actual TX bandwidth: %fM...") % (s->usrp->get_tx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX antenna: %s...") % (s->usrp->get_tx_antenna(i)) << std::endl; - } - } - - std::cout << boost::format("Device timestamp: %f...") % (s->usrp->get_time_now().get_real_secs()) << std::endl; - - // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - uhd::device_addrs_t device_adds = uhd::device::find(args); - - if(device_adds.size() == 0) { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; - } - LOG_I(PHY,"Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // lock mboard clocks - s->usrp->set_clock_source("internal"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; - - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); - - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - // from usrp_time_offset - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - - } else { - LOG_I(PHY,"Found USRP B200\n"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); - device->type = USRP_B200_DEV; - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - } else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - } - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); exit(-1); break; } } + + /* device specific */ + //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered + //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_rxrescale = 15;//rescale iqs @@ -870,6 +660,7 @@ extern "C" { // display USRP settings LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); + sleep(1); // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); From 3c191c26f384359381f76b28039ea15b7b8a2e95 Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 9 Feb 2017 17:46:04 +0100 Subject: [PATCH 07/13] fix BCH tracking --- openair2/UTIL/LOG/log.h | 2 + targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 363 +++++++++---------- targets/RT/USER/lte-ue.c | 264 ++++---------- 3 files changed, 245 insertions(+), 384 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 1735a89a73..5e5be23e0d 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -46,7 +46,9 @@ #include #include #include +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #else #include "rtai_fifos.h" diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index c12cc50ead..00db1f46c6 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -66,17 +66,17 @@ typedef struct { // -------------------------------- //! USRP device pointer uhd::usrp::multi_usrp::sptr usrp; - - //create a send streamer and a receive streamer - //! USRP TX Stream - uhd::tx_streamer::sptr tx_stream; - //! USRP RX Stream - uhd::rx_streamer::sptr rx_stream; - //! USRP TX Metadata - uhd::tx_metadata_t tx_md; - //! USRP RX Metadata - uhd::rx_metadata_t rx_md; + //create a send streamer and a receive streamer + //! USRP TX Stream + uhd::tx_streamer::sptr tx_stream; + //! USRP RX Stream + uhd::rx_streamer::sptr rx_stream; + + //! USRP TX Metadata + uhd::tx_metadata_t tx_md; + //! USRP RX Metadata + uhd::rx_metadata_t rx_md; //! Sampling rate double sample_rate; @@ -109,7 +109,7 @@ static int trx_usrp_start(openair0_device *device) { // init recv and send streaming uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); - cmd.stream_now = true; + cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); @@ -122,7 +122,7 @@ static int trx_usrp_start(openair0_device *device) { s->rx_timestamp = 0; return 0; } -/*! \brief Terminate operation of the USRP transceiver -- free all associated resources +/*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ static void trx_usrp_end(openair0_device *device) { @@ -151,36 +151,33 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); s->tx_md.has_time_spec = flags; - - if(flags>0) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; - if (flags == 2) { // start of burst - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; - } - else if (flags == 3) { // end of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = true; - } - else if (flags == 4) { // start and end - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = true; - } - else if (flags==1) { // middle of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = false; - } - - if (cc>1) { - std::vector buff_ptrs; + if(flags>0) + s->tx_md.has_time_spec = true; + else + s->tx_md.has_time_spec = false; + + if (flags == 2) { // start of burst + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; + } else if (flags == 3) { // end of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = true; + } else if (flags == 4) { // start and end + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = true; + } else if (flags==1) { // middle of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = false; + } + + if (cc>1) { + std::vector buff_ptrs; for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); + ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); } else - ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); + ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); @@ -239,27 +236,27 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp for (int j=0; jtype == USRP_X300_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; + + for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); + } } - } else if (device->type == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; - - for (int i=0;irx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); - } - } if (samples_received < nsamps) LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); @@ -280,39 +277,39 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp * \param b second variable */ static bool is_equal(double a, double b) { - return std::fabs(a-b) < std::numeric_limits::epsilon(); + return std::fabs(a-b) < std::numeric_limits::epsilon(); } void *freq_thread(void *arg) { - - openair0_device *device=(openair0_device *)arg; - usrp_state_t *s = (usrp_state_t*)device->priv; - - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + + openair0_device *device=(openair0_device *)arg; + usrp_state_t *s = (usrp_state_t*)device->priv; + + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); } /*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application * \param dummy dummy variable not used - * \returns 0 in success + * \returns 0 in success */ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) { - usrp_state_t *s = (usrp_state_t*)device->priv; - pthread_t f_thread; + usrp_state_t *s = (usrp_state_t*)device->priv; + pthread_t f_thread; - printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); + printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - // spawn a thread to handle the frequency change to not block the calling thread - if (dont_block == 1) - pthread_create(&f_thread,NULL,freq_thread,(void*)device); - else { - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); - } + // spawn a thread to handle the frequency change to not block the calling thread + if (dont_block == 1) + pthread_create(&f_thread,NULL,freq_thread,(void*)device); + else { + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + } - return(0); + return(0); } @@ -361,14 +358,14 @@ int trx_usrp_set_gains(openair0_device* device, openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], openair0_cfg[0].rx_gain[0],gain_range.stop()); - return(0); + return(0); } /*! \brief Stop USRP * \param card refers to the hardware index to use */ int trx_usrp_stop(openair0_device* device) { - return(0); + return(0); } /*! \brief USRPB210 RX calibration table */ @@ -441,12 +438,12 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_ LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", i, openair0_cfg->rx_gain_calib_table[i].freq, - openair0_cfg->rx_gain_calib_table[i].offset,diff); - if (min_diff > diff) { - min_diff = diff; - openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; - } - i++; + openair0_cfg->rx_gain_calib_table[i].offset,diff); + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; + } + i++; } } @@ -491,11 +488,11 @@ extern "C" { double usrp_master_clock = 184.32e6; std::string args = "type=x300"; - // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate - args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - + // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate + args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; uhd::device_addrs_t device_adds = uhd::device::find(args); @@ -507,10 +504,10 @@ extern "C" { LOG_I(PHY,"Found USRP X300\n"); s->usrp = uhd::usrp::multi_usrp::make(args); // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); //Setting device type to USRP X300/X310 device->type=USRP_X300_DEV; @@ -523,29 +520,29 @@ extern "C" { switch ((int)openair0_cfg[0].sample_rate) { case 30720000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + case 7680000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + case 1920000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 1.25e6; + openair0_cfg[0].rx_bw = 1.25e6; break; default: LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); @@ -558,19 +555,19 @@ extern "C" { args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; s->usrp = uhd::usrp::multi_usrp::make(args); - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // do not explicitly set the clock to "internal", because this will disable the gpsdo - // // lock mboard clocks - // s->usrp->set_clock_source("internal"); - // set master clock rate and sample rate for tx & rx for streaming + // s->usrp->set_rx_subdev_spec(rx_subdev); + // s->usrp->set_tx_subdev_spec(tx_subdev); - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); + // do not explicitly set the clock to "internal", because this will disable the gpsdo + // // lock mboard clocks + // s->usrp->set_clock_source("internal"); + // set master clock rate and sample rate for tx & rx for streaming + + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); device->type = USRP_B200_DEV; if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { @@ -581,52 +578,52 @@ extern "C" { bw_gain_adjust=1; } - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 23040000: + s->usrp->set_master_clock_rate(23.04e6); //to be checked + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + s->usrp->set_master_clock_rate(30.72e06); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 103; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 7680000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 1920000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + default: LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); exit(-1); break; } } - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered + /* device specific */ + //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered + //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_rxrescale = 15;//rescale iqs @@ -660,7 +657,7 @@ extern "C" { // display USRP settings LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); - sleep(1); + sleep(1); // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); @@ -711,24 +708,24 @@ extern "C" { device->trx_start_func = trx_usrp_start; device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; - s->sample_rate = openair0_cfg[0].sample_rate; - // TODO: - // init tx_forward_nsamps based usrp_time_offset ex - if(is_equal(s->sample_rate, (double)30.72e6)) - s->tx_forward_nsamps = 176; - if(is_equal(s->sample_rate, (double)15.36e6)) - s->tx_forward_nsamps = 90; - if(is_equal(s->sample_rate, (double)7.68e6)) - s->tx_forward_nsamps = 50; - return 0; - } + s->sample_rate = openair0_cfg[0].sample_rate; + // TODO: + // init tx_forward_nsamps based usrp_time_offset ex + if(is_equal(s->sample_rate, (double)30.72e6)) + s->tx_forward_nsamps = 176; + if(is_equal(s->sample_rate, (double)15.36e6)) + s->tx_forward_nsamps = 90; + if(is_equal(s->sample_rate, (double)7.68e6)) + s->tx_forward_nsamps = 50; + return 0; + } } /*@}*/ diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5115a824fc..0f341d29a5 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -79,6 +79,7 @@ #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL +#define FIFO_PRIORITY 40 typedef enum { pss=0, @@ -241,171 +242,69 @@ static void *UE_thread_synch(void *arg) { int current_offset = 0; sync_mode_t sync_mode = pbch; int CC_id = UE->CC_id; - int ind; - int found; int freq_offset=0; - UE->is_synchronized = 0; - printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); - printf("waiting for sync (UE_thread_synch) \n"); - -#ifndef DEADLINE_SCHEDULER - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; cpu_set_t cpuset; - - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ CPU_ZERO(&cpuset); + CPU_SET(3, &cpuset); + // this thread priority must be lower that the main acquisition thread + init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, + "sync UE"); -#ifdef CPU_AFFINITY - if (get_nprocs() >2) { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - } -#endif - - /* Check the actual affinity mask assigned to the thread */ - - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - - } - - LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); - -#endif - - printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); - ind = 0; - found = 0; - + UE->is_synchronized = 0; if (UE->UE_scan == 0) { - do { + int ind; + for ( ind=0; + ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]); + ind++) { current_band = eutra_bands[ind].band; - printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); - - if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) { + LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); + if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) { for (i=0; i<4; i++) uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; - - found = 1; break; } - - ind++; - } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - - if (found == 0) { - exit_fun("Can't find EUTRA band for frequency"); - return &UE_thread_synch_retval; } + AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency"); - - - - - - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels); + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", + downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0], + oai_exit, openair0_cfg[0].rx_num_channels); for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; if (uplink_frequency_offset[CC_id][i] != 0) // openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; else //FDD openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; } - sync_mode = pbch; - } else if (UE->UE_scan == 1) { + } else { current_band=0; - for (i=0; irf_map.card].rx_num_channels; i++) { downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; - + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = + bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; } } - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_sync_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); - - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } + AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); while (oai_exit==0) { - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } - - - while (UE->proc.instance_cnt_synch < 0) { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + while (UE->proc.instance_cnt_synch < 0) // the thread waits here most of the time pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); - } - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_synch_retval; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 ); + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); switch (sync_mode) { case pss: @@ -453,17 +352,16 @@ static void *UE_thread_synch(void *arg) { UE->UE_scan_carrier ); if (UE->UE_scan_carrier == 1) { - UE->UE_scan_carrier = 0; // rerun with new cell parameters and frequency-offset for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (freq_offset >= 0) { + if (freq_offset >= 0) openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += UE->common_vars.freq_offset; - } else { + else openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; - } - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; freq_offset=0; } @@ -506,7 +404,9 @@ static void *UE_thread_synch(void *arg) { oai_exit=1; } } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); UE->is_synchronized = 1; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if( UE->mode == rx_dump_frame ) { FILE *fd; @@ -524,7 +424,10 @@ static void *UE_thread_synch(void *arg) { exit(0); } } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); UE->is_synchronized = 0; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + } } } @@ -532,12 +435,9 @@ static void *UE_thread_synch(void *arg) { // initial sync failed // calculate new offset and try again if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) { + if (freq_offset >= 0) freq_offset += 100; - freq_offset *= -1; - } else { - freq_offset *= -1; - } + freq_offset *= -1; if (abs(freq_offset) > 7500) { LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); @@ -554,8 +454,6 @@ static void *UE_thread_synch(void *arg) { mac_xface->macphy_exit("No cell synchronization found, abandoning"); return &UE_thread_synch_retval; // not reached } - } else { - } LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", freq_offset, @@ -566,40 +464,22 @@ static void *UE_thread_synch(void *arg) { for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - - if (UE->UE_scan_carrier==1) { + if (UE->UE_scan_carrier==1) openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } } - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 - break; - case si: default: break; } - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } - + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); // indicate readiness UE->proc.instance_cnt_synch--; - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); } // while !oai_exit @@ -631,7 +511,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(proc->sub_frame_start+1, &cpuset); - init_thread(900000,1000000 , 40, &cpuset,//sched_get_priority_max(SCHED_FIFO)-1, + init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, threadname); while (!oai_exit) { @@ -750,12 +630,11 @@ void *UE_thread(void *arg) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(3, &cpuset); - init_thread(100000, 500000, 40, &cpuset, //sched_get_priority_max(SCHED_FIFO), + init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, "main UE"); AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); UE->rfdevice.host_type = BBU_HOST; - sleep(1); init_UE_threads(UE); #ifdef NAS_UE @@ -767,13 +646,12 @@ void *UE_thread(void *arg) { int sub_frame=-1; //int cumulated_shift=0; while (!oai_exit) { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + int instance_cnt_synch = UE->proc.instance_cnt_synch; + int is_synchronized = UE->is_synchronized; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - if (UE->is_synchronized == 0) { - - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - int instance_cnt_synch = UE->proc.instance_cnt_synch; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - + if (is_synchronized == 0) { if (instance_cnt_synch < 0) { // we can invoke the synch // grab 10 ms of signal and wakeup synch thread for (int i=0; iframe_parms.nb_antennas_rx; i++) @@ -793,14 +671,12 @@ void *UE_thread(void *arg) { LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); exit_fun("nothing to add"); } - } // - else { + } else { // grab 10 ms of signal into dummy buffer - if (UE->mode != loop_through_memory) { for (int i=0; iframe_parms.nb_antennas_rx; i++) rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0; sf<10; sf++) { + for (int sf=0; sf<10; sf++) // printf("Reading dummy sf %d\n",sf); AssertFatal ( UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice, @@ -808,8 +684,6 @@ void *UE_thread(void *arg) { rxp, UE->frame_parms.samples_per_tti, UE->frame_parms.nb_antennas_rx), ""); - - } } } @@ -861,32 +735,20 @@ void *UE_thread(void *arg) { readBlockSize=UE->frame_parms.samples_per_tti; writeBlockSize=UE->frame_parms.samples_per_tti; } else { - static int rx_correction_timer=5; - static int rx_off_diff =0; - if ((UE->rx_offset<(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset > 0) && - (rx_correction_timer == 0)) { - rx_off_diff = -1 ; - LOG_D(PHY,"AbsSubframe %d.%d UE->rx_offset %d > %d, diff %d\n", - proc->frame_rx,proc->subframe_rx,UE->rx_offset,0,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset < ((10*UE->frame_parms.samples_per_tti))) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = 1; - LOG_D(PHY,"AbsSubframe %d.%d UE->rx_offset %d < %d, diff %d\n", - proc->frame_rx,proc->subframe_rx,UE->rx_offset,10*UE->frame_parms.samples_per_tti,rx_off_diff); - rx_correction_timer = 5; - } - if (rx_correction_timer>0) - rx_correction_timer--; - UE->rx_offset_diff = rx_off_diff; + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && + UE->rx_offset > 0 ) + UE->rx_offset_diff = -1 ; + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && + UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) + UE->rx_offset_diff = 1; + LOG_D(PHY,"SET rx_off_diff to %d\n",UE->rx_offset_diff); - rx_off_diff = 0; - readBlockSize=UE->frame_parms.samples_per_tti- - UE->frame_parms.ofdm_symbol_size- - UE->frame_parms.nb_prefix_samples0; - writeBlockSize=UE->frame_parms.samples_per_tti - rx_off_diff; + readBlockSize=UE->frame_parms.samples_per_tti - + UE->frame_parms.ofdm_symbol_size - + UE->frame_parms.nb_prefix_samples0 - + UE->rx_offset_diff; + writeBlockSize=UE->frame_parms.samples_per_tti - + UE->rx_offset_diff; } AssertFatal(readBlockSize == From b9e03cf2517bea0d3621b84439e70f80194f5f65 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 9 Feb 2017 19:17:28 +0100 Subject: [PATCH 08/13] fix usrp thread priority --- common/utils/T/T.h | 12 ++++++++++++ targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/common/utils/T/T.h b/common/utils/T/T.h index bd090ac221..819615131e 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -188,6 +188,12 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ + if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ + printf("%s:%d:%s: " \ + "bad use of T, pass a message ID as first parameter\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ struct timespec T_HEADER_time; \ if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \ memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \ @@ -199,6 +205,12 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ + if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ + printf("%s:%d:%s: " \ + "bad use of T, pass a message ID as first parameter\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ T_PUT_int(1, (int)(uintptr_t)(x)); \ } while (0) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 00db1f46c6..2ac70b2d82 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -469,7 +469,7 @@ extern "C" { * \param openair0_cfg RF frontend parameters set by application */ int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { - //uhd::set_thread_priority_safe(1.0); + uhd::set_thread_priority_safe(1.0); usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); // Initialize USRP device device->openair0_cfg = openair0_cfg; From 012d333c8ef61f5bf53559d00d984a82d608c1d6 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 10 Feb 2017 17:08:28 +0100 Subject: [PATCH 09/13] tune USRP/USB packet size --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 2ac70b2d82..b2b386ba7d 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -662,14 +662,18 @@ extern "C" { // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); int samples=openair0_cfg[0].sample_rate; - //while ( samples > s->rx_stream->get_max_num_samps()) - samples/=24000; - stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); + samples/=10000; + LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); + if ( samples < max ) + stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + LOG_I(PHY,"rx_max_num_samps %u\n", + s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - LOG_I(PHY,"rx_max_num_samps %u\n",s->rx_stream->get_max_num_samps()); - + uhd::stream_args_t stream_args_tx("sc16", "sc16"); for (int i = 0; i Date: Mon, 13 Feb 2017 13:58:09 +0100 Subject: [PATCH 10/13] optim measurement function checkcpu() --- targets/RT/USER/lte-ue.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 0f341d29a5..1292fef095 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -528,9 +528,11 @@ static void *UE_thread_rxn_txnp4(void *arg) { initRefTimes(t3); pickTime(current); updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); + check(2200); // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + check(100); if ((sf_type == SF_DL) || (UE->frame_parms.frame_type == FDD) || (sf_type == SF_S)) { @@ -553,7 +555,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { } phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); } - + check(900); if (UE->mac_enabled==1) { ret = mac_xface->ue_scheduler(UE->Mod_id, @@ -583,6 +585,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); } } + check(350); // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || @@ -596,6 +599,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { if (UE->mode != loop_through_memory) phy_procedures_UE_S_TX(UE,0,0,no_relay); updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); + check(300); } @@ -603,10 +607,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { return &UE_thread_rxtx_retval; } -#define RX_OFF_MAX 10 -#define RX_OFF_MIN 5 -#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2) - /*! * \brief This is the main UE thread. * This thread controls the other three UE threads: From d65d91ddcc8f08a637f9eef9f72006e42687cd95 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 14 Feb 2017 18:18:34 +0100 Subject: [PATCH 11/13] gcc warning fix --- openair2/UTIL/LOG/log.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 5e5be23e0d..b31efbcf74 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -370,10 +370,10 @@ static inline uint64_t checkTCPU(int timeout, char * file, int line) { double microCycles=(double)(cpuf*1000); int duration=(int)((cur-last)/microCycles); if ( last!=0 && duration > timeout ) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - printf("%.3f %s:%d lte-ue delay %d (exceed %d), CPU for this period: %.2f\n", ts.tv_sec+ts.tv_nsec/(1000*1000*1000.0), file, line, - duration, timeout, (CPUTime-lastCPUTime)/1000.0 ); + //struct timespec ts; + //clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line, + duration, timeout, (long long)CPUTime-lastCPUTime ); } last=cur; lastCPUTime=CPUTime; From 23c75476984c2eb33e62fe566d53c6d109a135fa Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 14 Feb 2017 18:24:31 +0100 Subject: [PATCH 12/13] remove debug traces --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 3 --- targets/RT/USER/lte-ue.c | 5 ----- 2 files changed, 8 deletions(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index b2b386ba7d..dc2589de44 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -266,9 +266,6 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp s->rx_count += nsamps; s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; -#ifdef DEBUG_USRP - check(50); -#endif return samples_received; } diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 1292fef095..0a7c87a152 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -528,11 +528,9 @@ static void *UE_thread_rxn_txnp4(void *arg) { initRefTimes(t3); pickTime(current); updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); - check(2200); // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - check(100); if ((sf_type == SF_DL) || (UE->frame_parms.frame_type == FDD) || (sf_type == SF_S)) { @@ -555,7 +553,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { } phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); } - check(900); if (UE->mac_enabled==1) { ret = mac_xface->ue_scheduler(UE->Mod_id, @@ -585,7 +582,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); } } - check(350); // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || @@ -599,7 +595,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { if (UE->mode != loop_through_memory) phy_procedures_UE_S_TX(UE,0,0,no_relay); updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); - check(300); } From be0541aa8c2d7a1eacd0164bf717fa4588c2fd8d Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 16 Feb 2017 11:38:38 +0100 Subject: [PATCH 13/13] remove a race --- .../GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf | 8 ++++---- targets/RT/USER/lte-ue.c | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index 27ec283115..752ab6d123 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -31,16 +31,16 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2630000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; - N_RB_DL = 25; + N_RB_DL = 50; Nid_cell_mbsfn = 0; nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 80; - rx_gain = 90; + tx_gain = 90; + rx_gain = 110; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index decc793411..b4e02f1874 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -625,7 +625,9 @@ void *UE_thread(void *arg) { rxp, UE->frame_parms.samples_per_tti*10, UE->frame_parms.nb_antennas_rx), ""); + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); instance_cnt_synch = ++UE->proc.instance_cnt_synch; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if (instance_cnt_synch == 0) { AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); } else {