Added timing traces for phy/mac/radio classes.

This commit is contained in:
ismagom 2015-06-09 11:49:25 +02:00
parent f9b7b7827b
commit 033d50978b
15 changed files with 302 additions and 28 deletions

View File

@ -0,0 +1,19 @@
function [ tti, values ] = read_trace_uint( filename, count )
[tidin msg]=fopen(filename,'r');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (nargin==1)
count=inf;
end
x=fread(tidin,2*count,'uint');
i=1:2:length(x);
tti=x(i);
values=x(i+1);
end

View File

@ -26,12 +26,14 @@
*/
#include <pthread.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
bool threads_new_rt(pthread_t *thread, void *(*start_routine) (void*), void *arg);
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu);
bool threads_new_rt_prio(pthread_t *thread, void *(*start_routine) (void*), void *arg, uint32_t prio_offset);
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu, uint32_t prio_offset);
void threads_print_self();
#ifdef __cplusplus

View File

@ -0,0 +1,98 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 The srsLTE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE 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 Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <stdio.h>
#include <string>
#include <vector>
#ifndef TRACE_H
#define TRACE_H
namespace srslte {
template<class elemType>
class trace
{
public:
trace(uint32_t nof_elems_) : tti(nof_elems_), data(nof_elems_) {
rpm=0;
nof_elems=nof_elems_;
wrapped = false;
};
void push_cur_time_us(uint32_t cur_tti) {
struct timeval t;
gettimeofday(&t, NULL);
elemType us = t.tv_sec*1e6+t.tv_usec;
push(cur_tti, us);
}
void push(uint32_t value_tti, elemType value) {
tti[rpm] = value_tti;
data[rpm] = value;
rpm++;
if (rpm >= nof_elems) {
rpm = 0;
wrapped = true;
}
}
bool writeToBinary(std::string filename) {
FILE *f = fopen(filename.c_str(), "w");
if (f != NULL) {
uint32_t st=wrapped?(rpm+1):0;
do {
writeToBinaryValue(f, st++);
if (st >= nof_elems) {
st=0;
}
} while(st<rpm);
fclose(f);
return true;
} else {
perror("fopen");
return false;
}
}
private:
std::vector<uint32_t> tti;
std::vector<elemType> data;
uint32_t rpm;
uint32_t nof_elems;
bool wrapped;
void writeToBinaryValue(FILE *f, uint32_t idx) {
fwrite(&tti[idx], 1, sizeof(uint32_t), f);
fwrite(&data[idx], 1, sizeof(elemType), f);
}
};
}
#endif

View File

