rework threads in 5G
This commit is contained in:
@@ -754,6 +754,7 @@ include_directories("${OPENAIR_BIN_DIR}")
|
||||
|
||||
# Legacy exact order
|
||||
|
||||
include_directories("${OPENAIR_DIR}/executables")
|
||||
include_directories("${OPENAIR2_DIR}/COMMON")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/LOG")
|
||||
@@ -792,10 +793,7 @@ include_directories("${OPENAIR3_DIR}/S1AP")
|
||||
include_directories("${OPENAIR2_DIR}/X2AP")
|
||||
include_directories("${OPENAIR3_DIR}/UDP")
|
||||
include_directories("${OPENAIR3_DIR}/GTPV1-U")
|
||||
include_directories("${OPENAIR_DIR}/targets/COMMON")
|
||||
include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON")
|
||||
include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/USERSPACE/LIB/")
|
||||
include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS")
|
||||
include_directories("${OPENAIR2_DIR}/ENB_APP")
|
||||
include_directories("${OPENAIR2_DIR}/GNB_APP")
|
||||
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC")
|
||||
@@ -2107,7 +2105,7 @@ if (${XFORMS})
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_scope.c
|
||||
)
|
||||
set(XFORMS_SOURCE_SOFTMODEM
|
||||
${OPENAIR_TARGETS}/RT/USER/stats.c
|
||||
${OPENAIR_DIR}/executables/stats.c
|
||||
)
|
||||
set(XFORMS_LIBRARIES "forms")
|
||||
endif (${XFORMS})
|
||||
@@ -2335,12 +2333,10 @@ add_executable(nr-softmodem
|
||||
${nr_rrc_h}
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-gnb.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-ru.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-softmodem.c
|
||||
${OPENAIR_DIR}/executables/nr-gnb.c
|
||||
${OPENAIR_DIR}/executables/nr-ru.c
|
||||
${OPENAIR_DIR}/executables/nr-softmodem.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_nr_tasks.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
@@ -2373,13 +2369,10 @@ add_executable(nr-softmodem-nos1
|
||||
${rrc_h}
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-gnb.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-ru.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-softmodem.c
|
||||
${OPENAIR_DIR}/executables/nr-gnb.c
|
||||
${OPENAIR_DIR}/executables/nr-ru.c
|
||||
${OPENAIR_DIR}/executables/nr-softmodem.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_tasks.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_nr_tasks.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
@@ -2448,11 +2441,9 @@ add_executable(nr-uesoftmodem-nos1
|
||||
${rrc_h}
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
||||
${OPENAIR_DIR}/executables/nr-ue.c
|
||||
${OPENAIR_DIR}/executables/nr-uesoftmodem.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
#${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <intertask_interface.h>
|
||||
#include <common/utils/system.h>
|
||||
|
||||
typedef struct timer_elm_s {
|
||||
timer_type_t type; ///< Timer type
|
||||
@@ -280,22 +281,8 @@ extern "C" {
|
||||
|
||||
int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) {
|
||||
task_list_t *t=&tasks[task_id];
|
||||
AssertFatal ( pthread_create (&t->thread, NULL, start_routine, args_p) ==0,
|
||||
"Thread creation for task %d failed!\n", task_id);
|
||||
pthread_setname_np( t->thread, itti_get_task_name(task_id) );
|
||||
threadCreate (&t->thread, start_routine, args_p, itti_get_task_name(task_id),-1,OAI_PRIORITY_RT);
|
||||
LOG_I(TMR,"Created Posix thread %s\n", itti_get_task_name(task_id) );
|
||||
#if 1 // BMC test RT prio
|
||||
{
|
||||
int policy;
|
||||
struct sched_param sparam;
|
||||
memset(&sparam, 0, sizeof(sparam));
|
||||
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-10;
|
||||
policy = SCHED_FIFO ;
|
||||
if (pthread_setschedparam(t->thread, policy, &sparam) != 0) {
|
||||
LOG_E(TMR,"task %s : Failed to set pthread priority\n", itti_get_task_name(task_id) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+115
-21
@@ -28,13 +28,23 @@
|
||||
* separate process solves this problem.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <common/utils/assertions.h>
|
||||
#include <common/utils/LOG/log.h>
|
||||
#define MAX_COMMAND 4096
|
||||
|
||||
static int command_pipe_read;
|
||||
@@ -50,37 +60,37 @@ static int module_initialized = 0;
|
||||
/* util functions */
|
||||
/********************************************************************/
|
||||
|
||||
static void lock_system(void)
|
||||
{
|
||||
static void lock_system(void) {
|
||||
if (pthread_mutex_lock(&lock) != 0) {
|
||||
printf("pthread_mutex_lock fails\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void unlock_system(void)
|
||||
{
|
||||
static void unlock_system(void) {
|
||||
if (pthread_mutex_unlock(&lock) != 0) {
|
||||
printf("pthread_mutex_unlock fails\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void write_pipe(int p, char *b, int size)
|
||||
{
|
||||
static void write_pipe(int p, char *b, int size) {
|
||||
while (size) {
|
||||
int ret = write(p, b, size);
|
||||
|
||||
if (ret <= 0) exit(0);
|
||||
|
||||
b += ret;
|
||||
size -= ret;
|
||||
}
|
||||
}
|
||||
|
||||
static void read_pipe(int p, char *b, int size)
|
||||
{
|
||||
static void read_pipe(int p, char *b, int size) {
|
||||
while (size) {
|
||||
int ret = read(p, b, size);
|
||||
|
||||
if (ret <= 0) exit(0);
|
||||
|
||||
b += ret;
|
||||
size -= ret;
|
||||
}
|
||||
@@ -95,14 +105,13 @@ static void read_pipe(int p, char *b, int size)
|
||||
* when the main process exits, because then a "read" on the pipe
|
||||
* will return 0, in which case "read_pipe" exits.
|
||||
*/
|
||||
static void background_system_process(void)
|
||||
{
|
||||
static void background_system_process(void) {
|
||||
int len;
|
||||
int ret;
|
||||
char command[MAX_COMMAND+1];
|
||||
|
||||
while (1) {
|
||||
read_pipe(command_pipe_read, (char*)&len, sizeof(int));
|
||||
read_pipe(command_pipe_read, (char *)&len, sizeof(int));
|
||||
read_pipe(command_pipe_read, command, len);
|
||||
ret = system(command);
|
||||
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
|
||||
@@ -114,8 +123,7 @@ static void background_system_process(void)
|
||||
/* return -1 on error, 0 on success */
|
||||
/********************************************************************/
|
||||
|
||||
int background_system(char *command)
|
||||
{
|
||||
int background_system(char *command) {
|
||||
int res;
|
||||
int len;
|
||||
|
||||
@@ -125,18 +133,22 @@ int background_system(char *command)
|
||||
}
|
||||
|
||||
len = strlen(command)+1;
|
||||
|
||||
if (len > MAX_COMMAND) {
|
||||
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
|
||||
printf("command was: '%s'\n", command);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* only one command can run at a time, so let's lock/unlock */
|
||||
lock_system();
|
||||
write_pipe(command_pipe_write, (char*)&len, sizeof(int));
|
||||
write_pipe(command_pipe_write, (char *)&len, sizeof(int));
|
||||
write_pipe(command_pipe_write, command, len);
|
||||
read_pipe(result_pipe_read, (char*)&res, sizeof(int));
|
||||
read_pipe(result_pipe_read, (char *)&res, sizeof(int));
|
||||
unlock_system();
|
||||
|
||||
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -146,17 +158,16 @@ int background_system(char *command)
|
||||
/* to be called very early by the main processing */
|
||||
/********************************************************************/
|
||||
|
||||
void start_background_system(void)
|
||||
{
|
||||
void start_background_system(void) {
|
||||
int p[2];
|
||||
pid_t son;
|
||||
|
||||
module_initialized = 1;
|
||||
|
||||
if (pipe(p) == -1) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
command_pipe_read = p[0];
|
||||
command_pipe_write = p[1];
|
||||
|
||||
@@ -164,10 +175,11 @@ void start_background_system(void)
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
result_pipe_read = p[0];
|
||||
result_pipe_write = p[1];
|
||||
|
||||
son = fork();
|
||||
|
||||
if (son == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
@@ -181,6 +193,88 @@ void start_background_system(void)
|
||||
|
||||
close(result_pipe_read);
|
||||
close(command_pipe_write);
|
||||
|
||||
background_system_process();
|
||||
}
|
||||
|
||||
void thread_top_init(char *thread_name,
|
||||
int affinity,
|
||||
uint64_t runtime,
|
||||
uint64_t deadline,
|
||||
uint64_t period) {
|
||||
#ifdef DEADLINE_SCHEDULER
|
||||
struct sched_attr attr;
|
||||
unsigned int flags = 0;
|
||||
attr.size = sizeof(attr);
|
||||
attr.sched_flags = 0;
|
||||
attr.sched_nice = 0;
|
||||
attr.sched_priority = 0;
|
||||
attr.sched_policy = SCHED_DEADLINE;
|
||||
attr.sched_runtime = runtime;
|
||||
attr.sched_deadline = deadline;
|
||||
attr.sched_period = period;
|
||||
|
||||
AssertFatal(sched_setattr(0, &attr, flags) == 0, "[SCHED] eNB tx thread: sched_setattr failed\n");
|
||||
|
||||
#else
|
||||
#ifdef CPU_AFFINITY
|
||||
/* Set affinity mask to include CPUs 2 to MAX_CPUS */
|
||||
/* CPU 0 is reserved for UHD threads */ /* CPU 1 is reserved for all RX_TX threads */
|
||||
/* Enable CPU Affinity only if number of CPUs > 2 */
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
if (affinity == 0) {
|
||||
LOG_W(HW,"thread_top_init() called with affinity==0, but overruled by #ifdef CPU_AFFINITY\n");
|
||||
} else if (get_nprocs() > 2) {
|
||||
for (j = 2; j < get_nprocs(); j++)
|
||||
CPU_SET(j, &cpuset);
|
||||
AssertFatal( pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
|
||||
}
|
||||
#endif //CPU_AFFINITY
|
||||
|
||||
struct sched_param sparam={0};
|
||||
sparam.sched_priority = OAI_PRIORITY_RT;
|
||||
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO , &sparam) == 0,"Error setting thread priority");
|
||||
pthread_setname_np(pthread_self(), thread_name);
|
||||
#endif
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
}
|
||||
|
||||
void threadTopInit(const char* name, const int affinity, const int priority){
|
||||
struct sched_param sparam={0};
|
||||
sparam.sched_priority = priority;
|
||||
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO , &sparam) == 0,"Error setting thread priority");
|
||||
pthread_setname_np(pthread_self(), name);
|
||||
if (affinity != -1 ) {
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(affinity, &cpuset);
|
||||
AssertFatal( pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
|
||||
}
|
||||
}
|
||||
|
||||
// Block CPU C-states deep sleep
|
||||
void configure_linux(void) {
|
||||
int ret;
|
||||
static int latency_target_fd=-1;
|
||||
uint32_t latency_target_value=10; // in microseconds
|
||||
if (latency_target_fd == -1) {
|
||||
if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
|
||||
ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
|
||||
if (ret == 0) {
|
||||
printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
|
||||
close(latency_target_fd);
|
||||
latency_target_fd=-1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (latency_target_fd != -1)
|
||||
LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
|
||||
else
|
||||
LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value);
|
||||
|
||||
// Set CPU frequency to it's maximum
|
||||
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
|
||||
LOG_W(HW,"Can't set cpu frequency\n");
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
|
||||
#ifndef _SYSTEM_H_OAI_
|
||||
#define _SYSTEM_H_OAI_
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************
|
||||
* send a command to the background process
|
||||
@@ -36,4 +41,23 @@ int background_system(char *command);
|
||||
|
||||
void start_background_system(void);
|
||||
|
||||
void set_latency_target(void);
|
||||
void configure_linux(void);
|
||||
|
||||
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
|
||||
#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
|
||||
#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
|
||||
#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
|
||||
|
||||
void thread_top_init(char *thread_name,
|
||||
int affinity,
|
||||
uint64_t runtime,
|
||||
uint64_t deadline,
|
||||
uint64_t period);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _SYSTEM_H_OAI_ */
|
||||
|
||||
@@ -49,23 +49,6 @@ void *one_thread(void *arg) {
|
||||
struct one_thread *myThread=(struct one_thread *) arg;
|
||||
struct thread_pool *tp=myThread->pool;
|
||||
|
||||
// configure the thread core assignment
|
||||
// TBD: reserve the core for us exclusively
|
||||
if ( myThread->coreID >= 0 && myThread->coreID < get_nprocs_conf()) {
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(myThread->coreID, &cpuset);
|
||||
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
|
||||
//Configure the thread scheduler policy for Linux
|
||||
struct sched_param sparam= {0};
|
||||
sparam.sched_priority = sched_get_priority_max(SCHED_RR);
|
||||
pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
|
||||
// set the thread name for debugging
|
||||
sprintf(myThread->name,"Tpool_%d",myThread->coreID);
|
||||
pthread_setname_np(pthread_self(), myThread->name );
|
||||
|
||||
// Infinite loop to process requests
|
||||
do {
|
||||
notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread);
|
||||
@@ -106,10 +89,6 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
|
||||
} else
|
||||
pool->traceFd=-1;
|
||||
|
||||
//Configure the thread scheduler policy for Linux
|
||||
struct sched_param sparam= {0};
|
||||
sparam.sched_priority = sched_get_priority_max(SCHED_RR)-1;
|
||||
pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
|
||||
pool->activated=true;
|
||||
initNotifiedFIFO(&pool->incomingFifo);
|
||||
char *saveptr, * curptr;
|
||||
@@ -136,7 +115,10 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
|
||||
pool->allthreads->coreID=atoi(curptr);
|
||||
pool->allthreads->id=pool->nbThreads;
|
||||
pool->allthreads->pool=pool;
|
||||
pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads);
|
||||
//Configure the thread scheduler policy for Linux
|
||||
// set the thread name for debugging
|
||||
sprintf(myThread->name,"Tpool_%d",myThread->coreID);
|
||||
threadCreate(&pool->allthreads->threadID, one_thread, (void *)pool->allthreads, Tpool, myThread->name, myThread->coreID, OAI_PRIORITY_RT);
|
||||
pool->nbThreads++;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <assertions.h>
|
||||
#include <LOG/log.h>
|
||||
#include <common/utils/system.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define THREADINIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
|
||||
|
||||
@@ -0,0 +1,952 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file lte-enb.c
|
||||
* \brief Top-level threads for gNodeB
|
||||
* \author R. Knopp, F. Kaltenberger, Navid Nikaein
|
||||
* \date 2012
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
|
||||
#include "time_utils.h"
|
||||
|
||||
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
#include "PHY/types.h"
|
||||
|
||||
#include "PHY/INIT/phy_init.h"
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "SCHED/sched_eNB.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
#include "SCHED_NR/fapi_nr_l1.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_proto.h"
|
||||
|
||||
#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
|
||||
|
||||
#include "../../ARCH/COMMON/common_lib.h"
|
||||
|
||||
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
#include "PHY/LTE_TRANSPORT/if4_tools.h"
|
||||
#include "PHY/LTE_TRANSPORT/if5_tools.h"
|
||||
|
||||
#include "PHY/phy_extern.h"
|
||||
|
||||
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "LAYER2/MAC/mac_extern.h"
|
||||
#include "LAYER2/MAC/mac_proto.h"
|
||||
#include "RRC/LTE/rrc_extern.h"
|
||||
#include "PHY_INTERFACE/phy_interface.h"
|
||||
#include "common/utils/LOG/log_extern.h"
|
||||
#include "UTIL/OTG/otg_tx.h"
|
||||
#include "UTIL/OTG/otg_externs.h"
|
||||
#include "UTIL/MATH/oml.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "UTIL/OPT/opt.h"
|
||||
#include "enb_config.h"
|
||||
|
||||
|
||||
#ifndef OPENAIR2
|
||||
#include "UTIL/OTG/otg_extern.h"
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
#if defined(ENABLE_USE_MME)
|
||||
#include "s1ap_eNB.h"
|
||||
#ifdef PDCP_USE_NETLINK
|
||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "T.h"
|
||||
|
||||
//#define DEBUG_THREADS 1
|
||||
|
||||
//#define USRP_DEBUG 1
|
||||
// Fix per CC openair rf/if device update
|
||||
// extern openair0_device openair0;
|
||||
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
extern volatile int start_gNB;
|
||||
extern volatile int start_UE;
|
||||
#endif
|
||||
extern volatile int oai_exit;
|
||||
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
extern int transmission_mode;
|
||||
|
||||
uint16_t sl_ahead=4;
|
||||
uint16_t sf_ahead=4;
|
||||
//pthread_t main_gNB_thread;
|
||||
|
||||
time_stats_t softmodem_stats_mt; // main thread
|
||||
time_stats_t softmodem_stats_hw; // hw acquisition
|
||||
time_stats_t softmodem_stats_rxtx_sf; // total tx time
|
||||
time_stats_t nfapi_meas; // total tx time
|
||||
time_stats_t softmodem_stats_rx_sf; // total rx time
|
||||
|
||||
/* mutex, cond and variable to serialize phy proc TX calls
|
||||
* (this mechanism may be relaxed in the future for better
|
||||
* performances)
|
||||
*/
|
||||
static struct {
|
||||
pthread_mutex_t mutex_phy_proc_tx;
|
||||
pthread_cond_t cond_phy_proc_tx;
|
||||
volatile uint8_t phy_proc_CC_id;
|
||||
} sync_phy_proc;
|
||||
|
||||
extern double cpuf;
|
||||
|
||||
void init_gNB(int,int);
|
||||
void stop_gNB(int nb_inst);
|
||||
|
||||
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB);
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB);
|
||||
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
|
||||
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||
|
||||
|
||||
void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe);
|
||||
|
||||
extern uint8_t nfapi_mode;
|
||||
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
|
||||
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
|
||||
|
||||
//#define TICK_TO_US(ts) (ts.diff)
|
||||
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
|
||||
|
||||
|
||||
static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_name) {
|
||||
start_meas(&softmodem_stats_rxtx_sf);
|
||||
|
||||
// *******************************************************************
|
||||
|
||||
if (nfapi_mode == 1) {
|
||||
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
|
||||
uint16_t frame = proc->frame_rx;
|
||||
uint16_t slot = proc->slot_rx;
|
||||
//add_subframe(&frame, &subframe, 4);
|
||||
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
|
||||
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
|
||||
start_meas(&nfapi_meas);
|
||||
oai_subframe_ind(frame, slot);
|
||||
stop_meas(&nfapi_meas);
|
||||
|
||||
if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
|
||||
gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
|
||||
gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
|
||||
gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
|
||||
gNB->UL_INFO.cqi_ind.number_of_cqis
|
||||
) {
|
||||
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
|
||||
NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
|
||||
gNB->UL_INFO.cqi_ind.number_of_cqis,
|
||||
proc->frame_rx, proc->slot_rx,
|
||||
proc->frame_tx, proc->slot_tx);
|
||||
}
|
||||
}
|
||||
|
||||
/// NR disabling
|
||||
// ****************************************
|
||||
// Common RX procedures subframe n
|
||||
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->slot_tx));
|
||||
/*
|
||||
// if this is IF5 or 3GPP_gNB
|
||||
if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
|
||||
wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
|
||||
}
|
||||
|
||||
// UE-specific RX processing for subframe n
|
||||
if (nfapi_mode == 0 || nfapi_mode == 1) {
|
||||
phy_procedures_gNB_uespec_RX(gNB, proc, no_relay );
|
||||
}
|
||||
*/
|
||||
pthread_mutex_lock(&gNB->UL_INFO_mutex);
|
||||
gNB->UL_INFO.frame = proc->frame_rx;
|
||||
gNB->UL_INFO.slot = proc->slot_rx;
|
||||
gNB->UL_INFO.module_id = gNB->Mod_id;
|
||||
gNB->UL_INFO.CC_id = gNB->CC_id;
|
||||
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
|
||||
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
|
||||
|
||||
/// end
|
||||
// *****************************************
|
||||
// TX processing for subframe n+sl_ahead
|
||||
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
|
||||
// (may be relaxed in the future for performance reasons)
|
||||
// *****************************************
|
||||
//if (wait_CCs(proc)<0) return(-1);
|
||||
|
||||
if (oai_exit) return(-1);
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
}
|
||||
|
||||
stop_meas( &softmodem_stats_rxtx_sf );
|
||||
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx);
|
||||
#if 0
|
||||
LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
|
||||
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
|
||||
TICK_TO_US(gNB->phy_proc),
|
||||
TICK_TO_US(gNB->phy_proc_tx),
|
||||
TICK_TO_US(gNB->phy_proc_rx),
|
||||
TICK_TO_US(gNB->rx_prach),
|
||||
TICK_TO_US(gNB->ofdm_mod_stats),
|
||||
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now);
|
||||
LOG_D(PHY,
|
||||
"dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
|
||||
TICK_TO_US(gNB->dlsch_encoding_stats),
|
||||
TICK_TO_US(gNB->dlsch_modulation_stats),
|
||||
TICK_TO_US(gNB->dlsch_scrambling_stats),
|
||||
TICK_TO_US(gNB->dlsch_rate_matching_stats),
|
||||
TICK_TO_US(gNB->dlsch_turbo_encoding_stats),
|
||||
TICK_TO_US(gNB->dlsch_interleaving_stats),
|
||||
TICK_TO_US(gNB->rx_dft_stats));
|
||||
LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
|
||||
TICK_TO_US(gNB->ulsch_channel_estimation_stats),
|
||||
TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats),
|
||||
TICK_TO_US(gNB->ulsch_decoding_stats),
|
||||
TICK_TO_US(gNB->ulsch_demodulation_stats),
|
||||
TICK_TO_US(gNB->ulsch_rate_unmatching_stats));
|
||||
LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
|
||||
TICK_TO_US(gNB->ulsch_turbo_decoding_stats),
|
||||
TICK_TO_US(gNB->ulsch_deinterleaving_stats),
|
||||
TICK_TO_US(gNB->ulsch_demultiplexing_stats),
|
||||
TICK_TO_US(gNB->ulsch_llr_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_init_stats));
|
||||
LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n",
|
||||
TICK_TO_US(gNB->ulsch_tc_alpha_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_beta_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_gamma_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_ext_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_intl1_stats),
|
||||
TICK_TO_US(gNB->ulsch_tc_intl2_stats)
|
||||
);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void *gNB_L1_thread_tx(void *param) {
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||
gNB_L1_proc_t *gNB_proc = &gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc_tx;
|
||||
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||
char thread_name[100];
|
||||
sprintf(thread_name,"TXnp4_%d\n",&gNB->proc.L1_proc == proc ? 0 : 1);
|
||||
//thread_top_init(thread_name,1,470000,500000,500000);
|
||||
|
||||
//wait_sync("tx_thread");
|
||||
|
||||
while (!oai_exit) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
|
||||
|
||||
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 );
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
// *****************************************
|
||||
// TX processing for subframe n+4
|
||||
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
|
||||
// (may be relaxed in the future for performance reasons)
|
||||
// *****************************************
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,proc->slot_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB,proc->slot_rx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,proc->frame_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_GNB,proc->frame_rx);
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
pthread_mutex_lock( &proc->mutex );
|
||||
proc->instance_cnt = -1;
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&proc->cond) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &proc->mutex );
|
||||
wakeup_txfh(proc,gNB);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The RX UE-specific and TX thread of gNB.
|
||||
* \param param is a \ref gNB_L1_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 *gNB_L1_thread( void *param ) {
|
||||
static int gNB_thread_rxtx_status;
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||
gNB_L1_proc_t *gNB_proc = &gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc;
|
||||
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||
char thread_name[100];
|
||||
// set default return value
|
||||
gNB_thread_rxtx_status = 0;
|
||||
sprintf(thread_name,"RXn_TXnp4_%d",&gNB->proc.L1_proc == proc ? 0 : 1);
|
||||
//thread_top_init(thread_name,1,850000L,1000000L,2000000L);
|
||||
|
||||
while (!oai_exit) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 );
|
||||
|
||||
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,proc->slot_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,proc->slot_rx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,proc->frame_tx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,proc->frame_rx);
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
if (gNB->CC_id==0) {
|
||||
if (rxtx(gNB,proc,thread_name) < 0) break;
|
||||
}
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
|
||||
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||
}
|
||||
|
||||
if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||
wakeup_tx(gNB);
|
||||
} else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
|
||||
wakeup_txfh(proc,gNB);
|
||||
}
|
||||
} // while !oai_exit
|
||||
|
||||
LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n");
|
||||
gNB_thread_rxtx_status = 0;
|
||||
return &gNB_thread_rxtx_status;
|
||||
}
|
||||
|
||||
|
||||
#if 0 //defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
|
||||
// Wait for gNB application initialization to be complete (gNB registration to MME)
|
||||
static void wait_system_ready (char *message, volatile int *start_flag) {
|
||||
static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....",
|
||||
" ....", " ...", " ..", " .", " "
|
||||
};
|
||||
int i = 0;
|
||||
|
||||
while ((!oai_exit) && (*start_flag == 0)) {
|
||||
LOG_N(EMU, message, indicator[i]);
|
||||
fflush(stdout);
|
||||
i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
|
||||
usleep(200000);
|
||||
}
|
||||
|
||||
LOG_D(EMU,"\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) {
|
||||
gNB_L1_proc_t *proc = &gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
RU_proc_t *ru_proc=&ru->proc;
|
||||
proc->frame_rx = frame_rx;
|
||||
proc->slot_rx = slot_rx;
|
||||
|
||||
if (!oai_exit) {
|
||||
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx));
|
||||
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
|
||||
L1_proc->frame_rx = ru_proc->frame_rx;
|
||||
L1_proc->slot_rx = ru_proc->tti_rx;
|
||||
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
|
||||
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
|
||||
|
||||
if (rxtx(gNB,L1_proc,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
|
||||
|
||||
ru_proc->timestamp_tx = L1_proc->timestamp_tx;
|
||||
ru_proc->tti_tx = L1_proc->slot_tx;
|
||||
ru_proc->frame_tx = L1_proc->frame_tx;
|
||||
}
|
||||
}
|
||||
|
||||
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) {
|
||||
RU_t *ru;
|
||||
RU_proc_t *ru_proc;
|
||||
struct timespec wait;
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->slot_tx, proc->instance_cnt_RUs);
|
||||
|
||||
if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
|
||||
LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->slot_tx);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
|
||||
gNB->proc.RU_mask_tx = 0;
|
||||
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
|
||||
|
||||
if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
|
||||
|
||||
for(int i=0; i<gNB->num_RU; i++) {
|
||||
ru = gNB->RU_list[i];
|
||||
ru_proc = &ru->proc;
|
||||
|
||||
if (ru_proc->instance_cnt_gNBs == 0) {
|
||||
LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&wait) != 0) {
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->tti_rx&1,ru_proc->instance_cnt_gNBs );
|
||||
exit_fun( "error locking mutex_gNB" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ru_proc->instance_cnt_gNBs = 0;
|
||||
ru_proc->timestamp_tx = proc->timestamp_tx;
|
||||
ru_proc->tti_tx = proc->slot_tx;
|
||||
ru_proc->frame_tx = proc->frame_tx;
|
||||
LOG_I(PHY,"Signaling tx_thread_fh for %d.%d\n",ru_proc->frame_tx,ru_proc->tti_tx);
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&ru_proc->cond_gNBs) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &ru_proc->mutex_gNBs );
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int wakeup_tx(PHY_VARS_gNB *gNB) {
|
||||
gNB_L1_proc_t *proc=&gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
|
||||
gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
|
||||
struct timespec wait;
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
|
||||
if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) {
|
||||
LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n");
|
||||
exit_fun("ERROR pthread_lock");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
while(L1_proc_tx->instance_cnt == 0) {
|
||||
pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
|
||||
}
|
||||
|
||||
L1_proc_tx->instance_cnt = 0;
|
||||
L1_proc_tx->slot_rx = L1_proc->slot_rx;
|
||||
L1_proc_tx->frame_rx = L1_proc->frame_rx;
|
||||
L1_proc_tx->slot_tx = L1_proc->slot_tx;
|
||||
L1_proc_tx->frame_tx = L1_proc->frame_tx;
|
||||
L1_proc_tx->timestamp_tx = L1_proc->timestamp_tx;
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &L1_proc_tx->mutex);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
gNB_L1_proc_t *proc=&gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
RU_proc_t *ru_proc=&ru->proc;
|
||||
int i;
|
||||
struct timespec wait;
|
||||
pthread_mutex_lock(&proc->mutex_RU);
|
||||
|
||||
for (i=0; i<gNB->num_RU; i++) {
|
||||
if (ru == gNB->RU_list[i]) {
|
||||
if ((proc->RU_mask&(1<<i)) > 0)
|
||||
LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
|
||||
gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
|
||||
|
||||
proc->RU_mask |= (1<<i);
|
||||
}
|
||||
}
|
||||
|
||||
if (proc->RU_mask != (1<<gNB->num_RU)-1) { // not all RUs have provided their information so return
|
||||
LOG_E(PHY,"Not all RUs have provided their info\n");
|
||||
pthread_mutex_unlock(&proc->mutex_RU);
|
||||
return(0);
|
||||
} else { // all RUs have provided their information so continue on and wakeup gNB processing
|
||||
proc->RU_mask = 0;
|
||||
pthread_mutex_unlock(&proc->mutex_RU);
|
||||
}
|
||||
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
|
||||
/* accept some delay in processing - up to 5ms */
|
||||
for (i = 0; i < fp->slots_per_frame && L1_proc->instance_cnt == 0; i++) {
|
||||
LOG_W( PHY,"[gNB] SFN.SL %d.%d, gNB RXn-TXnp4 thread busy!! (i %d, cnt %i)\n", L1_proc->frame_tx, L1_proc->slot_tx, i,L1_proc->instance_cnt);
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
if (L1_proc->instance_cnt == 0) {
|
||||
exit_fun( "TX thread busy" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// wake up TX for subframe n+sl_ahead
|
||||
// lock the TX mutex and make sure the thread is ready
|
||||
if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
|
||||
exit_fun( "error locking mutex" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
++L1_proc->instance_cnt;
|
||||
// We have just received and processed the common part of a subframe, say n.
|
||||
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
|
||||
// transmitted timestamp of the next TX slot (first).
|
||||
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
|
||||
// we want to generate subframe (n+sl_ahead), so TS_tx = TX_rx+sl_ahead*samples_per_tti,
|
||||
// and proc->slot_tx = proc->slot_rx+sl_ahead
|
||||
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
|
||||
L1_proc->frame_rx = ru_proc->frame_rx;
|
||||
L1_proc->slot_rx = ru_proc->tti_rx;
|
||||
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
|
||||
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
|
||||
LOG_I(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead);
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc->cond) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &L1_proc->mutex );
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) {
|
||||
|
||||
gNB_L1_proc_t *proc = &gNB->proc;
|
||||
LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
int i;
|
||||
|
||||
if (ru!=NULL) {
|
||||
pthread_mutex_lock(&proc->mutex_RU_PRACH);
|
||||
for (i=0;i<gNB->num_RU;i++) {
|
||||
if (ru == gNB->RU_list[i]) {
|
||||
LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU);
|
||||
if ((proc->RU_mask_prach&(1<<i)) > 0)
|
||||
LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
|
||||
gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach);
|
||||
proc->RU_mask_prach |= (1<<i);
|
||||
}
|
||||
}
|
||||
if (proc->RU_mask_prach != (1<<gNB->num_RU)-1) { // not all RUs have provided their information so return
|
||||
pthread_mutex_unlock(&proc->mutex_RU_PRACH);
|
||||
return;
|
||||
}
|
||||
else { // all RUs have provided their information so continue on and wakeup gNB processing
|
||||
proc->RU_mask_prach = 0;
|
||||
pthread_mutex_unlock(&proc->mutex_RU_PRACH);
|
||||
}
|
||||
}
|
||||
|
||||
// check if we have to detect PRACH first
|
||||
if (is_prach_subframe(fp,frame,subframe)>0) {
|
||||
LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
|
||||
if (proc->instance_cnt_prach == 0) {
|
||||
LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
|
||||
return;
|
||||
}
|
||||
|
||||
// wake up thread for PRACH RX
|
||||
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach);
|
||||
exit_fun( "error locking mutex_prach" );
|
||||
return;
|
||||
}
|
||||
|
||||
++proc->instance_cnt_prach;
|
||||
// set timing for prach thread
|
||||
proc->frame_prach = frame;
|
||||
proc->subframe_prach = subframe;
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&proc->cond_prach) != 0) {
|
||||
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index);
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &proc->mutex_prach );
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
/*!
|
||||
* \brief The prach receive thread of gNB.
|
||||
* \param param is a \ref gNB_L1_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* gNB_thread_prach( void* param ) {
|
||||
static int gNB_thread_prach_status;
|
||||
|
||||
|
||||
PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param;
|
||||
gNB_L1_proc_t *proc = &gNB->proc;
|
||||
|
||||
// set default return value
|
||||
gNB_thread_prach_status = 0;
|
||||
|
||||
thread_top_init("gNB_thread_prach",1,500000L,1000000L,20000000L);
|
||||
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
|
||||
if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
|
||||
|
||||
LOG_D(PHY,"Running gNB prach procedures\n");
|
||||
prach_procedures(gNB
|
||||
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,0
|
||||
#endif
|
||||
);
|
||||
|
||||
if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
|
||||
}
|
||||
|
||||
LOG_I(PHY, "Exiting gNB thread PRACH\n");
|
||||
|
||||
gNB_thread_prach_status = 0;
|
||||
return &gNB_thread_prach_status;
|
||||
}
|
||||
*/
|
||||
|
||||
extern void init_td_thread(PHY_VARS_gNB *, pthread_attr_t *);
|
||||
extern void init_te_thread(PHY_VARS_gNB *, pthread_attr_t *);
|
||||
|
||||
void init_gNB_proc(int inst) {
|
||||
int i=0;
|
||||
int CC_id;
|
||||
PHY_VARS_gNB *gNB;
|
||||
gNB_L1_proc_t *proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
|
||||
pthread_attr_t *attr0=NULL,*attr1=NULL;
|
||||
//*attr_prach=NULL;
|
||||
LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]);
|
||||
|
||||
for (CC_id=0; CC_id<RC.nb_nr_CC[inst]; CC_id++) {
|
||||
gNB = RC.gNB[inst][CC_id];
|
||||
#ifndef OCP_FRAMEWORK
|
||||
LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id);
|
||||
#endif
|
||||
proc = &gNB->proc;
|
||||
L1_proc = &proc->L1_proc;
|
||||
L1_proc_tx = &proc->L1_proc_tx;
|
||||
L1_proc->instance_cnt = -1;
|
||||
L1_proc_tx->instance_cnt = -1;
|
||||
L1_proc->instance_cnt_RUs = 0;
|
||||
L1_proc_tx->instance_cnt_RUs = 0;
|
||||
proc->instance_cnt_prach = -1;
|
||||
proc->instance_cnt_asynch_rxtx = -1;
|
||||
proc->CC_id = CC_id;
|
||||
proc->first_rx =1;
|
||||
proc->first_tx =1;
|
||||
proc->RU_mask =0;
|
||||
proc->RU_mask_tx = (1<<gNB->num_RU)-1;
|
||||
proc->RU_mask_prach =0;
|
||||
pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
|
||||
pthread_mutex_init( &L1_proc->mutex, NULL);
|
||||
pthread_mutex_init( &L1_proc_tx->mutex, NULL);
|
||||
pthread_cond_init( &L1_proc->cond, NULL);
|
||||
pthread_cond_init( &L1_proc_tx->cond, NULL);
|
||||
pthread_mutex_init( &proc->mutex_prach, NULL);
|
||||
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
|
||||
pthread_mutex_init( &proc->mutex_RU,NULL);
|
||||
pthread_mutex_init( &proc->mutex_RU_tx,NULL);
|
||||
pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
|
||||
pthread_cond_init( &proc->cond_prach, NULL);
|
||||
pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
|
||||
pthread_attr_init( &proc->attr_prach);
|
||||
pthread_attr_init( &proc->attr_asynch_rxtx);
|
||||
// pthread_attr_init( &proc->attr_td);
|
||||
// pthread_attr_init( &proc->attr_te);
|
||||
pthread_attr_init( &L1_proc->attr);
|
||||
pthread_attr_init( &L1_proc_tx->attr);
|
||||
attr0 = &L1_proc->attr;
|
||||
attr1 = &L1_proc_tx->attr;
|
||||
LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
|
||||
|
||||
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||
threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT );
|
||||
threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT);
|
||||
}
|
||||
|
||||
//pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
|
||||
char name[16];
|
||||
|
||||
if (gNB->single_thread_flag==0) {
|
||||
snprintf( name, sizeof(name), "L1 %d", i );
|
||||
pthread_setname_np( L1_proc->pthread, name );
|
||||
snprintf( name, sizeof(name), "L1TX %d", i );
|
||||
pthread_setname_np( L1_proc_tx->pthread, name );
|
||||
}
|
||||
|
||||
AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
|
||||
}
|
||||
|
||||
/* setup PHY proc TX sync mechanism */
|
||||
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
|
||||
pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
|
||||
sync_phy_proc.phy_proc_CC_id = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Terminate gNB TX and RX threads.
|
||||
*/
|
||||
void kill_gNB_proc(int inst) {
|
||||
int *status;
|
||||
PHY_VARS_gNB *gNB;
|
||||
gNB_L1_proc_t *proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
|
||||
|
||||
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
gNB=RC.gNB[inst][CC_id];
|
||||
proc = &gNB->proc;
|
||||
L1_proc = &proc->L1_proc;
|
||||
L1_proc_tx = &proc->L1_proc_tx;
|
||||
LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
|
||||
|
||||
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||
pthread_mutex_lock(&L1_proc->mutex);
|
||||
L1_proc->instance_cnt = 0;
|
||||
pthread_cond_signal(&L1_proc->cond);
|
||||
pthread_mutex_unlock(&L1_proc->mutex);
|
||||
pthread_mutex_lock(&L1_proc_tx->mutex);
|
||||
L1_proc_tx->instance_cnt = 0;
|
||||
pthread_cond_signal(&L1_proc_tx->cond);
|
||||
pthread_mutex_unlock(&L1_proc_tx->mutex);
|
||||
}
|
||||
|
||||
proc->instance_cnt_prach = 0;
|
||||
pthread_cond_signal( &proc->cond_prach );
|
||||
pthread_cond_signal( &proc->cond_asynch_rxtx );
|
||||
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
|
||||
// LOG_D(PHY, "joining pthread_prach\n");
|
||||
// pthread_join( proc->pthread_prach, (void**)&status );
|
||||
LOG_I(PHY, "Destroying prach mutex/cond\n");
|
||||
pthread_mutex_destroy( &proc->mutex_prach );
|
||||
pthread_cond_destroy( &proc->cond_prach );
|
||||
LOG_I(PHY, "Destroying UL_INFO mutex\n");
|
||||
pthread_mutex_destroy(&gNB->UL_INFO_mutex);
|
||||
|
||||
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||
LOG_I(PHY, "Joining L1_proc mutex/cond\n");
|
||||
pthread_join( L1_proc->pthread, (void **)&status );
|
||||
LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
|
||||
pthread_join( L1_proc_tx->pthread, (void **)&status );
|
||||
}
|
||||
|
||||
LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
|
||||
pthread_mutex_destroy( &L1_proc->mutex );
|
||||
pthread_cond_destroy( &L1_proc->cond );
|
||||
LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
|
||||
pthread_mutex_destroy( &L1_proc_tx->mutex );
|
||||
pthread_cond_destroy( &L1_proc_tx->cond );
|
||||
pthread_mutex_destroy( &proc->mutex_RU );
|
||||
pthread_mutex_destroy( &proc->mutex_RU_tx );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void reset_opp_meas(void) {
|
||||
int sfn;
|
||||
reset_meas(&softmodem_stats_mt);
|
||||
reset_meas(&softmodem_stats_hw);
|
||||
|
||||
for (sfn=0; sfn < 10; sfn++) {
|
||||
reset_meas(&softmodem_stats_rxtx_sf);
|
||||
reset_meas(&softmodem_stats_rx_sf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_opp_meas(void) {
|
||||
int sfn=0;
|
||||
print_meas(&softmodem_stats_mt, "Main gNB Thread", NULL, NULL);
|
||||
print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);
|
||||
|
||||
for (sfn=0; sfn < 10; sfn++) {
|
||||
print_meas(&softmodem_stats_rxtx_sf,"[gNB][total_phy_proc_rxtx]",NULL, NULL);
|
||||
print_meas(&softmodem_stats_rx_sf,"[gNB][total_phy_proc_rx]",NULL,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// eNB kept in function name for nffapi calls, TO FIX
|
||||
void init_eNB_afterRU(void) {
|
||||
int inst,CC_id,ru_id,i,aa;
|
||||
PHY_VARS_gNB *gNB;
|
||||
LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);
|
||||
|
||||
for (inst=0; inst<RC.nb_nr_inst; inst++) {
|
||||
LOG_I(PHY,"RC.nb_nr_CC[inst]:%d\n", RC.nb_nr_CC[inst]);
|
||||
|
||||
for (CC_id=0; CC_id<RC.nb_nr_CC[inst]; CC_id++) {
|
||||
LOG_I(PHY,"RC.nb_nr_CC[inst:%d][CC_id:%d]:%p\n", inst, CC_id, RC.gNB[inst][CC_id]);
|
||||
gNB = RC.gNB[inst][CC_id];
|
||||
phy_init_nr_gNB(gNB,0,0);
|
||||
|
||||
// map antennas and PRACH signals to gNB RX
|
||||
if (0) AssertFatal(gNB->num_RU>0,"Number of RU attached to gNB %d is zero\n",gNB->Mod_id);
|
||||
|
||||
LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id);
|
||||
//LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]);
|
||||
gNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
|
||||
LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
|
||||
|
||||
for (ru_id=0,aa=0; ru_id<gNB->num_RU; ru_id++) {
|
||||
AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
|
||||
"RU %d : common.rxdataF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
|
||||
"RU %d : prach_rxsigF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
|
||||
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
|
||||
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
|
||||
gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
|
||||
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: review this code, there is something wrong.
|
||||
* In monolithic mode, we come here with nb_antennas_rx == 0
|
||||
* (not tested in other modes).
|
||||
*/
|
||||
//init_precoding_weights(RC.gNB[inst][CC_id]);
|
||||
}
|
||||
|
||||
init_gNB_proc(inst);
|
||||
}
|
||||
|
||||
for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
|
||||
AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id);
|
||||
RC.ru[ru_id]->nr_wakeup_rxtx = wakeup_rxtx;
|
||||
// RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_gNB;
|
||||
RC.ru[ru_id]->gNB_top = gNB_top;
|
||||
}
|
||||
}
|
||||
|
||||
void init_gNB(int single_thread_flag,int wait_for_sync) {
|
||||
int CC_id;
|
||||
int inst;
|
||||
PHY_VARS_gNB *gNB;
|
||||
LOG_I(PHY,"[nr-softmodem.c] gNB structure about to allocated RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC[0]:%d\n",RC.nb_nr_L1_inst,RC.nb_nr_L1_CC[0]);
|
||||
|
||||
if (RC.gNB == NULL) RC.gNB = (PHY_VARS_gNB ***) malloc(RC.nb_nr_L1_inst*sizeof(PHY_VARS_gNB **));
|
||||
|
||||
LOG_I(PHY,"[lte-softmodem.c] gNB structure RC.gNB allocated\n");
|
||||
|
||||
for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
|
||||
if (RC.gNB[inst] == NULL) RC.gNB[inst] = (PHY_VARS_gNB **) malloc(RC.nb_nr_CC[inst]*sizeof(PHY_VARS_gNB *));
|
||||
|
||||
for (CC_id=0; CC_id<RC.nb_nr_L1_CC[inst]; CC_id++) {
|
||||
if (RC.gNB[inst][CC_id] == NULL) RC.gNB[inst][CC_id] = (PHY_VARS_gNB *) malloc(sizeof(PHY_VARS_gNB));
|
||||
|
||||
gNB = RC.gNB[inst][CC_id];
|
||||
gNB->abstraction_flag = 0;
|
||||
gNB->single_thread_flag = single_thread_flag;
|
||||
/*nr_polar_init(&gNB->nrPolar_params,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
|
||||
LOG_I(PHY,"Initializing gNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
|
||||
#ifndef OCP_FRAMEWORK
|
||||
LOG_I(PHY,"Initializing gNB %d CC_id %d\n",inst,CC_id);
|
||||
#endif
|
||||
LOG_I(PHY,"Registering with MAC interface module\n");
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
|
||||
gNB->if_inst->NR_Schedule_response = nr_schedule_response;
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||
memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO));
|
||||
LOG_I(PHY,"Setting indication lists\n");
|
||||
gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list;
|
||||
gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
|
||||
gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
|
||||
gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
|
||||
gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
|
||||
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
|
||||
gNB->prach_energy_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n");
|
||||
}
|
||||
|
||||
|
||||
void stop_gNB(int nb_inst) {
|
||||
for (int inst=0; inst<nb_inst; inst++) {
|
||||
LOG_I(PHY,"Killing gNB %d processing threads\n",inst);
|
||||
kill_gNB_proc(inst);
|
||||
}
|
||||
}
|
||||
+2312
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,251 @@
|
||||
#ifndef NR_SOFTMODEM_H
|
||||
#define NR_SOFTMODEM_H
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <execinfo.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syscall.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/sysinfo.h>
|
||||
#include "targets/ARCH/COMMON/common_lib.h"
|
||||
#undef MALLOC
|
||||
#include "assertions.h"
|
||||
#include "msc.h"
|
||||
#include "PHY/types.h"
|
||||
|
||||
#include "flexran_agent.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
#if defined(ENABLE_USE_MME)
|
||||
#include "s1ap_eNB.h"
|
||||
#ifdef PDCP_USE_NETLINK
|
||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
||||
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
|
||||
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
|
||||
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
|
||||
#define CONFIG_HLP_CALUERM ""
|
||||
#define CONFIG_HLP_CALUERB ""
|
||||
#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n"
|
||||
#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n"
|
||||
#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n"
|
||||
#define CONFIG_HLP_UERXG "set UE RX gain\n"
|
||||
#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n"
|
||||
#define CONFIG_HLP_UETXG "set UE TX gain\n"
|
||||
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
|
||||
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
|
||||
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
|
||||
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
|
||||
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
|
||||
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
|
||||
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
|
||||
#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n"
|
||||
#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n"
|
||||
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
|
||||
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
|
||||
#define CONFIG_HLP_TADV "Set timing_advance\n"
|
||||
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
|
||||
#define CONFIG_HLP_CHOFF "Channel id offset\n"
|
||||
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
|
||||
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
|
||||
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
|
||||
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
|
||||
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
|
||||
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
|
||||
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
|
||||
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
|
||||
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
|
||||
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
|
||||
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
|
||||
#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n"
|
||||
#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"
|
||||
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
|
||||
#define CONFIG_HLP_TPORT "tracer port\n"
|
||||
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
|
||||
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
|
||||
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
|
||||
|
||||
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
|
||||
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
|
||||
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
|
||||
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
|
||||
|
||||
/***************************************************************************************************************************************/
|
||||
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
|
||||
when calling config_get or config_getlist functions */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters defining UE running mode */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_UEMODEPARAMS_DESC { \
|
||||
{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \
|
||||
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
|
||||
}
|
||||
#define CMDLINE_CALIBUERX_IDX 0
|
||||
#define CMDLINE_CALIBUERXMED_IDX 1
|
||||
#define CMDLINE_CALIBUERXBYP_IDX 2
|
||||
#define CMDLINE_DEBUGUEPRACH_IDX 3
|
||||
#define CMDLINE_NOL2CONNECT_IDX 4
|
||||
#define CMDLINE_CALIBPRACHTX_IDX 5
|
||||
#define CMDLINE_MEMLOOP_IDX 6
|
||||
#define CMDLINE_DUMPMEMORY_IDX 7
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters specific to UE */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_UEPARAMS_DESC { \
|
||||
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
|
||||
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
|
||||
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
|
||||
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
|
||||
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
|
||||
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||
}
|
||||
|
||||
#define DEFAULT_DLF 2680000000
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters common to eNodeB and UE */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_PARAMS_DESC { \
|
||||
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \
|
||||
{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
|
||||
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
|
||||
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
|
||||
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
|
||||
{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \
|
||||
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
|
||||
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
|
||||
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
|
||||
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \
|
||||
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
|
||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
|
||||
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
|
||||
{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
|
||||
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
|
||||
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
|
||||
{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \
|
||||
{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
|
||||
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
|
||||
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
|
||||
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
|
||||
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
|
||||
}
|
||||
|
||||
#define CONFIG_HLP_FLOG "Enable online log \n"
|
||||
#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
|
||||
#define CONFIG_HLP_LOGV "Set the global log verbosity \n"
|
||||
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters for LOG utility */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_LOGPARAMS_DESC { \
|
||||
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
|
||||
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
|
||||
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \
|
||||
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
|
||||
}
|
||||
#define CMDLINE_ONLINELOG_IDX 0
|
||||
#define CMDLINE_GLOGLEVEL_IDX 1
|
||||
#define CMDLINE_GLOGVERBO_IDX 2
|
||||
#define CMDLINE_STARTTELN_IDX 3
|
||||
|
||||
|
||||
extern int T_port;
|
||||
extern int T_nowait;
|
||||
extern int T_dont_fork;
|
||||
|
||||
|
||||
/***************************************************************************************************************************************/
|
||||
/* */
|
||||
extern pthread_cond_t sync_cond;
|
||||
extern pthread_mutex_t sync_mutex;
|
||||
extern int sync_var;
|
||||
|
||||
|
||||
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
extern int rx_input_level_dBm;
|
||||
extern uint8_t exit_missed_slots;
|
||||
extern uint64_t num_missed_slots; // counter for the number of missed slots
|
||||
|
||||
extern int oaisim_flag;
|
||||
extern volatile int oai_exit;
|
||||
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
extern pthread_cond_t sync_cond;
|
||||
extern pthread_mutex_t sync_mutex;
|
||||
extern int sync_var;
|
||||
extern int transmission_mode;
|
||||
extern double cpuf;
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
extern volatile int start_gNB;
|
||||
#endif
|
||||
|
||||
#include "threads_t.h"
|
||||
extern threads_t threads;
|
||||
|
||||
// In nr-gnb.c
|
||||
extern void init_gNB(int single_thread_flag,int wait_for_sync);
|
||||
extern void stop_gNB(int);
|
||||
extern void kill_gNB_proc(int inst);
|
||||
|
||||
// In nr-ru.c
|
||||
extern void init_RU(const char *);
|
||||
extern void init_RU_proc(RU_t *ru);
|
||||
extern void stop_RU(int nb_ru);
|
||||
extern void kill_RU_proc(int inst);
|
||||
extern void set_function_spec_param(RU_t *ru);
|
||||
|
||||
extern void reset_opp_meas(void);
|
||||
extern void print_opp_meas(void);
|
||||
|
||||
extern void init_fep_thread(PHY_VARS_gNB *, pthread_attr_t *);
|
||||
|
||||
void init_gNB_afterRU(void);
|
||||
|
||||
extern int stop_L1L2(module_id_t gnb_id);
|
||||
extern int restart_L1L2(module_id_t gnb_id);
|
||||
|
||||
#endif
|
||||
|
||||
+7
-38
@@ -43,6 +43,7 @@
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/system.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#include "T.h"
|
||||
@@ -123,35 +124,6 @@ extern double cpuf;
|
||||
|
||||
#define FRAME_PERIOD 100000000ULL
|
||||
#define DAQ_PERIOD 66667ULL
|
||||
#define FIFO_PRIORITY 40
|
||||
|
||||
|
||||
void init_thread(int core, char *name) {
|
||||
pthread_setname_np(pthread_self(),name);
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
|
||||
if (core >0)
|
||||
CPU_SET(core, &cpuset);
|
||||
|
||||
AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset), "");
|
||||
struct sched_param sp;
|
||||
sp.sched_priority = FIFO_PRIORITY;
|
||||
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
|
||||
"Can't set thread priority, Are you root?\n");
|
||||
/* Check the actual affinity mask assigned to the thread */
|
||||
cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
|
||||
|
||||
if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) {
|
||||
char txt[512]= {0};
|
||||
|
||||
for (int j = 0; j < CPU_SETSIZE; j++)
|
||||
if (CPU_ISSET(j, cset))
|
||||
sprintf(txt+strlen(txt), " %d ", j);
|
||||
|
||||
printf("CPU Affinity of thread %s is %s\n", name, txt);
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
pss=0,
|
||||
@@ -403,7 +375,9 @@ void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
|
||||
#ifdef UE_SLOT_PARALLELISATION
|
||||
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
|
||||
#else
|
||||
uint64_t a=rdtsc();
|
||||
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
|
||||
printf("phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
|
||||
// printf(">>> nr_ue_pdcch_procedures ended\n");
|
||||
#endif
|
||||
}
|
||||
@@ -563,7 +537,8 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
|
||||
}
|
||||
|
||||
void *UE_thread(void *arg) {
|
||||
init_thread(1, "IQ samples");
|
||||
//this thread should be over the processing thread to keep in real time
|
||||
threadTopInit("UE_IQ",1,OAI_PRIORITY_RT_MAX);
|
||||
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
|
||||
// int tx_enabled = 0;
|
||||
openair0_timestamp timestamp;
|
||||
@@ -770,10 +745,7 @@ void init_UE(int nb_inst) {
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
||||
struct sched_param sched;
|
||||
sched.sched_priority = sched_get_priority_max(SCHED_RR)-1;
|
||||
pthread_attr_setschedparam(&attr, &sched);
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
|
||||
|
||||
for (inst=0; inst < nb_inst; inst++) {
|
||||
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
|
||||
@@ -794,10 +766,7 @@ void init_UE(int nb_inst) {
|
||||
mac_inst->initial_bwp_ul.N_RB = UE->frame_parms.N_RB_UL;
|
||||
mac_inst->initial_bwp_ul.cyclic_prefix = UE->frame_parms.Ncp;
|
||||
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
|
||||
AssertFatal(0 == pthread_create(&threads[inst],
|
||||
&attr,
|
||||
UE_thread,
|
||||
(void *)UE), "");
|
||||
threadCreate(&threads[inst], UE_thread, (void *)UE), "UEthread", -1, OAI_PRIORITY_RT);
|
||||
}
|
||||
|
||||
printf("UE threads created by %ld\n", gettid());
|
||||
|
||||
@@ -64,7 +64,6 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#endif
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "create_tasks.h"
|
||||
|
||||
#include "PHY/INIT/phy_init.h"
|
||||
#include "system.h"
|
||||
@@ -311,11 +310,6 @@ void reset_stats(FL_OBJECT *button, long arg) {
|
||||
}
|
||||
|
||||
static void *scope_thread(void *arg) {
|
||||
struct sched_param sched_param;
|
||||
sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
|
||||
sched_setscheduler(0, SCHED_FIFO,&sched_param);
|
||||
printf("Scope thread has priority %d\n",sched_param.sched_priority);
|
||||
//wait the modem is runnign
|
||||
sleep(5);
|
||||
|
||||
while (!oai_exit) {
|
||||
@@ -343,12 +337,7 @@ void init_scope(void) {
|
||||
fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
|
||||
fl_set_button(form_ue[UE_id]->button_0,0);
|
||||
fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
|
||||
ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
|
||||
|
||||
if (ret == 0)
|
||||
pthread_setname_np( forms_thread, "xforms" );
|
||||
|
||||
printf("Scope thread created, ret=%d\n",ret);
|
||||
threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -763,6 +752,7 @@ int main( int argc, char **argv ) {
|
||||
// init UE_PF_PO and mutex lock
|
||||
pthread_mutex_init(&ue_pf_po_mutex, NULL);
|
||||
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
|
||||
configure_linux();
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
init_scope();
|
||||
number_of_cards = 1;
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef OPENAIRINTERFACE5G_LIMITS_H_
|
||||
#define OPENAIRINTERFACE5G_LIMITS_H_
|
||||
|
||||
#if 1 /*defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)*/
|
||||
#define NUMBER_OF_eNB_MAX 1
|
||||
#define NUMBER_OF_gNB_MAX 1
|
||||
#define NUMBER_OF_RU_MAX 2
|
||||
#define NUMBER_OF_NR_RU_MAX 2
|
||||
#ifndef PHYSIM
|
||||
#ifndef UE_EXPANSION
|
||||
#define NUMBER_OF_UE_MAX 16
|
||||
#define NUMBER_OF_NR_UE_MAX 16
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 3
|
||||
#define NUMBER_OF_CONNECTED_gNB_MAX 3
|
||||
#else
|
||||
#define NUMBER_OF_UE_MAX 256
|
||||
#define NUMBER_OF_NR_UE_MAX 256
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||
#endif
|
||||
#else
|
||||
#define NUMBER_OF_UE_MAX 1
|
||||
#define NUMBER_OF_NR_UE_MAX 1
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||
#endif
|
||||
#else
|
||||
#define NUMBER_OF_eNB_MAX 7
|
||||
#define NUMBER_OF_gNB_MAX 7
|
||||
#define NUMBER_OF_RU_MAX 32
|
||||
#define NUMBER_OF_NR_RU_MAX 32
|
||||
#ifndef UE_EXPANSION
|
||||
#define NUMBER_OF_UE_MAX 20
|
||||
#define NUMBER_OF_NR_UE_MAX 20
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 3
|
||||
#define NUMBER_OF_CONNECTED_gNB_MAX 3
|
||||
#else
|
||||
#define NUMBER_OF_UE_MAX 256
|
||||
#define NUMBER_OF_NR_UE_MAX 256
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||
#endif
|
||||
#if defined(STANDALONE) && STANDALONE==1
|
||||
#undef NUMBER_OF_eNB_MAX
|
||||
#undef NUMBER_OF_gNB_MAX
|
||||
|
||||
#undef NUMBER_OF_UE_MAX
|
||||
#undef NUMBER_OF_NR_UE_MAX
|
||||
|
||||
#undef NUMBER_OF_RU_MAX
|
||||
#undef NUMBER_OF_NR_RU_MAX
|
||||
|
||||
#define NUMBER_OF_eNB_MAX 3
|
||||
#define NUMBER_OF_gNB_MAX 3
|
||||
|
||||
#define NUMBER_OF_UE_MAX 3
|
||||
#define NUMBER_OF_NR_UE_MAX 3
|
||||
|
||||
#define NUMBER_OF_RU_MAX 3
|
||||
#define NUMBER_OF_NR_RU_MAX 3
|
||||
#endif
|
||||
#if defined(LARGE_SCALE) && LARGE_SCALE
|
||||
#undef NUMBER_OF_eNB_MAX
|
||||
#undef NUMBER_OF_gNB_MAX
|
||||
|
||||
#undef NUMBER_OF_UE_MAX
|
||||
#undef NUMBER_OF_NR_UE_MAX
|
||||
|
||||
#undef NUMBER_OF_CONNECTED_eNB_MAX
|
||||
#undef NUMBER_OF_CONNECTED_gNB_MAX
|
||||
|
||||
#undef NUMBER_OF_RU_MAX
|
||||
#undef NUMBER_OF_NR_RU_MAX
|
||||
|
||||
#define NUMBER_OF_eNB_MAX 2
|
||||
#define NUMBER_OF_gNB_MAX 2
|
||||
|
||||
#define NUMBER_OF_UE_MAX 120
|
||||
#define NUMBER_OF_NR_UE_MAX 120
|
||||
|
||||
#define NUMBER_OF_RU_MAX 16
|
||||
#define NUMBER_OF_NR_RU_MAX 16
|
||||
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory
|
||||
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* OPENAIRINTERFACE5G_LIMITS_H_ */
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/* Form definition file generated by fdesign */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "stats.h"
|
||||
|
||||
|
||||
/***************************************
|
||||
***************************************/
|
||||
|
||||
FD_stats_form *
|
||||
create_form_stats_form( void ) {
|
||||
FL_OBJECT *obj;
|
||||
FD_stats_form *fdui = fl_malloc( sizeof *fdui );
|
||||
fdui->vdata = fdui->cdata = NULL;
|
||||
fdui->ldata = 0;
|
||||
fdui->stats_form = fl_bgn_form( FL_NO_BOX, 1115, 900 );
|
||||
obj = fl_add_box( FL_UP_BOX, 0, 0, 1115, 900, "" );
|
||||
//fdui->stats_text = obj = fl_add_text( FL_NORMAL_TEXT, 60, 50, 1000, 810, "test" );
|
||||
//fl_set_object_lsize( obj, FL_TINY_SIZE );
|
||||
fdui->stats_text = obj = fl_add_browser( FL_NORMAL_BROWSER, 60, 50, 1000, 810, "test" );
|
||||
fl_set_browser_fontsize(obj,FL_TINY_SIZE);
|
||||
fdui->stats_button = obj = fl_add_button( FL_PUSH_BUTTON, 60, 10, 130, 30, "Reset Stats" );
|
||||
fl_set_object_lalign( obj, FL_ALIGN_CENTER );
|
||||
fl_set_object_color( obj, FL_GREEN, FL_GREEN);
|
||||
fl_set_object_callback( obj, reset_stats, 0 );
|
||||
fl_end_form( );
|
||||
fdui->stats_form->fdui = fdui;
|
||||
return fdui;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/* Header file generated by fdesign on Thu Aug 28 12:13:51 2014 */
|
||||
|
||||
#ifndef FD_stats_form_h_
|
||||
#define FD_stats_form_h_
|
||||
|
||||
#include <forms.h>
|
||||
|
||||
/* Callbacks, globals and object handlers */
|
||||
|
||||
extern void reset_stats( FL_OBJECT *, long );
|
||||
|
||||
/* Forms and Objects */
|
||||
|
||||
typedef struct {
|
||||
FL_FORM *stats_form;
|
||||
void *vdata;
|
||||
char *cdata;
|
||||
long ldata;
|
||||
FL_OBJECT *stats_text;
|
||||
FL_OBJECT *stats_button;
|
||||
} FD_stats_form;
|
||||
|
||||
extern FD_stats_form *create_form_stats_form( void );
|
||||
|
||||
#endif /* FD_stats_form_h_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef _THREADS_T_H_
|
||||
#define _THREADS_T_H_
|
||||
|
||||
typedef struct threads_s {
|
||||
int main;
|
||||
int sync;
|
||||
int one;
|
||||
int two;
|
||||
int three;
|
||||
int slot1_proc_one;
|
||||
int slot1_proc_two;
|
||||
int slot1_proc_three;
|
||||
//int dlsch_td_one;
|
||||
//int dlsch_td_two;
|
||||
//int dlsch_td_three;
|
||||
//int dlsch_td1_one;
|
||||
//int dlsch_td1_two;
|
||||
//int dlsch_td1_three;
|
||||
} threads_t;
|
||||
|
||||
#endif /* _THREADS_T_H_ */
|
||||
@@ -64,7 +64,7 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
|
||||
}
|
||||
|
||||
if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
||||
AssertFatal((N_reg%(bsize*R))==0, "CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",
|
||||
AssertFatal((N_reg % (bsize*R))==0, "CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",
|
||||
N_reg, bsize, R);
|
||||
C = N_reg/(bsize*R);
|
||||
}
|
||||
|
||||
@@ -84,6 +84,20 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
|
||||
|
||||
extern void print_shorts(char *s,int16_t *x);
|
||||
|
||||
static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
|
||||
int **dl_ch_estimates_ext_i,
|
||||
int **dl_ch_rho_ext,
|
||||
unsigned char n_tx,
|
||||
unsigned char n_rx,
|
||||
unsigned char output_shift,
|
||||
int length,
|
||||
int start_point);
|
||||
|
||||
static void nr_dlsch_layer_demapping(int16_t **llr_cw,
|
||||
uint8_t Nl,
|
||||
uint8_t mod_order,
|
||||
uint16_t length,
|
||||
int16_t **llr_layers);
|
||||
|
||||
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
PDSCH_t type,
|
||||
@@ -112,7 +126,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
uint8_t slot = 0;
|
||||
#endif
|
||||
|
||||
unsigned char aatx,aarx;
|
||||
unsigned char aatx=0,aarx=0;
|
||||
|
||||
unsigned short nb_rb = 0, nb_re =0, round;
|
||||
int avgs = 0;// rb;
|
||||
@@ -1120,6 +1134,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
nr_dlsch_layer_demapping(pdsch_vars[eNB_id]->llr,
|
||||
dlsch[0]->harq_processes[harq_pid]->Nl,
|
||||
dlsch[0]->harq_processes[harq_pid]->G,
|
||||
-1,
|
||||
pdsch_vars[eNB_id]->layer_llr);
|
||||
}
|
||||
|
||||
@@ -2179,7 +2194,7 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
|
||||
|
||||
}
|
||||
|
||||
void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
|
||||
static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
|
||||
int **dl_ch_estimates_ext_i,
|
||||
int **dl_ch_rho_ext,
|
||||
unsigned char n_tx,
|
||||
@@ -2287,7 +2302,7 @@ void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
|
||||
__m128i *rxdataF_comp128_0, *rxdataF_comp128_1, *rxdataF_comp128_2, *rxdataF_comp128_3;
|
||||
__m128i *dl_ch_mag128_0, *dl_ch_mag128_1, *dl_ch_mag128_2, *dl_ch_mag128_3;
|
||||
__m128i *dl_ch_mag128_0b, *dl_ch_mag128_1b, *dl_ch_mag128_2b, *dl_ch_mag128_3b;
|
||||
__m128i *rho128_0, *rho128_1, *rho128_2, *rho128_3;
|
||||
__m128i *rho128_0, *rho128_1, *rho128_2=NULL, *rho128_3=NULL;
|
||||
__m128i *rho128_i0, *rho128_i1, *rho128_i2, *rho128_i3;
|
||||
int length_mod4 = 0;
|
||||
int length2;
|
||||
@@ -2592,9 +2607,9 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
|
||||
//int prb_off,prb_off2;
|
||||
int skip_half=0,l;//sss_symb,pss_symb=0,nsymb
|
||||
int i,aarx;
|
||||
int32_t *dl_ch0,*dl_ch0p,*dl_ch0_ext,*dl_ch1,*dl_ch1p,*dl_ch1_ext,*rxF,*rxF_ext;
|
||||
int32_t *dl_ch0=NULL,*dl_ch0p=NULL,*dl_ch0_ext=NULL,*dl_ch1=NULL,*dl_ch1p=NULL,*dl_ch1_ext=NULL,*rxF=NULL,*rxF_ext=NULL;
|
||||
int symbol_mod,pilots=0,j=0;
|
||||
unsigned char *pmi_loc;
|
||||
unsigned char *pmi_loc=NULL;
|
||||
|
||||
pilots = (symbol==2) ? 1 : 0; //to updated from config
|
||||
k = frame_parms->first_carrier_offset + 516; //0
|
||||
@@ -2673,7 +2688,7 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
|
||||
return(nb_rb/frame_parms->nb_antennas_rx);
|
||||
}
|
||||
|
||||
void nr_dlsch_layer_demapping(int16_t **llr_cw,
|
||||
static void nr_dlsch_layer_demapping(int16_t **llr_cw,
|
||||
uint8_t Nl,
|
||||
uint8_t mod_order,
|
||||
uint16_t length,
|
||||
|
||||
@@ -205,7 +205,7 @@ void nr_init_feptx_thread(RU_t *ru,pthread_attr_t *attr_feptx) {
|
||||
pthread_mutex_init( &proc->mutex_feptx, NULL);
|
||||
pthread_cond_init( &proc->cond_feptx, NULL);
|
||||
|
||||
pthread_create(&proc->pthread_feptx, attr_feptx, nr_feptx_thread, (void*)ru);
|
||||
threadCreate(&proc->pthread_feptx, nr_feptx_thread, (void*)ru, "feptx", -1, OAI_PRIORITY_RT);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2814,7 +2814,6 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
|
||||
//uint8_t pbch_phase;
|
||||
int ret = 0;
|
||||
uint16_t frame_tx;
|
||||
static uint8_t first_run = 1;
|
||||
uint8_t pbch_trials = 0;
|
||||
|
||||
DevAssert(ue);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define RRC_CONFIG_TOOLS_H_
|
||||
|
||||
#define KHz (1000UL)
|
||||
#define MHz (1000 * KHz)
|
||||
#define MHz (1000*KHz)
|
||||
|
||||
typedef struct eutra_band_s {
|
||||
int16_t band;
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
*/
|
||||
|
||||
#include "flexran_agent.h"
|
||||
#include <common/utils/system.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
void *send_thread(void *args);
|
||||
void *receive_thread(void *args);
|
||||
pthread_t new_thread(void *(*f)(void *), void *b);
|
||||
Protocol__FlexranMessage *flexran_agent_timeout(void* args);
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ void *flexran_agent_task(void *args){
|
||||
}
|
||||
|
||||
void *receive_thread(void *args) {
|
||||
threadTopInit("flexran",-1,OAI_PRIORITY_RT_LOW);
|
||||
|
||||
flexran_agent_info_t *d = args;
|
||||
void *data;
|
||||
@@ -145,38 +146,6 @@ error:
|
||||
}
|
||||
|
||||
|
||||
/* utility function to create a thread */
|
||||
pthread_t new_thread(void *(*f)(void *), void *b) {
|
||||
pthread_t t;
|
||||
pthread_attr_t att;
|
||||
|
||||
if (pthread_attr_init(&att)){
|
||||
fprintf(stderr, "pthread_attr_init err\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct sched_param sched_param_recv_thread;
|
||||
|
||||
sched_param_recv_thread.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
|
||||
pthread_attr_setschedparam(&att, &sched_param_recv_thread);
|
||||
pthread_attr_setschedpolicy(&att, SCHED_FIFO);
|
||||
|
||||
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) {
|
||||
fprintf(stderr, "pthread_attr_setdetachstate err\n");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_create(&t, &att, f, b)) {
|
||||
fprintf(stderr, "pthread_create err\n");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_attr_destroy(&att)) {
|
||||
fprintf(stderr, "pthread_attr_destroy err\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
int channel_container_init = 0;
|
||||
int flexran_agent_start(mid_t mod_id)
|
||||
{
|
||||
@@ -227,8 +196,8 @@ int flexran_agent_start(mid_t mod_id)
|
||||
|
||||
/*Initialize the continuous stats update mechanism*/
|
||||
flexran_agent_init_cont_stats_update(mod_id);
|
||||
|
||||
new_thread(receive_thread, flexran);
|
||||
pthread_t t;
|
||||
threadCreate(&t, receive_thread, flexran, "flexran", -1, OAI_PRIORITY_RT);
|
||||
|
||||
/*Initialize and register the mac xface. Must be modified later
|
||||
*for more flexibility in agent management */
|
||||
|
||||
@@ -101,33 +101,12 @@ static void *pdcp_thread_main(void* param)
|
||||
int init_pdcp_thread(void)
|
||||
{
|
||||
|
||||
int error_code;
|
||||
struct sched_param p;
|
||||
|
||||
pthread_attr_init (&pdcp_thread_attr);
|
||||
pthread_attr_setstacksize(&pdcp_thread_attr,OPENAIR_THREAD_STACK_SIZE);
|
||||
//attr_dlsch_threads.priority = 1;
|
||||
|
||||
p.sched_priority = OPENAIR_THREAD_PRIORITY;
|
||||
pthread_attr_setschedparam (&pdcp_thread_attr, &p);
|
||||
pthread_attr_setschedpolicy (&pdcp_thread_attr, SCHED_FIFO);
|
||||
pthread_mutex_init(&pdcp_mutex,NULL);
|
||||
pthread_cond_init(&pdcp_cond,NULL);
|
||||
|
||||
pdcp_instance_cnt = -1;
|
||||
LOG_I(PDCP,"Allocating PDCP thread\n");
|
||||
error_code = pthread_create(&pdcp_thread,
|
||||
&pdcp_thread_attr,
|
||||
pdcp_thread_main,
|
||||
(void*)NULL);
|
||||
|
||||
if (error_code!= 0) {
|
||||
LOG_I(PDCP,"Could not allocate PDCP thread, error %d\n",error_code);
|
||||
return(error_code);
|
||||
} else {
|
||||
LOG_I(PDCP,"Allocate PDCP thread successful\n");
|
||||
pthread_setname_np( pdcp_thread, "PDCP" );
|
||||
}
|
||||
threadCreate(&pdcp_thread, pdcp_thread_main, (void*)NULL, "PDCP", -1, OAI_PRIORITY_RT);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
#include "pdcp.h"
|
||||
#include "plmn_data.h"
|
||||
#include "msc.h"
|
||||
#include <common/utils/system.h>
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
# include "intertask_interface.h"
|
||||
@@ -5477,7 +5478,6 @@ void rrc_control_socket_init(){
|
||||
|
||||
struct sockaddr_in rrc_ctrl_socket_addr;
|
||||
pthread_attr_t attr;
|
||||
struct sched_param sched_param;
|
||||
int optval; // flag value for setsockopt
|
||||
//int n; // message byte size
|
||||
|
||||
@@ -5505,27 +5505,11 @@ void rrc_control_socket_init(){
|
||||
LOG_E(RRC,"[rrc_control_socket_init] ERROR: Failed on binding the socket\n");
|
||||
exit(1);
|
||||
}
|
||||
//create thread to listen to incoming packets
|
||||
if (pthread_attr_init(&attr) != 0) {
|
||||
LOG_E(RRC, "[rrc_control_socket_init]Failed to initialize pthread attribute for ProSe -> RRC communication (%d:%s)\n",
|
||||
errno, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sched_param.sched_priority = 10;
|
||||
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
||||
pthread_attr_setschedparam(&attr, &sched_param);
|
||||
|
||||
threadTopInit("RRC Control Socket",-1,OAI_PRIORITY_RT);
|
||||
pthread_t rrc_control_socket_thread;
|
||||
|
||||
if (pthread_create(&rrc_control_socket_thread, &attr, rrc_control_socket_thread_fct, NULL) != 0) {
|
||||
LOG_E(RRC, "[rrc_control_socket_init]Failed to create new thread for RRC/ProSeApp communication (%d:%s)\n",
|
||||
errno, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pthread_setname_np( rrc_control_socket_thread, "RRC Control Socket" );
|
||||
threadCreate(&rrc_control_socket_thread, rrc_control_socket_thread_fct, NULL, "RRC/ProSeApp", -1, OAI_PRIORITY_RT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
|
||||
|
||||
#ifdef DEBUG_RRC
|
||||
int i;
|
||||
LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -116,10 +116,9 @@ mui_t rrc_gNB_mui = 0;
|
||||
|
||||
void openair_nr_rrc_on(const protocol_ctxt_t* const ctxt_pP){
|
||||
|
||||
int CC_id;
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" gNB:OPENAIR NR RRC IN....\n",PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP));
|
||||
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
rrc_config_nr_buffer (&RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1);
|
||||
RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1;
|
||||
rrc_config_nr_buffer (&RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].Srb0, CCCH, 1);
|
||||
@@ -144,8 +143,6 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
){
|
||||
|
||||
uint8_t size;
|
||||
uint8_t buffer[100];
|
||||
int CC_id = ue_context_pP->ue_context.primaryCC_id;
|
||||
OCTET_STRING_t *secondaryCellGroup;
|
||||
NR_CellGroupConfig_t *cellGroupconfig;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "link_manager.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include <common/utils/system.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -112,41 +113,14 @@ link_manager_t *create_link_manager(
|
||||
ret->socket_link = link;
|
||||
ret->run = 1;
|
||||
|
||||
if (pthread_attr_init(&attr))
|
||||
goto error;
|
||||
|
||||
// Make the async interface threads real-time
|
||||
//#ifndef LOWLATENCY
|
||||
struct sched_param sched_param_recv_thread;
|
||||
|
||||
sched_param_recv_thread.sched_priority = sched_get_priority_max(SCHED_RR) - 1;
|
||||
pthread_attr_setschedparam(&attr, &sched_param_recv_thread);
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
||||
//#endif
|
||||
|
||||
if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
|
||||
goto error;
|
||||
|
||||
if (pthread_create(&t, &attr, link_manager_sender_thread, ret))
|
||||
goto error;
|
||||
threadCreate(&t, link_manager_sender_thread, ret, "flexranSender", -1, OAI_PRIORITY_RT_LOW);
|
||||
ret->sender = t;
|
||||
|
||||
if (pthread_create(&t, &attr, link_manager_receiver_thread, ret))
|
||||
/* we should destroy the other thread here */
|
||||
goto error;
|
||||
threadCreate(&t, link_manager_receiver_thread, ret, "flexranReceiver", -1, OAI_PRIORITY_RT_LOW);
|
||||
ret->receiver = t;
|
||||
|
||||
if (pthread_attr_destroy(&attr))
|
||||
/* to be clean we should destroy the threads at this point,
|
||||
* even if in practice we never reach it */
|
||||
goto error;
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void destroy_link_manager(link_manager_t *manager)
|
||||
|
||||
@@ -90,10 +90,7 @@ int cli_server_init(cli_handler_t handler)
|
||||
}
|
||||
|
||||
/* create telnet listener thread */
|
||||
if (pthread_create(&cli_server_listener, NULL, cli_server_listen, NULL)) {
|
||||
perror("thread");
|
||||
return -1;
|
||||
}
|
||||
threadCreate(&cli_server_listener, cli_server_listen, NULL, "telnet", -1, OAI_PRIORITY_RT_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ what about the implementation
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <common/utils/system.h>
|
||||
|
||||
#include "opt.h"
|
||||
|
||||
@@ -203,15 +204,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pthread_create(&opt_listener.thread, NULL, opt_listener_thread, NULL);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_E(OPT, "Failed to create thread for server socket: %s\n", strerror(errno));
|
||||
opt_type = OPT_NONE;
|
||||
close(opt_listener.sd);
|
||||
opt_listener.sd = -1;
|
||||
return -1;
|
||||
}
|
||||
threadCreate(&opt_listener.thread, opt_listener_thread, NULL, "flexran", -1, OAI_PRIORITY_RT_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -195,17 +195,7 @@ void server_socket_tcp_ip4()
|
||||
|
||||
|
||||
/* create new thread for the new connection */
|
||||
if (pthread_create(&id, NULL, (void *)recv_ip4_tcp, (void*)csock))
|
||||
LOG_W(OTG,"SOCKET:: TCP-IP4 ::pthread_create OK!\n");
|
||||
|
||||
else
|
||||
LOG_W(OTG,"SOCKET:: TCP-IP4 ::Error in pthread_create \n");
|
||||
|
||||
if (pthread_detach(id))
|
||||
LOG_W(OTG,"SOCKET:: TCP-IP4 ::pthread_detach OK!\n");
|
||||
else
|
||||
LOG_W(OTG,"SOCKET:: TCP-IP4 ::Error in pthread_detach\n");
|
||||
|
||||
threadCreate(&id, (void *)recv_ip4_tcp, (void*)csock), "OTG", -1, OAI_PRIORITY_RT_LOW);
|
||||
LOG_I(OTG,"SOCKET:: TCP-IP4 :: Client n=%d finish transmission\n", cmpt_cl);
|
||||
cmpt_cl+=1;
|
||||
}
|
||||
|
||||
@@ -160,27 +160,15 @@ int main(int argc, const char *argv[])
|
||||
*/
|
||||
pthread_t user_mngr;
|
||||
|
||||
if (pthread_create (&user_mngr, &attr, _nas_user_mngr, &user_fd) != 0) {
|
||||
LOG_TRACE (ERROR, "UE-MAIN - "
|
||||
"Failed to create the user management thread");
|
||||
user_api_close (user_api_id);
|
||||
network_api_close (network_fd);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
threadCreate (&user_mngr, , _nas_user_mngr, &user_fd, "UE-nas", -1, OAI_PRIORITY_RT_LOW) ;
|
||||
|
||||
/*
|
||||
* Start thread use to manage the network connection endpoint
|
||||
*/
|
||||
pthread_t network_mngr;
|
||||
|
||||
if (pthread_create (&network_mngr, &attr, _nas_network_mngr,
|
||||
&network_fd) != 0) {
|
||||
LOG_TRACE (ERROR, "UE-MAIN - "
|
||||
"Failed to create the network management thread");
|
||||
user_api_close (user_api_id);
|
||||
network_api_close (network_fd);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
threadCreate (&network_mngr, _nas_network_mngr,
|
||||
&network_fd, "UE-nas-mgr", -1, OAI_PRIORITY_RT_LOW) ;
|
||||
|
||||
pthread_attr_destroy (&attr);
|
||||
|
||||
|
||||
@@ -1102,6 +1102,9 @@ extern "C" {
|
||||
device->type=USRP_X300_DEV;
|
||||
usrp_master_clock = 184.32e6;
|
||||
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
|
||||
// USRP recommended: https://files.ettus.com/manual/page_usrp_x3x0_config.html
|
||||
if ( 0 != system("sysctl -w net.core.rmem_max=33554432 net.core.wmem_max=33554432") )
|
||||
LOG_W(HW,"Can't set kernel paramters for X3xx\n");
|
||||
}
|
||||
|
||||
s->usrp = uhd::usrp::multi_usrp::make(args);
|
||||
|
||||
@@ -1005,7 +1005,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con
|
||||
|
||||
|
||||
|
||||
#ifndef DEADLINE_SCHEDULER
|
||||
#if 0 // #ifndef DEADLINE_SCHEDULER
|
||||
|
||||
printf("NO deadline scheduler\n");
|
||||
/* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
|
||||
|
||||
Reference in New Issue
Block a user