Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhongxiao
OpenXG-RAN
Commits
ec209bd4
Commit
ec209bd4
authored
Jul 31, 2016
by
Raymond Knopp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
if5 modifications. Use of asynchronous RX thread for RCC->RRU IF5 link
parent
5817a62c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
105 additions
and
59 deletions
+105
-59
openair1/PHY/LTE_TRANSPORT/if5_tools.c
openair1/PHY/LTE_TRANSPORT/if5_tools.c
+5
-5
openair1/PHY/defs.h
openair1/PHY/defs.h
+12
-6
targets/RT/USER/lte-enb.c
targets/RT/USER/lte-enb.c
+88
-48
No files found.
openair1/PHY/LTE_TRANSPORT/if5_tools.c
View file @
ec209bd4
...
...
@@ -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
);
eNB
->
ifdevice
.
trx_write_func
(
&
eNB
->
ifdevice
,
(
proc_timestamp
+
packet_id
*
spp_eth
),
txp
,
(
void
**
)
txp
,
spp_eth
,
fp
->
nb_antennas_tx
,
0
);
...
...
@@ -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
);
eNB
->
ifdevice
.
trx_write_func
(
&
eNB
->
ifdevice
,
(
proc_timestamp
+
packet_id
*
spp_eth
),
rxp
,
(
void
**
)
rxp
,
spp_eth
,
fp
->
nb_antennas_rx
,
0
);
...
...
@@ -131,7 +131,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
// Write the packet to the fronthaul
if
((
eNB
->
ifdevice
.
trx_write_func
(
&
eNB
->
ifdevice
,
packet_id
,
&
tx_buffer
,
(
void
**
)
&
tx_buffer
,
db_fulllength
,
1
,
IF5_MOBIPASS
))
<
0
)
{
...
...
@@ -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
);
eNB
->
ifdevice
.
trx_read_func
(
&
eNB
->
ifdevice
,
&
timestamp
[
packet_id
],
txp
,
(
void
**
)
txp
,
spp_eth
,
fp
->
nb_antennas_tx
);
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
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF
,
1
);
eNB
->
ifdevice
.
trx_read_func
(
&
eNB
->
ifdevice
,
&
timestamp
[
packet_id
],
rxp
,
(
void
**
)
rxp
,
spp_eth
,
fp
->
nb_antennas_rx
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF
,
0
);
...
...
openair1/PHY/defs.h
View file @
ec209bd4
...
...
@@ -252,10 +252,12 @@ typedef struct eNB_proc_t_s {
/// \brief Instance count for rx processing thread.
/// \internal This variable is protected by \ref mutex_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_t
pthread_FH
;
/// pthread structure for asychronous RX processing thread
pthread_t
pthread_asynch_rx
;
/// pthread structure for asychronous RX
/TX
processing thread
pthread_t
pthread_asynch_rx
tx
;
/// flag to indicate first RX acquisition
int
first_rx
;
/// pthread attributes for FH processing thread
...
...
@@ -263,23 +265,27 @@ typedef struct eNB_proc_t_s {
/// pthread attributes for prach processing thread
pthread_attr_t
attr_prach
;
/// pthread attributes for asynchronous RX thread
pthread_attr_t
attr_asynch_rx
;
pthread_attr_t
attr_asynch_rx
tx
;
/// scheduling parameters for FH thread
struct
sched_param
sched_param_FH
;
/// scheduling parameters for prach thread
struct
sched_param
sched_param_prach
;
/// scheduling parameters for asynch_rx thread
struct
sched_param
sched_param_asynch_rx
;
///
condition variable for F
H thread
/// scheduling parameters for asynch_rx
tx
thread
struct
sched_param
sched_param_asynch_rx
tx
;
///
pthread structure for PRAC
H thread
pthread_t
pthread_prach
;
/// condition variable for FH thread
pthread_cond_t
cond_FH
;
/// condition variable for PRACH processing thread;
pthread_cond_t
cond_prach
;
/// condition variable for asynch RX/TX thread
pthread_cond_t
cond_asynch_rxtx
;
/// mutex for FH
pthread_mutex_t
mutex_FH
;
/// mutex for PRACH thread
pthread_mutex_t
mutex_prach
;
/// mutex for asynch RX/TX thread
pthread_mutex_t
mutex_asynch_rxtx
;
/// set of scheduling variables RXn-TXnp4 threads
eNB_rxtx_proc_t
proc_rxtx
[
2
];
/// number of slave threads
...
...
targets/RT/USER/lte-enb.c
View file @
ec209bd4
...
...
@@ -641,21 +641,22 @@ static void wait_system_ready (char *message, volatile int *start_flag) {
#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
* \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.
*/
static
void
*
eNB_thread_asynch_rx
(
void
*
param
)
{
static
void
*
eNB_thread_asynch_rx
tx
(
void
*
param
)
{
static
int
eNB_thread_asynch_rx_status
;
static
int
eNB_thread_asynch_rx
tx
_status
;
eNB_proc_t
*
proc
=
(
eNB_proc_t
*
)
param
;
PHY_VARS_eNB
*
eNB
=
PHY_vars_eNB_g
[
0
][
proc
->
CC_id
];
LTE_DL_FRAME_PARMS
*
fp
=
&
eNB
->
frame_parms
;
openair0_timestamp
timestamp_rx
;
int
frame_rx
,
subframe_rx
;
openair0_timestamp
timestamp_rx
,
timestamp_tx
;
int
frame_rx
,
subframe_rx
=
0
,
subframe_tx
=
0
;
static
int
first_rx
=
1
;
static
int
first_tx
=
1
;
uint16_t
packet_type
;
uint32_t
symbol_number
=
0
;
uint32_t
symbol_mask
,
symbol_mask_full
;
...
...
@@ -768,40 +769,67 @@ static void* eNB_thread_asynch_rx( void* param ) {
printf
(
"got sync (eNB_thread_asynch_rx)
\n
"
);
if
(
eNB
->
node_function
==
eNodeB_3GPP
)
{
// acquisition from RF
if
(
eNB
->
rfdevice
.
trx_read_func
)
rxs
=
eNB
->
rfdevice
.
trx_read_func
(
&
eNB
->
rfdevice
,
&
proc
->
timestamp_rx
,
(
void
**
)
dummy_rx
,
fp
->
samples_per_tti
,
fp
->
nb_antennas_rx
);
else
{
printf
(
"eNB asynch RX
\n
"
);
sleep
(
1
);
}
if
(
rxs
!=
fp
->
samples_per_tti
)
{
exit_fun
(
"error receiving samples
\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
->
rfdevice
.
trx_read_func
)
rxs
=
eNB
->
rfdevice
.
trx_read_func
(
&
eNB
->
rfdevice
,
&
proc
->
timestamp_rx
,
(
void
**
)
dummy_rx
,
fp
->
samples_per_tti
,
fp
->
nb_antennas_rx
);
else
{
printf
(
"eNB asynch RX
\n
"
);
sleep
(
1
);
}
if
(
rxs
!=
fp
->
samples_per_tti
)
{
exit_fun
(
"error receiving samples
\n
"
);
}
}
}
else
if
(
eNB
->
node_function
==
eNodeB_3GPP_BBU
)
{
// acquisition from IF
else
if
(
eNB
->
node_function
==
eNodeB_3GPP_BBU
)
{
// acquisition from IF
/// **** recv_IF5 of rxdata from RRH **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5
,
1
);
recv_IF5
(
eNB
,
&
timestamp_rx
,
subframe_rx
++
,
IF5_RRH_GW_UL
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5
,
0
);
if
(
first_rx
==
1
)
{
first_rx
=
0
;
subframe_rx
=
(
timestamp_rx
/
fp
->
samples_per_tti
)
%
10
;
}
else
{
// check timestamp
if
((
timestamp_rx
-
proc
->
timestamp_rx
)
<
(
2
*
fp
->
samples_per_tti
))
printf
(
"RX overflow ...
\n
"
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5
,
1
);
recv_IF5
(
eNB
,
&
timestamp_rx
,
subframe_rx
++
,
IF5_RRH_GW_UL
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5
,
0
);
if
(
first_rx
==
1
)
{
first_rx
=
0
;
subframe_rx
=
(
timestamp_rx
/
fp
->
samples_per_tti
)
%
10
;
}
else
{
// check timestamp
if
((
timestamp_rx
-
proc
->
timestamp_rx
)
<
(
2
*
fp
->
samples_per_tti
))
printf
(
"RX overflow ...
\n
"
);
}
}
// 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
;
}
}
}
// eNodeB_3GPP_BBU
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 rxsigF from RRU **** ///
// get frame/subframe information from IF4p5 interface
...
...
@@ -811,10 +839,10 @@ static void* eNB_thread_asynch_rx( void* param ) {
symbol_mask
=
0
;
symbol_mask_full
=
(
1
<<
fp
->
symbols_per_tti
)
-
1
;
prach_rx
=
0
;
do
{
// Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
recv_IF4p5
(
eNB
,
&
frame_rx
,
&
subframe_rx
,
&
packet_type
,
&
symbol_number
);
if
(
packet_type
==
IF4p5_PULFFT
)
{
symbol_mask
=
symbol_mask
|
(
1
<<
symbol_number
);
prach_rx
=
(
is_prach_subframe
(
fp
,
proc
->
frame_rx
,
proc
->
subframe_rx
)
>
0
)
?
1
:
0
;
...
...
@@ -834,9 +862,9 @@ static void* eNB_thread_asynch_rx( void* param ) {
else
{
// should not get here
AssertFatal
(
1
==
0
,
"Unknown eNB->node_function %d"
,
eNB
->
node_function
);
}
eNB_thread_asynch_rx_status
=
0
;
return
(
&
eNB_thread_asynch_rx_status
);
}
eNB_thread_asynch_rx
tx
_status
=
0
;
return
(
&
eNB_thread_asynch_rx
tx
_status
);
}
void
rx_rf
(
PHY_VARS_eNB
*
eNB
,
eNB_proc_t
*
proc
,
int
*
frame
,
int
*
subframe
)
{
...
...
@@ -848,16 +876,17 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
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_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE
,
1
);
// prepare tx buffer pointers
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
,
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
,
fp
->
samples_per_tti
,
fp
->
nb_antennas_tx
,
...
...
@@ -877,7 +906,7 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
rxp
[
i
]
=
(
void
*
)
&
eNB
->
common_vars
.
rxdata
[
0
][
i
][
*
subframe
*
fp
->
samples_per_tti
];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ
,
1
);
rxs
=
eNB
->
rfdevice
.
trx_read_func
(
&
eNB
->
rfdevice
,
&
(
proc
->
timestamp_rx
),
rxp
,
...
...
@@ -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
->
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
->
subframe_rx
!=
*
subframe
){
...
...
@@ -1232,6 +1262,12 @@ static void* eNB_thread_FH( void* param ) {
if
(
eNB
->
start_rf
(
eNB
)
!=
0
)
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
while
(
!
oai_exit
)
{
...
...
@@ -1527,6 +1563,7 @@ void init_eNB_proc(int inst) {
proc_rxtx
[
1
].
instance_cnt_rxtx
=
-
1
;
proc
->
instance_cnt_prach
=
-
1
;
proc
->
instance_cnt_FH
=
-
1
;
proc
->
instance_cnt_asynch_rxtx
=
-
1
;
proc
->
CC_id
=
CC_id
;
proc
->
first_rx
=
4
;
...
...
@@ -1534,24 +1571,27 @@ void init_eNB_proc(int inst) {
pthread_mutex_init
(
&
proc_rxtx
[
0
].
mutex_rxtx
,
NULL
);
pthread_mutex_init
(
&
proc_rxtx
[
1
].
mutex_rxtx
,
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
[
1
].
cond_rxtx
,
NULL
);
pthread_cond_init
(
&
proc
->
cond_prach
,
NULL
);
pthread_cond_init
(
&
proc
->
cond_FH
,
NULL
);
pthread_cond_init
(
&
proc
->
cond_asynch_rxtx
,
NULL
);
#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
[
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_prach
,
&
proc
->
attr_prach
,
eNB_thread_prach
,
&
eNB
->
proc
);
if
(
eNB
->
node_timing
==
synch_to_other
)
pthread_create
(
&
proc
->
pthread_asynch_rx
,
&
proc
->
attr_asynch_rx
,
eNB_thread_asynch_rx
,
&
eNB
->
proc
);
if
((
eNB
->
node_timing
==
synch_to_other
)
||
(
eNB
->
node_function
==
NGFI_RRU_IF5
))
pthread_create
(
&
proc
->
pthread_asynch_rxtx
,
&
proc
->
attr_asynch_rxtx
,
eNB_thread_asynch_rxtx
,
&
eNB
->
proc
);
#else
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
->
pthread_FH
,
NULL
,
eNB_thread_FH
,
&
eNB
->
proc
);
pthread_create
(
&
proc
->
pthread_prach
,
NULL
,
eNB_thread_prach
,
&
eNB
->
proc
);
if
(
eNB
->
node_timing
==
synch_to_other
)
pthread_create
(
&
proc
->
pthread_asynch_rx
,
NULL
,
eNB_thread_asynch_r
x
,
&
eNB
->
proc
);
pthread_create
(
&
proc
->
pthread_asynch_rx
tx
,
NULL
,
eNB_thread_asynch_rxt
x
,
&
eNB
->
proc
);
#endif
char
name
[
16
];
...
...
@@ -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
->
fep
=
eNB_fep_rru_if5
;
eNB
->
proc_uespec_rx
=
NULL
;
eNB
->
proc_tx
=
proc_tx_rru_if5
;
eNB
->
proc_tx
=
NULL
;
eNB
->
tx_fh
=
NULL
;
eNB
->
rx_fh
=
rx_rf
;
eNB
->
start_rf
=
start_rf
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment