Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG UE
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
Michael Black
OpenXG UE
Commits
c5582c4c
Commit
c5582c4c
authored
May 09, 2016
by
Raymond Knopp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
removal of EXPRESSMIMO #ifdef's in lte-ue. move UE-specific code from lte-softmodem.c to lte-ue.c
parent
17c99ad1
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
96 additions
and
1570 deletions
+96
-1570
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+0
-13
targets/RT/USER/lte-softmodem.c
targets/RT/USER/lte-softmodem.c
+11
-43
targets/RT/USER/lte-ue.c
targets/RT/USER/lte-ue.c
+85
-584
targets/RT/USER/sched_dlsch.c
targets/RT/USER/sched_dlsch.c
+0
-354
targets/RT/USER/sched_rx_pdsch.c
targets/RT/USER/sched_rx_pdsch.c
+0
-321
targets/RT/USER/sched_ulsch.c
targets/RT/USER/sched_ulsch.c
+0
-255
No files found.
cmake_targets/CMakeLists.txt
View file @
c5582c4c
...
@@ -259,15 +259,6 @@ if (${ENABLE_ITTI})
...
@@ -259,15 +259,6 @@ if (${ENABLE_ITTI})
endif
(
${
ENABLE_ITTI
}
)
endif
(
${
ENABLE_ITTI
}
)
add_boolean_option
(
RTAI False
"Use RTAI"
)
add_boolean_option
(
RTAI False
"Use RTAI"
)
if
(
${
RTAI
}
)
set
(
LOWLATENCY False
)
set
(
CPU_AFFINITY False
)
add_definitions
(
"-DENABLE_RTAI_CLOCK"
)
add_definitions
(
"-DCONFIG_RTAI_LXRT_INLINE"
)
include_directories
(
"/usr/realtime/include"
)
include_directories
(
"/usr/realtime/include/asm"
)
set
(
RTAI_SOURCE sched_dlsch.c sched_rx_pdsch.c rt_wrapper.c vcd_signal_dumper.c log.c
)
endif
(
${
RTAI
}
)
#############################
#############################
# ASN.1 grammar C code generation & dependancies
# ASN.1 grammar C code generation & dependancies
...
@@ -1574,8 +1565,6 @@ add_executable(lte-softmodem
...
@@ -1574,8 +1565,6 @@ add_executable(lte-softmodem
${
rrc_h
}
${
rrc_h
}
${
s1ap_h
}
${
s1ap_h
}
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_TARGETS
}
/RT/USER/sched_dlsch.c
${
OPENAIR_TARGETS
}
/RT/USER/sched_rx_pdsch.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-softmodem.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-softmodem.c
...
@@ -1611,8 +1600,6 @@ add_executable(lte-softmodem-nos1
...
@@ -1611,8 +1600,6 @@ add_executable(lte-softmodem-nos1
${
rrc_h
}
${
rrc_h
}
${
s1ap_h
}
${
s1ap_h
}
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_TARGETS
}
/RT/USER/sched_dlsch.c
${
OPENAIR_TARGETS
}
/RT/USER/sched_rx_pdsch.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-softmodem.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-softmodem.c
...
...
targets/RT/USER/lte-softmodem.c
View file @
c5582c4c
...
@@ -113,12 +113,18 @@ unsigned short config_frames[4] = {2,9,11,13};
...
@@ -113,12 +113,18 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "stats.h"
#include "stats.h"
#endif
#endif
// In lte-enb.c
int
setup_eNB_buffers
(
PHY_VARS_eNB
**
phy_vars_eNB
,
openair0_config_t
*
openair0_cfg
,
openair0_rf_map
rf_map
[
MAX_NUM_CCs
]);
int
setup_eNB_buffers
(
PHY_VARS_eNB
**
phy_vars_eNB
,
openair0_config_t
*
openair0_cfg
,
openair0_rf_map
rf_map
[
MAX_NUM_CCs
]);
int
setup_ue_buffers
(
PHY_VARS_UE
**
phy_vars_ue
,
openair0_config_t
*
openair0_cfg
,
openair0_rf_map
rf_map
[
MAX_NUM_CCs
]);
extern
void
init_eNB
(
void
);
extern
void
init_eNB
(
void
);
extern
void
stop_eNB
(
void
);
extern
void
stop_eNB
(
void
);
extern
void
kill_eNB_proc
(
void
);
// In lte-ue.c
int
setup_ue_buffers
(
PHY_VARS_UE
**
phy_vars_ue
,
openair0_config_t
*
openair0_cfg
,
openair0_rf_map
rf_map
[
MAX_NUM_CCs
]);
void
fill_ue_band_info
(
void
);
void
fill_ue_band_info
(
void
);
extern
void
init_UE
(
void
);
#ifdef XFORMS
#ifdef XFORMS
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
// at eNB 0, an UL scope for every UE
// at eNB 0, an UL scope for every UE
...
@@ -130,9 +136,6 @@ unsigned char scope_enb_num_ue = 2;
...
@@ -130,9 +136,6 @@ unsigned char scope_enb_num_ue = 2;
#endif //XFORMS
#endif //XFORMS
pthread_t
main_ue_thread
;
pthread_attr_t
attr_UE_thread
;
...
@@ -144,7 +147,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex.
...
@@ -144,7 +147,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex.
struct
sched_param
sched_param_UE_thread
;
#ifdef XFORMS
#ifdef XFORMS
...
@@ -284,9 +286,8 @@ openair0_config_t openair0_cfg[MAX_CARDS];
...
@@ -284,9 +286,8 @@ openair0_config_t openair0_cfg[MAX_CARDS];
double
cpuf
;
double
cpuf
;
char
uecap_xer
[
1024
],
uecap_xer_in
=
0
;
char
uecap_xer
[
1024
],
uecap_xer_in
=
0
;
extern
void
*
UE_thread
(
void
*
arg
);
extern
void
init_UE_threads
(
void
);
extern
void
kill_eNB_proc
(
void
);
/*---------------------BMC: timespec helpers -----------------------------*/
/*---------------------BMC: timespec helpers -----------------------------*/
...
@@ -1120,7 +1121,6 @@ int main( int argc, char **argv )
...
@@ -1120,7 +1121,6 @@ int main( int argc, char **argv )
uint16_t
Nid_cell
=
0
;
uint16_t
Nid_cell
=
0
;
uint8_t
cooperation_flag
=
0
,
abstraction_flag
=
0
;
uint8_t
cooperation_flag
=
0
,
abstraction_flag
=
0
;
uint8_t
beta_ACK
=
0
,
beta_RI
=
0
,
beta_CQI
=
2
;
uint8_t
beta_ACK
=
0
,
beta_RI
=
0
,
beta_CQI
=
2
;
int
error_code
;
#if defined (XFORMS)
#if defined (XFORMS)
int
ret
;
int
ret
;
...
@@ -1752,43 +1752,11 @@ int main( int argc, char **argv )
...
@@ -1752,43 +1752,11 @@ int main( int argc, char **argv )
rt_sleep_ns
(
10
*
100000000ULL
);
rt_sleep_ns
(
10
*
100000000ULL
);
pthread_attr_init
(
&
attr_UE_thread
);
pthread_attr_setstacksize
(
&
attr_UE_thread
,
8192
);
//5*PTHREAD_STACK_MIN);
#ifndef LOWLATENCY
sched_param_UE_thread
.
sched_priority
=
sched_get_priority_max
(
SCHED_FIFO
);
pthread_attr_setschedparam
(
&
attr_UE_thread
,
&
sched_param_UE_thread
);
#endif
// start the main thread
// start the main thread
if
(
UE_flag
==
1
)
{
if
(
UE_flag
==
1
)
init_UE
();
printf
(
"Intializing UE Threads ...
\n
"
);
else
init_eNB
();
init_UE_threads
();
sleep
(
1
);
error_code
=
pthread_create
(
&
main_ue_thread
,
&
attr_UE_thread
,
UE_thread
,
NULL
);
if
(
error_code
!=
0
)
{
LOG_D
(
HW
,
"[lte-softmodem.c] Could not allocate UE_thread, error %d
\n
"
,
error_code
);
return
(
error_code
);
}
else
{
LOG_D
(
HW
,
"[lte-softmodem.c] Allocate UE_thread successful
\n
"
);
pthread_setname_np
(
main_ue_thread
,
"main UE"
);
}
printf
(
"UE threads created
\n
"
);
#ifdef USE_MME
while
(
start_UE
==
0
)
{
sleep
(
1
);
}
#endif
}
else
{
init_eNB
();
}
// Sleep to allow all threads to setup
// Sleep to allow all threads to setup
sleep
(
1
);
sleep
(
1
);
...
...
targets/RT/USER/lte-ue.c
View file @
c5582c4c
...
@@ -69,11 +69,7 @@
...
@@ -69,11 +69,7 @@
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#ifdef EXMIMO
#include "openair0_lib.h"
#else
#include "../../ARCH/COMMON/common_lib.h"
#include "../../ARCH/COMMON/common_lib.h"
#endif
#include "PHY/extern.h"
#include "PHY/extern.h"
#include "SCHED/extern.h"
#include "SCHED/extern.h"
...
@@ -96,10 +92,9 @@ typedef enum {
...
@@ -96,10 +92,9 @@ typedef enum {
si
=
2
si
=
2
}
sync_mode_t
;
}
sync_mode_t
;
int
init_dlsch_threads
(
void
);
void
init_UE_threads
(
void
);
void
cleanup_dlsch_threads
(
void
);
void
*
UE_thread
(
void
*
arg
);
int32_t
init_rx_pdsch_thread
(
void
);
void
init_UE
(
void
);
void
cleanup_rx_pdsch_thread
(
void
);
extern
pthread_cond_t
sync_cond
;
extern
pthread_cond_t
sync_cond
;
extern
pthread_mutex_t
sync_mutex
;
extern
pthread_mutex_t
sync_mutex
;
...
@@ -125,19 +120,6 @@ extern uint64_t num_missed_slots; // counter for the number of missed slots
...
@@ -125,19 +120,6 @@ extern uint64_t num_missed_slots; // counter for the number of missed slots
extern
void
exit_fun
(
const
char
*
s
);
extern
void
exit_fun
(
const
char
*
s
);
#ifdef EXMIMO
extern
unsigned
int
rxg_max
[
4
];
extern
unsigned
int
rxg_med
[
4
];
extern
unsigned
int
rxg_byp
[
4
];
extern
unsigned
int
nf_max
[
4
];
extern
unsigned
int
nf_med
[
4
];
extern
unsigned
int
nf_byp
[
4
];
extern
rx_gain_t
rx_gain_mode
[
MAX_NUM_CCs
][
4
];
extern
double
tx_gain
[
MAX_NUM_CCs
][
4
];
extern
double
rx_gain
[
MAX_NUM_CCs
][
4
];
#endif
#define KHz (1000UL)
#define KHz (1000UL)
#define MHz (1000 * KHz)
#define MHz (1000 * KHz)
...
@@ -189,6 +171,38 @@ static const eutra_band_t eutra_bands[] = {
...
@@ -189,6 +171,38 @@ static const eutra_band_t eutra_bands[] = {
{
44
,
703
*
MHz
,
803
*
MHz
,
703
*
MHz
,
803
*
MHz
,
TDD
},
{
44
,
703
*
MHz
,
803
*
MHz
,
703
*
MHz
,
803
*
MHz
,
TDD
},
};
};
pthread_t
main_ue_thread
;
pthread_attr_t
attr_UE_thread
;
struct
sched_param
sched_param_UE_thread
;
void
init_UE
()
{
int
error_code
;
printf
(
"Intializing UE Threads ...
\n
"
);
init_UE_threads
();
sleep
(
1
);
error_code
=
pthread_create
(
&
main_ue_thread
,
&
attr_UE_thread
,
UE_thread
,
NULL
);
if
(
error_code
!=
0
)
{
LOG_D
(
HW
,
"[lte-softmodem.c] Could not allocate UE_thread, error %d
\n
"
,
error_code
);
return
;
}
else
{
LOG_D
(
HW
,
"[lte-softmodem.c] Allocate UE_thread successful
\n
"
);
pthread_setname_np
(
main_ue_thread
,
"main UE"
);
}
printf
(
"UE threads created
\n
"
);
#ifdef USE_MME
while
(
start_UE
==
0
)
{
sleep
(
1
);
}
#endif
}
/*!
/*!
* \brief This is the UE synchronize thread.
* \brief This is the UE synchronize thread.
* It performs band scanning and synchonization.
* It performs band scanning and synchonization.
...
@@ -512,15 +526,10 @@ static void *UE_thread_synch(void *arg)
...
@@ -512,15 +526,10 @@ static void *UE_thread_synch(void *arg)
// openair0_cfg[0].rx_gain[0] -= 0;
// openair0_cfg[0].rx_gain[0] -= 0;
break
;
break
;
}
}
#ifndef EXMIMO
openair0
.
trx_set_freq_func
(
&
openair0
,
&
openair0_cfg
[
0
],
0
);
openair0
.
trx_set_freq_func
(
&
openair0
,
&
openair0_cfg
[
0
],
0
);
//openair0.trx_set_gains_func(&openair0,&openair0_cfg[0]);
//openair0.trx_set_gains_func(&openair0,&openair0_cfg[0]);
//openair0.trx_stop_func(0);
//openair0.trx_stop_func(0);
#else
openair0_set_frequencies
(
&
openair0
,
&
openair0_cfg
[
0
],
0
);
openair0_set_gains
(
&
openair0
,
&
openair0_cfg
[
0
]);
openair0_stop
(
0
);
#endif
sleep
(
1
);
sleep
(
1
);
init_frame_parms
(
&
UE
->
lte_frame_parms
,
1
);
init_frame_parms
(
&
UE
->
lte_frame_parms
,
1
);
}
}
...
@@ -550,13 +559,9 @@ static void *UE_thread_synch(void *arg)
...
@@ -550,13 +559,9 @@ static void *UE_thread_synch(void *arg)
}
}
#ifndef EXMIMO
UE
->
slot_rx
=
0
;
UE
->
slot_rx
=
0
;
UE
->
slot_tx
=
4
;
UE
->
slot_tx
=
4
;
#else
UE
->
slot_rx
=
18
;
UE
->
slot_tx
=
2
;
#endif
}
}
}
else
{
}
else
{
// initial sync failed
// initial sync failed
...
@@ -598,42 +603,13 @@ static void *UE_thread_synch(void *arg)
...
@@ -598,42 +603,13 @@ static void *UE_thread_synch(void *arg)
for
(
i
=
0
;
i
<
openair0_cfg
[
card
].
rx_num_channels
;
i
++
)
{
for
(
i
=
0
;
i
<
openair0_cfg
[
card
].
rx_num_channels
;
i
++
)
{
openair0_cfg
[
card
].
rx_freq
[
i
]
=
downlink_frequency
[
card
][
i
]
+
freq_offset
;
openair0_cfg
[
card
].
rx_freq
[
i
]
=
downlink_frequency
[
card
][
i
]
+
freq_offset
;
openair0_cfg
[
card
].
tx_freq
[
i
]
=
downlink_frequency
[
card
][
i
]
+
uplink_frequency_offset
[
card
][
i
]
+
freq_offset
;
openair0_cfg
[
card
].
tx_freq
[
i
]
=
downlink_frequency
[
card
][
i
]
+
uplink_frequency_offset
[
card
][
i
]
+
freq_offset
;
#ifndef EXMIMO
openair0
.
trx_set_freq_func
(
&
openair0
,
&
openair0_cfg
[
0
],
0
);
#else
openair0
.
trx_set_freq_func
(
&
openair0
,
&
openair0_cfg
[
0
],
0
);
openair0_set_frequencies
(
&
openair0
,
&
openair0_cfg
[
0
],
0
);
#endif
#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
openair0_cfg
[
card
].
rx_gain
[
i
]
=
UE
->
rx_total_gain_dB
;
//-USRP_GAIN_OFFSET;
openair0_cfg
[
card
].
rx_gain
[
i
]
=
UE
->
rx_total_gain_dB
;
//-USRP_GAIN_OFFSET;
#if 0
switch(UE->lte_frame_parms.N_RB_DL) {
case 6:
openair0_cfg[card].rx_gain[i] -= 12;
break;
case 25:
openair0_cfg[card].rx_gain[i] -= 6;
break;
case 50:
openair0_cfg[card].rx_gain[i] -= 0;//3;
break;
case 100:
openair0_cfg[card].rx_gain[i] -= 0;
break;
default:
printf("Unknown number of RBs %d\n",UE->lte_frame_parms.N_RB_DL);
break;
}
#endif
#endif
}
}
}
}
if
(
UE
->
UE_scan_carrier
==
1
)
{
if
(
UE
->
UE_scan_carrier
==
1
)
{
...
@@ -690,17 +666,6 @@ static void *UE_thread_tx(void *arg)
...
@@ -690,17 +666,6 @@ static void *UE_thread_tx(void *arg)
UE
->
instance_cnt_tx
=-
1
;
UE
->
instance_cnt_tx
=-
1
;
#ifdef RTAI
RT_TASK
*
task
=
rt_task_init_schmod
(
nam2num
(
"UE TX Thread"
),
0
,
0
,
0
,
SCHED_FIFO
,
0xF
);
if
(
task
==
NULL
)
{
LOG_E
(
PHY
,
"[SCHED][UE] Problem starting UE TX thread!!!!
\n
"
);
return
0
;
}
LOG_D
(
HW
,
"Started UE TX thread (id %p)
\n
"
,
task
);
#else
#ifdef LOWLATENCY
#ifdef LOWLATENCY
struct
sched_attr
attr
;
struct
sched_attr
attr
;
unsigned
int
flags
=
0
;
unsigned
int
flags
=
0
;
...
@@ -745,7 +710,7 @@ static void *UE_thread_tx(void *arg)
...
@@ -745,7 +710,7 @@ static void *UE_thread_tx(void *arg)
exit_fun
(
"Error setting processor affinity"
);
exit_fun
(
"Error setting processor affinity"
);
}
}
}
}
#endif
#endif
/* Check the actual affinity mask assigned to the thread */
/* Check the actual affinity mask assigned to the thread */
...
@@ -790,7 +755,6 @@ static void *UE_thread_tx(void *arg)
...
@@ -790,7 +755,6 @@ static void *UE_thread_tx(void *arg)
(
int
)
sparam
.
sched_priority
,
cpu_affinity
);
(
int
)
sparam
.
sched_priority
,
cpu_affinity
);
#endif
#endif
#endif
printf
(
"waiting for sync (UE_thread_tx)
\n
"
);
printf
(
"waiting for sync (UE_thread_tx)
\n
"
);
...
@@ -909,17 +873,6 @@ static void *UE_thread_rx(void *arg)
...
@@ -909,17 +873,6 @@ static void *UE_thread_rx(void *arg)
UE
->
instance_cnt_rx
=-
1
;
UE
->
instance_cnt_rx
=-
1
;
#ifdef RTAI
RT_TASK
*
task
=
rt_task_init_schmod
(
nam2num
(
"UE RX Thread"
),
0
,
0
,
0
,
SCHED_FIFO
,
0xF
);
if
(
task
==
NULL
)
{
LOG_E
(
PHY
,
"[SCHED][UE] Problem starting UE RX thread!!!!
\n
"
);
return
&
UE_thread_rx_retval
;
}
LOG_D
(
HW
,
"Started UE RX thread (id %p)
\n
"
,
task
);
#else
#ifdef LOWLATENCY
#ifdef LOWLATENCY
struct
sched_attr
attr
;
struct
sched_attr
attr
;
unsigned
int
flags
=
0
;
unsigned
int
flags
=
0
;
...
@@ -1008,7 +961,6 @@ static void *UE_thread_rx(void *arg)
...
@@ -1008,7 +961,6 @@ static void *UE_thread_rx(void *arg)
(
int
)
sparam
.
sched_priority
,
cpu_affinity
);
(
int
)
sparam
.
sched_priority
,
cpu_affinity
);
#endif
#endif
#endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
...
@@ -1186,7 +1138,7 @@ static void *UE_thread_rx(void *arg)
...
@@ -1186,7 +1138,7 @@ static void *UE_thread_rx(void *arg)
#ifndef EXMIMO
#define RX_OFF_MAX 10
#define RX_OFF_MAX 10
#define RX_OFF_MIN 5
#define RX_OFF_MIN 5
#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2)
#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2)
...
@@ -1227,16 +1179,6 @@ void *UE_thread(void *arg)
...
@@ -1227,16 +1179,6 @@ void *UE_thread(void *arg)
MessageDef
*
message_p
;
MessageDef
*
message_p
;
#endif
#endif
#ifdef RTAI
RT_TASK
*
task
=
rt_task_init_schmod
(
nam2num
(
"UE thread"
),
0
,
0
,
0
,
SCHED_FIFO
,
0xF
);
if
(
task
==
NULL
)
{
LOG_E
(
PHY
,
"[SCHED][UE] Problem starting UE thread!!!!
\n
"
);
return
0
;
}
#else
#ifdef LOWLATENCY
#ifdef LOWLATENCY
struct
sched_attr
attr
;
struct
sched_attr
attr
;
unsigned
int
flags
=
0
;
unsigned
int
flags
=
0
;
...
@@ -1264,7 +1206,6 @@ void *UE_thread(void *arg)
...
@@ -1264,7 +1206,6 @@ void *UE_thread(void *arg)
struct
sched_param
sp
;
struct
sched_param
sp
;
sp
.
sched_priority
=
sched_get_priority_max
(
SCHED_FIFO
);
sp
.
sched_priority
=
sched_get_priority_max
(
SCHED_FIFO
);
pthread_setschedparam
(
pthread_self
(),
SCHED_FIFO
,
&
sp
);
pthread_setschedparam
(
pthread_self
(),
SCHED_FIFO
,
&
sp
);
#endif
#endif
#endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
...
@@ -1591,409 +1532,8 @@ void *UE_thread(void *arg)
...
@@ -1591,409 +1532,8 @@ void *UE_thread(void *arg)
return
&
UE_thread_retval
;
return
&
UE_thread_retval
;
}
}
#endif
#ifdef EXMIMO
/* This is the main UE thread. Initially it is doing a periodic get_frame. One synchronized it gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */
void
*
UE_thread
(
void
*
arg
)
{
PHY_VARS_UE
*
UE
=
PHY_vars_UE_g
[
0
][
0
];
#ifdef RTAI
RT_TASK
*
task
;
#endif
// RTIME in, out, diff;
int
slot
=
0
,
frame
=
0
,
hw_slot
;
// unsigned int aa;
int
delay_cnt
;
RTIME
time_in
;
int
/* hw_slot_offset=0, */
rx_offset_mbox
=
0
,
mbox_target
=
0
,
mbox_current
=
0
;
int
diff2
;
int
/* i, */
ret
;
int
/* CC_id, */
card
;
volatile
unsigned
int
*
DAQ_MBOX
=
openair0_daq_cnt
();
int
wait_sync_cnt
=
0
;
int
first_synch
=
1
;
#ifdef LOWLATENCY
struct
sched_attr
attr
;
unsigned
int
flags
=
0
;
// unsigned long mask = 1; // processor 0
#endif
int
freq_offset
;
#ifdef RTAI
task
=
rt_task_init_schmod
(
nam2num
(
"UE thread"
),
0
,
0
,
0
,
SCHED_FIFO
,
0xF
);
if
(
task
==
NULL
)
{
LOG_E
(
PHY
,
"[SCHED][UE] Problem starting UE thread!!!!
\n
"
);
return
0
;
}
#endif
#ifdef HARD_RT
rt_make_hard_real_time
();
#endif
#ifdef LOWLATENCY
attr
.
size
=
sizeof
(
attr
);
attr
.
sched_flags
=
0
;
attr
.
sched_nice
=
0
;
attr
.
sched_priority
=
0
;
// This creates a .25 ms reservation
attr
.
sched_policy
=
SCHED_DEADLINE
;
attr
.
sched_runtime
=
(
0
.
1
*
100
)
*
10000
;
attr
.
sched_deadline
=
(
0
.
25
*
100
)
*
10000
;
attr
.
sched_period
=
(
0
.
5
*
100
)
*
10000
;
// pin the UE main thread to CPU0
// if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) {
// perror("[MAIN_ENB_THREAD] pthread_setaffinity_np failed\n");
// }
if
(
sched_setattr
(
0
,
&
attr
,
flags
)
<
0
)
{
perror
(
"[SCHED] main UE thread: sched_setattr failed
\n
"
);
exit_fun
(
"Nothing to add"
);
}
else
{
LOG_I
(
HW
,
"[SCHED][eNB] eNB main deadline thread %ld started on CPU %d
\n
"
,
gettid
(),
sched_getcpu
());
}
#endif
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
printf
(
"waiting for sync (UE_thread)
\n
"
);
pthread_mutex_lock
(
&
sync_mutex
);
printf
(
"Locked sync_mutex, waiting (UE_thread)
\n
"
);
while
(
sync_var
<
0
)
pthread_cond_wait
(
&
sync_cond
,
&
sync_mutex
);
pthread_mutex_unlock
(
&
sync_mutex
);
printf
(
"unlocked sync_mutex, waiting (UE_thread)
\n
"
);
printf
(
"starting UE thread
\n
"
);
freq_offset
=
0
;
//-7500;
first_synch
=
1
;
while
(
!
oai_exit
)
{
hw_slot
=
(((((
volatile
unsigned
int
*
)
DAQ_MBOX
)[
0
]
+
1
)
%
150
)
<<
1
)
/
15
;
//the slot the hw is about to store
if
(
UE
->
is_synchronized
)
{
if
(
first_synch
==
1
)
{
first_synch
=
0
;
for
(
card
=
0
;
card
<
openair0_num_detected_cards
;
card
++
)
openair0_start_rt_acquisition
(
card
);
rt_sleep_ns
(
FRAME_PERIOD
/
10
);
}
//this is the mbox counter that indicates the start of the frame
rx_offset_mbox
=
(
UE
->
rx_offset
*
150
)
/
(
10
*
UE
->
lte_frame_parms
.
samples_per_tti
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_UE_RX_OFFSET
,
UE
->
rx_offset
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_UE_OFFSET_MBOX
,
rx_offset_mbox
);
//this is the mbox counter where we should be
mbox_target
=
(((((
slot
+
1
)
%
20
)
*
15
+
1
)
>>
1
)
+
rx_offset_mbox
+
1
)
%
150
;
// round up to the next multiple of two (mbox counter from express MIMO gives only even numbers)
mbox_target
=
((
mbox_target
+
1
)
-
((
mbox_target
-
1
)
%
2
))
%
150
;
//this is the mbox counter where we are
mbox_current
=
((
volatile
unsigned
int
*
)
DAQ_MBOX
)[
0
];
//this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD)
if
((
mbox_current
>=
120
)
&&
(
mbox_target
<
30
))
//handle the frame wrap-arround
diff2
=
150
-
mbox_current
+
mbox_target
;
else
if
((
mbox_current
<
30
)
&&
(
mbox_target
>=
120
))
diff2
=
-
150
+
mbox_target
-
mbox_current
;
else
diff2
=
mbox_target
-
mbox_current
;
if
(
diff2
<
(
-
7
))
{
LOG_D
(
HW
,
"UE Frame %d: missed slot, proceeding with next one (slot %d, hw_slot %d, diff %d)
\n
"
,
frame
,
slot
,
hw_slot
,
diff2
);
if
(
frame
>
0
)
{
if
(
exit_missed_slots
==
1
)
exit_fun
(
"[HW][UE] missed slot"
);
else
{
num_missed_slots
++
;
LOG_W
(
HW
,
"[UE] just missed slot (total missed slots %ld)
\n
"
,
num_missed_slots
);
}
}
slot
++
;
if
(
slot
==
20
)
{
slot
=
0
;
frame
++
;
}
// update thread slot/frame counters because of skipped slot
UE
->
slot_rx
++
;
UE
->
slot_tx
++
;
if
(
UE
->
slot_rx
==
20
)
{
UE
->
slot_rx
=
0
;
UE
->
frame_rx
++
;
}
if
(
UE
->
slot_tx
==
20
)
{
UE
->
slot_tx
=
0
;
UE
->
frame_tx
++
;
}
continue
;
}
if
(
diff2
>
8
)
LOG_D
(
HW
,
"UE Frame %d: skipped slot, waiting for hw to catch up (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)
\n
"
,
frame
,
slot
,
hw_slot
,
mbox_current
,
mbox_target
,
diff2
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX
,
*
DAQ_MBOX
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_DIFF
,
diff2
);
// This loop implements the delay of 1 slot to allow for processing
delay_cnt
=
0
;
while
((
diff2
>
0
)
&&
(
!
oai_exit
)
)
{
time_in
=
rt_get_time_ns
();
//LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d (%d), diff %d, time %llu\n",frame,delay_cnt,hw_slot,((volatile unsigned int *)DAQ_MBOX)[0],slot,mbox_target,diff2,time_in);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX
,
*
DAQ_MBOX
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP
,
1
);
ret
=
rt_sleep_ns
(
diff2
*
DAQ_PERIOD
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP
,
0
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX
,
*
DAQ_MBOX
);
if
(
ret
)
LOG_D
(
HW
,
"eNB Frame %d, time %llu: rt_sleep_ns returned %d
\n
"
,
frame
,
time_in
);
hw_slot
=
(((((
volatile
unsigned
int
*
)
DAQ_MBOX
)[
0
]
+
1
)
%
150
)
<<
1
)
/
15
;
//LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns());
delay_cnt
++
;
if
(
delay_cnt
==
30
)
{
LOG_D
(
HW
,
"UE frame %d: HW stopped ...
\n
"
,
frame
);
exit_fun
(
"[HW][UE] HW stopped"
);
}
mbox_current
=
((
volatile
unsigned
int
*
)
DAQ_MBOX
)[
0
];
if
((
mbox_current
>=
135
)
&&
(
mbox_target
<
15
))
//handle the frame wrap-arround
diff2
=
150
-
mbox_current
+
mbox_target
;
else
if
((
mbox_current
<
15
)
&&
(
mbox_target
>=
135
))
diff2
=
-
150
+
mbox_target
-
mbox_current
;
else
diff2
=
mbox_target
-
mbox_current
;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX
,
*
DAQ_MBOX
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_DIFF
,
diff2
);
}
// on even slots, schedule processing of entire subframe
if
((
slot
&
1
)
==
0
)
{
if
(
pthread_mutex_lock
(
&
UE
->
mutex_rx
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][UE] error locking mutex for UE RX thread
\n
"
);
exit_fun
(
"nothing to add"
);
}
else
{
int
instance_cnt_rx
=
++
UE
->
instance_cnt_rx
;
pthread_mutex_unlock
(
&
UE
->
mutex_rx
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX
,
instance_cnt_rx
);
if
(
instance_cnt_rx
==
0
)
{
LOG_D
(
HW
,
"Scheduling UE RX for frame %d (hw frame %d), subframe %d (%d), mode %d
\n
"
,
UE
->
frame_rx
,
frame
,
slot
>>
1
,
UE
->
slot_rx
>>
1
,
UE
->
mode
);
if
(
pthread_cond_signal
(
&
UE
->
cond_rx
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][UE] ERROR pthread_cond_signal for UE RX thread
\n
"
);
exit_fun
(
"nothing to add"
);
}
else
{
// printf("UE_thread: cond_signal for RX ok (%p) @ %llu\n",(void*)&UE->cond_rx,rt_get_time_ns()-T0);
}
if
(
UE
->
mode
==
rx_calib_ue
)
{
if
(
frame
==
10
)
{
LOG_D
(
PHY
,
"[SCHED][UE] Found cell with N_RB_DL %d, PHICH CONFIG (%d,%d), Nid_cell %d, NB_ANTENNAS_TX %d, initial frequency offset %d Hz, frequency offset %d Hz, RSSI (digital) %d dB, measured Gain %d dB, total_rx_gain %d dB, USRP rx gain %f dB
\n
"
,
UE
->
lte_frame_parms
.
N_RB_DL
,
UE
->
lte_frame_parms
.
phich_config_common
.
phich_duration
,
UE
->
lte_frame_parms
.
phich_config_common
.
phich_resource
,
UE
->
lte_frame_parms
.
Nid_cell
,
UE
->
lte_frame_parms
.
nb_antennas_tx_eNB
,
freq_offset
,
UE
->
lte_ue_common_vars
.
freq_offset
,
UE
->
PHY_measurements
.
rx_power_avg_dB
[
0
],
UE
->
PHY_measurements
.
rx_power_avg_dB
[
0
]
-
rx_input_level_dBm
,
UE
->
rx_total_gain_dB
,
openair0_cfg
[
0
].
rx_gain
[
0
]
);
exit_fun
(
"[HW][UE] UE in RX calibration mode, exiting"
);
}
}
}
else
{
LOG_E
(
PHY
,
"[SCHED][UE] UE RX thread busy!!
\n
"
);
exit_fun
(
"nothing to add"
);
}
}
if
(
pthread_mutex_lock
(
&
UE
->
mutex_tx
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][UE] error locking mutex for UE TX thread
\n
"
);
exit_fun
(
"nothing to add"
);
}
else
{
int
instance_cnt_tx
=
++
UE
->
instance_cnt_tx
;
pthread_mutex_unlock
(
&
UE
->
mutex_tx
);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX
,
instance_cnt_tx
);
if
(
instance_cnt_tx
==
0
)
{
LOG_D
(
HW
,
"Scheduling UE TX for frame %d (hw frame %d), subframe %d (%d), mode %d
\n
"
,
UE
->
frame_tx
,
frame
,
slot
>>
1
,
UE
->
slot_tx
>>
1
,
UE
->
mode
);
if
(
pthread_cond_signal
(
&
UE
->
cond_tx
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][UE] ERROR pthread_cond_signal for UE TX thread
\n
"
);
exit_fun
(
"nothing to add"
);
}
else
{
// printf("UE_thread: cond_signal for RX ok (%p) @ %llu\n",(void*)&UE->cond_rx,rt_get_time_ns()-T0);
}
}
else
{
LOG_E
(
PHY
,
"[SCHED][UE] UE TX thread busy!!
\n
"
);
exit_fun
(
"nothing to add"
);
}
}
}
/*
if ((slot%2000)<10)
LOG_D(HW,"fun0: doing very hard work\n");
*/
// now increment slot and frame counters
slot
++
;
if
(
slot
==
20
)
{
slot
=
0
;
frame
++
;
}
}
else
if
(
UE
->
is_synchronized
==
0
)
{
// we are not yet synchronized
//hw_slot_offset = 0;
first_synch
=
1
;
slot
=
0
;
// wait until we can lock mutex_synch
//printf("Locking mutex_synch (UE_thread)\n");
if
(
pthread_mutex_lock
(
&
UE
->
mutex_synch
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][UE] error locking mutex for UE initial synch thread
\n
"
);
exit_fun
(
"noting to add"
);
}
else
{
if
(
UE
->
instance_cnt_synch
<
0
)
{
wait_sync_cnt
=
0
;
openair0_config
(
&
openair0_cfg
[
0
],
1
);
// openair0_set_gains(&openair0,&openair0_cfg[0]);
printf
(
"Getting frame
\n
"
);
openair0_get_frame
(
0
);
rt_sleep_ns
(
FRAME_PERIOD
);
// increment instance count for sync thread
UE
->
instance_cnt_synch
++
;
pthread_mutex_unlock
(
&
UE
->
mutex_synch
);
if
(
pthread_cond_signal
(
&
UE
->
cond_synch
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][UE] ERROR pthread_cond_signal for UE sync thread
\n
"
);
exit_fun
(
"nothing to add"
);
}
}
else
{
wait_sync_cnt
++
;
pthread_mutex_unlock
(
&
UE
->
mutex_synch
);
if
(
wait_sync_cnt
>
1000
)
exit_fun
(
"waiting to long for synch thread"
);
else
rt_sleep_ns
(
FRAME_PERIOD
);
}
}
/*
if (initial_sync(UE,mode)==0) {
if (mode == rx_calib_ue) {
exit_fun("[HW][UE] UE in RX calibration mode");
}
else {
is_synchronized = 1;
//start the streaming DMA transfers
for (card=0;card<openair0_num_detected_cards;card++)
openair0_start_rt_acquisition(card);
hw_slot_offset = (UE->rx_offset<<1) / UE->lte_frame_parms.samples_per_tti;
}
}
else {
if (freq_offset >= 0) {
freq_offset += 100;
freq_offset *= -1;
}
else {
freq_offset *= -1;
}
if (abs(freq_offset) > 7500) {
LOG_I(PHY,"[initial_sync] No cell synchronization found, abondoning\n");
mac_xface->macphy_exit("No cell synchronization found, abondoning");
}
else {
// LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",freq_offset);
#ifndef USRP
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (i=0; i<openair0_cfg[rf_map[CC_id].card].rx_num_channels; i++)
openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+freq_offset;
for (i=0; i<openair0_cfg[rf_map[CC_id].card].tx_num_channels; i++)
openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+freq_offset;
}
openair0_config(&openair0_cfg[0],UE_flag);
#endif
rt_sleep_ns(FRAME_PERIOD);
}
}
*/
}
}
LOG_D
(
HW
,
"UE_thread: finished, ran %d times.
\n
"
,
frame
);
#ifdef HARD_RT
rt_make_soft_real_time
();
#endif
// clean task
#ifdef RTAI
rt_task_delete
(
task
);
#endif
LOG_D
(
HW
,
"Task deleted. returning
\n
"
);
return
0
;
}
#else // This is for USRP or ETHERNET targets
#endif
/*!
/*!
...
@@ -2008,6 +1548,14 @@ void init_UE_threads(void)
...
@@ -2008,6 +1548,14 @@ void init_UE_threads(void)
{
{
PHY_VARS_UE
*
UE
=
PHY_vars_UE_g
[
0
][
0
];
PHY_VARS_UE
*
UE
=
PHY_vars_UE_g
[
0
][
0
];
pthread_attr_init
(
&
attr_UE_thread
);
pthread_attr_setstacksize
(
&
attr_UE_thread
,
8192
);
//5*PTHREAD_STACK_MIN);
#ifndef LOWLATENCY
sched_param_UE_thread
.
sched_priority
=
sched_get_priority_max
(
SCHED_FIFO
);
pthread_attr_setschedparam
(
&
attr_UE_thread
,
&
sched_param_UE_thread
);
#endif
// the threads are not yet active, therefore access is allowed without locking
// the threads are not yet active, therefore access is allowed without locking
UE
->
instance_cnt_tx
=
-
1
;
UE
->
instance_cnt_tx
=
-
1
;
UE
->
instance_cnt_rx
=
-
1
;
UE
->
instance_cnt_rx
=
-
1
;
...
@@ -2063,10 +1611,6 @@ void fill_ue_band_info(void)
...
@@ -2063,10 +1611,6 @@ void fill_ue_band_info(void)
int
setup_ue_buffers
(
PHY_VARS_UE
**
phy_vars_ue
,
openair0_config_t
*
openair0_cfg
,
openair0_rf_map
rf_map
[
MAX_NUM_CCs
])
int
setup_ue_buffers
(
PHY_VARS_UE
**
phy_vars_ue
,
openair0_config_t
*
openair0_cfg
,
openair0_rf_map
rf_map
[
MAX_NUM_CCs
])
{
{
//#ifndef EXMIMO
// uint16_t N_TA_offset = 0;
//#endif
int
i
,
CC_id
;
int
i
,
CC_id
;
LTE_DL_FRAME_PARMS
*
frame_parms
;
LTE_DL_FRAME_PARMS
*
frame_parms
;
...
@@ -2079,58 +1623,16 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg,
...
@@ -2079,58 +1623,16 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg,
}
}
//#ifndef EXMIMO
if
(
frame_parms
->
frame_type
==
TDD
)
{
// if (frame_parms->frame_type == TDD) {
if
(
frame_parms
->
N_RB_DL
==
100
)
// if (frame_parms->N_RB_DL == 100)
N_TA_offset
=
624
;
// N_TA_offset = 624;
else
if
(
frame_parms
->
N_RB_DL
==
50
)
// else if (frame_parms->N_RB_DL == 50)
N_TA_offset
=
624
/
2
;
// N_TA_offset = 624/2;
else
if
(
frame_parms
->
N_RB_DL
==
25
)
// else if (frame_parms->N_RB_DL == 25)
N_TA_offset
=
624
/
4
;
// N_TA_offset = 624/4;
// }
//#endif
#ifdef EXMIMO
openair0_cfg
[
CC_id
].
tx_num_channels
=
0
;
openair0_cfg
[
CC_id
].
rx_num_channels
=
0
;
// replace RX signal buffers with mmaped HW versions
for
(
i
=
0
;
i
<
frame_parms
->
nb_antennas_rx
;
i
++
)
{
printf
(
"Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d
\n
"
,
CC_id
,
i
,
downlink_frequency
[
CC_id
][
i
],
rf_map
[
CC_id
].
card
,
rf_map
[
CC_id
].
chain
+
i
);
free
(
phy_vars_ue
[
CC_id
]
->
lte_ue_common_vars
.
rxdata
[
i
]);
phy_vars_ue
[
CC_id
]
->
lte_ue_common_vars
.
rxdata
[
i
]
=
(
int32_t
*
)
openair0_exmimo_pci
[
rf_map
[
CC_id
].
card
].
adc_head
[
rf_map
[
CC_id
].
chain
+
i
];
if
(
openair0_cfg
[
rf_map
[
CC_id
].
card
].
rx_freq
[
rf_map
[
CC_id
].
chain
+
i
])
{
printf
(
"Error with rf_map! A channel has already been allocated!
\n
"
);
return
(
-
1
);
}
else
{
openair0_cfg
[
rf_map
[
CC_id
].
card
].
rx_freq
[
rf_map
[
CC_id
].
chain
+
i
]
=
downlink_frequency
[
CC_id
][
i
];
openair0_cfg
[
rf_map
[
CC_id
].
card
].
rx_gain
[
rf_map
[
CC_id
].
chain
+
i
]
=
rx_gain
[
CC_id
][
i
];
openair0_cfg
[
rf_map
[
CC_id
].
card
].
rxg_mode
[
rf_map
[
CC_id
].
chain
+
i
]
=
rx_gain_mode
[
CC_id
][
i
];
openair0_cfg
[
rf_map
[
CC_id
].
card
].
rx_num_channels
++
;
}
printf
(
"rxdata[%d] @ %p
\n
"
,
i
,
phy_vars_ue
[
CC_id
]
->
lte_ue_common_vars
.
rxdata
[
i
]);
}
for
(
i
=
0
;
i
<
frame_parms
->
nb_antennas_tx
;
i
++
)
{
printf
(
"Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d
\n
"
,
CC_id
,
i
,
downlink_frequency
[
CC_id
][
i
],
rf_map
[
CC_id
].
card
,
rf_map
[
CC_id
].
chain
+
i
);
free
(
phy_vars_ue
[
CC_id
]
->
lte_ue_common_vars
.
txdata
[
i
]);
phy_vars_ue
[
CC_id
]
->
lte_ue_common_vars
.
txdata
[
i
]
=
(
int32_t
*
)
openair0_exmimo_pci
[
rf_map
[
CC_id
].
card
].
dac_head
[
rf_map
[
CC_id
].
chain
+
i
];
if
(
openair0_cfg
[
rf_map
[
CC_id
].
card
].
tx_freq
[
rf_map
[
CC_id
].
chain
+
i
])
{
printf
(
"Error with rf_map! A channel has already been allocated!
\n
"
);
return
(
-
1
);
}
else
{
openair0_cfg
[
rf_map
[
CC_id
].
card
].
tx_freq
[
rf_map
[
CC_id
].
chain
+
i
]
=
downlink_frequency
[
CC_id
][
i
]
+
uplink_frequency_offset
[
CC_id
][
i
];
openair0_cfg
[
rf_map
[
CC_id
].
card
].
tx_gain
[
rf_map
[
CC_id
].
chain
+
i
]
=
tx_gain
[
CC_id
][
i
];
openair0_cfg
[
rf_map
[
CC_id
].
card
].
tx_num_channels
++
;
}
}
printf
(
"txdata[%d] @ %p
\n
"
,
i
,
phy_vars_ue
[
CC_id
]
->
lte_ue_common_vars
.
txdata
[
i
]);
}
#else
// replace RX signal buffers with mmaped HW versions
// replace RX signal buffers with mmaped HW versions
rxdata
=
(
int32_t
**
)
malloc16
(
frame_parms
->
nb_antennas_rx
*
sizeof
(
int32_t
*
)
);
rxdata
=
(
int32_t
**
)
malloc16
(
frame_parms
->
nb_antennas_rx
*
sizeof
(
int32_t
*
)
);
txdata
=
(
int32_t
**
)
malloc16
(
frame_parms
->
nb_antennas_tx
*
sizeof
(
int32_t
*
)
);
txdata
=
(
int32_t
**
)
malloc16
(
frame_parms
->
nb_antennas_tx
*
sizeof
(
int32_t
*
)
);
...
@@ -2153,7 +1655,6 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg,
...
@@ -2153,7 +1655,6 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg,
// txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[x]
// txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[x]
// be careful when releasing memory!
// be careful when releasing memory!
// because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes)
// because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes)
#endif
}
}
...
...
targets/RT/USER/sched_dlsch.c
deleted
100644 → 0
View file @
17c99ad1
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file sched_dlsch.c
* \brief DLSCH decoding thread (RTAI)
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include "rt_wrapper.h"
#include <sys/mman.h>
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#define DEBUG_PHY
/// Mutex for instance count on dlsch scheduling
pthread_mutex_t
dlsch_mutex
[
8
];
/// Condition variable for dlsch thread
pthread_cond_t
dlsch_cond
[
8
];
pthread_t
dlsch_threads
[
8
];
pthread_attr_t
attr_dlsch_threads
;
unsigned
char
dlsch_thread_indices
[
8
];
// activity indicators for harq_pid's
int
dlsch_instance_cnt
[
8
];
// process ids for cpu
int
dlsch_cpuid
[
8
];
// subframe number for each harq_pid (needed to store ack in right place for UL)
int
dlsch_subframe
[
8
];
extern
int
oai_exit
;
/*
extern int dlsch_errors;
extern int dlsch_received;
extern int dlsch_errors_last;
extern int dlsch_received_last;
extern int dlsch_fer;
extern int current_dlsch_cqi;
*/
/** DLSCH Decoding Thread */
static
void
*
dlsch_thread
(
void
*
param
)
{
//unsigned long cpuid;
unsigned
char
dlsch_thread_index
=
*
((
unsigned
char
*
)
param
);
unsigned
int
ret
=
0
;
uint8_t
harq_pid
;
#ifdef RTAI
RT_TASK
*
task
;
char
task_name
[
8
];
#endif
int
eNB_id
=
0
,
UE_id
=
0
,
CC_id
=
0
;
PHY_VARS_UE
*
phy_vars_ue
=
PHY_vars_UE_g
[
UE_id
][
CC_id
];
if
((
dlsch_thread_index
<
0
)
||
(
dlsch_thread_index
>
7
))
{
LOG_E
(
PHY
,
"[SCHED][DLSCH] Illegal dlsch_thread_index %d (%p)!!!!
\n
"
,
dlsch_thread_index
,
param
);
return
0
;
}
#ifdef RTAI
sprintf
(
task_name
,
"DLSCH%d"
,
dlsch_thread_index
);
task
=
rt_task_init_schmod
(
nam2num
(
task_name
),
0
,
0
,
0
,
SCHED_FIFO
,
0xF
);
if
(
task
==
NULL
)
{
LOG_E
(
PHY
,
"[SCHED][DLSCH] Problem starting dlsch_thread_index %d (%s)!!!!
\n
"
,
dlsch_thread_index
,
task_name
);
return
0
;
}
else
{
LOG_I
(
PHY
,
"[SCHED][DLSCH] dlsch_thread for process %d started with id %p
\n
"
,
dlsch_thread_index
,
task
);
}
#endif
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
//rt_set_runnable_on_cpuid(task,1);
//cpuid = rtai_cpuid();
#ifdef HARD_RT
rt_make_hard_real_time
();
#endif
//dlsch_cpuid[dlsch_thread_index] = cpuid;
while
(
!
oai_exit
)
{
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_THREAD0
+
dlsch_thread_index
,
0
);
if
(
pthread_mutex_lock
(
&
dlsch_mutex
[
dlsch_thread_index
])
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][DLSCH] error locking mutex.
\n
"
);
}
else
{
while
(
dlsch_instance_cnt
[
dlsch_thread_index
]
<
0
)
{
pthread_cond_wait
(
&
dlsch_cond
[
dlsch_thread_index
],
&
dlsch_mutex
[
dlsch_thread_index
]);
}
if
(
pthread_mutex_unlock
(
&
dlsch_mutex
[
dlsch_thread_index
])
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][DLSCH] error unlocking mutex.
\n
"
);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_THREAD0
+
dlsch_thread_index
,
1
);
if
(
oai_exit
)
break
;
LOG_I
(
PHY
,
"[SCHED][DLSCH] Frame %d: Calling dlsch_decoding with dlsch_thread_index = %d
\n
"
,
phy_vars_ue
->
frame_rx
,
dlsch_thread_index
);
if
(
phy_vars_ue
->
frame_rx
<
phy_vars_ue
->
dlsch_errors
[
eNB_id
])
{
phy_vars_ue
->
dlsch_errors
[
eNB_id
]
=
0
;
phy_vars_ue
->
dlsch_received
[
eNB_id
]
=
0
;
}
harq_pid
=
dlsch_thread_index
;
if
(
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
])
{
// rt_printk("[SCHED][DLSCH] Frame %d, slot %d, start %llu, end %llu, proc time: %llu ns\n",phy_vars_ue->frame,last_slot,time0,time1,(time1-time0));
dlsch_unscrambling
(
&
phy_vars_ue
->
lte_frame_parms
,
0
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
],
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
G
,
phy_vars_ue
->
lte_ue_pdsch_vars
[
eNB_id
]
->
llr
[
0
],
0
,
dlsch_subframe
[
dlsch_thread_index
]
<<
1
);
LOG_I
(
PHY
,
"[UE %d] PDSCH Calling dlsch_decoding for subframe %d, harq_pid %d, G%d
\n
"
,
phy_vars_ue
->
Mod_id
,
dlsch_subframe
[
dlsch_thread_index
],
harq_pid
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
G
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0
+
dlsch_thread_index
,
1
);
ret
=
dlsch_decoding
(
phy_vars_ue
,
phy_vars_ue
->
lte_ue_pdsch_vars
[
eNB_id
]
->
llr
[
0
],
&
phy_vars_ue
->
lte_frame_parms
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
],
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
],
dlsch_subframe
[
dlsch_thread_index
],
harq_pid
,
1
,
// is_crnti
0
);
// llr8_flag
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0
+
dlsch_thread_index
,
0
);
LOG_D
(
PHY
,
"[UE %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)
\n
"
,
phy_vars_ue
->
Mod_id
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
rnti
,
harq_pid
,
phy_vars_ue
->
frame_rx
,
dlsch_subframe
[
dlsch_thread_index
],
ret
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
mcs
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
rvidx
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
TBS
);
if
(
ret
==
(
1
+
MAX_TURBO_ITERATIONS
))
{
phy_vars_ue
->
dlsch_errors
[
eNB_id
]
++
;
#ifdef DEBUG_PHY
LOG_I
(
PHY
,
"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d)
\n
"
,
phy_vars_ue
->
Mod_id
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
rnti
,
harq_pid
,
phy_vars_ue
->
frame_rx
,
dlsch_subframe
[
dlsch_thread_index
],
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
rvidx
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
mcs
);
#endif
}
else
{
LOG_I
(
PHY
,
"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH (rv %d,mcs %d)
\n
"
,
phy_vars_ue
->
Mod_id
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
rnti
,
harq_pid
,
phy_vars_ue
->
frame_rx
,
dlsch_subframe
[
dlsch_thread_index
],
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
rvidx
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
mcs
);
#ifdef OPENAIR2
mac_xface
->
ue_send_sdu
(
phy_vars_ue
->
Mod_id
,
0
,
// CC_id
phy_vars_ue
->
frame_rx
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
b
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
TBS
>>
3
,
eNB_id
);
#endif
phy_vars_ue
->
total_TBS
[
eNB_id
]
=
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
TBS
+
phy_vars_ue
->
total_TBS
[
eNB_id
];
phy_vars_ue
->
total_received_bits
[
eNB_id
]
=
phy_vars_ue
->
total_received_bits
[
eNB_id
]
+
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
TBS
;
}
}
// this is done in main thread
/*
if (phy_vars_ue->frame % 100 == 0) {
if ((phy_vars_ue->dlsch_received[eNB_id] - phy_vars_ue->dlsch_received_last[eNB_id]) != 0)
phy_vars_ue->dlsch_fer[eNB_id] = (100*(phy_vars_ue->dlsch_errors[eNB_id] - phy_vars_ue->dlsch_errors_last[eNB_id]))/(phy_vars_ue->dlsch_received[eNB_id] - phy_vars_ue->dlsch_received_last[eNB_id]);
phy_vars_ue->dlsch_errors_last[eNB_id] = phy_vars_ue->dlsch_errors[eNB_id];
phy_vars_ue->dlsch_received_last[eNB_id] = phy_vars_ue->dlsch_received[eNB_id];
}
*/
#ifdef DEBUG_PHY
if
(
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
])
{
LOG_I
(
PHY
,
"[UE %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)
\n
"
,
phy_vars_ue
->
Mod_id
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
rnti
,
harq_pid
,
phy_vars_ue
->
frame_rx
,
dlsch_subframe
[
dlsch_thread_index
],
ret
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
mcs
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
rvidx
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
TBS
);
if
(
phy_vars_ue
->
frame_rx
%
100
==
0
)
{
LOG_D
(
PHY
,
"[UE %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d
\n
"
,
phy_vars_ue
->
Mod_id
,
phy_vars_ue
->
dlsch_ue
[
eNB_id
][
0
]
->
rnti
,
phy_vars_ue
->
frame_rx
,
dlsch_subframe
[
dlsch_thread_index
],
phy_vars_ue
->
dlsch_errors
[
eNB_id
],
phy_vars_ue
->
dlsch_received
[
eNB_id
],
phy_vars_ue
->
dlsch_fer
[
eNB_id
],
phy_vars_ue
->
PHY_measurements
.
wideband_cqi_tot
[
eNB_id
]);
}
}
else
{
LOG_I
(
PHY
,
"[UE %d][PDSCH ?/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (phy_vars_ue->dlsch_ue[eNB_id][0] == 0)
\n
"
,
phy_vars_ue
->
Mod_id
,
harq_pid
,
phy_vars_ue
->
frame_rx
,
dlsch_subframe
[
dlsch_thread_index
],
ret
);
}
#endif
if
(
pthread_mutex_lock
(
&
dlsch_mutex
[
dlsch_thread_index
])
!=
0
)
{
msg
(
"[openair][SCHED][DLSCH] error locking mutex.
\n
"
);
}
else
{
dlsch_instance_cnt
[
dlsch_thread_index
]
--
;
if
(
pthread_mutex_unlock
(
&
dlsch_mutex
[
dlsch_thread_index
])
!=
0
)
{
msg
(
"[openair][SCHED][DLSCH] error unlocking mutex.
\n
"
);
}
}
}
#ifdef HARD_RT
rt_make_soft_real_time
();
#endif
msg
(
"[openair][SCHED][DLSCH] DLSCH thread %d exiting
\n
"
,
dlsch_thread_index
);
return
0
;
}
int
init_dlsch_threads
(
void
)
{
int
error_code
;
struct
sched_param
p
;
unsigned
char
dlsch_thread_index
;
pthread_attr_init
(
&
attr_dlsch_threads
);
pthread_attr_setstacksize
(
&
attr_dlsch_threads
,
OPENAIR_THREAD_STACK_SIZE
);
//attr_dlsch_threads.priority = 1;
p
.
sched_priority
=
OPENAIR_THREAD_PRIORITY
;
pthread_attr_setschedparam
(
&
attr_dlsch_threads
,
&
p
);
#ifndef RTAI_ISNT_POSIX
pthread_attr_setschedpolicy
(
&
attr_dlsch_threads
,
SCHED_FIFO
);
#endif
for
(
dlsch_thread_index
=
0
;
dlsch_thread_index
<
8
;
dlsch_thread_index
++
)
{
pthread_mutex_init
(
&
dlsch_mutex
[
dlsch_thread_index
],
NULL
);
pthread_cond_init
(
&
dlsch_cond
[
dlsch_thread_index
],
NULL
);
dlsch_instance_cnt
[
dlsch_thread_index
]
=
-
1
;
dlsch_thread_indices
[
dlsch_thread_index
]
=
dlsch_thread_index
;
rt_printk
(
"[openair][SCHED][DLSCH][INIT] Allocating DLSCH thread for dlsch_thread_index %d (%p)
\n
"
,
dlsch_thread_index
,
&
dlsch_thread_indices
[
dlsch_thread_index
]);
error_code
=
pthread_create
(
&
dlsch_threads
[
dlsch_thread_index
],
&
attr_dlsch_threads
,
dlsch_thread
,
(
void
*
)
&
dlsch_thread_indices
[
dlsch_thread_index
]);
if
(
error_code
!=
0
)
{
rt_printk
(
"[openair][SCHED][DLSCH][INIT] Could not allocate dlsch_thread %d, error %d
\n
"
,
dlsch_thread_index
,
error_code
);
return
(
error_code
);
}
else
{
rt_printk
(
"[openair][SCHED][DLSCH][INIT] Allocate dlsch_thread %d successful
\n
"
,
dlsch_thread_index
);
}
}
return
(
0
);
}
void
cleanup_dlsch_threads
(
void
)
{
unsigned
char
dlsch_thread_index
;
for
(
dlsch_thread_index
=
0
;
dlsch_thread_index
<
8
;
dlsch_thread_index
++
)
{
// pthread_exit(&dlsch_threads[dlsch_thread_index]);
rt_printk
(
"[openair][SCHED][DLSCH] Scheduling dlsch_thread %d to exit
\n
"
,
dlsch_thread_index
);
dlsch_instance_cnt
[
dlsch_thread_index
]
=
0
;
if
(
pthread_cond_signal
(
&
dlsch_cond
[
dlsch_thread_index
])
!=
0
)
rt_printk
(
"[openair][SCHED][DLSCH] ERROR pthread_cond_signal
\n
"
);
else
rt_printk
(
"[openair][SCHED][DLSCH] Signalled dlsch_thread %d to exit
\n
"
,
dlsch_thread_index
);
rt_printk
(
"[openair][SCHED][DLSCH] Exiting ...
\n
"
);
pthread_cond_destroy
(
&
dlsch_cond
[
dlsch_thread_index
]);
pthread_mutex_destroy
(
&
dlsch_mutex
[
dlsch_thread_index
]);
}
}
targets/RT/USER/sched_rx_pdsch.c
deleted
100644 → 0
View file @
17c99ad1
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file sched_dlsch.c
* \brief DLSCH decoding thread (RTAI)
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include "rt_wrapper.h"
#include <sys/mman.h>
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
RTIME
time0
,
time1
;
#define DEBUG_PHY
/// Mutex for instance count on rx_pdsch scheduling
pthread_mutex_t
rx_pdsch_mutex
;
/// Condition variable for rx_pdsch thread
pthread_cond_t
rx_pdsch_cond
;
pthread_t
rx_pdsch_thread_var
;
pthread_attr_t
attr_rx_pdsch_thread
;
// activity indicators for harq_pid's
int
rx_pdsch_instance_cnt
;
// process ids for cpu
int
rx_pdsch_cpuid
;
// subframe number for each harq_pid (needed to store ack in right place for UL)
int
rx_pdsch_slot
;
extern
int
oai_exit
;
extern
pthread_mutex_t
dlsch_mutex
[
8
];
extern
int
dlsch_instance_cnt
[
8
];
extern
int
dlsch_subframe
[
8
];
extern
pthread_cond_t
dlsch_cond
[
8
];
/** RX_PDSCH Decoding Thread */
static
void
*
rx_pdsch_thread
(
void
*
param
)
{
//unsigned long cpuid;
uint8_t
dlsch_thread_index
=
0
;
uint8_t
pilot2
,
harq_pid
,
subframe
;
// uint8_t last_slot;
uint8_t
dual_stream_UE
=
0
;
uint8_t
i_mod
=
0
;
#ifdef RTAI
RT_TASK
*
task
;
#endif
int
m
,
eNB_id
=
0
;
int
eNB_id_i
=
1
;
PHY_VARS_UE
*
UE
=
PHY_vars_UE_g
[
0
][
0
];
#ifdef RTAI
task
=
rt_task_init_schmod
(
nam2num
(
"RX_PDSCH_THREAD"
),
0
,
0
,
0
,
SCHED_FIFO
,
0xF
);
if
(
task
==
NULL
)
{
LOG_E
(
PHY
,
"[SCHED][RX_PDSCH] Problem starting rx_pdsch thread!!!!
\n
"
);
return
0
;
}
else
{
LOG_I
(
PHY
,
"[SCHED][RX_PDSCH] rx_pdsch_thread started for with id %p
\n
"
,
task
);
}
#endif
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
//rt_set_runnable_on_cpuid(task,1);
//cpuid = rtai_cpuid();
#ifdef HARD_RT
rt_make_hard_real_time
();
#endif
if
(
UE
->
lte_frame_parms
.
Ncp
==
NORMAL
)
{
// normal prefix
pilot2
=
7
;
}
else
{
// extended prefix
pilot2
=
6
;
}
while
(
!
oai_exit
)
{
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_THREAD
,
0
);
if
(
pthread_mutex_lock
(
&
rx_pdsch_mutex
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][RX_PDSCH] error locking mutex.
\n
"
);
}
else
{
while
(
rx_pdsch_instance_cnt
<
0
)
{
pthread_cond_wait
(
&
rx_pdsch_cond
,
&
rx_pdsch_mutex
);
}
if
(
pthread_mutex_unlock
(
&
rx_pdsch_mutex
)
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][RX_PDSCH] error unlocking mutex.
\n
"
);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_THREAD
,
1
);
// last_slot = rx_pdsch_slot;
subframe
=
UE
->
slot_rx
>>
1
;
// Important! assumption that PDCCH procedure of next SF is not called yet
harq_pid
=
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
current_harq_pid
;
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
G
=
get_G
(
&
UE
->
lte_frame_parms
,
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
nb_rb
,
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
rb_alloc_even
,
get_Qm
(
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
mcs
),
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
Nl
,
UE
->
lte_ue_pdcch_vars
[
eNB_id
]
->
num_pdcch_symbols
,
UE
->
frame_rx
,
subframe
);
if
((
UE
->
transmission_mode
[
eNB_id
]
==
5
)
&&
(
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
dl_power_off
==
0
)
&&
(
openair_daq_vars
.
use_ia_receiver
>
0
))
{
dual_stream_UE
=
1
;
eNB_id_i
=
UE
->
n_connected_eNB
;
if
(
openair_daq_vars
.
use_ia_receiver
==
2
)
{
i_mod
=
get_Qm
(((
UE
->
frame_rx
%
1024
)
/
3
)
%
28
);
}
else
{
i_mod
=
get_Qm
(
UE
->
dlsch_ue
[
eNB_id
][
0
]
->
harq_processes
[
harq_pid
]
->
mcs
);
}
}
else
{
dual_stream_UE
=
0
;
eNB_id_i
=
eNB_id
+
1
;
i_mod
=
0
;
}
if
(
oai_exit
)
break
;
LOG_D
(
PHY
,
"[SCHED][RX_PDSCH] Frame %d, slot %d: Calling rx_pdsch_decoding with harq_pid %d
\n
"
,
UE
->
frame_rx
,
UE
->
slot_rx
,
harq_pid
);
// Check if we are in even or odd slot
if
(
UE
->
slot_rx
%
2
)
{
// odd slots
// measure time
//time0 = rt_get_time_ns();
// rt_printk("[SCHED][RX_PDSCH][before rx_pdsch] Frame %d, slot %d, time %llu\n",UE->frame,last_slot,rt_get_time_ns());
for
(
m
=
pilot2
;
m
<
UE
->
lte_frame_parms
.
symbols_per_tti
;
m
++
)
{
rx_pdsch
(
UE
,
PDSCH
,
eNB_id
,
eNB_id_i
,
subframe
,
m
,
0
,
dual_stream_UE
,
i_mod
,
harq_pid
);
}
// time1 = rt_get_time_ns();
// rt_printk("[SCHED][RX_PDSCH] Frame %d, slot %d, start %llu, end %llu, proc time: %llu ns\n",UE->frame_rx,last_slot,time0,time1,(time1-time0));
dlsch_thread_index
=
harq_pid
;
if
(
pthread_mutex_lock
(
&
dlsch_mutex
[
dlsch_thread_index
])
!=
0
)
{
// Signal MAC_PHY Scheduler
LOG_E
(
PHY
,
"[UE %d] ERROR pthread_mutex_lock
\n
"
,
UE
->
Mod_id
);
// lock before accessing shared resource
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
//return(-1);
}
dlsch_instance_cnt
[
dlsch_thread_index
]
++
;
dlsch_subframe
[
dlsch_thread_index
]
=
subframe
;
pthread_mutex_unlock
(
&
dlsch_mutex
[
dlsch_thread_index
]);
if
(
dlsch_instance_cnt
[
dlsch_thread_index
]
==
0
)
{
if
(
pthread_cond_signal
(
&
dlsch_cond
[
dlsch_thread_index
])
!=
0
)
{
LOG_E
(
PHY
,
"[UE %d] ERROR pthread_cond_signal for dlsch_cond[%d]
\n
"
,
UE
->
Mod_id
,
dlsch_thread_index
);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
//return(-1);
}
}
else
{
LOG_W
(
PHY
,
"[UE %d] DLSCH thread for dlsch_thread_index %d busy!!!
\n
"
,
UE
->
Mod_id
,
dlsch_thread_index
);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
//return(-1);
}
}
else
{
// even slots
for
(
m
=
UE
->
lte_ue_pdcch_vars
[
eNB_id
]
->
num_pdcch_symbols
;
m
<
pilot2
;
m
++
)
{
rx_pdsch
(
UE
,
PDSCH
,
eNB_id
,
eNB_id_i
,
subframe
,
m
,
(
m
==
UE
->
lte_ue_pdcch_vars
[
eNB_id
]
->
num_pdcch_symbols
)
?
1
:
0
,
// first_symbol_flag
dual_stream_UE
,
i_mod
,
harq_pid
);
}
}
if
(
pthread_mutex_lock
(
&
rx_pdsch_mutex
)
!=
0
)
{
msg
(
"[openair][SCHED][RX_PDSCH] error locking mutex.
\n
"
);
}
else
{
rx_pdsch_instance_cnt
--
;
if
(
pthread_mutex_unlock
(
&
rx_pdsch_mutex
)
!=
0
)
{
msg
(
"[openair][SCHED][RX_PDSCH] error unlocking mutex.
\n
"
);
}
}
}
#ifdef HARD_RT
rt_make_soft_real_time
();
#endif
LOG_D
(
PHY
,
"[openair][SCHED][RX_PDSCH] RX_PDSCH thread exiting
\n
"
);
return
0
;
}
int
init_rx_pdsch_thread
(
void
)
{
int
error_code
;
struct
sched_param
p
;
pthread_mutex_init
(
&
rx_pdsch_mutex
,
NULL
);
pthread_cond_init
(
&
rx_pdsch_cond
,
NULL
);
pthread_attr_init
(
&
attr_rx_pdsch_thread
);
pthread_attr_setstacksize
(
&
attr_rx_pdsch_thread
,
OPENAIR_THREAD_STACK_SIZE
);
//attr_rx_pdsch_thread.priority = 1;
p
.
sched_priority
=
OPENAIR_THREAD_PRIORITY
;
pthread_attr_setschedparam
(
&
attr_rx_pdsch_thread
,
&
p
);
#ifndef RTAI_ISNT_POSIX
pthread_attr_setschedpolicy
(
&
attr_rx_pdsch_thread
,
SCHED_FIFO
);
#endif
rx_pdsch_instance_cnt
=
-
1
;
rt_printk
(
"[openair][SCHED][RX_PDSCH][INIT] Allocating RX_PDSCH thread
\n
"
);
error_code
=
pthread_create
(
&
rx_pdsch_thread_var
,
&
attr_rx_pdsch_thread
,
rx_pdsch_thread
,
0
);
if
(
error_code
!=
0
)
{
rt_printk
(
"[openair][SCHED][RX_PDSCH][INIT] Could not allocate rx_pdsch_thread, error %d
\n
"
,
error_code
);
return
(
error_code
);
}
else
{
rt_printk
(
"[openair][SCHED][RX_PDSCH][INIT] Allocate rx_pdsch_thread successful
\n
"
);
return
(
0
);
}
}
void
cleanup_rx_pdsch_thread
(
void
)
{
rt_printk
(
"[openair][SCHED][RX_PDSCH] Scheduling rx_pdsch_thread to exit
\n
"
);
rx_pdsch_instance_cnt
=
0
;
if
(
pthread_cond_signal
(
&
rx_pdsch_cond
)
!=
0
)
rt_printk
(
"[openair][SCHED][RX_PDSCH] ERROR pthread_cond_signal
\n
"
);
else
rt_printk
(
"[openair][SCHED][RX_PDSCH] Signalled rx_pdsch_thread to exit
\n
"
);
rt_printk
(
"[openair][SCHED][RX_PDSCH] Exiting ...
\n
"
);
pthread_cond_destroy
(
&
rx_pdsch_cond
);
pthread_mutex_destroy
(
&
rx_pdsch_mutex
);
}
targets/RT/USER/sched_ulsch.c
deleted
100644 → 0
View file @
17c99ad1
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file sched_ulsch.c
* \brief ULSCH decoding thread (RTAI)
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include "rt_wrapper.h"
#include <sys/mman.h>
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "MAC_INTERFACE/extern.h"
#ifdef CBMIMO1
#include "ARCH/CBMIMO1/DEVICE_DRIVER/cbmimo1_device.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h"
#endif // CBMIMO1
#define DEBUG_PHY
/// Mutex for instance count on ulsch scheduling
pthread_mutex_t
ulsch_mutex
[
NUMBER_OF_UE_MAX
];
/// Condition variable for ulsch thread
pthread_cond_t
ulsch_cond
[
NUMBER_OF_UE_MAX
];
pthread_t
ulsch_threads
[
NUMBER_OF_UE_MAX
];
pthread_attr_t
attr_ulsch_threads
;
// activity indicators for harq_pid's
int
ulsch_instance_cnt
[
NUMBER_OF_UE_MAX
];
// process ids for cpu
int
ulsch_cpuid
[
NUMBER_OF_UE_MAX
];
// subframe number for each harq_pid (needed to store ack in right place for UL)
int
ulsch_subframe
[
NUMBER_OF_UE_MAX
];
extern
int
oai_exit
;
/*
extern int ulsch_errors;
extern int ulsch_received;
extern int ulsch_errors_last;
extern int ulsch_received_last;
extern int ulsch_fer;
extern int current_ulsch_cqi;
*/
/** ULSCH Decoding Thread */
static
void
*
ulsch_thread
(
void
*
param
)
{
//unsigned long cpuid;
unsigned
int
ulsch_thread_index
=
(
unsigned
int
)
param
;
RTIME
time_in
,
time_out
;
#ifdef RTAI
RT_TASK
*
task
;
char
ulsch_thread_name
[
64
];
#endif
int
eNB_id
=
0
,
UE_id
=
0
;
PHY_VARS_eNB
*
phy_vars_eNB
=
PHY_vars_eNB_g
[
eNB_id
];
if
((
ulsch_thread_index
<
0
)
||
(
ulsch_thread_index
>
NUMBER_OF_UE_MAX
))
{
LOG_E
(
PHY
,
"[SCHED][ULSCH] Illegal ulsch_thread_index %d!!!!
\n
"
,
ulsch_thread_index
);
return
0
;
}
#ifdef RTAI
sprintf
(
ulsch_thread_name
,
"ULSCH_THREAD%d"
,
ulsch_thread_index
);
LOG_I
(
PHY
,
"[SCHED][ULSCH] starting ulsch_thread %s for process %d
\n
"
,
ulsch_thread_name
,
ulsch_thread_index
);
task
=
rt_task_init_schmod
(
nam2num
(
ulsch_thread_name
),
0
,
0
,
0
,
SCHED_FIFO
,
0xF
);
if
(
task
==
NULL
)
{
LOG_E
(
PHY
,
"[SCHED][ULSCH] Problem starting ulsch_thread_index %d!!!!
\n
"
,
ulsch_thread_index
);
return
0
;
}
else
{
LOG_I
(
PHY
,
"[SCHED][ULSCH] ulsch_thread for process %d started with id %p
\n
"
,
ulsch_thread_index
,
task
);
}
#endif
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
//rt_set_runnable_on_cpuid(task,1);
//cpuid = rtai_cpuid();
#ifdef HARD_RT
rt_make_hard_real_time
();
#endif
//ulsch_cpuid[ulsch_thread_index] = cpuid;
while
(
!
oai_exit
)
{
if
(
pthread_mutex_lock
(
&
ulsch_mutex
[
ulsch_thread_index
])
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][ULSCH] error locking mutex.
\n
"
);
}
else
{
while
(
ulsch_instance_cnt
[
ulsch_thread_index
]
<
0
)
{
pthread_cond_wait
(
&
ulsch_cond
[
ulsch_thread_index
],
&
ulsch_mutex
[
ulsch_thread_index
]);
}
if
(
pthread_mutex_unlock
(
&
ulsch_mutex
[
ulsch_thread_index
])
!=
0
)
{
LOG_E
(
PHY
,
"[SCHED][ULSCH] error unlocking mutex.
\n
"
);
}
}
if
(
oai_exit
)
break
;
LOG_D
(
PHY
,
"[SCHED][ULSCH] Frame %d: Calling ulsch_decoding with ulsch_thread_index = %d
\n
"
,
phy_vars_eNB
->
proc
[
0
].
frame_tx
,
ulsch_thread_index
);
time_in
=
rt_get_time_ns
();
ulsch_decoding_procedures
(
ulsch_subframe
[
ulsch_thread_index
]
<<
1
,
ulsch_thread_index
,
phy_vars_eNB
,
0
);
time_out
=
rt_get_time_ns
();
if
(
pthread_mutex_lock
(
&
ulsch_mutex
[
ulsch_thread_index
])
!=
0
)
{
msg
(
"[openair][SCHED][ULSCH] error locking mutex.
\n
"
);
}
else
{
ulsch_instance_cnt
[
ulsch_thread_index
]
--
;
if
(
pthread_mutex_unlock
(
&
ulsch_mutex
[
ulsch_thread_index
])
!=
0
)
{
msg
(
"[openair][SCHED][ULSCH] error unlocking mutex.
\n
"
);
}
}
}
#ifdef HARD_RT
rt_make_soft_real_time
();
#endif
msg
(
"[openair][SCHED][ULSCH] ULSCH thread %d exiting
\n
"
,
ulsch_thread_index
);
return
0
;
}
int
init_ulsch_threads
(
void
)
{
int
error_code
,
return_code
=
0
;
struct
sched_param
p
;
int
ulsch_thread_index
;
// later loop on all harq_pids, do 0 for now
for
(
ulsch_thread_index
=
0
;
ulsch_thread_index
<
NUMBER_OF_UE_MAX
;
ulsch_thread_index
++
)
{
pthread_mutex_init
(
&
ulsch_mutex
[
ulsch_thread_index
],
NULL
);
pthread_cond_init
(
&
ulsch_cond
[
ulsch_thread_index
],
NULL
);
pthread_attr_init
(
&
attr_ulsch_threads
);
pthread_attr_setstacksize
(
&
attr_ulsch_threads
,
OPENAIR_THREAD_STACK_SIZE
);
//attr_ulsch_threads.priority = 1;
p
.
sched_priority
=
OPENAIR_THREAD_PRIORITY
;
pthread_attr_setschedparam
(
&
attr_ulsch_threads
,
&
p
);
#ifndef RTAI_ISNT_POSIX
pthread_attr_setschedpolicy
(
&
attr_ulsch_threads
,
SCHED_FIFO
);
#endif
ulsch_instance_cnt
[
ulsch_thread_index
]
=
-
1
;
rt_printk
(
"[openair][SCHED][ULSCH][INIT] Allocating ULSCH thread for ulsch_thread_index %d
\n
"
,
ulsch_thread_index
);
error_code
=
pthread_create
(
&
ulsch_threads
[
ulsch_thread_index
],
&
attr_ulsch_threads
,
ulsch_thread
,
(
void
*
)
ulsch_thread_index
);
if
(
error_code
!=
0
)
{
rt_printk
(
"[openair][SCHED][ULSCH][INIT] Could not allocate ulsch_thread %d, error %d
\n
"
,
ulsch_thread_index
,
error_code
);
return_code
+=
error_code
;
//return(error_code);
}
else
{
rt_printk
(
"[openair][SCHED][ULSCH][INIT] Allocate ulsch_thread %d successful
\n
"
,
ulsch_thread_index
);
//return(0);
}
}
return
(
return_code
);
}
void
cleanup_ulsch_threads
(
void
)
{
int
ulsch_thread_index
;
for
(
ulsch_thread_index
=
0
;
ulsch_thread_index
<
NUMBER_OF_UE_MAX
;
ulsch_thread_index
++
)
{
// pthread_exit(&ulsch_threads[ulsch_thread_index]);
rt_printk
(
"[openair][SCHED][ULSCH] Scheduling ulsch_thread %d to exit
\n
"
,
ulsch_thread_index
);
ulsch_instance_cnt
[
ulsch_thread_index
]
=
0
;
if
(
pthread_cond_signal
(
&
ulsch_cond
[
ulsch_thread_index
])
!=
0
)
rt_printk
(
"[openair][SCHED][ULSCH] ERROR pthread_cond_signal
\n
"
);
else
rt_printk
(
"[openair][SCHED][ULSCH] Signalled ulsch_thread %d to exit
\n
"
,
ulsch_thread_index
);
rt_printk
(
"[openair][SCHED][ULSCH] Exiting ...
\n
"
);
pthread_cond_destroy
(
&
ulsch_cond
[
ulsch_thread_index
]);
pthread_mutex_destroy
(
&
ulsch_mutex
[
ulsch_thread_index
]);
}
}
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