Commit ff2f8098 authored by navid's avatar navid

* add RRH gateway module, IQ transports, and its gtkwave template (experimental)

* update ethernet library and common lib 
* update runtime values of the lte-softmodem tx and rx threads based on an empirical model


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7709 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 4ef9500a
...@@ -362,13 +362,13 @@ elseif (${RF_BOARD} STREQUAL "OAI_BLADERF") ...@@ -362,13 +362,13 @@ elseif (${RF_BOARD} STREQUAL "OAI_BLADERF")
${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c ${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
) )
LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu/") LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu/")
set(option_HW_lib "bladeRF")
elseif (${RF_BOARD} STREQUAL "ETHERNET") elseif (${RF_BOARD} STREQUAL "ETHERNET")
include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB") include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB")
set(HW_SOURCE ${HW_SOURCE} set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
) )
set(LOWLATENCY True)
elseif (${RF_BOARD} STREQUAL "CPRIGW") elseif (${RF_BOARD} STREQUAL "CPRIGW")
set(HW_SOURCE ${HW_SOURCE} set(HW_SOURCE ${HW_SOURCE}
...@@ -1567,6 +1567,8 @@ add_executable(lte-softmodem-nos1 ...@@ -1567,6 +1567,8 @@ add_executable(lte-softmodem-nos1
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c
#${OPENAIR2_DIR}/RRC/NAS/nas_config.c # enable if you want rrc to mount ip interface
#${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${HW_SOURCE} ${HW_SOURCE}
${RTAI_SOURCE} ${RTAI_SOURCE}
...@@ -1711,6 +1713,36 @@ target_link_libraries (oai_sgw ...@@ -1711,6 +1713,36 @@ target_link_libraries (oai_sgw
) )
endif(MESSAGE_CHART_GENERATOR) endif(MESSAGE_CHART_GENERATOR)
# rrh
################################
set(DRIVER2013)
#Note: only on RF type is currently supported for RRH
add_executable(rrh_gw
${OPENAIR_TARGETS}/RT/USER/rrh_gw.c
${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
${HW_SOURCE}
)
# assert and common_lib.h
target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti ${OPENAIR_TARGETS}/ARCH/COMMON ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ )
target_link_libraries(rrh_gw
-Wl,--start-group
UTIL LFDS
-Wl,--end-group )
target_link_libraries (rrh_gw rt pthread m )
target_link_libraries (rrh_gw ${option_HW_lib} ${LIBBOOST_LIBRARIES} )
#Message("-- default_HW_lib=ETHERNET") # only in case of RRH
Message("-- option_HW_lib=${option_HW_lib}")
Message("-- HW_SOURCE=${HW_SOURCE}")
# USIM process # USIM process
################# #################
#add_executable(usim #add_executable(usim
......
...@@ -34,7 +34,7 @@ mkdir -p $tdir/bin $tdir/log ...@@ -34,7 +34,7 @@ mkdir -p $tdir/bin $tdir/log
updated=$(svn st -q $OPENAIR_DIR) updated=$(svn st -q $OPENAIR_DIR)
if [ "$updated" != "" ] ; then if [ "$updated" != "" ] ; then
echo_warning "some files are not in svn: $updated" echo_warning "some files are not in svn:\n $updated"
fi fi
cd $tdir cd $tdir
...@@ -83,5 +83,9 @@ test_compile \ ...@@ -83,5 +83,9 @@ test_compile \
test.0120 nasmesh \ test.0120 nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $tdir/bin/nasmesh.ko CMakeFiles/nasmesh/nasmesh.ko $tdir/bin/nasmesh.ko
test_compile \
test.0130 rrh_gw \
rrh_gw $tdir/bin/rrh_gw
# write the test results into a file # write the test results into a file
xUnit_write "$tdir/log/compilation_autotests.xml" xUnit_write "$tdir/log/compilation_autotests.xml"
cmake_minimum_required(VERSION 2.8)
set(ENABLE_VCD_FIFO False )
set(ENABLE_ITTI False )
set(RF_BOARD "ETHERNET")
set(PACKAGE_NAME "\"rrh_gw\"")
include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt)
...@@ -75,11 +75,13 @@ Options ...@@ -75,11 +75,13 @@ Options
Makes the UE specific parts (ue_ip, usim, nvram) Makes the UE specific parts (ue_ip, usim, nvram)
--EPC --EPC
Makes the EPC (MME-SPGW, HSS) Makes the EPC (MME-SPGW, HSS)
--RRH
Makes the RRH
-r | --3gpp-release -r | --3gpp-release
default is Rel10, default is Rel10,
Rel8 limits the implementation to 3GPP Release 8 version Rel8 limits the implementation to 3GPP Release 8 version
-w | --hardware -w | --hardware
EXMIMO (Default), USRP, BLADERF, None EXMIMO (Default), USRP, BLADERF, ETHERNET, None
Adds this RF board support (in external packages installation and in compilation) Adds this RF board support (in external packages installation and in compilation)
--oaisim --oaisim
Makes the oaisim simulator. Hardware will be defaulted to "NONE". Makes the oaisim simulator. Hardware will be defaulted to "NONE".
...@@ -147,6 +149,10 @@ function main() { ...@@ -147,6 +149,10 @@ function main() {
EPC=1 EPC=1
echo_info "Will compile EPC" echo_info "Will compile EPC"
shift;; shift;;
--RRH)
RRH=1
echo_info "Will compile RRH"
shift;;
-r | --3gpp-release) -r | --3gpp-release)
REL=$2 REL=$2
echo_info "setting release to: $REL" echo_info "setting release to: $REL"
...@@ -497,6 +503,32 @@ function main() { ...@@ -497,6 +503,32 @@ function main() {
# oaisim_mme $dbin/oaisim_mme.$REL # oaisim_mme $dbin/oaisim_mme.$REL
fi fi
# RRH compilation
##################
if [ "$RRH" = "1" ] ; then
echo_info "Compiling RRH"
if [ $HW == "ETHERNET" ] ; then
echo_info "RF frontend for RRH is not defined. This mode is used for testing (loopback)."
elif [ $HW != "EXMIMO" -a $HW != "OAI_USRP" -a $HW != "OAI_BLADERF" ] ; then
echo_fatal "Hardware not defined ($HW)"
fi
cmake_file=$DIR/rrh_gw/CMakeLists.txt
echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file
echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file
echo "set(ENABLE_ITTI False )" >> $cmake_file
echo "set(RF_BOARD \"${HW}\")" >> $cmake_file
echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
[ "$CLEAN" = "1" ] && rm -rf $DIR/rrh_gw/build
mkdir -p $DIR/rrh_gw/build
cd $DIR/rrh_gw/build
cmake ..
compilations \
rrh_gw rrh_gw \
rrh_gw $dbin/rrh_gw
fi
# EPC compilation # EPC compilation
################## ##################
if [ "$EPC" = "1" ] ; then if [ "$EPC" = "1" ] ; then
......
cmake_minimum_required(VERSION 2.8)
set(ENABLE_VCD_FIFO False )
set(ENABLE_ITTI False )
set(RF_BOARD "ETHERNET")
set(PACKAGE_NAME "\"rrh_gw\"")
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
...@@ -39,10 +39,12 @@ double get_cpu_freq_GHz(void) { ...@@ -39,10 +39,12 @@ double get_cpu_freq_GHz(void) {
time_stats_t ts = {0}; time_stats_t ts = {0};
reset_meas(&ts); reset_meas(&ts);
start_meas(&ts); ts.trials++;
ts.in = rdtsc_oai();
sleep(1); sleep(1);
stop_meas(&ts); ts.diff = (rdtsc_oai()-ts.in);
cpu_freq_GHz = (double)ts.diff/1000000000; cpu_freq_GHz = (double)ts.diff/1000000000;
printf("CPU Freq is %f \n", cpu_freq_GHz);
return cpu_freq_GHz; return cpu_freq_GHz;
} }
......
...@@ -43,8 +43,8 @@ double cpu_freq_GHz; ...@@ -43,8 +43,8 @@ double cpu_freq_GHz;
typedef struct { typedef struct {
long long in; long long in;
long long diff_now;
long long diff; long long diff;
long long diff_now;
long long p_time; /*!< \brief absolute process duration */ long long p_time; /*!< \brief absolute process duration */
long long diff_square; /*!< \brief process duration square */ long long diff_square; /*!< \brief process duration square */
long long max; long long max;
...@@ -116,6 +116,7 @@ static inline void stop_meas(time_stats_t *ts) ...@@ -116,6 +116,7 @@ static inline void stop_meas(time_stats_t *ts)
ts->diff_now = (out-ts->in); ts->diff_now = (out-ts->in);
ts->diff_now = (out-ts->in);
ts->diff += (out-ts->in); ts->diff += (out-ts->in);
/// process duration is the difference between two clock points /// process duration is the difference between two clock points
ts->p_time = (out-ts->in); ts->p_time = (out-ts->in);
...@@ -127,25 +128,17 @@ static inline void stop_meas(time_stats_t *ts) ...@@ -127,25 +128,17 @@ static inline void stop_meas(time_stats_t *ts)
} }
} }
static inline void reset_meas(time_stats_t *ts) static inline void reset_meas(time_stats_t *ts) {
{
static int cpu_freq_set=0; static int cpu_freq_set=0;
if (opp_enabled) {
ts->trials=0; ts->trials=0;
ts->diff_now=0;
ts->diff=0; ts->diff=0;
ts->diff_now=0;
ts->p_time=0; ts->p_time=0;
ts->diff_square=0; ts->diff_square=0;
ts->max=0; ts->max=0;
if (cpu_freq_set == 0) {
cpu_freq_set = 1;
get_cpu_freq_GHz();
printf("CPU Freq is %f \n", cpu_freq_GHz);
}
}
} }
static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts)
......
...@@ -399,6 +399,14 @@ int logInit (void) ...@@ -399,6 +399,14 @@ int logInit (void)
g_log->log_component[SCTP].filelog = 0; g_log->log_component[SCTP].filelog = 0;
g_log->log_component[SCTP].filelog_name = ""; g_log->log_component[SCTP].filelog_name = "";
g_log->log_component[RRH].name = "RRH";
g_log->log_component[RRH].level = LOG_EMERG;
g_log->log_component[RRH].flag = LOG_MED;
g_log->log_component[RRH].interval = 1;
g_log->log_component[RRH].fd = 0;
g_log->log_component[RRH].filelog = 0;
g_log->log_component[RRH].filelog_name = "";
g_log->level2string[LOG_EMERG] = "G"; //EMERG g_log->level2string[LOG_EMERG] = "G"; //EMERG
g_log->level2string[LOG_ALERT] = "A"; // ALERT g_log->level2string[LOG_ALERT] = "A"; // ALERT
g_log->level2string[LOG_CRIT] = "C"; // CRITIC g_log->level2string[LOG_CRIT] = "C"; // CRITIC
......
...@@ -267,6 +267,7 @@ typedef enum { ...@@ -267,6 +267,7 @@ typedef enum {
TMR, TMR,
USIM, USIM,
LOCALIZE, LOCALIZE,
RRH,
MAX_LOG_COMPONENTS, MAX_LOG_COMPONENTS,
} }
comp_name_t; comp_name_t;
......
...@@ -77,6 +77,8 @@ struct vcd_module_s { ...@@ -77,6 +77,8 @@ struct vcd_module_s {
const char* eurecomVariablesNames[] = { const char* eurecomVariablesNames[] = {
"frame_number_TX_eNB", "frame_number_TX_eNB",
"frame_number_RX_eNB", "frame_number_RX_eNB",
"runtime_TX_eNB",
"runtime_RX_eNB",
"frame_number_TX_UE", "frame_number_TX_UE",
"frame_number_RX_UE", "frame_number_RX_UE",
"slot_number_TX_UE", "slot_number_TX_UE",
...@@ -94,6 +96,13 @@ const char* eurecomVariablesNames[] = { ...@@ -94,6 +96,13 @@ const char* eurecomVariablesNames[] = {
"rxcnt", "rxcnt",
"trx_ts", "trx_ts",
"trx_tst", "trx_tst",
"tx_ts",
"rx_ts",
"hw_cnt_rx",
"lhw_cnt_rx",
"hw_cnt_tx",
"lhw_cnt_tx",
"pck_rx",
"dummy_dump", "dummy_dump",
"itti_send_msg", "itti_send_msg",
"itti_poll_msg", "itti_poll_msg",
...@@ -133,6 +142,15 @@ const char* eurecomFunctionsNames[] = { ...@@ -133,6 +142,15 @@ const char* eurecomFunctionsNames[] = {
"ue_thread_tx", "ue_thread_tx",
"ue_thread_rx", "ue_thread_rx",
/* RRH signals */
"eNB_tx",
"eNB_rx",
"eNB_trx",
"eNB_tm",
"eNB_rx_sleep",
"eNB_tx_sleep",
"eNB_proc_sleep",
/* PHY signals */ /* PHY signals */
"ue_synch", "ue_synch",
"ue_slot_fep", "ue_slot_fep",
......
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
typedef enum { typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB = 0, VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB = 0,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_UE, VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_UE, VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX_UE, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX_UE,
...@@ -66,6 +68,13 @@ typedef enum { ...@@ -66,6 +68,13 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,
VCD_SIGNAL_DUMPER_VARIABLES_TX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_RX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TX_HWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP, VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG, VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG, VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG,
...@@ -107,6 +116,16 @@ typedef enum { ...@@ -107,6 +116,16 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RX, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RX,
/* RRH signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TM,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_SLEEP,
/* PHY signals */ /* PHY signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP,
......
...@@ -132,7 +132,7 @@ int trx_brf_end(openair0_device *device) { ...@@ -132,7 +132,7 @@ int trx_brf_end(openair0_device *device) {
return 0; return 0;
} }
//int openair0_device_brf_init(openair0_device *device, openair0_config_t *openair0_cfg) { //int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) {
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) { int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
int status; int status;
...@@ -263,15 +263,27 @@ int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cf ...@@ -263,15 +263,27 @@ int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cf
return 0; return 0;
} }
void brf_error(int status) { int brf_error(int status) {
exit(-1); exit(-1);
//return 1; // or status error code
} }
int openair0_stop(int card) { int openair0_stop(int card) {
return(0); return(0);
}
int openair0_print_stats(openair0_device* device) {
return(0);
}
int openair0_reset_stats(openair0_device* device) {
return(0);
} }
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int dummy) { int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int dummy) {
return 0; return 0;
......
...@@ -78,4 +78,4 @@ typedef struct { ...@@ -78,4 +78,4 @@ typedef struct {
* func prototypes * func prototypes
*/ */
void brf_error(int status); int brf_error(int status);
...@@ -26,16 +26,23 @@ ...@@ -26,16 +26,23 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/ *******************************************************************************/
/*! \file common_lib.h
* \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
/** common_lib.h
*
* Author: HongliangXU : hong-liang-xu@agilent.com
*/
#ifndef COMMON_LIB_H #ifndef COMMON_LIB_H
#define COMMON_LIB_H #define COMMON_LIB_H
#include <stdint.h> #include <stdint.h>
typedef int64_t openair0_timestamp; typedef int64_t openair0_timestamp;
typedef volatile int64_t openair0_vtimestamp;
typedef struct openair0_device_t openair0_device; typedef struct openair0_device_t openair0_device;
/* structrue holds the parameters to configure USRP devices /* structrue holds the parameters to configure USRP devices
*/ */
...@@ -56,10 +63,18 @@ typedef struct { ...@@ -56,10 +63,18 @@ typedef struct {
int Mod_id; int Mod_id;
// device log level // device log level
int log_level; int log_level;
//! number of downlink resource blocks
int num_rb_dl;
//! number of samples per frame
unsigned int samples_per_frame;
//! the sample rate for both transmit and receive. //! the sample rate for both transmit and receive.
double sample_rate; double sample_rate;
//! number of samples per RX/TX packet (USRP + Ethernet) //! number of samples per RX/TX packet (USRP + Ethernet)
int samples_per_packet; int samples_per_packet;
// delay in sending samples (write) due to hardware access, softmodem processing and fronthaul delay if exist
int tx_delay;
//! adjust the position of the samples after delay when sending
unsigned int tx_forward_nsamps;
//! number of RX channels (=RX antennas) //! number of RX channels (=RX antennas)
int rx_num_channels; int rx_num_channels;
//! number of TX channels (=TX antennas) //! number of TX channels (=TX antennas)
...@@ -84,9 +99,14 @@ typedef struct { ...@@ -84,9 +99,14 @@ typedef struct {
//! Auto calibration flag //! Auto calibration flag
int autocal[4]; int autocal[4];
//! RRH IP addr for Ethernet interface //! RRH IP addr for Ethernet interface
char *rrh_ip; char *remote_ip;
//! RRH port number for Ethernet interface //! RRH port number for Ethernet interface
int rrh_port; int remote_port;
//! my IP addr for Ethernet interface (eNB/BBU, UE)
char *my_ip;
//! my port number for Ethernet interface (eNB/BBU, UE)
int my_port;
} openair0_config_t; } openair0_config_t;
typedef struct { typedef struct {
...@@ -98,10 +118,42 @@ typedef struct { ...@@ -98,10 +118,42 @@ typedef struct {
/*!\brief device type */
typedef enum {
MIN_DEV_TYPE = 0,
/*!\brief device is ETH */
ETH_IF,
/*!\brief device is ExpressMIMO */
EXMIMO_IF,
/*!\brief device is USRP*/
USRP_IF,
/*!\brief device is BLADE RF*/
BLADERF_IF,
/*!\brief device is NONE*/
NONE_IF,
MAX_DEV_TYPE
} dev_type_t;
/*!\brief type */
typedef enum {
MIN_FUNC_TYPE = 0,
BBU_FUNC,
RRH_FUNC,
MAX_FUNC_TYPE
}func_type_t;
struct openair0_device_t { struct openair0_device_t {
/* Module ID of this device */ /* Module ID of this device */
int Mod_id; int Mod_id;
/* Type of this device */
func_type_t func_type;
/* Type of this device */
dev_type_t type;
/* RF frontend parameters set by application */ /* RF frontend parameters set by application */
openair0_config_t openair0_cfg; openair0_config_t openair0_cfg;
...@@ -113,11 +165,20 @@ struct openair0_device_t { ...@@ -113,11 +165,20 @@ struct openair0_device_t {
/* Called to start the transceiver. Return 0 if OK, < 0 if error */ /* Called to start the transceiver. Return 0 if OK, < 0 if error */
int (*trx_start_func)(openair0_device *device); int (*trx_start_func)(openair0_device *device);
/* Called to initiate transceiver threads */
void (*trx_thread_func)(openair0_device *device, unsigned int rt_period, uint8_t RT_flag,uint8_t NRT_flag);
/* Called to request connection from the transceiver/RRH. Return 0 if OK, < 0 if error */
int (*trx_request_func)(openair0_device *device);
/* Called to reply back to connection state to eNB/BBU. Return 0 if OK, < 0 if error */
int (*trx_reply_func)(openair0_device *openair0);
/* Write 'nsamps' samples on each channel from buffers. buff[0] is the array for /* Write 'nsamps' samples on each channel from buffers. buff[0] is the array for
* the first channel. timestamp if the time (in samples) at which the first sample * the first channel. timestamp if the time (in samples) at which the first sample
* MUST be sent * MUST be sent
* use flags = 1 to send as timestamp specfied*/ * use flags = 1 to send as timestamp specfied*/
void (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags); int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
/*! \brief Receive samples from hardware. /*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
...@@ -130,7 +191,19 @@ struct openair0_device_t { ...@@ -130,7 +191,19 @@ struct openair0_device_t {
* \param cc Number of channels. If cc == 1, only buff[0] is filled with samples. * \param cc Number of channels. If cc == 1, only buff[0] is filled with samples.
* \returns the number of sample read * \returns the number of sample read
*/ */
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int cc); int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
/*! \brief print the device statistics
* \param device the hardware to use
* \returns 0 on success
*/
int (*trx_get_stats_func)(openair0_device *device);
/*! \brief Reset device statistics
* \param device the hardware to use
* \returns 0 in success
*/
int (*trx_reset_stats_func)(openair0_device *device);
/* Terminate operation of the transceiver -- free all associated resources */ /* Terminate operation of the transceiver -- free all associated resources */
void (*trx_end_func)(openair0_device *device); void (*trx_end_func)(openair0_device *device);
...@@ -142,15 +215,33 @@ extern "C" ...@@ -142,15 +215,33 @@ extern "C"
{ {
#endif #endif
/* return 0 if OK, < 0 if error */ /* return 0 if OK */
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
openair0_timestamp get_usrp_time(openair0_device *device); int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config); openair0_timestamp get_usrp_time(openair0_device *device);
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
//EXMIMO
//int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg);
//USPRP
//int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg);
//BLADERF
//int openair0_dev_init_bladerf(openair0_device* device, openair0_config_t *openair0_cfg);
//ETHERNET
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_set_gains(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_print_stats(openair0_device* device);
int openair0_reset_stats(openair0_device* device);
int openair0_set_gains(openair0_device* device, openair0_config_t *openair0_cfg); int openair0_stop(int card);
int openair0_stop(int card);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file ethernet_lib.h
* \brief API to stream I/Q samples over standard ethernet
* \author Katerina Trilyraki, Navid Nikaein
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <stdio.h> #include <stdio.h>
...@@ -8,8 +47,75 @@ ...@@ -8,8 +47,75 @@
#include <net/if.h> #include <net/if.h>
#include <netinet/ether.h> #include <netinet/ether.h>
int ethernet_socket_init(int Mod_id, char *dest_ip,int dest_port);
int ethernet_write_data(int Mod_id, const void *buff, int nsamps,int cc); typedef struct {
// opaque eth data struct
//struct eth_if *dev;
// An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend)
int sockfd[4];
struct sockaddr_in dest_addr[4];
unsigned int buffer_size;
unsigned int timeout_ns;
//struct eth_metadata meta_rx;
//struct eth_metadata meta_tx;
unsigned int sample_rate;
// time offset between transmiter timestamp and receiver timestamp;
double tdiff;
// use brf_time_offset to get this value
int tx_forward_nsamps; //166 for 20Mhz
// --------------------------------
// Debug and output control
// --------------------------------
int num_underflows;
int num_overflows;
int num_seq_errors;
int num_rx_errors;
int num_tx_errors;
uint64_t tx_actual_nsamps; // actual number of samples transmitted
uint64_t rx_actual_nsamps;
uint64_t tx_nsamps; // number of planned samples
uint64_t rx_nsamps;
uint64_t tx_count; // number pf packets
uint64_t rx_count;
//openair0_timestamp rx_timestamp;
} eth_state_t;
#define ETH_META_STATUS_OVERRUN (1 << 0)
#define ETH_META_STATUS_UNDERRUN (1 << 1)
struct eth_meta_data{
uint64_t timestamp;
uint32_t flags;
uint32_t status;
unsigned int actual_count;
};
typedef struct {
/* packet's timestamp */
openair0_timestamp timestamp;
/* variable declared for alignment purposes (sample size=32 bit) */
int16_t not_used;
/* antenna port used to resynchronize*/
int16_t antenna_id;
} header_t;
int ethernet_socket_init(openair0_device *device);
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id);
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int antenna_id);
int ethernet_read_data(int Mod_id,void *buff, int nsamps,int cc); void ethernet_socket_opt (openair0_device *device);
...@@ -247,6 +247,7 @@ int openair0_stop_without_reset(int card) ...@@ -247,6 +247,7 @@ int openair0_stop_without_reset(int card)
#define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX) #define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX)
#define RF_MODE_BASE (LNA1ON + RFBBNORM) #define RF_MODE_BASE (LNA1ON + RFBBNORM)
//int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg) {
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) { int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// Initialize card // Initialize card
......
...@@ -44,8 +44,10 @@ ...@@ -44,8 +44,10 @@
#include <complex> #include <complex>
#include <fstream> #include <fstream>
#include <cmath> #include <cmath>
#include "common_lib.h" #include "common_lib.h"
typedef struct typedef struct
{ {
...@@ -121,7 +123,7 @@ static void trx_usrp_end(openair0_device *device) ...@@ -121,7 +123,7 @@ static void trx_usrp_end(openair0_device *device)
s->tx_stream->send("", 0, s->tx_md); s->tx_stream->send("", 0, s->tx_md);
s->tx_md.end_of_burst = false; s->tx_md.end_of_burst = false;
} }
static void trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{ {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate);
...@@ -138,6 +140,8 @@ static void trx_usrp_write(openair0_device *device, openair0_timestamp timestamp ...@@ -138,6 +140,8 @@ static void trx_usrp_write(openair0_device *device, openair0_timestamp timestamp
else else
s->tx_stream->send(buff[0], nsamps, s->tx_md); s->tx_stream->send(buff[0], nsamps, s->tx_md);
s->tx_md.start_of_burst = false; s->tx_md.start_of_burst = false;
return 0;
} }
static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc)
...@@ -195,7 +199,7 @@ static bool is_equal(double a, double b) ...@@ -195,7 +199,7 @@ static bool is_equal(double a, double b)
return std::fabs(a-b) < std::numeric_limits<double>::epsilon(); return std::fabs(a-b) < std::numeric_limits<double>::epsilon();
} }
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int dummy) { int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
...@@ -237,7 +241,17 @@ int openair0_stop(int card) { ...@@ -237,7 +241,17 @@ int openair0_stop(int card) {
return(0); return(0);
} }
int openair0_print_stats(openair0_device* device) {
return(0);
}
int openair0_reset_stats(openair0_device* device) {
return(0);
}
//int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg)
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg) int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg)
{ {
uhd::set_thread_priority_safe(1.0); uhd::set_thread_priority_safe(1.0);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -119,8 +119,8 @@ extern int oai_exit; ...@@ -119,8 +119,8 @@ extern int oai_exit;
extern int32_t **rxdata; extern int32_t **rxdata;
extern int32_t **txdata; extern int32_t **txdata;
extern unsigned int tx_forward_nsamps; //extern unsigned int tx_forward_nsamps;
extern int tx_delay; //extern int tx_delay;
extern int rx_input_level_dBm; extern int rx_input_level_dBm;
extern uint8_t exit_missed_slots; extern uint8_t exit_missed_slots;
...@@ -583,9 +583,9 @@ static void *UE_thread_tx(void *arg) ...@@ -583,9 +583,9 @@ static void *UE_thread_tx(void *arg)
/* This creates a 1ms reservation every 10ms period*/ /* This creates a 1ms reservation every 10ms period*/
attr.sched_policy = SCHED_DEADLINE; attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 1 * 900000; // each tx thread requires .5ms to finish its job attr.sched_runtime = (0.9 * 100) * 10000; // each tx thread requires .5ms to finish its job
attr.sched_deadline =1 * 1000000; // each tx thread will finish within 1ms attr.sched_deadline = (1 * 100) * 10000; // each tx thread will finish within 1ms
attr.sched_period = 1 * 1000000; // each tx thread has a period of 1ms from the starting point attr.sched_period = (1 * 100) * 10000; // each tx thread has a period of 1ms from the starting point
if (sched_setattr(0, &attr, flags) < 0 ) { if (sched_setattr(0, &attr, flags) < 0 ) {
...@@ -732,9 +732,9 @@ static void *UE_thread_rx(void *arg) ...@@ -732,9 +732,9 @@ static void *UE_thread_rx(void *arg)
// This creates a .5ms reservation every 1ms period // This creates a .5ms reservation every 1ms period
attr.sched_policy = SCHED_DEADLINE; attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 1 * 900000; // each rx thread requires 1ms to finish its job attr.sched_runtime = (0.9 * 100) * 10000;//900000; // each rx thread requires 1ms to finish its job
attr.sched_deadline =1 * 1000000; // each rx thread will finish within 1ms attr.sched_deadline = (1 * 100) * 10000; // each rx thread will finish within 1ms
attr.sched_period = 1 * 1000000; // each rx thread has a period of 1ms from the starting point attr.sched_period = (1 * 100) * 10000; // each rx thread has a period of 1ms from the starting point
if (sched_setattr(0, &attr, flags) < 0 ) { if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] UE_thread_rx : sched_setattr failed\n"); perror("[SCHED] UE_thread_rx : sched_setattr failed\n");
...@@ -938,7 +938,7 @@ void *UE_thread(void *arg) ...@@ -938,7 +938,7 @@ void *UE_thread(void *arg)
static int UE_thread_retval; static int UE_thread_retval;
PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
int spp = openair0_cfg[0].samples_per_packet; int spp = openair0_cfg[0].samples_per_packet;
int slot=1, frame=0, hw_subframe=0, rxpos=0, txpos=spp*tx_delay; int slot=1, frame=0, hw_subframe=0, rxpos=0, txpos=spp*openair0_cfg[0].tx_delay;
int dummy[2][spp]; int dummy[2][spp];
int dummy_dump = 0; int dummy_dump = 0;
int tx_enabled = 0; int tx_enabled = 0;
...@@ -972,9 +972,9 @@ void *UE_thread(void *arg) ...@@ -972,9 +972,9 @@ void *UE_thread(void *arg)
// This creates a .5 ms reservation // This creates a .5 ms reservation
attr.sched_policy = SCHED_DEADLINE; attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 0.25 * 1000000; attr.sched_runtime = (0.25 * 100) * 10000;
attr.sched_deadline = 0.25 * 1000000; attr.sched_deadline = (0.25 * 100) * 10000;
attr.sched_period = 0.5 * 1000000; attr.sched_period = (0.5 * 100) * 10000;
if (sched_setattr(0, &attr, flags) < 0 ) { if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] main eNB thread: sched_setattr failed\n"); perror("[SCHED] main eNB thread: sched_setattr failed\n");
...@@ -1056,7 +1056,7 @@ void *UE_thread(void *arg) ...@@ -1056,7 +1056,7 @@ void *UE_thread(void *arg)
txp[i] = (void*)&txdata[i][txpos]; txp[i] = (void*)&txdata[i][txpos];
openair0.trx_write_func(&openair0, openair0.trx_write_func(&openair0,
(timestamp+spp*tx_delay-tx_forward_nsamps), (timestamp+spp*openair0_cfg[0].tx_delay-openair0_cfg[0].tx_forward_nsamps),
txp, txp,
spp - ((first_rx==1) ? rx_off_diff : 0), spp - ((first_rx==1) ? rx_off_diff : 0),
UE->lte_frame_parms.nb_antennas_tx, UE->lte_frame_parms.nb_antennas_tx,
...@@ -1353,9 +1353,9 @@ void *UE_thread(void *arg) ...@@ -1353,9 +1353,9 @@ void *UE_thread(void *arg)
// This creates a .25 ms reservation // This creates a .25 ms reservation
attr.sched_policy = SCHED_DEADLINE; attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 0.1 * 1000000; attr.sched_runtime = (0.1 * 100) * 10000;
attr.sched_deadline = 0.25 * 1000000; attr.sched_deadline = (0.25 * 100) * 10000;
attr.sched_period = 0.5 * 1000000; attr.sched_period = (0.5 * 100) * 10000;
// pin the UE main thread to CPU0 // pin the UE main thread to CPU0
// if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) { // if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) {
......
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Thu Jul 9 09:53:25 2015
[*]
[dumpfile] "/tmp/openair_dump_eNB.vcd"
[dumpfile_mtime] "Thu Jul 9 09:52:29 2015"
[dumpfile_size] 170586112
[savefile] "/home/sud/openair4G/targets/RT/USER/eNB2.gtkw"
[timestart] 16177999000
[size] 1535 876
[pos] -1 -1
*-17.749426 16178576148 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 224
[signals_width] 230
[sst_expanded] 1
[sst_vpaned_height] 230
@28
[color] 1
functions.eNB_rx
functions.eNB_rx_sleep
[color] 7
functions.trx_write
@c00024
variables.rxcnt[63:0]
@28
(0)variables.rxcnt[63:0]
(1)variables.rxcnt[63:0]
(2)variables.rxcnt[63:0]
(3)variables.rxcnt[63:0]
(4)variables.rxcnt[63:0]
(5)variables.rxcnt[63:0]
(6)variables.rxcnt[63:0]
(7)variables.rxcnt[63:0]
(8)variables.rxcnt[63:0]
(9)variables.rxcnt[63:0]
(10)variables.rxcnt[63:0]
(11)variables.rxcnt[63:0]
(12)variables.rxcnt[63:0]
(13)variables.rxcnt[63:0]
(14)variables.rxcnt[63:0]
(15)variables.rxcnt[63:0]
(16)variables.rxcnt[63:0]
(17)variables.rxcnt[63:0]
(18)variables.rxcnt[63:0]
(19)variables.rxcnt[63:0]
(20)variables.rxcnt[63:0]
(21)variables.rxcnt[63:0]
(22)variables.rxcnt[63:0]
(23)variables.rxcnt[63:0]
(24)variables.rxcnt[63:0]
(25)variables.rxcnt[63:0]
(26)variables.rxcnt[63:0]
(27)variables.rxcnt[63:0]
(28)variables.rxcnt[63:0]
(29)variables.rxcnt[63:0]
(30)variables.rxcnt[63:0]
(31)variables.rxcnt[63:0]
(32)variables.rxcnt[63:0]
(33)variables.rxcnt[63:0]
(34)variables.rxcnt[63:0]
(35)variables.rxcnt[63:0]
(36)variables.rxcnt[63:0]
(37)variables.rxcnt[63:0]
(38)variables.rxcnt[63:0]
(39)variables.rxcnt[63:0]
(40)variables.rxcnt[63:0]
(41)variables.rxcnt[63:0]
(42)variables.rxcnt[63:0]
(43)variables.rxcnt[63:0]
(44)variables.rxcnt[63:0]
(45)variables.rxcnt[63:0]
(46)variables.rxcnt[63:0]
(47)variables.rxcnt[63:0]
(48)variables.rxcnt[63:0]
(49)variables.rxcnt[63:0]
(50)variables.rxcnt[63:0]
(51)variables.rxcnt[63:0]
(52)variables.rxcnt[63:0]
(53)variables.rxcnt[63:0]
(54)variables.rxcnt[63:0]
(55)variables.rxcnt[63:0]
(56)variables.rxcnt[63:0]
(57)variables.rxcnt[63:0]
(58)variables.rxcnt[63:0]
(59)variables.rxcnt[63:0]
(60)variables.rxcnt[63:0]
(61)variables.rxcnt[63:0]
(62)variables.rxcnt[63:0]
(63)variables.rxcnt[63:0]
@1401200
-group_end
@28
[color] 1
functions.eNB_tx
functions.eNB_tx_sleep
[color] 7
functions.trx_read
@24
variables.txcnt[63:0]
variables.rx_ts[63:0]
variables.tx_ts[63:0]
variables.pck_rx[63:0]
variables.hw_cnt_rx[63:0]
variables.lhw_cnt_rx[63:0]
variables.hw_frame[63:0]
@28
functions.eNB_tm
@29
functions.eNB_trx
[pattern_trace] 1
[pattern_trace] 0
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file rrh_gw.h
* \brief header file for remote radio head gateway (RRH_gw) module
* \author Navid Nikaein, Katerina Trilyraki, Raymond Knopp
* \date 2015
* \version 0.1
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning very experimental
*/
#ifndef RRH_GW_H_
#define RRH_GW_H_
#include "ethernet_lib.h"
#include "vcd_signal_dumper.h"
#include "assertions.h"
#define DEFAULT_PERIOD_NS 200000
#define RRH_UE_PORT 51000
#define RRH_UE_DEST_IP "127.0.0.1"
/*! \brief RRH supports two types of modules: eNB and UE
each module is associated a device of type ETH_IF
and optionally with another device (USRP/BLADERF/EXMIMO) */
typedef struct {
//! module id
uint8_t id;
//! loopback flag
uint8_t loopback;
//! measurement flag
uint8_t measurements;
//! module's ethernet device
openair0_device eth_dev;
//! pointer to RF module's device (pointer->since its optional)
openair0_device *devs;
}rrh_module_t;
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
void signal_handler(int sig);
void timer_signal_handler(int);
void *timer_proc(void *);
void create_timer_thread(void);
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
void create_UE_trx_threads( rrh_module_t *dev_ue, uint8_t RT_flag, uint8_t NRT_flag);
void create_eNB_trx_threads( rrh_module_t *dev_enb, uint8_t RT_flag, uint8_t NRT_flag);
#endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file rrh_gw_extern.h
* \brief rrh gatewy external vars
* \author Navid Nikaein, Katerina Trilyraki, Raymond Knopp
* \date 2015
* \version 0.1
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning very experimental
*/
#ifndef RRH_GW_EXTERNS_H_
#define RRH_GW_EXTERNS_H_
extern openair0_timestamp timestamp_UE_tx[4] ,timestamp_UE_rx[4] ,timestamp_eNB_rx[4],timestamp_eNB_tx[4];
extern openair0_vtimestamp hw_counter;
extern int32_t UE_tx_started,UE_rx_started,eNB_rx_started ,eNB_tx_started;
extern int32_t nsamps_UE[4],nsamps_eNB[4];
extern int32_t overflow_rx_buffer_eNB[4],overflow_rx_buffer_UE[4];
extern uint8_t rrh_exit;
extern int32_t **rx_buffer_eNB, **rx_buffer_UE;
extern unsigned int rt_period;
#endif
...@@ -28,17 +28,51 @@ ...@@ -28,17 +28,51 @@
*******************************************************************************/ *******************************************************************************/
/*! \file rt_wrapper.h /*! \file rt_wrapper.h
* \brief provides a wrapper for the timing function for real-time opeartions depending on weather RTAI is used or not * \brief provides a wrapper for the timing function, runtime calculations for real-time opeartions depending on weather RTAI or LOWLATENCY kernels are used or not
* \author F. Kaltenberger * \author F. Kaltenberger and Navid Nikaein
* \date 2013 * \date 2013
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: florian.kaltenberger@eurecom.fr * \email: florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
* \note * \note
* \warning * \warning
*/ */
#include "rt_wrapper.h" #include "rt_wrapper.h"
static int latency_target_fd = -1;
static int32_t latency_target_value = 0;
/* Latency trick - taken from cyclictest.c
* if the file /dev/cpu_dma_latency exists,
* open it and write a zero into it. This will tell
* the power management system not to transition to
* a high cstate (in fact, the system acts like idle=poll)
* When the fd to /dev/cpu_dma_latency is closed, the behavior
* goes back to the system default.
*
* Documentation/power/pm_qos_interface.txt
*/
void set_latency_target(void) {
struct stat s;
int ret;
if (stat("/dev/cpu_dma_latency", &s) == 0) {
latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR);
if (latency_target_fd == -1)
return;
ret = write(latency_target_fd, &latency_target_value, 4);
if (ret == 0) {
printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
close(latency_target_fd);
return;
}
printf("# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
}
}
#ifndef RTAI #ifndef RTAI
...@@ -89,6 +123,135 @@ void check_clock(void) ...@@ -89,6 +123,135 @@ void check_clock(void)
} }
} }
uint16_t cell_processing_dl[6]={10,15,24,42,80,112};
uint16_t platform_processing_dl=20; // upperbound for GPP, LXC, DOCKER and KVM
uint16_t user_processing_dl_a[6]={2,4,5,7,10,12};
uint16_t user_processing_dl_b[6]={10, 15, 25, 70, 110, 150};
uint16_t user_processing_dl_err[6]={20, 40, 60, 90, 120, 160};
uint16_t protocol_processing_dl[6]={150, 250, 350, 450, 650, 800}; // assumption: max MCS 27 --> gives an upper bound for the transport block size : to be measured
uint16_t cell_processing_ul[6]={10,15,24,42,80,112};
uint16_t platform_processing_ul=30; // upperbound for GPP, LXC, DOCKER and KVM
uint16_t user_processing_ul_a[6]={5, 9, 12, 24, 33, 42};
uint16_t user_processing_ul_b[6]={20, 30, 40, 76, 140, 200};
uint16_t user_processing_ul_err[6]={15, 25, 32, 60, 80, 95};
uint16_t protocol_processing_ul[6]={100, 200, 300, 400, 550, 700}; // assumption: max MCS 16 --> gives an upper bound for the transport block size
int fill_modeled_runtime_table(uint16_t runtime_phy_rx[29][6],
uint16_t runtime_phy_tx[29][6]){
//double cpu_freq;
//cpu_freq = get_cpu_freq_GHz();
// target_dl_mcs
// target_ul_mcs
// frame_parms[0]->N_RB_DL
int i,j;
memset(runtime_phy_rx,0,sizeof(uint16_t)*29*6);
memset(runtime_phy_tx,0,sizeof(uint16_t)*29*6);
/* only the BBU/PHY procesing time */
for (i=0;i<29;i++){
for (j=0;j<6;j++){
runtime_phy_rx[i][j] = cell_processing_ul[j] + platform_processing_ul + user_processing_ul_err[j] + user_processing_ul_a[j]*i+ user_processing_ul_b[j];
runtime_phy_tx[i][j] = cell_processing_dl[j] + platform_processing_dl + user_processing_dl_err[j] + user_processing_dl_a[j]*i+ user_processing_dl_b[j];
}
}
}
// int runtime_upper_layers[6]; // values for different RBs
// int runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
// int runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
// target_dl_mcs
// target_ul_mcs
// frame_parms[0]->N_RB_DL
//runtime_upper_layers[6]; // values for different RBs
// int runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
// int runtime_phy_tx[29][6]
double get_runtime_tx(int tx_subframe, uint16_t runtime_phy_tx[29][6], uint32_t mcs, int N_RB_DL,double cpuf,int nb_tx_antenna){
int i;
double runtime;
//printf("cpuf =%lf \n",cpuf);
switch(N_RB_DL){
case 6:
i = 0;
break;
case 15:
i = 1;
break;
case 25:
i = 2;
break;
case 50:
i = 3;
break;
case 75:
i = 4;
break;
case 100:
i = 5;
break;
default:
i = 3;
break;
}
runtime = ( (3.2/cpuf)*(double)runtime_phy_tx[mcs][i] + (3.2/cpuf)*(double)protocol_processing_dl[i])/1000 ;
printf("Setting tx %d runtime value (ms) = %lf\n",tx_subframe,runtime);
return runtime;
}
double get_runtime_rx(int rx_subframe, uint16_t runtime_phy_rx[29][6], uint32_t mcs, int N_RB_DL,double cpuf,int nb_rx_antenna){
int i;
double runtime;
//printf("N_RB_DL=%d cpuf =%lf \n",N_RB_DL, cpuf);
switch(N_RB_DL){
case 6:
i = 0;
break;
case 15:
i = 1;
break;
case 25:
i = 2;
break;
case 50:
i = 3;
break;
case 75:
i = 4;
break;
case 100:
i = 5;
break;
default:
i = 3;
break;
}
runtime = ((3.2/cpuf)*(double)runtime_phy_rx[mcs][i] + (3.2/cpuf)*(double)protocol_processing_ul[i])/1000 ;
printf("Setting rx %d runtime value (ms) = %lf \n",rx_subframe, runtime);
return runtime;
}
#ifdef LOWLATENCY
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int sched_getattr(pid_t pid,struct sched_attr *attr,unsigned int size, unsigned int flags)
{
return syscall(__NR_sched_getattr, pid, attr, size, flags);
}
#endif
#else #else
int rt_sleep_ns(RTIME x) int rt_sleep_ns(RTIME x)
......
...@@ -38,13 +38,20 @@ ...@@ -38,13 +38,20 @@
* \warning This code will be removed when a legacy libc API becomes available. * \warning This code will be removed when a legacy libc API becomes available.
*/ */
void set_latency_target(void);
#ifndef RTAI #ifndef RTAI
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h> #include <pthread.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <syscall.h>
#include <math.h>
#define RTIME long long int #define RTIME long long int
...@@ -56,6 +63,11 @@ int rt_sleep_ns (RTIME x); ...@@ -56,6 +63,11 @@ int rt_sleep_ns (RTIME x);
void check_clock(void); void check_clock(void);
int fill_modeled_runtime_table(uint16_t runtime_phy_rx[29][6],uint16_t runtime_phy_tx[29][6]);
double get_runtime_tx(int tx_subframe, uint16_t runtime_phy_tx[29][6],uint32_t mcs, int N_RB_DL,double cpuf,int nb_tx_antenna);
double get_runtime_rx(int rx_subframe, uint16_t runtime_phy_rx[29][6], uint32_t mcs, int N_RB_DL,double cpuf,int nb_rx_antenna);
/** /**
* see https://www.kernel.org/doc/Documentation/scheduler/sched-deadline.txt or * see https://www.kernel.org/doc/Documentation/scheduler/sched-deadline.txt or
* http://www.blaess.fr/christophe/2014/04/05/utiliser-un-appel-systeme-inconnu-de-la-libc/ * http://www.blaess.fr/christophe/2014/04/05/utiliser-un-appel-systeme-inconnu-de-la-libc/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment