From 17d5bcd396bcd41a81a1a2f7929119b95ad4da2f Mon Sep 17 00:00:00 2001 From: laurent <laurent.thomas@open-cells.com> Date: Tue, 18 Jun 2019 08:57:08 +0200 Subject: [PATCH] dev continue --- common/utils/system.c | 104 ++++++++++--- common/utils/system.h | 25 ++++ executables/dl_fs6.c | 35 +---- executables/split_headers.h | 21 ++- executables/transport_split.c | 65 +++++++++ openair1/SIMULATION/TOOLS/random_channel.c | 4 + targets/RT/USER/lte-softmodem.c | 161 ++++----------------- 7 files changed, 226 insertions(+), 189 deletions(-) create mode 100644 executables/transport_split.c diff --git a/common/utils/system.c b/common/utils/system.c index dcec681e2d..31c1035129 100644 --- a/common/utils/system.c +++ b/common/utils/system.c @@ -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,56 @@ void start_background_system(void) close(result_pipe_read); close(command_pipe_write); - background_system_process(); } + + +void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + struct sched_param sparam={0}; + sparam.sched_priority = priority; + pthread_attr_setschedparam(&attr, &sparam); + + pthread_create(t, &attr, func, param); + + pthread_setname_np(*t, name); + if (affinity != -1 ) { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(affinity, &cpuset); + AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity"); + } + + pthread_attr_destroy(&attr); +} + +// 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"); + +} diff --git a/common/utils/system.h b/common/utils/system.h index 658c17adc1..a89a6c5b17 100644 --- a/common/utils/system.h +++ b/common/utils/system.h @@ -21,6 +21,12 @@ #ifndef _SYSTEM_H_OAI_ #define _SYSTEM_H_OAI_ +#include <stdint.h> +#include <pthread.h> +#ifdef __cplusplus +extern "C" { +#endif + /**************************************************** * send a command to the background process @@ -36,4 +42,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_ */ diff --git a/executables/dl_fs6.c b/executables/dl_fs6.c index 4eae805eb7..079f368f1d 100644 --- a/executables/dl_fs6.c +++ b/executables/dl_fs6.c @@ -1,21 +1,5 @@ -#define MTU 65536 -#define UDP_TIMEOUT 100000L // in nano second - -receiveSubFrame(int sock) { - //read all subframe data from the control unit - char * buf[MTU]; - int ret=recv(sock, buf, sizeof(buf), 0); - if ( ret==-1) { - if ( errno == EWOULDBLOCK || errno== EINTR ) { - finishSubframeRecv(); - } else { - LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno)); - return; - } - } else { - } - -} +#include <split_headers.h> + void pdsch_procedures(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, @@ -206,21 +190,6 @@ DL_thread_fs6() { ru->fh_south_out(ru); } -int createListner (port) { - int sock; - AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, ""); - struct sockaddr_in addr = { -sin_family: - AF_INET, -sin_port: -htons(port), -sin_addr: - { s_addr: INADDR_ANY } - }; - AssertFatal(bind(sock, const struct sockaddr *addr, socklen_t addrlen)==0,""); - struct timeval tv={0,UDP_TIMEOUT}; - AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,""); -} DL_thread_frequency() { diff --git a/executables/split_headers.h b/executables/split_headers.h index 7a580affd4..1fe4088971 100644 --- a/executables/split_headers.h +++ b/executables/split_headers.h @@ -1,13 +1,28 @@ #ifndef __SPLIT_HEADERS_H #define __SPLIT_HEADERS_H -struct frequency_s { +#define MTU 65536 +#define UDP_TIMEOUT 100000L // in nano second +#define MAX_BLOCKS 16 +#define blockAlign 32 //bytes + +typedef struct commonUDP_s { + uint64_t timestamp; // id of the group (subframe for LTE) + uint16_t nbBlocks; // total number of blocks for this timestamp + uint16_t blockID; // id: 0..nbBocks-1 + uint16_t contentType; // defines the content format + uint16_t contentBytes; // will be sent in a UDP packet, so must be < 2^16 bytes +} commonUDP_t; + +typedef struct frequency_s { int frame; int subframe; - int timestamp; int sampleSize; int nbAnt int nbSamples; } frequency_t; - + +int createListner (port); +int receiveSubFrame(int sock, uint64_t expectedTS, void* bufferZone, int bufferSize); +int sendSubFrame(int sock, void* bufferZone, int nbBlocks);} #endif diff --git a/executables/transport_split.c b/executables/transport_split.c new file mode 100644 index 0000000000..a1e0738458 --- /dev/null +++ b/executables/transport_split.c @@ -0,0 +1,65 @@ +#include <split_headers.h> + +int createListner (port) { + int sock; + AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, ""); + struct sockaddr_in addr = { +sin_family: + AF_INET, +sin_port: +htons(port), +sin_addr: + { s_addr: INADDR_ANY } + }; + int enable=1; + AssertFatal(setsockopt(eth->sockfdc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,""); + AssertFatal(bind(sock, const struct sockaddr *addr, socklen_t addrlen)==0,""); + struct timeval tv={0,UDP_TIMEOUT}; + AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,""); + // Make a send/recv buffer larger than a a couple of subframe + // so the kernel will store for us in and out paquets + int buff=1000*1000*10; + AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, ""); + AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, ""); +} + +// sock: udp socket +// expectedTS: the expected timestamp, 0 if unknown +// bufferZone: a reception area of bufferSize +int receiveSubFrame(int sock, uint64_t expectedTS, void* bufferZone, int bufferSize) { + int rcved=0; + do { + //read all subframe data from the control unit + int ret=recv(sock, bufferZone, bufferSize, 0); + if ( ret==-1) { + if ( errno == EWOULDBLOCK || errno== EINTR ) { + return rcved; // Timeout, subframe incomplete + } else { + LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno)); + return -1; + } + } else { + commonUDP_t * tmp=(commonUDP_t *)bufferZone; + if ( expectedTS && tmp->timestamp != expectedTS) { + LOG_W(HW,"Received a paquet in mixed subframes, dropping it\n"); + } else { + rcved++; + bufferZone+=ret; + } + } + } while ( !recved || recved < tmp->nbBlocks); + return recv; +} + +int sendSubFrame(int sock, void* bufferZone, int nbBlocks) { + do { + int sz=alignedSize(bufferZone); + int ret=send(sock, bufferZone, sz, 0); + if ( ret != sz ) + LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d)\n", + sz, ret, errno); + bufferZone+=sz; + nbBlocks--; + } while (nbBlocks); + return 0; +} diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 8341c574da..f056d51b5d 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -1204,6 +1204,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, return(chan_desc); } +void free_channel_desc_scm(channel_desc_t * ch) { + // Must be made cleanly, a lot of leaks... + free(ch); +} int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 0dfbcff954..50e866358b 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -108,10 +108,6 @@ pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; -uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] -uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] - - volatile int oai_exit = 0; uint32_t downlink_frequency[MAX_NUM_CCs][4]; @@ -149,21 +145,13 @@ uint8_t nb_antenna_rx = 1; char ref[128] = "internal"; char channels[128] = "0"; -int rx_input_level_dBm; - - -int otg_enabled; - - +int rx_input_level_dBm; +int otg_enabled; uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots - -extern void reset_opp_meas(void); -extern void print_opp_meas(void); - - extern void init_eNB_afterRU(void); +extern void phy_free_RU(RU_t *); int transmission_mode=1; int emulate_rf = 0; @@ -172,73 +160,11 @@ int numerology = 0; THREAD_STRUCT thread_struct; /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; - double cpuf; - - /* forward declarations */ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); -/*---------------------BMC: timespec helpers -----------------------------*/ - -struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; -struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - -struct timespec clock_difftime(struct timespec start, struct timespec end) { - struct timespec temp; - - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - - return temp; -} - -void print_difftimes(void) { -#ifdef DEBUG - printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); -#else - LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); -#endif -} - -void update_difftimes(struct timespec start, struct timespec end) { - struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - int changed = 0; - diff_time = clock_difftime(start, end); - - if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { - min_diff_time.tv_nsec = diff_time.tv_nsec; - changed = 1; - } - - if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { - max_diff_time.tv_nsec = diff_time.tv_nsec; - changed = 1; - } - -#if 1 - - if (changed) print_difftimes(); - -#endif -} - -/*------------------------------------------------------------------------*/ - -unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) { - return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); -} -unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { - return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); -} - - void signal_handler(int sig) { void *array[10]; size_t size; @@ -256,7 +182,6 @@ void signal_handler(int sig) { } } - void exit_function(const char *file, const char *function, const int line, const char *s) { int ru_id; @@ -285,8 +210,6 @@ void exit_function(const char *file, const char *function, const int line, const exit(1); } - - static void get_options(void) { CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); get_common_options(); @@ -297,11 +220,11 @@ static void get_options(void) { /* Read RC configuration file */ RCConfig(); NB_eNB_INST = RC.nb_inst; - printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU); + LOG_I(ENB_APP,"Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU); if (!IS_SOFTMODEM_NONBIOT) { load_NB_IoT(); - printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n", + LOG_I(ENB_APP," nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n", RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst); } else { printf("All Nb-IoT instances disabled\n"); @@ -310,10 +233,6 @@ static void get_options(void) { } } - - - - void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { int CC_id; @@ -528,75 +447,58 @@ int main( int argc, char **argv ) { int CC_id = 0; int ru_id; - if ( load_configmodule(argc,argv,0) == NULL) { - exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); - } - + AssertFatal(load_configmodule(argc,argv,0) != NULL, + "[SOFTMODEM] Error, configuration module init failed\n"); mode = normal_txrx; - set_latency_target(); + logInit(); - printf("Reading in command-line options\n"); get_options (); + AssertFatal(!CONFIG_ISFLAGSET(CONFIG_ABORT),"Getting configuration failed\n"); + + configure_linux(); + // to make a graceful exit when ctrl-c is pressed + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGABRT, signal_handler); + cpuf=get_cpu_freq_GHz(); + + #ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#endif + LOG_I(HW, "OAI Version: %s\n", PACKAGE_VERSION); if (is_nos1exec(argv[0]) ) set_softmodem_optmask(SOFTMODEM_NOS1_BIT); EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; - if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { - fprintf(stderr,"Getting configuration failed\n"); - exit(-1); - } - #if T_TRACER T_Config_Init(); #endif //randominit (0); set_taus_seed (0); - printf("configuring for RAU/RRU\n"); - if (opp_enabled ==1) { + if (opp_enabled ==1) reset_opp_meas(); - } - cpuf=get_cpu_freq_GHz(); - printf("ITTI init, useMME: %i\n",EPC_MODE_ENABLED); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); - - // initialize mscgen log after ITTI - if (get_softmodem_params()->start_msc) { - load_module_shlib("msc",NULL,0,&msc_interface); - } - - MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); + // allows to forward in wireshark L2 protocol for decoding init_opt(); - // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGABRT, signal_handler); - check_clock(); -#ifndef PACKAGE_VERSION -# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" -#endif - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - printf("Runtime table\n"); - fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); /* Read configuration */ if (RC.nb_inst > 0) { read_config_and_init(); /* Start the agent. If it is turned off in the configuration, it won't start */ RCconfig_flexran(); - - for (i = 0; i < RC.nb_inst; i++) { + + for (i = 0; i < RC.nb_inst; i++) flexran_agent_start(i); - } - + /* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks * for monolithic/F1 modes */ init_pdcp(); - + if (create_tasks(1) < 0) { printf("cannot create ITTI tasks\n"); exit(-1); @@ -685,15 +587,11 @@ int main( int argc, char **argv ) { } printf("wait RUs\n"); - // CI -- Flushing the std outputs for the previous marker to show on the eNB / RRU log file - fflush(stdout); - fflush(stderr); // end of CI modifications wait_RUs(); LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU); // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration) - printf("ALL RUs ready - init eNBs\n"); - + if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) { LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n"); init_eNB_afterRU(); @@ -738,7 +636,6 @@ int main( int argc, char **argv ) { * threads have been stopped (they partially use the same memory) */ for (int inst = 0; inst < NB_eNB_INST; inst++) { for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { - free_transport(RC.eNB[inst][cc_id]); phy_free_lte_eNB(RC.eNB[inst][cc_id]); } } -- 2.26.2