git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5414 818b1a75-f10b-46b9-bf7c-635c3b92a50f

This commit is contained in:
Raymond Knopp
2014-06-20 09:21:48 +00:00
parent fe2e0ed0af
commit 275c7a7c7d
+204 -12
View File
@@ -252,6 +252,8 @@ static int mbox_bounds[20] = {8,16,24,30,38,46,54,60,68,7
static LTE_DL_FRAME_PARMS *frame_parms; static LTE_DL_FRAME_PARMS *frame_parms;
int multi_thread=0;
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
{ {
return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
@@ -623,7 +625,183 @@ void *l2l1_task(void *arg)
} }
#endif #endif
/* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */ static void * eNB_proc_thread(void *param) {
//unsigned long cpuid;
eNB_proc_t *proc = (eNB_proc_t*)param;
int i,tx_offset;
int next_slot,last_slot;
RTIME time_in,time_out;
#ifdef RTAI
RT_TASK *task;
char task_name[8];
#endif
int dummy_tx_b[7680*4] __attribute__((aligned(16)));
unsigned int aa,slot_offset,slot_offset_F,slot_offset_F2;
#ifdef RTAI
sprintf(task_name,"eNB_proc %d",proc->subframe);
task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);
if (task==NULL) {
LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc thread_index %d (%s)!!!!\n",proc->subframe,task_name);
return 0;
}
else {
LOG_I(PHY,"[SCHED][eNB] dlsch_thread for process %d started with id %p\n",
proc->subframe,
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
last_slot = ((proc->subframe<<1)-1)%20;
next_slot = ((proc->subframe<<1)+1)%20;
while (!oai_exit){
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC0+proc->subframe,0);
if (pthread_mutex_lock(&proc->mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB proc %d\n",proc->subframe);
}
else {
while (proc->instance_cnt < 0) {
pthread_cond_wait(&proc->cond,&proc->mutex);
}
if (pthread_mutex_unlock(&proc->mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB proc %d\n",proc->subframe);
}
}
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC0+proc->subframe,1);
if (oai_exit) break;
if ((((PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == TDD)&&(subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL))||
(PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == FDD))) {
#ifdef Rel10
if (phy_procedures_RN_eNB_TX(last_slot, next_slot, no_relay) != 0 )
#endif
phy_procedures_eNB_TX(next_slot,PHY_vars_eNB_g[0],0,no_relay,NULL);
}
if ((((PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == TDD )&&(subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,last_slot>>1)==SF_UL)) ||
(PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == FDD))){
phy_procedures_eNB_RX(last_slot,PHY_vars_eNB_g[0],0,no_relay);
}
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S)) {
#ifdef Rel10
if (phy_procedures_RN_eNB_TX(last_slot, next_slot, no_relay) != 0 )
#endif
phy_procedures_eNB_TX(next_slot,PHY_vars_eNB_g[0],0,no_relay,NULL);
}
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,last_slot>>1)==SF_S)){
phy_procedures_eNB_S_RX(last_slot,PHY_vars_eNB_g[0],0,no_relay);
}
}
slot_offset_F = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)*
((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7);
slot_offset = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1);
slot_offset_F2 = (next_slot+1)*
(PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)*
((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7);
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL)||
((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S))) {
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
for (aa=0; aa<PHY_vars_eNB_g[0]->lte_frame_parms.nb_antennas_tx; aa++) {
if (PHY_vars_eNB_g[0]->lte_frame_parms.Ncp == 1) {
PHY_ofdm_mod(&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F],
dummy_tx_b,
PHY_vars_eNB_g[0]->lte_frame_parms.log2_symbol_size,
6,
PHY_vars_eNB_g[0]->lte_frame_parms.nb_prefix_samples,
PHY_vars_eNB_g[0]->lte_frame_parms.twiddle_ifft,
PHY_vars_eNB_g[0]->lte_frame_parms.rev,
CYCLIC_PREFIX);
PHY_ofdm_mod(&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F2],
dummy_tx_b+(PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1),
PHY_vars_eNB_g[0]->lte_frame_parms.log2_symbol_size,
6,
PHY_vars_eNB_g[0]->lte_frame_parms.nb_prefix_samples,
PHY_vars_eNB_g[0]->lte_frame_parms.twiddle_ifft,
PHY_vars_eNB_g[0]->lte_frame_parms.rev,
CYCLIC_PREFIX);
}
#ifdef EXMIMO
for (i=0; i<PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti; i++) {
tx_offset = (int)slot_offset+time_offset[aa]+i;
if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti;
((short*)&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0]=
((short*)dummy_tx_b)[2*i]<<4;
((short*)&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]=
((short*)dummy_tx_b)[2*i+1]<<4;
}
#endif //EXMIMO
}
}
if (pthread_mutex_lock(&proc->mutex) != 0) {
msg("[openair][SCHED][eNB] error locking mutex for eNB proc %d\n",proc->subframe);
}
else {
proc->instance_cnt--;
if (pthread_mutex_unlock(&proc->mutex) != 0) {
msg("[openair][SCHED][eNB] error unlocking mutex for eNB proc %d\n",proc->subframe);
}
}
#ifdef HARD_RT
rt_make_soft_real_time();
#endif
}
void init_eNB_proc() {
int i;
for (i=0;i<10;i++) {
PHY_vars_eNB_g[0]->proc[i].instance_cnt=0;
PHY_vars_eNB_g[0]->proc[i].subframe=i;
pthread_mutex_init(&PHY_vars_eNB_g[0]->proc[i].mutex,NULL);
pthread_cond_init(&PHY_vars_eNB_g[0]->proc[i].cond,NULL);
pthread_create(&PHY_vars_eNB_g[0]->proc[i].pthread,NULL,eNB_proc_thread,(void*)&PHY_vars_eNB_g[0]->proc[i]);
}
}
void kill_eNB_proc() {
int i;
for (i=0;i<10;i++) {
pthread_join(PHY_vars_eNB_g[0]->proc[i].pthread,NULL);
pthread_mutex_destroy(&PHY_vars_eNB_g[0]->proc[i].mutex);
pthread_cond_destroy(&PHY_vars_eNB_g[0]->proc[i].cond);
}
}
/* This is the main eNB thread. */
static void *eNB_thread(void *arg) static void *eNB_thread(void *arg)
{ {
#ifdef RTAI #ifdef RTAI
@@ -638,6 +816,7 @@ static void *eNB_thread(void *arg)
int mbox_target=0,mbox_current=0; int mbox_target=0,mbox_current=0;
int i,ret; int i,ret;
int tx_offset; int tx_offset;
int sf;
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
/* Wait for eNB application initialization to be complete (eNB registration to MME) */ /* Wait for eNB application initialization to be complete (eNB registration to MME) */
@@ -726,7 +905,7 @@ static void *eNB_thread(void *arg)
last_slot = (slot)%LTE_SLOTS_PER_FRAME; last_slot = (slot)%LTE_SLOTS_PER_FRAME;
if (last_slot <0) if (last_slot <0)
last_slot+=20; last_slot+=20;
next_slot = (slot+3)%LTE_SLOTS_PER_FRAME; next_slot = (slot+2)%LTE_SLOTS_PER_FRAME;
//PHY_vars_eNB_g[0]->frame = frame; //PHY_vars_eNB_g[0]->frame = frame;
if (frame>5) if (frame>5)
@@ -763,15 +942,15 @@ static void *eNB_thread(void *arg)
if (fs4_test==0) if (fs4_test==0)
{ {
if (multi_thread == 0) {
phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[0], 0, no_relay,NULL); phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[0], 0, no_relay,NULL);
#ifndef IFFT_FPGA
slot_offset_F = (next_slot)* slot_offset_F = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)* (PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)*
((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7); ((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7);
slot_offset = (next_slot)* slot_offset = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1); (PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1);
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL)|| if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL)||
((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S)&&((next_slot&1)==0))) ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S)))
{ {
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
@@ -820,14 +999,22 @@ static void *eNB_thread(void *arg)
} }
} }
} }
else { // multi-thread > 0
#endif //IFFT_FPGA if ((slot&1) == 0) {
/* sf = (slot<<1)+1;
if (frame%100==0) if (PHY_vars_eNB_g[0]->proc[sf].instance_cnt == 0) {
LOG_D(HW,"hw_slot %d (after): DAQ_MBOX %d\n",hw_slot,DAQ_MBOX[0]); if (pthread_cond_signal(&PHY_vars_eNB_g[0]->proc[sf].cond) != 0) {
*/ LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB proc %d\n",sf);
}
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB proc %d busy!!\n",PHY_vars_eNB_g[0]->frame,sf);
}
}
}
}
} }
/* /*
if ((slot%2000)<10) if ((slot%2000)<10)
LOG_D(HW,"fun0: doing very hard work\n"); LOG_D(HW,"fun0: doing very hard work\n");
@@ -1122,7 +1309,7 @@ static void get_options (int argc, char **argv)
{"no-L2-connect", no_argument, NULL, LONG_OPTION_NO_L2_CONNECT}, {"no-L2-connect", no_argument, NULL, LONG_OPTION_NO_L2_CONNECT},
{NULL, 0, NULL, 0}}; {NULL, 0, NULL, 0}};
while ((c = getopt_long (argc, argv, "C:dF:K:qO:ST:UVR",long_options,NULL)) != -1) while ((c = getopt_long (argc, argv, "C:dF:K:qO:ST:UVRM",long_options,NULL)) != -1)
{ {
switch (c) switch (c)
{ {
@@ -1156,7 +1343,9 @@ static void get_options (int argc, char **argv)
case LONG_OPTION_NO_L2_CONNECT: case LONG_OPTION_NO_L2_CONNECT:
mode = no_L2_connect; mode = no_L2_connect;
break; break;
case 'M':
multi_thread=1;
break;
case 'C': case 'C':
downlink_frequency[0] = atof(optarg); // Use float to avoid issue with frequency over 2^31. downlink_frequency[0] = atof(optarg); // Use float to avoid issue with frequency over 2^31.
downlink_frequency[1] = downlink_frequency[0]; downlink_frequency[1] = downlink_frequency[0];
@@ -1983,6 +2172,9 @@ int main(int argc, char **argv) {
#ifdef ULSCH_THREAD #ifdef ULSCH_THREAD
init_ulsch_threads(); init_ulsch_threads();
#endif #endif
init_eNB_proc();
printf("eNB threads created\n"); printf("eNB threads created\n");
} }