@ -35,15 +35,19 @@
#include "srsapps/common/threads.h"
bool threads_new_rt(pthread_t *thread, void *(*start_routine) (void*), void *arg) {
return threads_new_rt_cpu(thread, start_routine, arg, -1);
return threads_new_rt_prio(thread, start_routine, arg, 0);
}
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu) {
bool threads_new_rt_prio(pthread_t *thread, void *(*start_routine) (void*), void *arg, uint32_t prio_offset) {
return threads_new_rt_cpu(thread, start_routine, arg, -1, prio_offset);
}
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu, uint32_t prio_offset) {
bool ret = false;
pthread_attr_t attr;
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
param.sched_priority = sched_get_priority_max(SCHED_FIFO) - prio_offset;
pthread_attr_init(&attr);
if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {

View File

@ -30,6 +30,7 @@
#include "srsapps/radio/radio.h"
#include "srslte/srslte.h"
#include "srslte/cuhd/cuhd.h"
#include "srsapps/common/trace.h"
#ifndef RADIO_UHD_H
#define RADIO_UHD_H
@ -42,6 +43,7 @@ namespace srslte {
class radio_uhd : public radio
{
public:
radio_uhd() : tr_local_time(1024*10), tr_usrp_time(1024*10), tr_tx_time(1024*10), tr_is_eob(1024*10) {};
bool init();
bool init(char *args);
bool init_agc();
@ -67,15 +69,19 @@ namespace srslte {
float get_tx_gain();
float get_rx_gain();
void start_trace();
void write_trace(std::string filename);
void start_rx();
void stop_rx();
private:
void save_trace(uint32_t is_eob, srslte_timestamp_t *usrp_time);
void *uhd;
static const double lo_offset = 8e6; // LO offset (in Hz)
static const double burst_settle_time = 0.4e-3; // Start of burst settle time (off->on RF transition time)
static const double burst_settle_time = 0.3e-3; // Start of burst settle time (off->on RF transition time)
const static uint32_t burst_settle_max_samples = 12288; // 30.72 MHz is maximum frequency
srslte_timestamp_t end_of_burst_time;
@ -84,6 +90,13 @@ namespace srslte {
double burst_settle_time_rounded; // settle time rounded to sample time
cf_t zeros[burst_settle_max_samples];
double cur_tx_srate;
trace<uint32_t> tr_local_time;
trace<uint32_t> tr_usrp_time;
trace<uint32_t> tr_tx_time;
trace<uint32_t> tr_is_eob;
bool trace_enabled;
uint32_t my_tti;
};
}

View File

@ -92,18 +92,23 @@ void radio_uhd::get_time(srslte_timestamp_t *now) {
bool radio_uhd::tx(void* buffer, uint32_t nof_samples, srslte_timestamp_t tx_time)
{
if (is_start_of_burst) {
if (burst_settle_samples != 0) {
srslte_timestamp_t tx_time_pad;
srslte_timestamp_copy(&tx_time_pad, &tx_time);
srslte_timestamp_sub(&tx_time_pad, 0, burst_settle_time_rounded);
save_trace(1, &tx_time_pad);
cuhd_send_timed2(uhd, zeros, burst_settle_samples, tx_time_pad.full_secs, tx_time_pad.frac_secs, true, false);
}
is_start_of_burst = false;
srslte_timestamp_copy(&end_of_burst_time, &tx_time);
srslte_timestamp_add(&end_of_burst_time, 0, nof_samples*cur_tx_srate);
}
if (cuhd_send_timed2(uhd, buffer, nof_samples, tx_time.full_secs, tx_time.frac_secs, false, false) > 0) {
// Save possible end of burst time
srslte_timestamp_copy(&end_of_burst_time, &tx_time);
srslte_timestamp_add(&end_of_burst_time, 0, (double) nof_samples/cur_tx_srate);
save_trace(0, &tx_time);
if (cuhd_send_timed2(uhd, buffer, nof_samples, tx_time.full_secs, tx_time.frac_secs, true, false) > 0) {
return true;
} else {
return false;
@ -112,10 +117,36 @@ bool radio_uhd::tx(void* buffer, uint32_t nof_samples, srslte_timestamp_t tx_tim
bool radio_uhd::tx_end()
{
save_trace(2, &end_of_burst_time);
cuhd_send_timed2(uhd, zeros, burst_settle_samples, end_of_burst_time.full_secs, end_of_burst_time.frac_secs, false, true);
is_start_of_burst = true;
}
void radio_uhd::start_trace() {
trace_enabled = true;
my_tti = 0;
}
void radio_uhd::write_trace(std::string filename)
{
tr_local_time.writeToBinary(filename + ".local");
tr_is_eob.writeToBinary(filename + ".eob");
tr_usrp_time.writeToBinary(filename + ".usrp");
tr_tx_time.writeToBinary(filename + ".tx");
}
void radio_uhd::save_trace(uint32_t is_eob, srslte_timestamp_t *tx_time) {
if (trace_enabled) {
tr_local_time.push_cur_time_us(my_tti);
srslte_timestamp_t usrp_time;
cuhd_get_time(uhd, &usrp_time.full_secs, &usrp_time.frac_secs);
tr_usrp_time.push(my_tti, srslte_timestamp_uint32(&usrp_time));
tr_tx_time.push(my_tti, srslte_timestamp_uint32(tx_time));
tr_is_eob.push(my_tti, is_eob);
my_tti++;
}
}
void radio_uhd::set_rx_freq(float freq)
{
cuhd_set_rx_freq(uhd, freq);

View File

@ -45,6 +45,8 @@
#include "srsapps/ue/mac/mux.h"
#include "srsapps/ue/mac/demux.h"
#include "srsapps/ue/mac/sdu_handler.h"
#include "srsapps/common/trace.h"
#ifndef UEMAC_H
#define UEMAC_H
@ -57,7 +59,7 @@ typedef _Complex float cf_t;
class mac : public timer_callback
{
public:
mac() : timers_db((uint32_t) NOF_MAC_TIMERS) {}
mac() : timers_db((uint32_t) NOF_MAC_TIMERS), tr_end_time(1024*10), tr_start_time(1024*10) {started=false;}
bool init(phy *phy_h, tti_sync *ttisync, log *log_h);
void stop();
int get_tti();
@ -83,6 +85,9 @@ public:
void reconfiguration();
void reset();
void start_trace();
void write_trace(std::string filename);
void timer_expired(uint32_t timer_id);
enum {
@ -110,7 +115,7 @@ private:
static void* mac_thread_fnc(void*);
int tti;
bool started = false;
bool started;
bool is_synchronized;
uint16_t last_temporal_crnti;
@ -144,6 +149,12 @@ private:
void setup_timers();
void timeAlignmentTimerExpire();
trace<uint32_t> tr_start_time;
trace<uint32_t> tr_end_time;
bool tr_enabled;
void tr_log_start(uint32_t tti);
void tr_log_end(uint32_t tti);
};
}

View File

@ -79,6 +79,32 @@ int mac::get_tti()
}
}
void mac::start_trace()
{
tr_enabled = true;
}
void mac::write_trace(std::string filename)
{
tr_start_time.writeToBinary(filename + ".start");
tr_end_time.writeToBinary(filename + ".end");
}
void mac::tr_log_start(uint32_t tti)
{
if (tr_enabled) {
tr_start_time.push_cur_time_us(tti);
}
}
void mac::tr_log_end(uint32_t tti)
{
if (tr_enabled) {
tr_end_time.push_cur_time_us(tti);
}
}
// Implement Section 5.8
void mac::reconfiguration()
{
@ -164,7 +190,9 @@ void mac::main_radio_loop() {
}
if (is_synchronized) {
/* Warning: Here order of invocation of procedures is important!! */
tr_log_end(tti);
tti = ttisync->wait();
tr_log_start(tti);
log_h->step(tti);
// Step all procedures

View File

@ -27,6 +27,7 @@
#include <unistd.h>
#include <signal.h>
#include "liblte_rrc.h"
#include "srsapps/radio/radio_uhd.h"
@ -46,6 +47,7 @@ typedef struct {
float uhd_rx_gain;
float uhd_tx_gain;
int verbose;
bool do_trace;
}prog_args_t;
void args_default(prog_args_t *args) {
@ -54,19 +56,21 @@ void args_default(prog_args_t *args) {
args->uhd_rx_gain = -1; // set to autogain
args->uhd_tx_gain = -1;
args->verbose = 0;
args->do_trace = false;
}
void usage(prog_args_t *args, char *prog) {
printf("Usage: %s [gv] -f rx_frequency (in Hz) -F tx_frequency (in Hz)\n", prog);
printf("Usage: %s [gGtv] -f rx_frequency (in Hz) -F tx_frequency (in Hz)\n", prog);
printf("\t-g UHD RX gain [Default AGC]\n");
printf("\t-G UHD TX gain [Default same as RX gain (AGC)]\n");
printf("\t-t Enable trace [Default disabled]\n");
printf("\t-v [increase verbosity, default none]\n");
}
void parse_args(prog_args_t *args, int argc, char **argv) {
int opt;
args_default(args);
while ((opt = getopt(argc, argv, "gGfFv")) != -1) {
while ((opt = getopt(argc, argv, "gGftFv")) != -1) {
switch (opt) {
case 'g':
args->uhd_rx_gain = atof(argv[optind]);
@ -80,6 +84,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
case 'F':
args->uhd_tx_freq = atof(argv[optind]);
break;
case 't':
args->do_trace = true;
break;
case 'v':
args->verbose++;
break;
@ -202,7 +209,6 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u
phy->set_param(srslte::ue::phy_params::SRS_CS_BWCFG, sib2->rr_config_common_sib.srs_ul_cnfg.bw_cnfg);
phy->set_param(srslte::ue::phy_params::SRS_CS_SFCFG, sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg);
phy->set_param(srslte::ue::phy_params::SRS_CS_ACKNACKSIMUL, sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx);
phy->set_param(srslte::ue::phy_params::SRS_IS_CS_CONFIGURED, 1);
}
printf("Set SRS ConfigCommon: BW-Configuration=%d, SF-Configuration=%d, ACKNACK=%d\n",
@ -233,7 +239,6 @@ void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac
phy->set_param(srslte::ue::phy_params::SRS_UE_HOP, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_hopping_bandwidth);
phy->set_param(srslte::ue::phy_params::SRS_UE_TXCOMB, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.tx_comb);
phy->set_param(srslte::ue::phy_params::SRS_BETA, 10);
phy->set_param(srslte::ue::phy_params::SRS_IS_UE_CONFIGURED, 1);
}
}
printf("Set PHY configuration: SR-n_pucch=%d, SR-ConfigIndex=%d, SRS-ConfigIndex=%d, SRS-bw=%d, SRS-Nrcc=%d, SRS-hop=%d, SRS-Ncs=%d\n",
@ -299,13 +304,23 @@ uint32_t lengths[2] = {37, 41};
uint8_t reply[2] = {0x00, 0x04};
srslte::radio_uhd radio_uhd;
srslte::ue::phy phy;
srslte::ue::mac mac;
void sig_int_handler(int signo)
{
//radio_uhd.write_trace("radio");
phy.write_trace("phy");
mac.write_trace("mac");
exit(0);
}
int main(int argc, char *argv[])
{
prog_args_t prog_args;
srslte::ue::tti_sync_cv ttisync(10240);
srslte::radio_uhd radio_uhd;
srslte::ue::phy phy;
srslte::ue::mac mac;
srslte::log_stdout mac_log("MAC"), phy_log("PHY");
parse_args(&prog_args, argc, argv);
@ -320,7 +335,15 @@ int main(int argc, char *argv[])
phy_log.set_level_debug();
break;
}
if (prog_args.do_trace) {
// Capture SIGINT to write traces
signal(SIGINT, sig_int_handler);
//radio_uhd.start_trace();
phy.start_trace();
mac.start_trace();
}
// Init Radio and PHY
if (prog_args.uhd_rx_gain > 0 && prog_args.uhd_tx_gain > 0) {
radio_uhd.init();
@ -449,6 +472,8 @@ int main(int argc, char *argv[])
// Wait for ConnectionSetup
n = mac.recv_dcch0_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
if (n > 0) {
phy.set_param(srslte::ue::phy_params::SRS_IS_CS_CONFIGURED, 1);
phy.set_param(srslte::ue::phy_params::SRS_IS_UE_CONFIGURED, 1);
printf("Received on DCCH0 %d bytes\n", n/8);
printf("Send RLC ACK\n");
srslte_bit_pack_vector(reply, bit_msg.msg, 2*8);

View File

@ -38,6 +38,7 @@
#include "srsapps/ue/phy/sched_grant.h"
#include "srsapps/common/queue.h"
#include "srsapps/radio/radio.h"
#include "srsapps/common/trace.h"
#ifndef UEPHY_H
#define UEPHY_H
@ -119,6 +120,9 @@ public:
ul_buffer* get_ul_buffer(uint32_t tti);
dl_buffer* get_dl_buffer(uint32_t tti);
void start_trace();
void write_trace(std::string filename);
void main_radio_loop();
private:
@ -166,6 +170,11 @@ private:
bool is_first_of_burst;
trace<uint32_t> tr_start_time;
trace<uint32_t> tr_end_time;
bool tr_enabled;
void tr_log_start();
void tr_log_end();
};
}

View File

@ -56,11 +56,11 @@ namespace ue {
bool send(srslte::radio* radio_handler, float cfo, srslte_timestamp_t rx_time);
private:
static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission
phy_params *params_db = NULL;
phy_params *params_db;
log *log_h;
int preamble_idx;
int allowed_subframe;
bool initiated = false;
bool initiated;
uint32_t len;
cf_t *buffer[64];
srslte_prach_t prach_obj;

View File

@ -116,15 +116,16 @@ bool dl_buffer::get_ul_grant(ul_sched_grant *grant)
if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, grant->get_rnti()) != 1) {
return false;
}
/*
grant->set_shortened(false);
if (params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)) {
if (srslte_refsignal_srs_send_cs((uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG), tti%10) == 1) {
if (srslte_refsignal_srs_send_cs((uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG), (tti+4)%10) == 1) {
grant->set_shortened(true);
printf("UL grant tti=%d is shortened. SF-CFG=%d\n", tti, (int) params_db->get_param(phy_params::SRS_CS_SFCFG));
printf("UL grant tti=%d is shortened. SF-CFG=%d\n", tti+4,
(int) params_db->get_param(phy_params::SRS_CS_SFCFG));
}
}
*/
return grant->create_from_dci(&dci_msg, cell, params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET));
}
}

View File

@ -43,7 +43,7 @@
namespace srslte {
namespace ue {
phy::phy()
phy::phy() : tr_end_time(1024*10), tr_start_time(1024*10)
{
started = false;
is_sfn_synched = false;
@ -59,6 +59,30 @@ bool phy::init_agc(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_
return init_(radio_handler_, ttisync_, log_h, true);
}
void phy::start_trace()
{
tr_enabled = true;
}
void phy::write_trace(std::string filename)
{
tr_start_time.writeToBinary(filename + ".start");
tr_end_time.writeToBinary(filename + ".end");
}
void phy::tr_log_start()
{
if (tr_enabled) {
tr_start_time.push_cur_time_us(get_current_tti());
}
}
void phy::tr_log_end()
{
if (tr_enabled) {
tr_end_time.push_cur_time_us(get_current_tti());
}
}
bool phy::init_(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, log *log_h_, bool do_agc_)
{
@ -314,7 +338,7 @@ bool phy::init_prach() {
ul_buffer* phy::get_ul_buffer(uint32_t tti)
{
if (tti + 1 < get_current_tti()) {
if ((tti + 1)%10240 < get_current_tti() && tti > 6) {
Warning("Warning access to PHY UL buffer too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
}
return (ul_buffer*) ul_buffer_queue->get(tti);
@ -524,8 +548,9 @@ void phy::run_rx_tx_state()
}
// Receive alligned buffer for the current tti
tr_log_end();
get_dl_buffer(current_tti)->recv_ue_sync(&ue_sync, &last_rx_time);
tr_log_start();
ttisync->increase();
}
}

View File

@ -39,6 +39,7 @@
#define TIMESTAMP_
#include <time.h>
#include <stdint.h>
#include "srslte/config.h"
typedef struct SRSLTE_API{
@ -63,4 +64,6 @@ SRSLTE_API int srslte_timestamp_sub(srslte_timestamp_t *t,
SRSLTE_API double srslte_timestamp_real(srslte_timestamp_t *t);
SRSLTE_API uint32_t srslte_timestamp_uint32(srslte_timestamp_t *t);
#endif // TIMESTAMP_

View File

@ -80,3 +80,8 @@ int srslte_timestamp_sub(srslte_timestamp_t *t, time_t full_secs, double frac_se
double srslte_timestamp_real(srslte_timestamp_t *t){
return t->frac_secs + t->full_secs;
}
uint32_t srslte_timestamp_uint32(srslte_timestamp_t *t){
uint32_t x = t->full_secs*1e6 + (uint32_t) (t->frac_secs*1e6);
return x;
}