Commit ec209bd4 authored by Raymond Knopp's avatar Raymond Knopp

if5 modifications. Use of asynchronous RX thread for RCC->RRU IF5 link

parent 5817a62c
...@@ -66,7 +66,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe ...@@ -66,7 +66,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
eNB->ifdevice.trx_write_func(&eNB->ifdevice, eNB->ifdevice.trx_write_func(&eNB->ifdevice,
(proc_timestamp + packet_id*spp_eth), (proc_timestamp + packet_id*spp_eth),
txp, (void**)txp,
spp_eth, spp_eth,
fp->nb_antennas_tx, fp->nb_antennas_tx,
0); 0);
...@@ -86,7 +86,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe ...@@ -86,7 +86,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
eNB->ifdevice.trx_write_func(&eNB->ifdevice, eNB->ifdevice.trx_write_func(&eNB->ifdevice,
(proc_timestamp + packet_id*spp_eth), (proc_timestamp + packet_id*spp_eth),
rxp, (void**)rxp,
spp_eth, spp_eth,
fp->nb_antennas_rx, fp->nb_antennas_rx,
0); 0);
...@@ -131,7 +131,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe ...@@ -131,7 +131,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
// Write the packet to the fronthaul // Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
packet_id, packet_id,
&tx_buffer, (void**)&tx_buffer,
db_fulllength, db_fulllength,
1, 1,
IF5_MOBIPASS)) < 0) { IF5_MOBIPASS)) < 0) {
...@@ -177,7 +177,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram ...@@ -177,7 +177,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
eNB->ifdevice.trx_read_func(&eNB->ifdevice, eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&timestamp[packet_id], &timestamp[packet_id],
txp, (void**)txp,
spp_eth, spp_eth,
fp->nb_antennas_tx); fp->nb_antennas_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
...@@ -197,7 +197,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram ...@@ -197,7 +197,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
eNB->ifdevice.trx_read_func(&eNB->ifdevice, eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&timestamp[packet_id], &timestamp[packet_id],
rxp, (void**)rxp,
spp_eth, spp_eth,
fp->nb_antennas_rx); fp->nb_antennas_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
......
...@@ -252,10 +252,12 @@ typedef struct eNB_proc_t_s { ...@@ -252,10 +252,12 @@ 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;
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
int instance_cnt_asynch_rxtx;
/// pthread structure for FH processing thread /// pthread structure for FH processing thread
pthread_t pthread_FH; pthread_t pthread_FH;
/// pthread structure for asychronous RX processing thread /// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rx; pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition /// flag to indicate first RX acquisition
int first_rx; int first_rx;
/// pthread attributes for FH processing thread /// pthread attributes for FH processing thread
...@@ -263,23 +265,27 @@ typedef struct eNB_proc_t_s { ...@@ -263,23 +265,27 @@ typedef struct eNB_proc_t_s {
/// 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 asynchronous RX thread /// pthread attributes for asynchronous RX thread
pthread_attr_t attr_asynch_rx; pthread_attr_t attr_asynch_rxtx;
/// scheduling parameters for FH thread /// scheduling parameters for FH thread
struct sched_param sched_param_FH; struct sched_param sched_param_FH;
/// 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 asynch_rx thread /// scheduling parameters for asynch_rxtx thread
struct sched_param sched_param_asynch_rx; struct sched_param sched_param_asynch_rxtx;
/// condition variable for FH thread /// pthread structure for PRACH thread
pthread_t pthread_prach; pthread_t pthread_prach;
/// condition variable for FH thread /// condition variable for FH thread
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 asynch RX/TX thread
pthread_cond_t cond_asynch_rxtx;
/// mutex for FH /// mutex for FH
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 asynch RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// set of scheduling variables RXn-TXnp4 threads /// set of scheduling variables RXn-TXnp4 threads
eNB_rxtx_proc_t proc_rxtx[2]; eNB_rxtx_proc_t proc_rxtx[2];
/// number of slave threads /// number of slave threads
......
...@@ -641,21 +641,22 @@ static void wait_system_ready (char *message, volatile int *start_flag) { ...@@ -641,21 +641,22 @@ static void wait_system_ready (char *message, volatile int *start_flag) {
#endif #endif
/*! /*!
* \brief The Asynchronous RX FH thread of RAU/RCC/eNB. * \brief The Asynchronous RX/TX FH thread of RAU/RCC/eNB/RRU.
* This handles the RX FH for an asynchronous RRU/UE * This handles the RX FH for an asynchronous RRU/UE
* \param param is a \ref eNB_proc_t structure which contains the info what to process. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void* eNB_thread_asynch_rx( void* param ) { static void* eNB_thread_asynch_rxtx( void* param ) {
static int eNB_thread_asynch_rx_status; static int eNB_thread_asynch_rxtx_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t*)param;
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; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
openair0_timestamp timestamp_rx; openair0_timestamp timestamp_rx,timestamp_tx;
int frame_rx,subframe_rx; int frame_rx,subframe_rx=0,subframe_tx=0;
static int first_rx = 1; static int first_rx = 1;
static int first_tx = 1;
uint16_t packet_type; uint16_t packet_type;
uint32_t symbol_number=0; uint32_t symbol_number=0;
uint32_t symbol_mask, symbol_mask_full; uint32_t symbol_mask, symbol_mask_full;
...@@ -768,6 +769,19 @@ static void* eNB_thread_asynch_rx( void* param ) { ...@@ -768,6 +769,19 @@ static void* eNB_thread_asynch_rx( void* param ) {
printf( "got sync (eNB_thread_asynch_rx)\n" ); printf( "got sync (eNB_thread_asynch_rx)\n" );
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
printf( "waiting for devices (eNB_thread_asynch_rx)\n");
pthread_mutex_lock( &proc->mutex_asynch_rxtx);
while (proc->instance_cnt_asynch_rxtx<0)
pthread_cond_wait( &proc->cond_asynch_rxtx, &proc->mutex_asynch_rxtx );
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
printf( "devices ok (eNB_thread_asynch_rx)\n");
while (!oai_exit) {
if (eNB->node_function == eNodeB_3GPP) { // acquisition from RF if (eNB->node_function == eNodeB_3GPP) { // acquisition from RF
if (eNB->rfdevice.trx_read_func) if (eNB->rfdevice.trx_read_func)
...@@ -801,6 +815,20 @@ static void* eNB_thread_asynch_rx( void* param ) { ...@@ -801,6 +815,20 @@ static void* eNB_thread_asynch_rx( void* param ) {
} }
} // eNodeB_3GPP_BBU } // eNodeB_3GPP_BBU
else if (eNB->node_function == NGFI_RRU_IF5) {
/// **** recv_IF5 of rxdata from RRH **** ///
subframe_tx = (subframe_tx+1)%10;
recv_IF5(eNB, &timestamp_tx, subframe_tx, IF5_RRH_GW_DL);
printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx);
if (first_tx == 1) {
first_tx = 0;
subframe_tx = (timestamp_tx/fp->samples_per_tti)%10;
}
}
else if (eNB->node_function == NGFI_RCC_IF4p5) { else if (eNB->node_function == NGFI_RCC_IF4p5) {
/// **** recv_IF4p5 of rxdataF from RRU **** /// /// **** recv_IF4p5 of rxdataF from RRU **** ///
/// **** recv_IF4p5 of rxsigF from RRU **** /// /// **** recv_IF4p5 of rxsigF from RRU **** ///
...@@ -834,9 +862,9 @@ static void* eNB_thread_asynch_rx( void* param ) { ...@@ -834,9 +862,9 @@ static void* eNB_thread_asynch_rx( void* param ) {
else { // should not get here else { // should not get here
AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function); AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
} }
}
eNB_thread_asynch_rx_status=0; eNB_thread_asynch_rxtx_status=0;
return(&eNB_thread_asynch_rx_status); return(&eNB_thread_asynch_rxtx_status);
} }
void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) { void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
...@@ -849,15 +877,16 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) { ...@@ -849,15 +877,16 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
if (proc->first_rx==0) { if (proc->first_rx==0) {
// Transmit TX buffer based on timestamp from RX // Transmit TX buffer based on timestamp from RX
printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers // prepare tx buffer pointers
for (i=0; i<fp->nb_antennas_tx; i++) for (i=0; i<fp->nb_antennas_tx; i++)
txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+3)%10)*fp->samples_per_tti]; txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+2)%10)*fp->samples_per_tti];
txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance, proc->timestamp_rx+(2*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
txp, txp,
fp->samples_per_tti, fp->samples_per_tti,
fp->nb_antennas_tx, fp->nb_antennas_tx,
...@@ -888,6 +917,7 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) { ...@@ -888,6 +917,7 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
printf("trx_read <- USRP TS %llu (sf %d, first_rx %d)\n", proc->timestamp_rx,proc->subframe_rx,proc->first_rx);
if (proc->first_rx == 0) { if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){ if (proc->subframe_rx != *subframe){
...@@ -1232,6 +1262,12 @@ static void* eNB_thread_FH( void* param ) { ...@@ -1232,6 +1262,12 @@ static void* eNB_thread_FH( void* param ) {
if (eNB->start_rf(eNB) != 0) if (eNB->start_rf(eNB) != 0)
LOG_E(HW,"Could not start the RF device\n"); LOG_E(HW,"Could not start the RF device\n");
// unlock asnych_rxtx thread
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);
// 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) {
...@@ -1527,6 +1563,7 @@ void init_eNB_proc(int inst) { ...@@ -1527,6 +1563,7 @@ void init_eNB_proc(int inst) {
proc_rxtx[1].instance_cnt_rxtx = -1; proc_rxtx[1].instance_cnt_rxtx = -1;
proc->instance_cnt_prach = -1; proc->instance_cnt_prach = -1;
proc->instance_cnt_FH = -1; proc->instance_cnt_FH = -1;
proc->instance_cnt_asynch_rxtx = -1;
proc->CC_id = CC_id; proc->CC_id = CC_id;
proc->first_rx=4; proc->first_rx=4;
...@@ -1534,24 +1571,27 @@ void init_eNB_proc(int inst) { ...@@ -1534,24 +1571,27 @@ void init_eNB_proc(int inst) {
pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init( &proc->mutex_prach, NULL);
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); pthread_cond_init( &proc_rxtx[1].cond_rxtx, 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);
#ifndef DEADLINE_SCHEDULER #ifndef DEADLINE_SCHEDULER
pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] ); pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] );
pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] ); pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] );
pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc ); pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc );
pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc ); pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc );
if (eNB->node_timing == synch_to_other) if ((eNB->node_timing == synch_to_other) ||
pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc ); (eNB->node_function == NGFI_RRU_IF5))
pthread_create( &proc->pthread_asynch_rxtx, &proc->attr_asynch_rxtx, eNB_thread_asynch_rxtx, &eNB->proc );
#else #else
pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] ); pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] );
pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] ); pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] );
pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc ); pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc );
pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc ); pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc );
if (eNB->node_timing == synch_to_other) if (eNB->node_timing == synch_to_other)
pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc ); pthread_create( &proc->pthread_asynch_rxtx, NULL, eNB_thread_asynch_rxtx, &eNB->proc );
#endif #endif
char name[16]; char name[16];
...@@ -1767,7 +1807,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1767,7 +1807,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->do_prach = NULL; eNB->do_prach = NULL;
eNB->fep = eNB_fep_rru_if5; eNB->fep = eNB_fep_rru_if5;
eNB->proc_uespec_rx = NULL; eNB->proc_uespec_rx = NULL;
eNB->proc_tx = proc_tx_rru_if5; eNB->proc_tx = NULL;
eNB->tx_fh = NULL; eNB->tx_fh = NULL;
eNB->rx_fh = rx_rf; eNB->rx_fh = rx_rf;
eNB->start_rf = start_rf; eNB->start_rf = start_rf;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment