From d83c935e4217f77584854c3c5730de6e53015622 Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Fri, 21 Feb 2020 16:19:43 +0100 Subject: [PATCH 1/6] add trx write thread --- executables/nr-ru.c | 6 + targets/ARCH/COMMON/common_lib.h | 36 +++++ targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 154 ++++++++++++++----- 3 files changed, 161 insertions(+), 35 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 0003cf770d..21a62678cf 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1444,6 +1444,9 @@ static void *ru_thread( void *param ) { // if this is a slave RRU, try to synchronize on the DL frequency if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); + + // start trx write thread + start_write_thread(ru); } pthread_mutex_lock(&proc->mutex_FH1); @@ -1651,6 +1654,9 @@ int stop_rf(RU_t *ru) { return 0; } +int start_write_thread(RU_t *ru) { + return(ru->rfdevice.trx_write_init(&ru->rfdevice)); +} void init_RU_proc(RU_t *ru) { int i=0; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 03ab4da5f9..d92c38a2a7 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -276,8 +276,38 @@ typedef struct { void *rx; } if_buffer_t; +typedef struct { + openair0_timestamp timestamp; + void **buff;// buffer to be write; + int nsamps; + int cc; + signed char first_packet; + signed char last_packet; +} openair0_write_package_t; + +typedef struct { + openair0_write_package_t write_package[10]; + /// write package number + int num_package; + int start; + int end; + /// \internal This variable is protected by \ref mutex_write + int instance_cnt_write; + /// pthread struct for trx write thread + pthread_t pthread_write; + /// pthread attributes for trx write thread + pthread_attr_t attr_write; + /// condition varible for trx write thread + pthread_cond_t cond_write; + /// mutex for trx write thread + pthread_mutex_t mutex_write; +} openair0_thread_t; + /*!\brief structure holds the parameters to configure USRP devices */ struct openair0_device_t { + /*!tx write thread*/ + openair0_thread_t write_thread; + /*!brief Module ID of this device */ int Mod_id; @@ -400,6 +430,12 @@ struct openair0_device_t { * \param arg pointer to capabilities or configuration */ void (*configure_rru)(int idx, void *arg); + + /*! \brief RRU Configuration callback + * \param idx RU index + * \param arg pointer to capabilities or configuration + */ + int (*trx_write_init)(openair0_device *device); }; /* type of device init function, implemented in shared lib */ diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index eb8c6ec010..798b6b6b4d 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -406,37 +406,9 @@ static int trx_usrp_write_recplay(openair0_device *device, openair0_timestamp ti */ 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 nsamps2; // aligned to upper 32 or 16 byte boundary -#if defined(__x86_64) || defined(__i386__) - #ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[8][nsamps2]; - #else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tx[8][nsamps2]; - #endif -#elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tx[8][nsamps2]; -#else -#error Unsupported CPU architecture, USRP device cannot be built -#endif - - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; iwrite_thread; + openair0_write_package_t *write_package = write_thread->write_package; boolean_t first_packet_state=false,last_packet_state=false; @@ -469,9 +441,98 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, last_packet_state = true; } + pthread_mutex_lock(&write_thread->mutex_write); + write_thread->end = (write_thread->end + 1)% write_thread->num_package; + end = write_thread->end; + write_package[end].timestamp = timestamp; + write_package[end].nsamps = nsamps; + write_package[end].cc = cc; + write_package[end].first_packet = first_packet_state; + write_package[end].last_packet = last_packet_state; + write_package[end].buff = buff; + write_thread->instance_cnt_write = 0; + pthread_cond_signal(&write_thread->cond_write); + printf("trx_usrp_write signal end\n"); + pthread_mutex_unlock(&write_thread->mutex_write); + + + return ret; +} + +//-----------------------start-------------------------- +/*! \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 which 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 antennas + @param flags flags must be set to TRUE if timestamp parameter needs to be applied +*/ +void *trx_usrp_write_thread(void * arg){ + int ret=0; + openair0_device *device=(openair0_device *)arg; + openair0_thread_t *write_thread = &device->write_thread; + openair0_write_package_t *write_package = write_thread->write_package; + + + + while(1){ + pthread_mutex_lock(&write_thread->mutex_write); + printf("waiting for signal \n"); + while (write_thread->instance_cnt_write < 0) { + pthread_cond_wait(&write_thread->cond_write,&write_thread->mutex_write); // this unlocks mutex_rxtx while waiting and then locks it again + } + printf("signal unlock\n"); + int start = write_thread->start; + printf("start = %d, end = %d\n", start, write_thread->end); + openair0_timestamp timestamp = write_package[start].timestamp; + void **buff = write_package[start].buff; + int nsamps = write_package[start].nsamps; + int cc = write_package[start].cc; + bool first_packet = write_package[start].first_packet; + bool last_packet = write_package[start].last_packet; + if(write_thread->end == (write_thread->start + 1)% write_thread->num_package){ + write_thread->instance_cnt_write = -1; + } + write_thread->start = (write_thread->start + 1)% write_thread->num_package; + pthread_mutex_unlock(&write_thread->mutex_write); + printf("end of write thread signal getting \n"); + + usrp_state_t *s = (usrp_state_t *)device->priv; + int nsamps2; // aligned to upper 32 or 16 byte boundary + #if defined(__x86_64) || defined(__i386__) + #ifdef __AVX2__ + nsamps2 = (nsamps+7)>>3; + __m256i buff_tx[8][nsamps2]; + #else + nsamps2 = (nsamps+3)>>2; + __m128i buff_tx[8][nsamps2]; + #endif + #elif defined(__arm__) + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tx[8][nsamps2]; + #else + #error Unsupported CPU architecture, USRP device cannot be built + #endif + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; itx_md.has_time_spec = true; - s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; - s->tx_md.end_of_burst = last_packet_state; + s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet; + s->tx_md.end_of_burst = last_packet; s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); s->tx_count++; @@ -483,11 +544,33 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); } else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); - if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); + if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); - return ret; + if(0) break; + } + + return NULL; } +int trx_write_init(openair0_device *device){ + + uhd::set_thread_priority_safe(1.0); + openair0_thread_t *write_thread = &device->write_thread; + printf("initializing tx write thread\n"); + + write_thread->num_package = 10; + write_thread->start = 0; + write_thread->end = 0; + write_thread->instance_cnt_write = -1; + printf("end of tx write thread\n"); + + pthread_create(&write_thread->pthread_write,NULL,trx_usrp_write_thread,(void *)device); + + return(0); +} + +//---------------------end------------------------- + /*! \brief Receive samples from iq file. * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for * the first channel. *ptimestamp is the time at which the first sample @@ -917,6 +1000,7 @@ extern "C" { 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->trx_write_init = trx_write_init; if ( s->recplay_mode == RECPLAY_REPLAYMODE) { // Replay subframes from from file From 61a24472db8f67eefad3e2e506379237e6eb2ede Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Tue, 25 Feb 2020 14:07:01 +0100 Subject: [PATCH 2/6] assertion removal and debuging message adding --- executables/nr-ru.c | 10 ++++- openair1/PHY/defs_RU.h | 2 + targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 44 +++++++++++++------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 21a62678cf..9abdd15192 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -717,6 +717,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; //nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; void *txp[ru->nb_tx]; + char *print_test[ru->nb_tx]; unsigned int txs; int i; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), @@ -761,23 +762,27 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { for (i=0; inb_tx; i++){ txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; } +print_test[0] = (char *)&ru->common.txdata[0][(slot*fp->samples_per_slot)-sf_extension]; +printf("txdata[0] = %d\n", print_test[0]); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers start_meas(&ru->tx_fhaul); +printf("sending trx write from tx_rf\n"); txs = ru->rfdevice.trx_write_func(&ru->rfdevice, timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, txp, siglen+sf_extension, ru->nb_tx, flags); +//printf("txp = %s\n", (char*)txp[0]); stop_meas(&ru->tx_fhaul); LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); + //AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); } } @@ -1446,7 +1451,7 @@ static void *ru_thread( void *param ) { if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); // start trx write thread - start_write_thread(ru); + ru->start_write_thread(ru); } pthread_mutex_lock(&proc->mutex_FH1); @@ -2051,6 +2056,7 @@ void set_function_spec_param(RU_t *ru) { ru->fh_south_out = tx_rf; // local synchronous RF TX ru->start_rf = start_rf; // need to start the local RF interface ru->stop_rf = stop_rf; + ru->start_write_thread = start_write_thread; // starting RF TX in different thread printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf); /* if (ru->function == gNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 94afeed12f..1d1a7ca257 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -538,6 +538,8 @@ typedef struct RU_t_s { void (*wakeup_prach_gNB)(struct PHY_VARS_gNB_s *gNB, struct RU_t_s *ru, int frame, int subframe); /// function pointer to wakeup routine in lte-enb. void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru, int frame, int subframe); + /// function pointer to start a thread of tx write for USRP. + int (*start_write_thread)(struct RU_t_s *ru); /// function pointer to NB entry routine void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 798b6b6b4d..33a4c71ede 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -440,23 +440,25 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, first_packet_state = false; last_packet_state = true; } - +printf("~~~1 buff in usrp write = %d\n", buff[0]); pthread_mutex_lock(&write_thread->mutex_write); - write_thread->end = (write_thread->end + 1)% write_thread->num_package; end = write_thread->end; +printf("package being write is %d\n", end); write_package[end].timestamp = timestamp; write_package[end].nsamps = nsamps; write_package[end].cc = cc; write_package[end].first_packet = first_packet_state; write_package[end].last_packet = last_packet_state; write_package[end].buff = buff; +printf("~~~2 write_package buff in usrp write = %d\n", write_package[end].buff[0]); write_thread->instance_cnt_write = 0; + write_thread->end = (write_thread->end + 1)% write_thread->num_package; pthread_cond_signal(&write_thread->cond_write); printf("trx_usrp_write signal end\n"); pthread_mutex_unlock(&write_thread->mutex_write); - return ret; + return 0; } //-----------------------start-------------------------- @@ -474,7 +476,15 @@ void *trx_usrp_write_thread(void * arg){ openair0_thread_t *write_thread = &device->write_thread; openair0_write_package_t *write_package = write_thread->write_package; - + usrp_state_t *s; + int nsamps2; // aligned to upper 32 or 16 byte boundary + int start; + openair0_timestamp timestamp; + void **buff; + int nsamps; + int cc; + signed char first_packet; + signed char last_packet; while(1){ pthread_mutex_lock(&write_thread->mutex_write); @@ -483,23 +493,24 @@ void *trx_usrp_write_thread(void * arg){ pthread_cond_wait(&write_thread->cond_write,&write_thread->mutex_write); // this unlocks mutex_rxtx while waiting and then locks it again } printf("signal unlock\n"); - int start = write_thread->start; - printf("start = %d, end = %d\n", start, write_thread->end); - openair0_timestamp timestamp = write_package[start].timestamp; - void **buff = write_package[start].buff; - int nsamps = write_package[start].nsamps; - int cc = write_package[start].cc; - bool first_packet = write_package[start].first_packet; - bool last_packet = write_package[start].last_packet; - if(write_thread->end == (write_thread->start + 1)% write_thread->num_package){ + s = (usrp_state_t *)device->priv; + start = write_thread->start; + printf("package bing use is start = %d, end = %d\n", start, write_thread->end); + timestamp = write_package[start].timestamp; + buff = write_package[start].buff; + nsamps = write_package[start].nsamps; + cc = write_package[start].cc; + first_packet = write_package[start].first_packet; + last_packet = write_package[start].last_packet; + write_thread->start = (write_thread->start + 1)% write_thread->num_package; + if(write_thread->end == write_thread->start){ write_thread->instance_cnt_write = -1; } - write_thread->start = (write_thread->start + 1)% write_thread->num_package; pthread_mutex_unlock(&write_thread->mutex_write); printf("end of write thread signal getting \n"); +printf("~~~2.5 write_package buff in thread = %d\n", write_package[start].buff[0]); +printf("~~~3 buff in tx write thread= %d\n", buff[0]); - usrp_state_t *s = (usrp_state_t *)device->priv; - int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -545,6 +556,7 @@ void *trx_usrp_write_thread(void * arg){ ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); } else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); +printf("end of sending buffer in trx write thread\n"); if(0) break; } From c2b3867f8a7469fe5b3321cf2ae5944739a06bdb Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Tue, 25 Feb 2020 15:16:18 +0100 Subject: [PATCH 3/6] fix for not using pointer to stash --- executables/nr-ru.c | 2 +- targets/ARCH/COMMON/common_lib.h | 2 +- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 9abdd15192..ec9414af87 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -763,7 +763,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; } print_test[0] = (char *)&ru->common.txdata[0][(slot*fp->samples_per_slot)-sf_extension]; -printf("txdata[0] = %d\n", print_test[0]); +printf("txdata[0] = %p\n", print_test[0]); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index d92c38a2a7..6dd3a84b7e 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -278,7 +278,7 @@ typedef struct { typedef struct { openair0_timestamp timestamp; - void **buff;// buffer to be write; + void *buff[8];// buffer to be write; int nsamps; int cc; signed char first_packet; diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 33a4c71ede..e6f0a92840 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -440,7 +440,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, first_packet_state = false; last_packet_state = true; } -printf("~~~1 buff in usrp write = %d\n", buff[0]); +printf("~~~1 buff in usrp write = %p\n", buff[0]); pthread_mutex_lock(&write_thread->mutex_write); end = write_thread->end; printf("package being write is %d\n", end); @@ -449,8 +449,9 @@ printf("package being write is %d\n", end); write_package[end].cc = cc; write_package[end].first_packet = first_packet_state; write_package[end].last_packet = last_packet_state; - write_package[end].buff = buff; -printf("~~~2 write_package buff in usrp write = %d\n", write_package[end].buff[0]); + for (int i = 0; i < cc; i++) + write_package[end].buff[i] = buff[i]; +printf("~~~2 write_package buff in usrp write = %p\n", write_package[end].buff[0]); write_thread->instance_cnt_write = 0; write_thread->end = (write_thread->end + 1)% write_thread->num_package; pthread_cond_signal(&write_thread->cond_write); @@ -508,8 +509,8 @@ void *trx_usrp_write_thread(void * arg){ } pthread_mutex_unlock(&write_thread->mutex_write); printf("end of write thread signal getting \n"); -printf("~~~2.5 write_package buff in thread = %d\n", write_package[start].buff[0]); -printf("~~~3 buff in tx write thread= %d\n", buff[0]); +printf("~~~2.5 write_package buff in thread = %p\n", write_package[start].buff[0]); +printf("~~~3 buff in tx write thread= %p\n", buff[0]); #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ From d30a28c3685574c93121f7297fe6ec5a378082ef Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Tue, 25 Feb 2020 16:49:39 +0100 Subject: [PATCH 4/6] adding check for overflow, removing prints and parameter setting fix --- executables/nr-ru.c | 7 +--- targets/ARCH/COMMON/common_lib.h | 9 ++--- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 35 ++++++++------------ 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ec9414af87..f7d63a94ad 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -717,7 +717,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; //nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; void *txp[ru->nb_tx]; - char *print_test[ru->nb_tx]; unsigned int txs; int i; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), @@ -762,27 +761,23 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { for (i=0; inb_tx; i++){ txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; } -print_test[0] = (char *)&ru->common.txdata[0][(slot*fp->samples_per_slot)-sf_extension]; -printf("txdata[0] = %p\n", print_test[0]); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers start_meas(&ru->tx_fhaul); -printf("sending trx write from tx_rf\n"); txs = ru->rfdevice.trx_write_func(&ru->rfdevice, timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, txp, siglen+sf_extension, ru->nb_tx, flags); -//printf("txp = %s\n", (char*)txp[0]); stop_meas(&ru->tx_fhaul); LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - //AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); + AssertFatal(txs == 0,"trx write function error %d\n", txs); } } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 6dd3a84b7e..4889f248e4 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -48,6 +48,9 @@ #define RAU_LOCAL_RADIO_HEAD 0 #define RAU_REMOTE_RADIO_HEAD 1 +#define WRITE_THREAD_PACKAGE 10 +#define WRITE_THREAD_BUFFER_SIZE 8 + #ifndef MAX_CARDS #define MAX_CARDS 8 #endif @@ -278,7 +281,7 @@ typedef struct { typedef struct { openair0_timestamp timestamp; - void *buff[8];// buffer to be write; + void *buff[WRITE_THREAD_BUFFER_SIZE];// buffer to be write; int nsamps; int cc; signed char first_packet; @@ -286,9 +289,7 @@ typedef struct { } openair0_write_package_t; typedef struct { - openair0_write_package_t write_package[10]; - /// write package number - int num_package; + openair0_write_package_t write_package[WRITE_THREAD_PACKAGE]; int start; int end; /// \internal This variable is protected by \ref mutex_write diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index e6f0a92840..b0b126634a 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -405,11 +405,11 @@ static int trx_usrp_write_recplay(openair0_device *device, openair0_timestamp ti @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) { - int ret=0; int end; openair0_thread_t *write_thread = &device->write_thread; openair0_write_package_t *write_package = write_thread->write_package; + AssertFatal( WRITE_THREAD_BUFFER_SIZE >= cc,"Do not support more than %d cc number\n", WRITE_THREAD_BUFFER_SIZE); boolean_t first_packet_state=false,last_packet_state=false; @@ -440,10 +440,15 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, first_packet_state = false; last_packet_state = true; } -printf("~~~1 buff in usrp write = %p\n", buff[0]); pthread_mutex_lock(&write_thread->mutex_write); + + if(write_thread->instance_cnt_write >= WRITE_THREAD_PACKAGE){ + LOG_W(HW,"Buffer overflow, resetting write package\n"); + write_thread->end = write_thread->start; + write_thread->instance_cnt_write = 0; + } + end = write_thread->end; -printf("package being write is %d\n", end); write_package[end].timestamp = timestamp; write_package[end].nsamps = nsamps; write_package[end].cc = cc; @@ -451,11 +456,9 @@ printf("package being write is %d\n", end); write_package[end].last_packet = last_packet_state; for (int i = 0; i < cc; i++) write_package[end].buff[i] = buff[i]; -printf("~~~2 write_package buff in usrp write = %p\n", write_package[end].buff[0]); - write_thread->instance_cnt_write = 0; - write_thread->end = (write_thread->end + 1)% write_thread->num_package; + ++write_thread->instance_cnt_write; + write_thread->end = (write_thread->end + 1)% WRITE_THREAD_PACKAGE; pthread_cond_signal(&write_thread->cond_write); - printf("trx_usrp_write signal end\n"); pthread_mutex_unlock(&write_thread->mutex_write); @@ -489,28 +492,20 @@ void *trx_usrp_write_thread(void * arg){ while(1){ pthread_mutex_lock(&write_thread->mutex_write); - printf("waiting for signal \n"); - while (write_thread->instance_cnt_write < 0) { + while (write_thread->instance_cnt_write == 0) { pthread_cond_wait(&write_thread->cond_write,&write_thread->mutex_write); // this unlocks mutex_rxtx while waiting and then locks it again } - printf("signal unlock\n"); s = (usrp_state_t *)device->priv; start = write_thread->start; - printf("package bing use is start = %d, end = %d\n", start, write_thread->end); timestamp = write_package[start].timestamp; buff = write_package[start].buff; nsamps = write_package[start].nsamps; cc = write_package[start].cc; first_packet = write_package[start].first_packet; last_packet = write_package[start].last_packet; - write_thread->start = (write_thread->start + 1)% write_thread->num_package; - if(write_thread->end == write_thread->start){ - write_thread->instance_cnt_write = -1; - } + write_thread->start = (write_thread->start + 1)% WRITE_THREAD_PACKAGE; + --write_thread->instance_cnt_write; pthread_mutex_unlock(&write_thread->mutex_write); - printf("end of write thread signal getting \n"); -printf("~~~2.5 write_package buff in thread = %p\n", write_package[start].buff[0]); -printf("~~~3 buff in tx write thread= %p\n", buff[0]); #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ @@ -557,7 +552,6 @@ printf("~~~3 buff in tx write thread= %p\n", buff[0]); ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); } else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); -printf("end of sending buffer in trx write thread\n"); if(0) break; } @@ -571,10 +565,9 @@ int trx_write_init(openair0_device *device){ openair0_thread_t *write_thread = &device->write_thread; printf("initializing tx write thread\n"); - write_thread->num_package = 10; write_thread->start = 0; write_thread->end = 0; - write_thread->instance_cnt_write = -1; + write_thread->instance_cnt_write = 0; printf("end of tx write thread\n"); pthread_create(&write_thread->pthread_write,NULL,trx_usrp_write_thread,(void *)device); From bd672c5f0fe2128c8e6b29d6df78072ba32d2b9f Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Wed, 26 Feb 2020 14:47:24 +0100 Subject: [PATCH 5/6] renaming of variable --- targets/ARCH/COMMON/common_lib.h | 10 +++++----- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 4889f248e4..1125195635 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -48,8 +48,8 @@ #define RAU_LOCAL_RADIO_HEAD 0 #define RAU_REMOTE_RADIO_HEAD 1 -#define WRITE_THREAD_PACKAGE 10 -#define WRITE_THREAD_BUFFER_SIZE 8 +#define MAX_WRITE_THREAD_PACKAGE 10 +#define MAX_WRITE_THREAD_BUFFER_SIZE 8 #ifndef MAX_CARDS #define MAX_CARDS 8 @@ -281,7 +281,7 @@ typedef struct { typedef struct { openair0_timestamp timestamp; - void *buff[WRITE_THREAD_BUFFER_SIZE];// buffer to be write; + void *buff[MAX_WRITE_THREAD_BUFFER_SIZE];// buffer to be write; int nsamps; int cc; signed char first_packet; @@ -289,11 +289,11 @@ typedef struct { } openair0_write_package_t; typedef struct { - openair0_write_package_t write_package[WRITE_THREAD_PACKAGE]; + openair0_write_package_t write_package[MAX_WRITE_THREAD_PACKAGE]; int start; int end; /// \internal This variable is protected by \ref mutex_write - int instance_cnt_write; + int count_write; /// pthread struct for trx write thread pthread_t pthread_write; /// pthread attributes for trx write thread diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index b0b126634a..78f76b6a21 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -409,7 +409,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, openair0_thread_t *write_thread = &device->write_thread; openair0_write_package_t *write_package = write_thread->write_package; - AssertFatal( WRITE_THREAD_BUFFER_SIZE >= cc,"Do not support more than %d cc number\n", WRITE_THREAD_BUFFER_SIZE); + AssertFatal( MAX_WRITE_THREAD_BUFFER_SIZE >= cc,"Do not support more than %d cc number\n", MAX_WRITE_THREAD_BUFFER_SIZE); boolean_t first_packet_state=false,last_packet_state=false; @@ -442,10 +442,10 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, } pthread_mutex_lock(&write_thread->mutex_write); - if(write_thread->instance_cnt_write >= WRITE_THREAD_PACKAGE){ + if(write_thread->count_write >= MAX_WRITE_THREAD_PACKAGE){ LOG_W(HW,"Buffer overflow, resetting write package\n"); write_thread->end = write_thread->start; - write_thread->instance_cnt_write = 0; + write_thread->count_write = 0; } end = write_thread->end; @@ -456,8 +456,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, write_package[end].last_packet = last_packet_state; for (int i = 0; i < cc; i++) write_package[end].buff[i] = buff[i]; - ++write_thread->instance_cnt_write; - write_thread->end = (write_thread->end + 1)% WRITE_THREAD_PACKAGE; + write_thread->count_write++; + write_thread->end = (write_thread->end + 1)% MAX_WRITE_THREAD_PACKAGE; pthread_cond_signal(&write_thread->cond_write); pthread_mutex_unlock(&write_thread->mutex_write); @@ -492,7 +492,7 @@ void *trx_usrp_write_thread(void * arg){ while(1){ pthread_mutex_lock(&write_thread->mutex_write); - while (write_thread->instance_cnt_write == 0) { + while (write_thread->count_write == 0) { pthread_cond_wait(&write_thread->cond_write,&write_thread->mutex_write); // this unlocks mutex_rxtx while waiting and then locks it again } s = (usrp_state_t *)device->priv; @@ -503,8 +503,8 @@ void *trx_usrp_write_thread(void * arg){ cc = write_package[start].cc; first_packet = write_package[start].first_packet; last_packet = write_package[start].last_packet; - write_thread->start = (write_thread->start + 1)% WRITE_THREAD_PACKAGE; - --write_thread->instance_cnt_write; + write_thread->start = (write_thread->start + 1)% MAX_WRITE_THREAD_PACKAGE; + write_thread->count_write--; pthread_mutex_unlock(&write_thread->mutex_write); #if defined(__x86_64) || defined(__i386__) @@ -567,7 +567,7 @@ int trx_write_init(openair0_device *device){ write_thread->start = 0; write_thread->end = 0; - write_thread->instance_cnt_write = 0; + write_thread->count_write = 0; printf("end of tx write thread\n"); pthread_create(&write_thread->pthread_write,NULL,trx_usrp_write_thread,(void *)device); From cc4a0c742e8b2d9deeb9bfc257c6089ef214cce6 Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Thu, 5 Mar 2020 17:38:47 +0100 Subject: [PATCH 6/6] adding debug message --- common/utils/LOG/vcd_signal_dumper.c | 5 ++++- common/utils/LOG/vcd_signal_dumper.h | 3 +++ common/utils/T/T_defs.h | 4 ++-- common/utils/T/T_messages.txt | 10 +++++++++ executables/nr-ru.c | 2 ++ targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 12 +++++++++-- targets/RT/USER/gNB_usrp.gtkw | 22 ++++++++++++-------- 7 files changed, 44 insertions(+), 14 deletions(-) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 103cf1cd94..5ba54f1536 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -248,7 +248,8 @@ const char* eurecomVariablesNames[] = { "slot_number_TX1_gNB", "slot_number_RX0_gNB", "slot_number_RX1_gNB", - "ru_tx_ofdm_mask" + "ru_tx_ofdm_mask", + "usrp_send_return" }; const char* eurecomFunctionsNames[] = { @@ -282,6 +283,8 @@ const char* eurecomFunctionsNames[] = { "lock_mutex_ru", "lock_mutex_ru1", "lock_mutex_ru2", + /* uhd signals */ + "trx_write_thread", /* simulation signals */ "do_DL_sig", "do_UL_sig", diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 9383b39b1e..d2efdda098 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -226,6 +226,7 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB, VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, + VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, VCD_SIGNAL_DUMPER_VARIABLES_END @@ -262,6 +263,8 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU, VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU1, VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU2, + /* uhd signals */ + VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, /* SIMULATION signals */ VCD_SIGNAL_DUMPER_FUNCTIONS_SIM_DO_DL_SIGNAL, VCD_SIGNAL_DUMPER_FUNCTIONS_SIM_DO_UL_SIGNAL, diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index b59fae2a0c..ad21819c7d 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -73,10 +73,10 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (247) +#define VCD_NUM_FUNCTIONS (248) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES (186) +#define VCD_NUM_VARIABLES (187) /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 387257d145..5374c09712 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -2138,6 +2138,11 @@ ID = VCD_VARIABLE_RU_TX_OFDM_MASK GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value VCD_NAME = ru_tx_ofdm_mask +ID = VCD_VARIABLE_USRP_SEND_RETURN + DESC = VCD variable USRP_SEND_RETURN + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = usrp_send_return #functions @@ -2286,6 +2291,11 @@ ID = VCD_FUNCTION_LOCK_MUTEX_RU2 GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value VCD_NAME = lock_mutex_ru2 +ID = VCD_FUNCTION_TRX_WRITE_THREAD + DESC = VCD function TRX_WRITE_THREAD + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = trx_write_thread ID = VCD_FUNCTION_SIM_DO_DL_SIGNAL DESC = VCD function SIM_DO_DL_SIGNAL GROUP = ALL:VCD:ENB:VCD_FUNCTION diff --git a/executables/nr-ru.c b/executables/nr-ru.c index f7d63a94ad..2355c78534 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -735,6 +735,8 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { else flags=4; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); + /* if (SF_type == SF_S) { siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 78f76b6a21..d48755266c 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -49,6 +49,8 @@ #include "common_lib.h" #include "assertions.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + #include #include "usrp_lib.h" @@ -443,7 +445,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, pthread_mutex_lock(&write_thread->mutex_write); if(write_thread->count_write >= MAX_WRITE_THREAD_PACKAGE){ - LOG_W(HW,"Buffer overflow, resetting write package\n"); + LOG_W("Buffer overflow, count_write = %d, start = %d end = %d, resetting write package\n", write_thread->count_write, write_thread->start, write_thread->end); write_thread->end = write_thread->start; write_thread->count_write = 0; } @@ -495,6 +497,7 @@ void *trx_usrp_write_thread(void * arg){ while (write_thread->count_write == 0) { pthread_cond_wait(&write_thread->cond_write,&write_thread->mutex_write); // this unlocks mutex_rxtx while waiting and then locks it again } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 1 ); s = (usrp_state_t *)device->priv; start = write_thread->start; timestamp = write_package[start].timestamp; @@ -506,6 +509,9 @@ void *trx_usrp_write_thread(void * arg){ write_thread->start = (write_thread->start + 1)% MAX_WRITE_THREAD_PACKAGE; write_thread->count_write--; pthread_mutex_unlock(&write_thread->mutex_write); + if(write_thread->count_write != 0){ + LOG_W(HW,"count write = %d, start = %d, end = %d\n", write_thread->count_write, write_thread->start, write_thread->end); + } #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ @@ -552,6 +558,8 @@ void *trx_usrp_write_thread(void * arg){ ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); } else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 ); if(0) break; } @@ -567,7 +575,7 @@ int trx_write_init(openair0_device *device){ write_thread->start = 0; write_thread->end = 0; - write_thread->count_write = 0; + write_thread->count_write = 0; printf("end of tx write thread\n"); pthread_create(&write_thread->pthread_write,NULL,trx_usrp_write_thread,(void *)device); diff --git a/targets/RT/USER/gNB_usrp.gtkw b/targets/RT/USER/gNB_usrp.gtkw index e6726e7d9f..6ece894bb6 100644 --- a/targets/RT/USER/gNB_usrp.gtkw +++ b/targets/RT/USER/gNB_usrp.gtkw @@ -1,21 +1,25 @@ [*] [*] GTKWave Analyzer v3.3.61 (w)1999-2014 BSI -[*] Tue Dec 17 15:31:51 2019 +[*] Wed Mar 4 14:05:43 2020 [*] -[dumpfile] "/tmp/gNB.vcd" -[dumpfile_mtime] "Tue Dec 17 15:25:49 2019" -[dumpfile_size] 6343431 +[dumpfile] "/tmp/gNB_trx_thread.vcd" +[dumpfile_mtime] "Wed Mar 4 14:05:10 2020" +[dumpfile_size] 10750468 [savefile] "/home/wangts/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw" -[timestart] 1517712000 -[size] 1920 1018 -[pos] -9 -33 -*-19.276148 1518358451 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[timestart] 31148700000 +[size] 1916 1002 +[pos] -1 -25 +*-23.852516 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [sst_width] 386 [signals_width] 344 [sst_expanded] 1 -[sst_vpaned_height] 267 +[sst_vpaned_height] 262 @28 functions.trx_read +functions.trx_write_thread +@25 +variables.trx_write_flags[63:0] +@28 functions.trx_write @420 variables.frame_number_TX0_UE[63:0]