From c9908f536c65d4b96ea6e27e754dd0da0075398b Mon Sep 17 00:00:00 2001 From: khadraou <younes.khadraoui@eurecom.fr> Date: Wed, 13 Dec 2017 11:05:54 +0100 Subject: [PATCH] ru_thread_control: still missing stop ru_thread; not tested --- targets/RT/USER/lte-ru.c | 223 +++++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 102 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 3e0f0471b2c..936b0ddf26d 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -152,7 +152,7 @@ int send_tick(RU_t *ru){ int send_config(RU_t *ru, RRU_CONFIG_msg_t *rru_config_msg){ - ssize_t msg_len,len; + ssize_t msg_len,len; rru_config_msg.type = RRU_config; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); @@ -180,6 +180,10 @@ int send_config(RU_t *ru, RRU_CONFIG_msg_t *rru_config_msg){ int send_capab(RU_t *ru){ + RRU_CONFIG_msg_t *rru_config_msg; + RRU_capabilities_t *cap; + int i=0; + rru_config_msg.type = RRU_capabilities; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); cap = (RRU_capabilities_t*)&rru_config_msg.msg[0]; @@ -1426,7 +1430,6 @@ static void* ru_thread_control( void* param ) { RU_t *ru = (RU_t*)param; RU_proc_t *proc = &ru->proc; RRU_CONFIG_msg_t rru_config_msg; - RRU_ack_msg_t rru_ack_msg; ssize_t msg_len; int tick_received = 0; int configuration_received = 0; @@ -1435,30 +1438,23 @@ static void* ru_thread_control( void* param ) { int i; int len; - - ru->state = RU_IDLE; - // Start IF device if any if (ru->start_if) { LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); - //if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); - if (ru->if_south != LOCAL_RF) { - - - } - AssertFatal(ret==0,"Cannot connect to radio\n"); } - while (true) // Change the cond + ru->state = RU_IDLE; + + while (!oai_exit) // Change the cond { - msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; + msg_len = sizeof(RRU_CONFIG_msg_t); // TODO : check what should be the msg len if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, msg_len))<0) { - LOG_I(PHY,"Control channel ON\n"); + LOG_I(PHY,"RAU Control channel for RU %d\n", ru->idx); } else { @@ -1515,11 +1511,11 @@ static void* ru_thread_control( void* param ) { // send CONFIG_OK - rru_ack_msg.type = RRU_config_ok; - rru_ack_msg.len = sizeof(RRU_ack_msg_t); + rru_config_msg.type = RRU_config_ok; + rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); LOG_I(PHY,"Sending CONFIG_OK to RRU %d\n", ru->idx); - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_ack_msg,rru_ack_msg.len)!=-1), + AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), "RU %d failed send CONFIG_OK to RAU\n",ru->idx); ru->state = RU_READY; @@ -1529,14 +1525,26 @@ static void* ru_thread_control( void* param ) { break; case RRU_config_ok: // RAU - // send start - rru_config_msg.type = RRU_start; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg type - - LOG_I(PHY,"Sending Start to RRU\n", ru->idx); - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RU %d\n",ru->idx); - - ru->state = RU_READY; + if (ru->if_south == LOCAL_RF){ + LOG_I(PHY,"Received RRU_config_ok msg...Ignoring\n"); + }else{ + // send start + rru_config_msg.type = RRU_start; + rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len + + LOG_I(PHY,"Sending Start to RRU\n", ru->idx); + AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RU %d\n",ru->idx); + + ru->state = RU_RUN; + + // TODO: Start ru_thread + proc->instance_cnt_ru = 1; + if (pthread_cond_signal(&proc->cond_ru_thread) != 0) { + LOG_E( PHY, "ERROR pthread_cond_signal for RU %d\n",ru->idx); + exit_fun( "ERROR pthread_cond_signal" ); + break; + } + } break; case RRU_start: // RRU @@ -1544,11 +1552,17 @@ static void* ru_thread_control( void* param ) { LOG_I(PHY,"Start received from RAU\n"); if (ru->state == RU_READY){ - // unblock ru_thread + // TODO: Start ru_thread ru->state = RU_RUN; + proc->instance_cnt_ru = 1; + if (pthread_cond_signal(&proc->cond_ru_thread) != 0) { + LOG_E( PHY, "ERROR pthread_cond_signal for RU %d\n",ru->idx); + exit_fun( "ERROR pthread_cond_signal" ); + break; + } } else{ - LOG_I(PHY,"RRU not ready, can't start\n"); + LOG_I(PHY,"RRU not ready, cannot start\n"); } }else{ LOG_I(PHY,"Received RRU_start msg...Ignoring\n"); @@ -1564,7 +1578,7 @@ static void* ru_thread_control( void* param ) { LOG_I(PHY,"Stopping RRU\n"); ru->state = RU_READY; - // stop ru_thread + // TODO: stop ru_thread }else{ LOG_I(PHY,"RRU not running, can't stop\n"); } @@ -1613,14 +1627,7 @@ static void* ru_thread( void* param ) { LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); - // Start IF device if any - if (ru->start_if) { - LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); - AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); - if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); - else ret = attach_rru(ru); - AssertFatal(ret==0,"Cannot connect to radio\n"); - } + if (ru->if_south == LOCAL_RF) { // configure RF parameters only fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); @@ -1641,95 +1648,102 @@ static void* ru_thread( void* param ) { pthread_mutex_unlock(&RC.ru_mutex); wait_sync("ru_thread"); + + + while (!oai_exit) { + // wait to be woken up + if (wait_on_condition(&ru->proc.mutex_ru_thread,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break; + + // Start RF device if any + if (ru->start_rf) { + if (ru->start_rf(ru) != 0) + LOG_E(HW,"Could not start the RF device\n"); + else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); + } + else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - // Start RF device if any - if (ru->start_rf) { - if (ru->start_rf(ru) != 0) - LOG_E(HW,"Could not start the RF device\n"); - else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); - } - else LOG_I(PHY,"RU %d no rf device\n",ru->idx); + // if an asnych_rxtx thread exists + // wakeup the thread because the devices are ready at this point + + if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { + pthread_mutex_lock(&proc->mutex_asynch_rxtx); + proc->instance_cnt_asynch_rxtx=0; + pthread_mutex_unlock(&proc->mutex_asynch_rxtx); + pthread_cond_signal(&proc->cond_asynch_rxtx); + } + else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); - // if an asnych_rxtx thread exists - // wakeup the thread because the devices are ready at this point - - if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx=0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); - } - else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); + // 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); - // 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); + // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices + while (ru->state == RU_RUN) { - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices - while (!oai_exit) { + // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. + // They are set on the first rx/tx in the underly FH routines. + if (subframe==9) { + subframe=0; + frame++; + frame&=1023; + } else { + subframe++; + } - // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. - // They are set on the first rx/tx in the underly FH routines. - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } + LOG_D(PHY,"RU thread (proc %p), frame %d (%p), subframe %d (%p)\n", + proc, frame,&frame,subframe,&subframe); - LOG_D(PHY,"RU thread (proc %p), frame %d (%p), subframe %d (%p)\n", - proc, frame,&frame,subframe,&subframe); + // synchronization on input FH interface, acquire signals/data and block + if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe); + else AssertFatal(1==0, "No fronthaul interface at south port"); - // synchronization on input FH interface, acquire signals/data and block - if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe); - else AssertFatal(1==0, "No fronthaul interface at south port"); + LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", + ru->do_prach, + is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx), + proc->frame_rx,proc->subframe_rx); + + if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) wakeup_prach_ru(ru); + #ifdef Rel14 + else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) wakeup_prach_ru_br(ru); + #endif - LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", - ru->do_prach, - is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx), - proc->frame_rx,proc->subframe_rx); - - if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) wakeup_prach_ru(ru); -#ifdef Rel14 - else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) wakeup_prach_ru_br(ru); -#endif + // adjust for timing offset between RU + if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; - // adjust for timing offset between RU - if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; + // do RX front-end processing (frequency-shift, dft) if needed + if (ru->feprx) ru->feprx(ru); - // do RX front-end processing (frequency-shift, dft) if needed - if (ru->feprx) ru->feprx(ru); + // At this point, all information for subframe has been received on FH interface + // If this proc is to provide synchronization, do so + wakeup_slaves(proc); - // At this point, all information for subframe has been received on FH interface - // If this proc is to provide synchronization, do so - wakeup_slaves(proc); + // wakeup all eNB processes waiting for this RU + if (ru->num_eNB>0) wakeup_eNBs(ru); - // wakeup all eNB processes waiting for this RU - if (ru->num_eNB>0) wakeup_eNBs(ru); + // wait until eNBs are finished subframe RX n and TX n+4 + wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread"); - // wait until eNBs are finished subframe RX n and TX n+4 - wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread"); + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if (ru->fh_north_out) ru->fh_north_out(ru); - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); - - // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - - if (ru->fh_north_out) ru->fh_north_out(ru); + } - } + } // while !oai_exit printf( "Exiting ru_thread \n"); @@ -1841,7 +1855,7 @@ void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; - pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL; + pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL, *attr_ctrl=NULL; //pthread_attr_t *attr_fep=NULL; #ifdef Rel14 pthread_attr_t *attr_prach_br=NULL; @@ -1859,6 +1873,7 @@ void init_RU_proc(RU_t *ru) { proc->instance_cnt_synch = -1; ; proc->instance_cnt_FH = -1; proc->instance_cnt_asynch_rxtx = -1; + proc->instance_cnt_ru = 1; proc->first_rx = 1; proc->first_tx = 1; proc->frame_offset = 0; @@ -1871,11 +1886,13 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_synch,NULL); pthread_mutex_init( &proc->mutex_FH,NULL); + pthread_mutex_init( &proc->mutex_ru,NULL); pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init( &proc->cond_synch,NULL); + pthread_cond_init( &proc->cond_ru_thread,NULL); pthread_attr_init( &proc->attr_FH); pthread_attr_init( &proc->attr_prach); @@ -1901,6 +1918,8 @@ void init_RU_proc(RU_t *ru) { #endif pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru ); + pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void*)ru ); + if (ru->function == NGFI_RRU_IF4p5) { pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); -- GitLab