Change architecture to 1 thread rx/tx + 1 thread usrp_rx

master
ismagom 10 years ago
parent 666225d3cb
commit c97b7f5b28

@ -81,7 +81,7 @@ namespace srslte {
void *uhd;
static const double lo_offset = 8e6; // LO offset (in Hz)
static const double burst_settle_time = 0.3e-3; // Start of burst settle time (off->on RF transition time)
static const double burst_settle_time = 0.4e-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;

@ -159,6 +159,7 @@ private:
trace<uint32_t> tr_start_time;
trace<uint32_t> tr_end_time;
bool tr_enabled;
bool is_first_of_burst;
void tr_log_start(uint32_t tti);
void tr_log_end(uint32_t tti);
void set_phy_crnti(uint16_t phy_rnti);

@ -89,6 +89,7 @@ private:
bool timer_retx;
bool sr_is_sent;
uint32_t last_print;
void update_pending_data();
bool check_highest_channel();
bool check_single_channel();

@ -56,6 +56,7 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
demux_unit.init(phy_h, log_h, &mac_io_lch, &timers_db);
ra_procedure.init(&params_db, phy_h, log_h, &timers_db, &mux_unit, &demux_unit);
sr_procedure.init(log_h, &params_db, phy_h);
is_first_of_burst = true;
reset();
if (threads_new_rt_prio(&mac_thread, mac_thread_fnc, this, 5)) {
@ -251,6 +252,28 @@ void mac::main_radio_loop() {
if (ra_procedure.is_contention_resolution() || ra_procedure.is_successful()) {
process_ul_grants(tti);
}
ul_buffer *ul_buffer = phy_h->get_ul_buffer(tti+4);
// Generate scheduling request if we have to
if (phy_h->sr_is_ready_to_send(tti+4)) {
ul_buffer->generate_sr();
}
// The UL buffer is released when successfully transmitted.
if (ul_buffer->is_released()) {
ul_buffer->ready();
is_first_of_burst = false;
} else if (ul_buffer->uci_ready() || ul_buffer->srs_is_ready_to_send()) {
// If the packet was not generated by a call from MAC, means it's PUCCH or SRS. Generate now the signal
ul_buffer->generate_data();
ul_buffer->ready();
is_first_of_burst = false;
} else {
if (!is_first_of_burst) {
ul_buffer->set_end_of_burst();
is_first_of_burst = true;
}
}
timers_db.step_all();

@ -44,6 +44,7 @@ bsr_proc::bsr_proc()
priorities[i] = -1;
last_pending_data[i] = 0;
}
last_print = 0;
triggered_bsr_type=NONE;
}
@ -67,14 +68,14 @@ void bsr_proc::timer_expired(uint32_t timer_id) {
case mac::BSR_TIMER_PERIODIC:
if (triggered_bsr_type == NONE) {
// Check condition 4 in Sec 5.4.5
//triggered_bsr_type = PERIODIC;
Info("BSR PERIODIC disabled\n");
triggered_bsr_type = PERIODIC;
Info("Triggering BSR PERIODIC\n");
}
break;
case mac::BSR_TIMER_RETX:
// Enable reTx of SR
//triggered_bsr_type = REGULAR;
Info("BSR reTX disabled\n");
triggered_bsr_type = REGULAR;
Info("Triggering BSR reTX\n");
sr_is_sent = false;
break;
}
@ -151,7 +152,7 @@ bool bsr_proc::generate_bsr(bsr_t *bsr, uint32_t nof_padding_bytes) {
for (int i=0;i<mac_io_h->NOF_UL_LCH;i++) {
if (lcg[i] >= 0) {
uint32_t n = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
bsr->buff_size[lcg[i]] += n;
bsr->buff_size[lcg[i]] += 8*n;
if (n > 0) {
nof_lcg++;
ret = true;
@ -216,6 +217,18 @@ void bsr_proc::step(uint32_t tti)
check_highest_channel();
update_pending_data();
if ((tti - last_print)%10240 > 40) {
char str[128];
bzero(str, 128);
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
sprintf(str, "%s%d (%d), ", str, mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8, last_pending_data[i]);
}
Info("QUEUE status: %s\n", str);
last_print = tti;
}
}
char* bsr_proc::bsr_type_tostring(triggered_bsr_type_t type) {

@ -25,4 +25,7 @@ IF(UHD_FOUND AND OPENLTE_FOUND)
INCLUDE_DIRECTORIES(${OPENLTE_INCLUDE_DIRS})
ADD_EXECUTABLE(mac_test mac_test.cc)
TARGET_LINK_LIBRARIES(mac_test srsapps_common srsapps_ue_mac srsapps_ue_phy srsapps_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd)
ENDIF(UHD_FOUND AND OPENLTE_FOUND)
ADD_EXECUTABLE(mac_test mac_test.cc)
TARGET_LINK_LIBRARIES(mac_test srsapps_common srsapps_ue_mac srsapps_ue_phy srsapps_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd)
ENDIF(UHD_FOUND AND OPENLTE_FOUND)

@ -125,12 +125,15 @@ public:
void write_trace(std::string filename);
void main_radio_loop();
bool sr_is_ready_to_send(uint32_t tti);
private:
enum {
IDLE, RXTX
} phy_state;
static const int NOF_ULDL_QUEUES = 6;
tti_sync *ttisync;
radio *radio_handler;
log *log_h;
@ -158,7 +161,6 @@ private:
double last_gain;
bool sr_enabled;
bool sr_is_ready_to_send(uint32_t tti);
bool init_(radio *radio_handler, tti_sync *ttisync, log *log_h, bool do_agc);
static void *phy_thread_fnc(void *arg);

@ -33,6 +33,7 @@
#include "srsapps/ue/phy/ul_sched_grant.h"
#include "srsapps/ue/phy/dl_sched_grant.h"
#include "srsapps/ue/phy/phy_params.h"
#include "srsapps/radio/radio.h"
#ifndef UEULBUFFER_H
#define UEULBUFFER_H
@ -47,7 +48,7 @@ namespace ue {
class ul_buffer : public queue::element {
public:
bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h);
bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h, radio *radio_h);
void free_cell();
void set_crnti(uint16_t rnti);
void set_current_tx_nb(uint32_t current_tx_nb);
@ -60,12 +61,18 @@ namespace ue {
bool generate_data();
bool generate_data(ul_sched_grant *pusch_grant, uint8_t *payload);
bool generate_data(ul_sched_grant *pusch_grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload);
bool send(radio* radio_handler, float time_adv_sec, float cfo, srslte_timestamp_t rx_time);
static const uint32_t tx_advance_sf = 2; // Number of subframes to advance transmission
void set_tx_params(float cfo, float time_adv_sec, srslte_timestamp_t tx_time);
void set_end_of_burst();
bool is_end_of_burst();
static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission
static const bool normalize_amp = true;
private:
log *log_h;
phy_params *params_db;
radio *radio_h;
float cfo;
bool tti_is_end_of_burst;
srslte_timestamp_t tx_time;
srslte_cell_t cell;
srslte_ue_ul_t ue_ul;
bool cell_initiated;

@ -94,8 +94,8 @@ bool phy::init_(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, l
ttisync = ttisync_;
log_h = log_h_;
radio_handler = radio_handler_;
ul_buffer_queue = new queue(6, sizeof(ul_buffer));
dl_buffer_queue = new queue(6, sizeof(dl_buffer));
ul_buffer_queue = new queue(NOF_ULDL_QUEUES, sizeof(ul_buffer));
dl_buffer_queue = new queue(NOF_ULDL_QUEUES, sizeof(dl_buffer));
do_agc = do_agc_;
last_gain = 1e4;
time_adv_sec = 0;
@ -118,7 +118,7 @@ void phy::stop()
pthread_join(phy_thread, NULL);
for (int i=0;i<6;i++) {
for (int i=0;i<NOF_ULDL_QUEUES;i++) {
((ul_buffer*) ul_buffer_queue->get(i))->free_cell();
((dl_buffer*) dl_buffer_queue->get(i))->free_cell();
}
@ -171,7 +171,7 @@ bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe, int target_pow
if (phy_state == RXTX) {
srslte_agc_lock(&ue_sync.agc, true);
old_gain = radio_handler->get_tx_gain();
radio_handler->set_tx_gain(10);
radio_handler->set_tx_gain(80);
Info("Stopped AGC. Set TX gain to %.1f dB\n", radio_handler->get_tx_gain());
return prach_buffer.prepare_to_send(preamble_idx, allowed_subframe, target_power_dbm);
}
@ -224,7 +224,7 @@ bool phy::measure()
}
void phy::set_crnti(uint16_t rnti) {
for(uint32_t i=0;i<6;i++) {
for(uint32_t i=0;i<NOF_ULDL_QUEUES;i++) {
((ul_buffer*) ul_buffer_queue->get(i))->set_crnti(rnti);
((dl_buffer*) dl_buffer_queue->get(i))->set_crnti(rnti);
@ -319,8 +319,8 @@ bool phy::set_cell(srslte_cell_t cell_) {
}
srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo);
for(uint32_t i=0;i<6;i++) {
((ul_buffer*) ul_buffer_queue->get(i))->init_cell(cell, &params_db, log_h);
for(uint32_t i=0;i<NOF_ULDL_QUEUES;i++) {
((ul_buffer*) ul_buffer_queue->get(i))->init_cell(cell, &params_db, log_h, radio_handler);
((dl_buffer*) dl_buffer_queue->get(i))->init_cell(cell, &params_db, log_h);
((dl_buffer*) dl_buffer_queue->get(i))->buffer_id = i;
((ul_buffer*) ul_buffer_queue->get(i))->ready();
@ -345,7 +345,7 @@ bool phy::init_prach() {
ul_buffer* phy::get_ul_buffer(uint32_t tti)
{
if ((tti + 1)%10240 < get_current_tti() && tti > 6) {
if (tti + 1 < get_current_tti() && tti > NOF_ULDL_QUEUES) {
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);
@ -519,15 +519,10 @@ void phy::run_rx_tx_state()
log_h->step(current_tti);
float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000;
bool tx_zeros = true;
// Advance transmission time for the next tti
srslte_timestamp_add(&last_rx_time, 0, 1e-3);
// Generate scheduling request if we have to
if (sr_is_ready_to_send(current_tti+ul_buffer::tx_advance_sf)) {
get_ul_buffer_adv(current_tti)->generate_sr();
}
/* Set CFO and next TX time for UL buffer for TTI+4 */
get_ul_buffer(current_tti+4)->set_tx_params(cfo, time_adv_sec, last_rx_time);
// Every subframe, TX a PRACH or a PUSCH/PUCCH
if (prach_buffer.is_ready_to_send(current_tti)) {
@ -537,24 +532,9 @@ void phy::run_rx_tx_state()
radio_handler->set_tx_gain(old_gain);
srslte_agc_lock(&ue_sync.agc, false);
Info("Restoring AGC. Set TX gain to %.1f dB\n", old_gain);
// If we don't transmit PRACH, check if need to transmit PUSCH/PUCCH
} else if (get_ul_buffer_adv(current_tti)->is_released() ||
get_ul_buffer_adv(current_tti)->uci_ready() ||
get_ul_buffer_adv(current_tti)->srs_is_ready_to_send())
{
// If the packet was not generated by a call from MAC, means it's PUCCH or SRS. Generate now the signal
if (!get_ul_buffer_adv(current_tti)->is_released()) {
get_ul_buffer_adv(current_tti)->generate_data();
}
// And transmit
get_ul_buffer_adv(current_tti)->send(radio_handler, time_adv_sec, cfo, last_rx_time);
is_first_of_burst = false;
} else {
if (!is_first_of_burst) {
radio_handler->tx_end();
is_first_of_burst = true;
}
} else if (get_ul_buffer_adv(current_tti)->is_end_of_burst()) {
radio_handler->tx_end();
Info("Sending TX END\n");
}
// Receive alligned buffer for the current tti

@ -41,16 +41,18 @@
namespace srslte {
namespace ue {
bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_) {
bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_, radio *radio_h_) {
cell = cell_;
log_h = log_h_;
radio_h = radio_h_;
params_db = params_db_;
current_tx_nb = 0;
tti_is_end_of_burst = false;
if (!srslte_ue_ul_init(&ue_ul, cell)) {
srslte_ue_ul_set_normalization(&ue_ul, false);
signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
cell_initiated = (signal_buffer)?true:false;
srslte_ue_ul_set_cfo_enable(&ue_ul, false);
srslte_ue_ul_set_cfo_enable(&ue_ul, true);
bzero(&uci_data, sizeof(srslte_uci_data_t));
uci_pending = false;
return cell_initiated;
@ -209,6 +211,8 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
uci_data.I_offset_cqi = params_db->get_param(phy_params::UCI_I_OFFSET_CQI);
uci_data.I_offset_ri = params_db->get_param(phy_params::UCI_I_OFFSET_RI);
srslte_ue_ul_set_cfo(&ue_ul, cfo);
int n = 0;
// Transmit on PUSCH if UL grant available, otherwise in PUCCH
if (grant) {
@ -230,8 +234,8 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
grant->get_rnti(),
signal_buffer);
Info("PUSCH: TTI=%d, TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, shortened=%s\n",
tti, grant->get_tbs(), srslte_mod_string(ue_ul.pusch_cfg.grant.mcs.mod), ue_ul.pusch_cfg.grant.n_prb[0],
Info("PUSCH: TTI=%d, CFO= %.1f KHz TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, shortened=%s\n",
tti, cfo*15e3, grant->get_tbs(), srslte_mod_string(ue_ul.pusch_cfg.grant.mcs.mod), ue_ul.pusch_cfg.grant.n_prb[0],
ue_ul.pusch_cfg.grant.L_prb,
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
grant->get_rnti(), ue_ul.pusch.shortened?"yes":"no");
@ -240,18 +244,37 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
} else if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len) {
n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti%10, signal_buffer);
Info("PUCCH: TTI=%d n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, last_n_cce,
Info("PUCCH: TTI=%d, CFO= %.1f KHz n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, cfo*15e3, last_n_cce,
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
ue_ul.pucch.shortened?"yes":"no");
} else {
n = srslte_ue_ul_srs_encode(&ue_ul, tti, signal_buffer);
Info("SRS only: TX at TTI=%d\n", tti);
Info("SRS: TTI=%d, CFO= %.1f KHz \n", tti, cfo*15e3);
}
// Reset UCI data
bzero(&uci_data, sizeof(srslte_uci_data_t));
uci_pending = false;
// Compute peak
float max = 0;
if (normalize_amp) {
float *t = (float*) signal_buffer;
for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) {
if (fabsf(t[i]) > max) {
max = fabsf(t[i]);
}
}
// Normalize before TX
srslte_vec_sc_prod_cfc(signal_buffer, 0.7/max, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
radio_h->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time);
release();
if (n < 0) {
fprintf(stderr, "Error in UL buffer: Error encoding %s\n", signal_buffer?"PUSCH":"PUCCH");
return false;
@ -266,47 +289,23 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
int nof_tx = 0;
bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo, srslte_timestamp_t rx_time)
void ul_buffer::set_tx_params(float cfo_, float time_adv_sec, srslte_timestamp_t tx_time_)
{
// send packet next timeslot minus time advance
srslte_timestamp_t tx_time;
srslte_timestamp_copy(&tx_time, &rx_time);
srslte_timestamp_add(&tx_time, 0, tx_advance_sf*1e-3 - time_adv_sec);
// Correct CFO before transmission
if (cfo != 0) {
srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb));
}
// Compute peak
float max = 0;
if (normalize_amp) {
float *t = (float*) signal_buffer;
for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) {
if (fabsf(t[i]) > max) {
max = fabsf(t[i]);
}
}
// Normalize before TX
srslte_vec_sc_prod_cfc(signal_buffer, 0.7/max, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
Info("TX CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f PeakAmplitude=%.2f PKT#%d\n",
cfo*15000, SRSLTE_SF_LEN_PRB(cell.nof_prb),
srslte_timestamp_real(&rx_time),
srslte_timestamp_real(&tx_time), time_adv_sec*1000000, max, nof_tx);
radio_handler->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time);
tti_is_end_of_burst = false;
cfo = cfo_;
srslte_timestamp_copy(&tx_time, &tx_time_);
srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec);
}
/*
char filename[25];
sprintf(filename, "pusch%d",nof_tx);
srslte_vec_save_file(filename, signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
nof_tx++;
*/
void ul_buffer::set_end_of_burst()
{
Info("Is end of burst\n");
tti_is_end_of_burst = true;
}
ready();
bool ul_buffer::is_end_of_burst()
{
return tti_is_end_of_burst;
}
} // namespace ue

@ -162,7 +162,7 @@ int cuhd_open_(char *args, void **h, bool create_thread_gain, bool tx_gain_same_
{
cuhd_handler *handler = new cuhd_handler();
std::string _args = std::string(args);
handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000");
handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000, num_recv_frames=512");
// handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=50000000" + ", num_recv_frames=512");
handler->usrp->set_clock_source("internal");

Loading…
Cancel
Save