integration of over-the-air synchronization mechanism for distributed RRU
This commit is contained in:
@@ -517,14 +517,15 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
|
|||||||
|
|
||||||
// perform a time domain correlation using the oversampled sync sequence
|
// perform a time domain correlation using the oversampled sync sequence
|
||||||
|
|
||||||
unsigned int n, ar, peak_val, peak_pos, mean_val;
|
unsigned int n, ar, peak_val, peak_pos;
|
||||||
|
uint64_t mean_val;
|
||||||
int result;
|
int result;
|
||||||
short *primary_synch_time;
|
short *primary_synch_time;
|
||||||
int eNB_id = frame_parms->Nid_cell%3;
|
int eNB_id = frame_parms->Nid_cell%3;
|
||||||
|
|
||||||
// msg("[SYNC TIME] Calling sync_time_eNB(%p,%p,%d,%d)\n",rxdata,frame_parms,eNB_id,length);
|
// msg("[SYNC TIME] Calling sync_time_eNB(%p,%p,%d,%d)\n",rxdata,frame_parms,eNB_id,length);
|
||||||
if (sync_corr_eNB == NULL) {
|
if (sync_corr_eNB == NULL) {
|
||||||
msg("[SYNC TIME] sync_corr_eNB not yet allocated! Exiting.\n");
|
LOG_E(PHY,"[SYNC TIME] sync_corr_eNB not yet allocated! Exiting.\n");
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +543,7 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
msg("[SYNC TIME] Illegal eNB_id!\n");
|
LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +575,7 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
|
|||||||
peak_val);
|
peak_val);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
mean_val += (sync_corr_eNB[n]>>10);
|
mean_val += sync_corr_eNB[n];
|
||||||
|
|
||||||
if (sync_corr_eNB[n]>peak_val) {
|
if (sync_corr_eNB[n]>peak_val) {
|
||||||
peak_val = sync_corr_eNB[n];
|
peak_val = sync_corr_eNB[n];
|
||||||
@@ -582,17 +583,15 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mean_val/=length;
|
||||||
|
|
||||||
*peak_val_out = peak_val;
|
*peak_val_out = peak_val;
|
||||||
|
|
||||||
if (peak_val <= (40*mean_val)) {
|
if (peak_val <= (40*(uint32_t)mean_val)) {
|
||||||
#ifdef DEBUG_PHY
|
LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%u,%u)\n",peak_pos,peak_val,mean_val,40*mean_val);
|
||||||
msg("[SYNC TIME] No peak found (%u,%u,%u,%u)\n",peak_pos,peak_val,mean_val,40*mean_val);
|
|
||||||
#endif
|
|
||||||
return(-1);
|
return(-1);
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_PHY
|
LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %u\n",peak_pos,peak_val,mean_val);
|
||||||
msg("[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %u\n",peak_pos,peak_val,mean_val);
|
|
||||||
#endif
|
|
||||||
return(peak_pos);
|
return(peak_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -256,6 +256,8 @@ typedef struct eNB_proc_t_s {
|
|||||||
/// \brief Instance count for rx processing thread.
|
/// \brief Instance count for rx processing thread.
|
||||||
/// \internal This variable is protected by \ref mutex_prach.
|
/// \internal This variable is protected by \ref mutex_prach.
|
||||||
int instance_cnt_prach;
|
int instance_cnt_prach;
|
||||||
|
// instance count for over-the-air eNB synchronization
|
||||||
|
int instance_cnt_synch;
|
||||||
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
|
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
|
||||||
int instance_cnt_asynch_rxtx;
|
int instance_cnt_asynch_rxtx;
|
||||||
/// pthread structure for FH processing thread
|
/// pthread structure for FH processing thread
|
||||||
@@ -280,6 +282,8 @@ typedef struct eNB_proc_t_s {
|
|||||||
pthread_attr_t attr_single;
|
pthread_attr_t attr_single;
|
||||||
/// pthread attributes for prach processing thread
|
/// pthread attributes for prach processing thread
|
||||||
pthread_attr_t attr_prach;
|
pthread_attr_t attr_prach;
|
||||||
|
/// pthread attributes for over-the-air synch thread
|
||||||
|
pthread_attr_t attr_synch;
|
||||||
/// pthread attributes for asynchronous RX thread
|
/// pthread attributes for asynchronous RX thread
|
||||||
pthread_attr_t attr_asynch_rxtx;
|
pthread_attr_t attr_asynch_rxtx;
|
||||||
/// scheduling parameters for parallel fep thread
|
/// scheduling parameters for parallel fep thread
|
||||||
@@ -294,6 +298,8 @@ typedef struct eNB_proc_t_s {
|
|||||||
struct sched_param sched_param_single;
|
struct sched_param sched_param_single;
|
||||||
/// scheduling parameters for prach thread
|
/// scheduling parameters for prach thread
|
||||||
struct sched_param sched_param_prach;
|
struct sched_param sched_param_prach;
|
||||||
|
/// scheduling parameters for over-the-air synchronization thread
|
||||||
|
struct sched_param sched_param_synch;
|
||||||
/// scheduling parameters for asynch_rxtx thread
|
/// scheduling parameters for asynch_rxtx thread
|
||||||
struct sched_param sched_param_asynch_rxtx;
|
struct sched_param sched_param_asynch_rxtx;
|
||||||
/// pthread structure for parallel fep thread
|
/// pthread structure for parallel fep thread
|
||||||
@@ -304,6 +310,8 @@ typedef struct eNB_proc_t_s {
|
|||||||
pthread_t pthread_te;
|
pthread_t pthread_te;
|
||||||
/// pthread structure for PRACH thread
|
/// pthread structure for PRACH thread
|
||||||
pthread_t pthread_prach;
|
pthread_t pthread_prach;
|
||||||
|
/// pthread structure for eNB synch thread
|
||||||
|
pthread_t pthread_synch;
|
||||||
/// condition variable for parallel fep thread
|
/// condition variable for parallel fep thread
|
||||||
pthread_cond_t cond_fep;
|
pthread_cond_t cond_fep;
|
||||||
/// condition variable for parallel turbo-decoder thread
|
/// condition variable for parallel turbo-decoder thread
|
||||||
@@ -314,6 +322,8 @@ typedef struct eNB_proc_t_s {
|
|||||||
pthread_cond_t cond_FH;
|
pthread_cond_t cond_FH;
|
||||||
/// condition variable for PRACH processing thread;
|
/// condition variable for PRACH processing thread;
|
||||||
pthread_cond_t cond_prach;
|
pthread_cond_t cond_prach;
|
||||||
|
// condition variable for over-the-air eNB synchronization
|
||||||
|
pthread_cond_t cond_synch;
|
||||||
/// condition variable for asynch RX/TX thread
|
/// condition variable for asynch RX/TX thread
|
||||||
pthread_cond_t cond_asynch_rxtx;
|
pthread_cond_t cond_asynch_rxtx;
|
||||||
/// mutex for parallel fep thread
|
/// mutex for parallel fep thread
|
||||||
@@ -326,6 +336,8 @@ typedef struct eNB_proc_t_s {
|
|||||||
pthread_mutex_t mutex_FH;
|
pthread_mutex_t mutex_FH;
|
||||||
/// mutex for PRACH thread
|
/// mutex for PRACH thread
|
||||||
pthread_mutex_t mutex_prach;
|
pthread_mutex_t mutex_prach;
|
||||||
|
// mutex for over-the-air eNB synchronization
|
||||||
|
pthread_mutex_t mutex_synch;
|
||||||
/// mutex for asynch RX/TX thread
|
/// mutex for asynch RX/TX thread
|
||||||
pthread_mutex_t mutex_asynch_rxtx;
|
pthread_mutex_t mutex_asynch_rxtx;
|
||||||
/// parameters for turbo-decoding worker thread
|
/// parameters for turbo-decoding worker thread
|
||||||
@@ -411,6 +423,10 @@ typedef struct PHY_VARS_eNB_s {
|
|||||||
openair0_rf_map rf_map;
|
openair0_rf_map rf_map;
|
||||||
int abstraction_flag;
|
int abstraction_flag;
|
||||||
openair0_timestamp ts_offset;
|
openair0_timestamp ts_offset;
|
||||||
|
// indicator for synchronization state of eNB
|
||||||
|
int in_synch;
|
||||||
|
// indicator for master/slave (RRU)
|
||||||
|
int is_slave;
|
||||||
void (*do_prach)(struct PHY_VARS_eNB_s *eNB);
|
void (*do_prach)(struct PHY_VARS_eNB_s *eNB);
|
||||||
void (*fep)(struct PHY_VARS_eNB_s *eNB);
|
void (*fep)(struct PHY_VARS_eNB_s *eNB);
|
||||||
int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag);
|
int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag);
|
||||||
|
|||||||
+189
-4
@@ -161,7 +161,7 @@ static struct {
|
|||||||
|
|
||||||
void exit_fun(const char* s);
|
void exit_fun(const char* s);
|
||||||
|
|
||||||
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *,int);
|
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *,int,int);
|
||||||
void stop_eNB(int nb_inst);
|
void stop_eNB(int nb_inst);
|
||||||
|
|
||||||
|
|
||||||
@@ -1122,6 +1122,114 @@ void wakeup_slaves(eNB_proc_t *proc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t sync_corr[307200] __attribute__((aligned(32)));
|
||||||
|
|
||||||
|
// This thread run the initial synchronization like a UE
|
||||||
|
void *eNB_thread_synch(void *arg) {
|
||||||
|
|
||||||
|
PHY_VARS_eNB *eNB = (PHY_VARS_eNB*)arg;
|
||||||
|
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
|
||||||
|
int32_t sync_pos,sync_pos2;
|
||||||
|
uint32_t peak_val;
|
||||||
|
|
||||||
|
thread_top_init("eNB_thread_synch",0,5000000,10000000,10000000);
|
||||||
|
|
||||||
|
wait_sync("eNB_thread_synch");
|
||||||
|
|
||||||
|
// initialize variables for PSS detection
|
||||||
|
lte_sync_time_init(&eNB->frame_parms);
|
||||||
|
|
||||||
|
while (!oai_exit) {
|
||||||
|
|
||||||
|
// wait to be woken up
|
||||||
|
pthread_mutex_lock(&eNB->proc.mutex_synch);
|
||||||
|
while (eNB->proc.instance_cnt_synch < 0)
|
||||||
|
pthread_cond_wait(&eNB->proc.cond_synch,&eNB->proc.mutex_synch);
|
||||||
|
pthread_mutex_unlock(&eNB->proc.mutex_synch);
|
||||||
|
|
||||||
|
// if we're not in synch, then run initial synch
|
||||||
|
if (eNB->in_synch == 0) {
|
||||||
|
// run intial synch like UE
|
||||||
|
LOG_I(PHY,"Running initial synchronization\n");
|
||||||
|
|
||||||
|
sync_pos = lte_sync_time_eNB(eNB->common_vars.rxdata[0],
|
||||||
|
fp,
|
||||||
|
fp->samples_per_tti*5,
|
||||||
|
&peak_val,
|
||||||
|
sync_corr);
|
||||||
|
LOG_I(PHY,"eNB synch: %d, val %d\n",sync_pos,peak_val);
|
||||||
|
|
||||||
|
if (sync_pos >= 0) {
|
||||||
|
if (sync_pos >= fp->nb_prefix_samples)
|
||||||
|
sync_pos2 = sync_pos - fp->nb_prefix_samples;
|
||||||
|
else
|
||||||
|
sync_pos2 = sync_pos + (fp->samples_per_tti*10) - fp->nb_prefix_samples;
|
||||||
|
|
||||||
|
if (fp->frame_type == FDD) {
|
||||||
|
|
||||||
|
// PSS is hypothesized in last symbol of first slot in Frame
|
||||||
|
int sync_pos_slot = (fp->samples_per_tti>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples;
|
||||||
|
|
||||||
|
if (sync_pos2 >= sync_pos_slot)
|
||||||
|
eNB->rx_offset = sync_pos2 - sync_pos_slot;
|
||||||
|
else
|
||||||
|
eNB->rx_offset = (fp->samples_per_tti*10) + sync_pos2 - sync_pos_slot;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,eNB->rx_offset);
|
||||||
|
|
||||||
|
|
||||||
|
/* if ((peak_val > 10000) && (sync_pos == -1)) {
|
||||||
|
// if (sync_pos++ > 3) {
|
||||||
|
write_output("eNB_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_tti*5,1,2);
|
||||||
|
write_output("eNB_rx.m","rxs",(void*)eNB->common_vars.rxdata[0][0],fp->samples_per_tti*10,1,1);
|
||||||
|
exit(-1);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// release thread
|
||||||
|
pthread_mutex_lock(&eNB->proc.mutex_synch);
|
||||||
|
eNB->proc.instance_cnt_synch--;
|
||||||
|
pthread_mutex_unlock(&eNB->proc.mutex_synch);
|
||||||
|
} // oai_exit
|
||||||
|
|
||||||
|
lte_sync_time_free();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int wakeup_synch(PHY_VARS_eNB *eNB){
|
||||||
|
|
||||||
|
struct timespec wait;
|
||||||
|
|
||||||
|
wait.tv_sec=0;
|
||||||
|
wait.tv_nsec=5000000L;
|
||||||
|
|
||||||
|
// wake up synch thread
|
||||||
|
// lock the synch mutex and make sure the thread is ready
|
||||||
|
if (pthread_mutex_timedlock(&eNB->proc.mutex_synch,&wait) != 0) {
|
||||||
|
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB synch thread (IC %d)\n", eNB->proc.instance_cnt_synch );
|
||||||
|
exit_fun( "error locking mutex_synch" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
++eNB->proc.instance_cnt_synch;
|
||||||
|
|
||||||
|
// the thread can now be woken up
|
||||||
|
if (pthread_cond_signal(&eNB->proc.cond_synch) != 0) {
|
||||||
|
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB synch thread\n");
|
||||||
|
exit_fun( "ERROR pthread_cond_signal" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock( &eNB->proc.mutex_synch );
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The Fronthaul thread of RRU/RAU/RCC/eNB
|
* \brief The Fronthaul thread of RRU/RAU/RCC/eNB
|
||||||
* In the case of RRU/eNB, handles interface with external RF
|
* In the case of RRU/eNB, handles interface with external RF
|
||||||
@@ -1242,6 +1350,8 @@ static void* eNB_thread_prach( void* param ) {
|
|||||||
return &eNB_thread_prach_status;
|
return &eNB_thread_prach_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void* eNB_thread_single( void* param ) {
|
static void* eNB_thread_single( void* param ) {
|
||||||
|
|
||||||
static int eNB_thread_single_status;
|
static int eNB_thread_single_status;
|
||||||
@@ -1249,9 +1359,24 @@ static void* eNB_thread_single( void* param ) {
|
|||||||
eNB_proc_t *proc = (eNB_proc_t*)param;
|
eNB_proc_t *proc = (eNB_proc_t*)param;
|
||||||
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
|
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
|
||||||
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
|
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
|
||||||
|
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
|
||||||
|
|
||||||
|
void *rxp[2],*rxp2[2];
|
||||||
|
|
||||||
int subframe=0, frame=0;
|
int subframe=0, frame=0;
|
||||||
|
|
||||||
|
int32_t dummy_rx[fp->nb_antennas_rx][fp->samples_per_tti] __attribute__((aligned(32)));
|
||||||
|
|
||||||
|
int ic;
|
||||||
|
|
||||||
|
int rxs;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// initialize the synchronization buffer to the common_vars.rxdata
|
||||||
|
for (int i=0;i<fp->nb_antennas_rx;i++)
|
||||||
|
rxp[i] = &eNB->common_vars.rxdata[0][i][0];
|
||||||
|
|
||||||
// set default return value
|
// set default return value
|
||||||
eNB_thread_single_status = 0;
|
eNB_thread_single_status = 0;
|
||||||
|
|
||||||
@@ -1280,6 +1405,57 @@ static void* eNB_thread_single( void* param ) {
|
|||||||
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
|
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
|
||||||
pthread_cond_signal(&proc->cond_asynch_rxtx);
|
pthread_cond_signal(&proc->cond_asynch_rxtx);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if this is a slave eNB, try to synchronize on the DL frequency
|
||||||
|
if ((eNB->is_slave) &&
|
||||||
|
((eNB->node_function >= NGFI_RRU_IF5))) {
|
||||||
|
// if FDD, switch RX on DL frequency
|
||||||
|
|
||||||
|
double temp_freq1 = eNB->rfdevice.openair0_cfg->rx_freq[0];
|
||||||
|
double temp_freq2 = eNB->rfdevice.openair0_cfg->tx_freq[0];
|
||||||
|
for (i=0;i<4;i++) {
|
||||||
|
eNB->rfdevice.openair0_cfg->rx_freq[i] = eNB->rfdevice.openair0_cfg->tx_freq[i];
|
||||||
|
eNB->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1;
|
||||||
|
}
|
||||||
|
eNB->rfdevice.trx_set_freq_func(&eNB->rfdevice,eNB->rfdevice.openair0_cfg,0);
|
||||||
|
|
||||||
|
while ((eNB->in_synch ==0)&&(!oai_exit)) {
|
||||||
|
// read in frame
|
||||||
|
rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
|
||||||
|
&(proc->timestamp_rx),
|
||||||
|
rxp,
|
||||||
|
fp->samples_per_tti*10,
|
||||||
|
fp->nb_antennas_rx);
|
||||||
|
// wakeup synchronization processing thread
|
||||||
|
wakeup_synch(eNB);
|
||||||
|
ic=0;
|
||||||
|
|
||||||
|
while ((ic>=0)&&(!oai_exit)) {
|
||||||
|
// continuously read in frames, 1ms at a time,
|
||||||
|
// until we are done with the synchronization procedure
|
||||||
|
|
||||||
|
for (i=0; i<fp->nb_antennas_rx; i++)
|
||||||
|
rxp2[i] = (void*)&dummy_rx[i][0];
|
||||||
|
for (i=0;i<10;i++)
|
||||||
|
rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
|
||||||
|
&(proc->timestamp_rx),
|
||||||
|
rxp2,
|
||||||
|
fp->samples_per_tti,
|
||||||
|
fp->nb_antennas_rx);
|
||||||
|
pthread_mutex_lock(&eNB->proc.mutex_synch);
|
||||||
|
ic = eNB->proc.instance_cnt_synch;
|
||||||
|
pthread_mutex_unlock(&eNB->proc.mutex_synch);
|
||||||
|
} // ic>=0
|
||||||
|
} // in_synch==0
|
||||||
|
for (i=0;i<4;i++) {
|
||||||
|
eNB->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1;
|
||||||
|
eNB->rfdevice.openair0_cfg->rx_freq[i] = temp_freq2;
|
||||||
|
}
|
||||||
|
eNB->rfdevice.trx_set_freq_func(&eNB->rfdevice,eNB->rfdevice.openair0_cfg,0);
|
||||||
|
} // if RRU and slave
|
||||||
|
|
||||||
|
|
||||||
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
|
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
|
||||||
while (!oai_exit) {
|
while (!oai_exit) {
|
||||||
|
|
||||||
@@ -1334,7 +1510,7 @@ void init_eNB_proc(int inst) {
|
|||||||
PHY_VARS_eNB *eNB;
|
PHY_VARS_eNB *eNB;
|
||||||
eNB_proc_t *proc;
|
eNB_proc_t *proc;
|
||||||
eNB_rxtx_proc_t *proc_rxtx;
|
eNB_rxtx_proc_t *proc_rxtx;
|
||||||
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te;
|
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te=NULL,*attr_synch=NULL;
|
||||||
|
|
||||||
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||||
eNB = PHY_vars_eNB_g[inst][CC_id];
|
eNB = PHY_vars_eNB_g[inst][CC_id];
|
||||||
@@ -1348,7 +1524,8 @@ void init_eNB_proc(int inst) {
|
|||||||
proc->instance_cnt_FH = -1;
|
proc->instance_cnt_FH = -1;
|
||||||
proc->instance_cnt_asynch_rxtx = -1;
|
proc->instance_cnt_asynch_rxtx = -1;
|
||||||
proc->CC_id = CC_id;
|
proc->CC_id = CC_id;
|
||||||
|
proc->instance_cnt_synch = -1;
|
||||||
|
|
||||||
proc->first_rx=1;
|
proc->first_rx=1;
|
||||||
proc->first_tx=1;
|
proc->first_tx=1;
|
||||||
|
|
||||||
@@ -1359,13 +1536,16 @@ void init_eNB_proc(int inst) {
|
|||||||
|
|
||||||
pthread_mutex_init( &proc->mutex_prach, NULL);
|
pthread_mutex_init( &proc->mutex_prach, NULL);
|
||||||
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
|
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
|
||||||
|
pthread_mutex_init( &proc->mutex_synch,NULL);
|
||||||
|
|
||||||
pthread_cond_init( &proc->cond_prach, NULL);
|
pthread_cond_init( &proc->cond_prach, NULL);
|
||||||
pthread_cond_init( &proc->cond_FH, NULL);
|
pthread_cond_init( &proc->cond_FH, NULL);
|
||||||
pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
|
pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
|
||||||
|
pthread_cond_init( &proc->cond_synch,NULL);
|
||||||
|
|
||||||
pthread_attr_init( &proc->attr_FH);
|
pthread_attr_init( &proc->attr_FH);
|
||||||
pthread_attr_init( &proc->attr_prach);
|
pthread_attr_init( &proc->attr_prach);
|
||||||
|
pthread_attr_init( &proc->attr_synch);
|
||||||
pthread_attr_init( &proc->attr_asynch_rxtx);
|
pthread_attr_init( &proc->attr_asynch_rxtx);
|
||||||
pthread_attr_init( &proc->attr_single);
|
pthread_attr_init( &proc->attr_single);
|
||||||
pthread_attr_init( &proc->attr_fep);
|
pthread_attr_init( &proc->attr_fep);
|
||||||
@@ -1378,6 +1558,7 @@ void init_eNB_proc(int inst) {
|
|||||||
attr1 = &proc_rxtx[1].attr_rxtx;
|
attr1 = &proc_rxtx[1].attr_rxtx;
|
||||||
attr_FH = &proc->attr_FH;
|
attr_FH = &proc->attr_FH;
|
||||||
attr_prach = &proc->attr_prach;
|
attr_prach = &proc->attr_prach;
|
||||||
|
attr_synch = &proc->attr_synch;
|
||||||
attr_asynch = &proc->attr_asynch_rxtx;
|
attr_asynch = &proc->attr_asynch_rxtx;
|
||||||
attr_single = &proc->attr_single;
|
attr_single = &proc->attr_single;
|
||||||
attr_fep = &proc->attr_fep;
|
attr_fep = &proc->attr_fep;
|
||||||
@@ -1397,6 +1578,7 @@ void init_eNB_proc(int inst) {
|
|||||||
init_te_thread(eNB,attr_te);
|
init_te_thread(eNB,attr_te);
|
||||||
}
|
}
|
||||||
pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc );
|
pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc );
|
||||||
|
pthread_create( &proc->pthread_synch, attr_synch, eNB_thread_synch, eNB);
|
||||||
if ((eNB->node_timing == synch_to_other) ||
|
if ((eNB->node_timing == synch_to_other) ||
|
||||||
(eNB->node_function == NGFI_RRU_IF5) ||
|
(eNB->node_function == NGFI_RRU_IF5) ||
|
||||||
(eNB->node_function == NGFI_RRU_IF4p5))
|
(eNB->node_function == NGFI_RRU_IF4p5))
|
||||||
@@ -1619,7 +1801,7 @@ extern void eNB_fep_full(PHY_VARS_eNB *eNB);
|
|||||||
extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB);
|
extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB);
|
||||||
extern void do_prach(PHY_VARS_eNB *eNB);
|
extern void do_prach(PHY_VARS_eNB *eNB);
|
||||||
|
|
||||||
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params,int single_thread_flag) {
|
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params,int single_thread_flag,int wait_for_sync) {
|
||||||
|
|
||||||
int CC_id;
|
int CC_id;
|
||||||
int inst;
|
int inst;
|
||||||
@@ -1634,6 +1816,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
|
|||||||
eNB->abstraction_flag = 0;
|
eNB->abstraction_flag = 0;
|
||||||
eNB->single_thread_flag = single_thread_flag;
|
eNB->single_thread_flag = single_thread_flag;
|
||||||
eNB->ts_offset = 0;
|
eNB->ts_offset = 0;
|
||||||
|
eNB->in_synch = 0;
|
||||||
|
eNB->is_slave = (wait_for_sync>0) ? 1 : 0;
|
||||||
|
|
||||||
LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]);
|
LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]);
|
||||||
|
|
||||||
switch (node_function[CC_id]) {
|
switch (node_function[CC_id]) {
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ extern int netlink_init(void);
|
|||||||
|
|
||||||
// In lte-enb.c
|
// In lte-enb.c
|
||||||
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg);
|
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg);
|
||||||
extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int);
|
extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int,int);
|
||||||
extern void stop_eNB(int);
|
extern void stop_eNB(int);
|
||||||
extern void kill_eNB_proc(void);
|
extern void kill_eNB_proc(void);
|
||||||
|
|
||||||
@@ -170,6 +170,8 @@ volatile int oai_exit = 0;
|
|||||||
|
|
||||||
static clock_source_t clock_source = internal;
|
static clock_source_t clock_source = internal;
|
||||||
|
|
||||||
|
static wait_for_sync = 0;
|
||||||
|
|
||||||
static char UE_flag=0;
|
static char UE_flag=0;
|
||||||
unsigned int mmapped_dma=0;
|
unsigned int mmapped_dma=0;
|
||||||
int single_thread_flag=0;
|
int single_thread_flag=0;
|
||||||
@@ -696,6 +698,7 @@ static void get_options (int argc, char **argv)
|
|||||||
LONG_OPTION_MMAPPED_DMA,
|
LONG_OPTION_MMAPPED_DMA,
|
||||||
LONG_OPTION_SINGLE_THREAD,
|
LONG_OPTION_SINGLE_THREAD,
|
||||||
LONG_OPTION_EXTERNAL_CLOCK,
|
LONG_OPTION_EXTERNAL_CLOCK,
|
||||||
|
LONG_OPTION_WAIT_FOR_SYNC,
|
||||||
#if T_TRACER
|
#if T_TRACER
|
||||||
LONG_OPTION_T_PORT,
|
LONG_OPTION_T_PORT,
|
||||||
LONG_OPTION_T_NOWAIT,
|
LONG_OPTION_T_NOWAIT,
|
||||||
@@ -722,6 +725,7 @@ static void get_options (int argc, char **argv)
|
|||||||
{"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
|
{"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
|
||||||
{"single-thread", no_argument, NULL, LONG_OPTION_SINGLE_THREAD},
|
{"single-thread", no_argument, NULL, LONG_OPTION_SINGLE_THREAD},
|
||||||
{"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK},
|
{"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK},
|
||||||
|
{"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC},
|
||||||
#if T_TRACER
|
#if T_TRACER
|
||||||
{"T_port", required_argument, 0, LONG_OPTION_T_PORT},
|
{"T_port", required_argument, 0, LONG_OPTION_T_PORT},
|
||||||
{"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT},
|
{"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT},
|
||||||
@@ -827,6 +831,10 @@ static void get_options (int argc, char **argv)
|
|||||||
clock_source = external;
|
clock_source = external;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LONG_OPTION_WAIT_FOR_SYNC:
|
||||||
|
wait_for_sync = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
#if T_TRACER
|
#if T_TRACER
|
||||||
case LONG_OPTION_T_PORT: {
|
case LONG_OPTION_T_PORT: {
|
||||||
extern int T_port;
|
extern int T_port;
|
||||||
@@ -1808,7 +1816,7 @@ int main( int argc, char **argv )
|
|||||||
// start the main thread
|
// start the main thread
|
||||||
if (UE_flag == 1) init_UE(1);
|
if (UE_flag == 1) init_UE(1);
|
||||||
else {
|
else {
|
||||||
init_eNB(node_function,node_timing,1,eth_params,single_thread_flag);
|
init_eNB(node_function,node_timing,1,eth_params,single_thread_flag,wait_for_sync);
|
||||||
// Sleep to allow all threads to setup
|
// Sleep to allow all threads to setup
|
||||||
|
|
||||||
number_of_cards = 1;
|
number_of_cards = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user