INTRA: better ring-buffer protection

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent c2621cc4f8
commit 32ea840a30

@ -218,7 +218,6 @@ private:
cf_t* search_buffer = nullptr; cf_t* search_buffer = nullptr;
uint32_t receive_cnt = 0;
srslte_ringbuffer_t ring_buffer = {}; srslte_ringbuffer_t ring_buffer = {};
srslte_refsignal_dl_sync_t refsignal_dl_sync = {}; srslte_refsignal_dl_sync_t refsignal_dl_sync = {};

@ -21,16 +21,16 @@
#include "srsue/hdr/phy/scell/intra_measure.h" #include "srsue/hdr/phy/scell/intra_measure.h"
#define Error(fmt, ...) \ #define Error(fmt, ...) \
if (SRSLTE_DEBUG_ENABLED) \ if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \
log_h->error(fmt, ##__VA_ARGS__) log_h->error(fmt, ##__VA_ARGS__)
#define Warning(fmt, ...) \ #define Warning(fmt, ...) \
if (SRSLTE_DEBUG_ENABLED) \ if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \
log_h->warning(fmt, ##__VA_ARGS__) log_h->warning(fmt, ##__VA_ARGS__)
#define Info(fmt, ...) \ #define Info(fmt, ...) \
if (SRSLTE_DEBUG_ENABLED) \ if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \
log_h->info(fmt, ##__VA_ARGS__) log_h->info(fmt, ##__VA_ARGS__)
#define Debug(fmt, ...) \ #define Debug(fmt, ...) \
if (SRSLTE_DEBUG_ENABLED) \ if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \
log_h->debug(fmt, ##__VA_ARGS__) log_h->debug(fmt, ##__VA_ARGS__)
namespace srsue { namespace srsue {
@ -100,12 +100,10 @@ void intra_measure::set_rx_gain_offset(float rx_gain_offset_db_)
void intra_measure::meas_stop() void intra_measure::meas_stop()
{ {
// Transition state to idle
// Ring-buffer shall not be reset, it will automatically be reset as soon as the FSM transitions to receive
state.set_state(internal_state::idle); state.set_state(internal_state::idle);
receive_cnt = 0; Info("INTRA: Disabled neighbour cell search for EARFCN %d\n", get_earfcn());
srslte_ringbuffer_reset(&ring_buffer);
if (log_h) {
log_h->info("INTRA: Disabled neighbour cell search for EARFCN %d\n", get_earfcn());
}
} }
void intra_measure::set_cells_to_meas(const std::set<uint32_t>& pci) void intra_measure::set_cells_to_meas(const std::set<uint32_t>& pci)
@ -119,6 +117,8 @@ void intra_measure::set_cells_to_meas(const std::set<uint32_t>& pci)
void intra_measure::write(uint32_t tti, cf_t* data, uint32_t nsamples) void intra_measure::write(uint32_t tti, cf_t* data, uint32_t nsamples)
{ {
int nbytes = (int)(nsamples * sizeof(cf_t));
int required_nbytes = (int)(intra_freq_meas_len_ms * current_sflen * sizeof(cf_t));
uint32_t elapsed_tti = TTI_SUB(tti, last_measure_tti); uint32_t elapsed_tti = TTI_SUB(tti, last_measure_tti);
switch (state.get_state()) { switch (state.get_state()) {
@ -131,19 +131,19 @@ void intra_measure::write(uint32_t tti, cf_t* data, uint32_t nsamples)
case internal_state::wait: case internal_state::wait:
if (elapsed_tti >= intra_freq_meas_period_ms) { if (elapsed_tti >= intra_freq_meas_period_ms) {
state.set_state(internal_state::receive); state.set_state(internal_state::receive);
receive_cnt = 0;
last_measure_tti = tti; last_measure_tti = tti;
srslte_ringbuffer_reset(&ring_buffer); srslte_ringbuffer_reset(&ring_buffer);
} }
break; break;
case internal_state::receive: case internal_state::receive:
if (srslte_ringbuffer_write(&ring_buffer, data, nsamples * sizeof(cf_t)) < (int)(nsamples * sizeof(cf_t))) { if (srslte_ringbuffer_write(&ring_buffer, data, nbytes) < nbytes) {
Warning("Error writing to ringbuffer\n"); Warning("INTRA: Error writing to ringbuffer (EARFCN=%d)\n", current_earfcn);
state.set_state(internal_state::idle);
// Transition to wait, so it can keep receiving without stopping the component operation
state.set_state(internal_state::wait);
} else { } else {
receive_cnt++; // As soon as there are enough samples in the buffer, transition to measure
if (receive_cnt == intra_freq_meas_len_ms) { if (srslte_ringbuffer_status(&ring_buffer) >= required_nbytes) {
// Buffer ready for measuring, start
state.set_state(internal_state::measure); state.set_state(internal_state::measure);
} }
} }
@ -161,7 +161,7 @@ void intra_measure::measure_proc()
active_pci_mutex.unlock(); active_pci_mutex.unlock();
// Read data from buffer and find cells in it // Read data from buffer and find cells in it
srslte_ringbuffer_read(&ring_buffer, search_buffer, intra_freq_meas_len_ms * current_sflen * sizeof(cf_t)); srslte_ringbuffer_read(&ring_buffer, search_buffer, (int)intra_freq_meas_len_ms * current_sflen * sizeof(cf_t));
// Go to receive before finishing, so new samples can be enqueued before the thread finishes // Go to receive before finishing, so new samples can be enqueued before the thread finishes
if (state.get_state() == internal_state::measure) { if (state.get_state() == internal_state::measure) {
@ -173,7 +173,7 @@ void intra_measure::measure_proc()
std::set<uint32_t> detected_cells = scell.find_cells(search_buffer, serving_cell, intra_freq_meas_len_ms); std::set<uint32_t> detected_cells = scell.find_cells(search_buffer, serving_cell, intra_freq_meas_len_ms);
// Add detected cells to the list of cells to measure // Add detected cells to the list of cells to measure
for (auto& c : detected_cells) { for (const uint32_t& c : detected_cells) {
cells_to_measure.insert(c); cells_to_measure.insert(c);
} }
@ -183,7 +183,7 @@ void intra_measure::measure_proc()
new_cell_itf->cell_meas_reset(cc_idx); new_cell_itf->cell_meas_reset(cc_idx);
// Use Cell Reference signal to measure cells in the time domain for all known active PCI // Use Cell Reference signal to measure cells in the time domain for all known active PCI
for (auto id : cells_to_measure) { for (const uint32_t& id : cells_to_measure) {
// Do not measure serving cell here since it's measured by workers // Do not measure serving cell here since it's measured by workers
if (id == serving_cell.id) { if (id == serving_cell.id) {
continue; continue;

@ -919,7 +919,8 @@ int sync::radio_recv_fnc(srslte::rf_buffer_t& data, srslte_timestamp_t* rx_time)
// Save signal for Intra-frequency measurement // Save signal for Intra-frequency measurement
if (srslte_cell_isvalid(&cell)) { if (srslte_cell_isvalid(&cell)) {
for (uint32_t i = 0; (uint32_t)i < intra_freq_meas.size(); i++) { for (uint32_t i = 0; (uint32_t)i < intra_freq_meas.size(); i++) {
intra_freq_meas[i]->write(tti, data.get(i, 0, worker_com->args->nof_rx_ant), SRSLTE_SF_LEN_PRB(cell.nof_prb)); // Feed the exact number of base-band samples for avoiding an invalid buffer read
intra_freq_meas[i]->write(tti, data.get(i, 0, worker_com->args->nof_rx_ant), data.get_nof_samples());
// Update RX gain // Update RX gain
intra_freq_meas[i]->set_rx_gain_offset(worker_com->get_rx_gain_offset()); intra_freq_meas[i]->set_rx_gain_offset(worker_com->get_rx_gain_offset());

Loading…
Cancel
Save