From 93b639da58d73cf43c4e48f49923237954b50cf4 Mon Sep 17 00:00:00 2001 From: David Michaeli Date: Sat, 3 Feb 2024 23:55:46 +0200 Subject: [PATCH] frame synchronization on read fix bug (seg fault) --- .../gr-caribouLite/examples/read_samples.grc | 64 +++++++---- .../lib/caribouLiteSource_impl.cc | 11 +- .../libcariboulite/src/CaribouLiteCpp.cpp | 102 +++++++++++++++++- .../src/CaribouLiteRadioCpp.cpp | 16 +++ .../src/caribou_smi/caribou_smi.c | 8 +- .../libcariboulite/src/cariboulite_radio.c | 5 +- 6 files changed, 174 insertions(+), 32 deletions(-) diff --git a/software/gr-caribouLite/examples/read_samples.grc b/software/gr-caribouLite/examples/read_samples.grc index 665584a..9fa984a 100644 --- a/software/gr-caribouLite/examples/read_samples.grc +++ b/software/gr-caribouLite/examples/read_samples.grc @@ -33,23 +33,6 @@ options: state: enabled blocks: -- name: blocks_null_sink_0 - id: blocks_null_sink - parameters: - affinity: '' - alias: '' - bus_structure_sink: '[[0,],]' - comment: '' - num_inputs: '1' - type: complex - vlen: '1' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [624, 256.0] - rotation: 0 - state: enabled - name: caribouLite_caribouLiteSource_0 id: caribouLite_caribouLiteSource parameters: @@ -57,8 +40,8 @@ blocks: alias: '' channel: '0' comment: '' - enable_agc: 'False' - freq: '900000000.0' + enable_agc: 'True' + freq: '905000000.0' maxoutbuf: '0' minoutbuf: '0' rx_bw: '2500000.0' @@ -71,9 +54,50 @@ blocks: coordinate: [296, 212.0] rotation: 0 state: enabled +- name: lora_sdr_fft_demod_0 + id: lora_sdr_fft_demod + parameters: + affinity: '' + alias: '' + comment: '' + max_log_approx: 'True' + maxoutbuf: '0' + minoutbuf: '0' + soft_decoding: soft_decoding + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [904, 252.0] + rotation: 0 + state: enabled +- name: lora_sdr_frame_sync_0 + id: lora_sdr_frame_sync + parameters: + affinity: '' + alias: '' + bandwidth: '500000' + center_freq: '0' + comment: '' + impl_head: 'True' + maxoutbuf: '0' + minoutbuf: '0' + os_factor: '4' + preamb_len: '8' + sf: '5' + show_log_port: 'True' + sync_word: '18' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [696, 236.0] + rotation: 0 + state: enabled connections: -- [caribouLite_caribouLiteSource_0, '0', blocks_null_sink_0, '0'] +- [caribouLite_caribouLiteSource_0, '0', lora_sdr_frame_sync_0, '0'] +- [lora_sdr_frame_sync_0, '0', lora_sdr_fft_demod_0, '0'] metadata: file_format: 1 diff --git a/software/gr-caribouLite/lib/caribouLiteSource_impl.cc b/software/gr-caribouLite/lib/caribouLiteSource_impl.cc index 3d9d14c..316b2b8 100644 --- a/software/gr-caribouLite/lib/caribouLiteSource_impl.cc +++ b/software/gr-caribouLite/lib/caribouLiteSource_impl.cc @@ -9,12 +9,7 @@ #include "caribouLiteSource_impl.h" namespace gr { - namespace caribouLite { - - #define NUM_NATIVE_MTUS_PER_QUEUE ( 10 ) - #define USE_ASYNC_OVERRIDE_WRITES ( true ) - #define USE_ASYNC_BLOCK_READS ( true ) - + namespace caribouLite { using output_type = gr_complex; void detectBoard() @@ -85,7 +80,9 @@ namespace gr { gr_vector_void_star &output_items) { auto out = static_cast(output_items[0]); - return _radio->ReadSamples(out, static_cast(noutput_items)); + int ret = _radio->ReadSamples(out, static_cast(noutput_items)); + if (ret <= 0) return 0; + return ret; } } /* namespace caribouLite */ diff --git a/software/libcariboulite/src/CaribouLiteCpp.cpp b/software/libcariboulite/src/CaribouLiteCpp.cpp index 2e8ac52..4cd8015 100644 --- a/software/libcariboulite/src/CaribouLiteCpp.cpp +++ b/software/libcariboulite/src/CaribouLiteCpp.cpp @@ -1,16 +1,116 @@ #include +#include +#include #include "CaribouLite.hpp" std::shared_ptr CaribouLite::_instance = nullptr; std::mutex CaribouLite::_instMutex; +//================================================================== +static const char* decode_si_code(int signo, int si_code) +{ + switch (signo) { + case SIGILL: + switch (si_code) { + case ILL_ILLOPC: return "Illegal opcode"; + case ILL_ILLOPN: return "Illegal operand"; + case ILL_ILLADR: return "Illegal addressing mode"; + case ILL_ILLTRP: return "Illegal trap"; + case ILL_PRVOPC: return "Privileged opcode"; + case ILL_PRVREG: return "Privileged register"; + case ILL_COPROC: return "Coprocessor error"; + case ILL_BADSTK: return "Internal stack error"; + default: return "Unknown SIGILL code"; + } + case SIGFPE: + switch (si_code) { + case FPE_INTDIV: return "Integer divide-by-zero"; + case FPE_INTOVF: return "Integer overflow"; + case FPE_FLTDIV: return "Floating point divide-by-zero"; + case FPE_FLTOVF: return "Floating point overflow"; + case FPE_FLTUND: return "Floating point underflow"; + case FPE_FLTRES: return "Floating point inexact result"; + case FPE_FLTINV: return "Invalid floating point operation"; + case FPE_FLTSUB: return "Subscript out of range"; + default: return "Unknown SIGFPE code"; + } + case SIGSEGV: + switch (si_code) { + case SEGV_MAPERR: return "Address not mapped"; + case SEGV_ACCERR: return "Invalid permissions"; + default: return "Unknown SIGSEGV code"; + } + case SIGBUS: + switch (si_code) { + case BUS_ADRALN: return "Invalid address alignment"; + case BUS_ADRERR: return "Non-existent physical address"; + case BUS_OBJERR: return "Object-specific hardware error"; + default: return "Unknown SIGBUS code"; + } + case SIGTRAP: + switch (si_code) { + case TRAP_BRKPT: return "Process breakpoint"; + case TRAP_TRACE: return "Process trace trap"; + default: return "Unknown SIGTRAP code"; + } + case SIGCHLD: + switch (si_code) { + case CLD_EXITED: return "Child has exited"; + case CLD_KILLED: return "Child has terminated abnormally and did not create a core file"; + case CLD_DUMPED: return "Child has terminated abnormally and created a core file"; + case CLD_TRAPPED: return "Traced child has trapped"; + case CLD_STOPPED: return "Child has stopped"; + case CLD_CONTINUED: return "Stopped child has continued"; + default: return "Unknown SIGCHLD code"; + } + case SIGPOLL: + switch (si_code) { + case POLL_IN: return "Data input available"; + case POLL_OUT: return "Output buffers available"; + case POLL_MSG: return "Input message available"; + case POLL_ERR: return "I/O error"; + case POLL_PRI: return "High priority input available"; + case POLL_HUP: return "Device disconnected"; + default: return "Unknown SIGPOLL/SIGIO code"; + } + default: + switch(si_code) + { + case SI_USER: return "Signal sent by kill()"; + case SI_QUEUE: return "Signal was sent by sigqueue()"; + case SI_TIMER: return "Signal was generated by expiration of a timer set by timer_settimer()"; + case SI_ASYNCIO: return "Signal was generated by completion of an asynchronous I/O request"; + case SI_MESGQ: return "Signal was generated by arrival of a message on an empty message queue."; + default: return "Unknown General code"; + } + } +} + +//================================================================== +static void print_siginfo(const siginfo_t *si) +{ + printf(" Signal Number: %d\n", si->si_signo); + printf(" Signal Code: %d (%s)\n", si->si_code, decode_si_code(si->si_signo, si->si_code)); + printf(" Signal Value (int): %d\n", si->si_value.sival_int); + printf(" Signal Value (ptr): %p\n", si->si_value.sival_ptr); + printf(" Error Number: %d => '%s'\n", si->si_errno, strerror(errno)); + printf(" Sending Process ID: %d\n", si->si_pid); + printf(" User ID: %d\n", si->si_uid); + printf(" Faulting Instruction Address: %p\n", si->si_addr); + printf(" Exit Value or Signal: %d\n", si->si_status); + printf(" Band Event for SIGPOLL: %ld\n", si->si_band); +} //================================================================== void CaribouLite::DefaultSignalHandler(void* context, int signal_number, siginfo_t *si) { CaribouLite* cl = (CaribouLite*)context; - std::cout << " >> Signal caught: " << signal_number << std::endl << std::flush; + printf(">> DefaultSignalHandler: Signal caught (sig %d), additional information: \n", signal_number); + print_siginfo(si); + fflush(stdout); if (cl->_on_signal_caught) cl->_on_signal_caught(signal_number); + + exit(-1); //cl->ReleaseResources(); } diff --git a/software/libcariboulite/src/CaribouLiteRadioCpp.cpp b/software/libcariboulite/src/CaribouLiteRadioCpp.cpp index d2f576b..8fd65dc 100644 --- a/software/libcariboulite/src/CaribouLiteRadioCpp.cpp +++ b/software/libcariboulite/src/CaribouLiteRadioCpp.cpp @@ -70,7 +70,14 @@ void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio) //================================================================== int CaribouLiteRadio::ReadSamples(std::complex* samples, size_t num_to_read) { + if (samples == 0) + { + printf("samples_is_null=%d", _read_samples==NULL); + return 0; + } + int ret = ReadSamples((std::complex*)NULL, num_to_read); + //printf("ret = %d\n", ret); if (ret <= 0) { return ret; @@ -89,6 +96,13 @@ int CaribouLiteRadio::ReadSamples(std::complex* samples, size_t num_to_re //================================================================== int CaribouLiteRadio::ReadSamples(std::complex* samples, size_t num_to_read) { + if (!_rx_is_active || _read_samples == NULL || _read_metadata == NULL || num_to_read == 0) + { + printf("reading from closed stream: rx_active = %d, _read_samples_is_null=%d, _read_metadata_is_null=%d, num_to_read=%ld\n", + _rx_is_active, _read_samples==NULL, _read_metadata==NULL, num_to_read); + return 0; + } + int ret = cariboulite_radio_read_samples((cariboulite_radio_state_st*)_radio, _read_samples, _read_metadata, @@ -185,7 +199,9 @@ CaribouLiteRadio::~CaribouLiteRadio() else { if (_read_samples) delete [] _read_samples; + _read_samples = NULL; if (_read_metadata) delete [] _read_metadata; + _read_metadata = NULL; } } diff --git a/software/libcariboulite/src/caribou_smi/caribou_smi.c b/software/libcariboulite/src/caribou_smi/caribou_smi.c index ea650fa..df0e137 100644 --- a/software/libcariboulite/src/caribou_smi/caribou_smi.c +++ b/software/libcariboulite/src/caribou_smi/caribou_smi.c @@ -237,10 +237,11 @@ static int caribou_smi_find_buffer_offset(caribou_smi_st* dev, uint8_t *buffer, size_t offs = 0; bool found = false; - if (len <= 4) + if (len <= (CARIBOU_SMI_BYTES_PER_SAMPLE*4)) { return 0; } + //smi_utils_dump_hex(buffer, 16); if (dev->debug_mode == caribou_smi_none) { @@ -283,6 +284,7 @@ static int caribou_smi_find_buffer_offset(caribou_smi_st* dev, uint8_t *buffer, if (found == false) { + smi_utils_dump_hex(buffer, 16); return -1; } @@ -623,7 +625,7 @@ static int caribou_smi_calc_read_timeout(uint32_t sample_rate, size_t len) { uint32_t to_millisec = (2 * len * 1000) / sample_rate; if (to_millisec < 1) to_millisec = 1; - return to_millisec; + return to_millisec * 2; } //========================================================================= @@ -662,7 +664,7 @@ int caribou_smi_read(caribou_smi_st* dev, caribou_smi_channel_en channel, int data_affset = caribou_smi_rx_data_analyze(dev, channel, dev->read_temp_buffer, ret, sample_offset, meta_offset); if (data_affset < 0) { - return -1; + return -3; } // A special functionality for debug modes diff --git a/software/libcariboulite/src/cariboulite_radio.c b/software/libcariboulite/src/cariboulite_radio.c index 2d3b938..962035a 100644 --- a/software/libcariboulite/src/cariboulite_radio.c +++ b/software/libcariboulite/src/cariboulite_radio.c @@ -1237,7 +1237,10 @@ int cariboulite_radio_read_samples(cariboulite_radio_state_st* radio, if (ret < 0) { // -2 reserved for debug mode - if (ret == -1) ZF_LOGE("SMI reading operation failed"); + if (ret == -1) {ZF_LOGE("SMI reading operation failed");} + else if (ret == -2) {} + else if (ret == -3) {ZF_LOGE("SMI data synchronization failed");} + } else if (ret == 0) {