From 81aff16c2decf9e4a9ed45ad3ad644922f69b8dc Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Wed, 4 Sep 2024 17:37:09 +0100 Subject: [PATCH] Fix race condition on multiple interfaces receiving at once --- Config.h | 7 +++++ RNode_Firmware_CE.ino | 62 ++++++++++++++++++------------------------- Radio.cpp | 7 ++--- Radio.hpp | 1 + 4 files changed, 36 insertions(+), 41 deletions(-) diff --git a/Config.h b/Config.h index aa862ba..7fe2140 100644 --- a/Config.h +++ b/Config.h @@ -28,6 +28,8 @@ #define CABLE_STATE_DISCONNECTED 0x00 #define CABLE_STATE_CONNECTED 0x01 uint8_t cable_state = CABLE_STATE_DISCONNECTED; + + #define MAX_INTERFACES 12 #define BT_STATE_NA 0xff #define BT_STATE_OFF 0x00 @@ -88,6 +90,11 @@ uint8_t seq = 0xFF; uint16_t read_len = 0; + + FIFOBuffer packet_rdy_interfaces; + + uint8_t packet_rdy_interfaces_buf[MAX_INTERFACES]; + // Incoming packet buffer uint8_t pbuf[MTU]; diff --git a/RNode_Firmware_CE.ino b/RNode_Firmware_CE.ino index c45eace..e208b5c 100644 --- a/RNode_Firmware_CE.ino +++ b/RNode_Firmware_CE.ino @@ -66,9 +66,6 @@ char sbuf[128]; bool packet_ready = false; -volatile bool process_packet = false; -volatile uint8_t packet_interface = 0; - uint8_t *packet_queue[INTERFACE_COUNT]; void setup() { @@ -140,6 +137,10 @@ void setup() { packet_queue[i] = (uint8_t*)malloc(getQueueSize(i)+1); } + memset(packet_rdy_interfaces_buf, 0, sizeof(packet_rdy_interfaces_buf)); + + fifo_init(&packet_rdy_interfaces, packet_rdy_interfaces_buf, MAX_INTERFACES); + // Create and configure interface objects for (uint8_t i = 0; i < INTERFACE_COUNT; i++) { switch (interfaces[i]) { @@ -330,7 +331,7 @@ inline void getPacketData(RadioInterface* radio, uint16_t len) { } } -void ISR_VECT receive_callback(uint8_t index, int packet_size) { +void receive_callback(uint8_t index, int packet_size) { if (!promisc) { selected_radio = interface_obj[index]; @@ -399,6 +400,24 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) { getPacketData(selected_radio, packet_size); packet_ready = true; } + + if (packet_ready) { + #if MCU_VARIANT == MCU_ESP32 + portENTER_CRITICAL(&update_lock); + #elif MCU_VARIANT == MCU_NRF52 + portENTER_CRITICAL(); + #endif + last_rssi = selected_radio->packetRssi(); + last_snr_raw = selected_radio->packetSnrRaw(); + #if MCU_VARIANT == MCU_ESP32 + portEXIT_CRITICAL(&update_lock); + #elif MCU_VARIANT == MCU_NRF52 + portEXIT_CRITICAL(); + #endif + kiss_indicate_stat_rssi(); + kiss_indicate_stat_snr(); + kiss_write_packet(index); + } last_rx = millis(); } @@ -1170,25 +1189,6 @@ void loop() { // If at least one radio is online then we can continue if (ready) { - if (packet_ready) { - selected_radio = interface_obj[packet_interface]; - #if MCU_VARIANT == MCU_ESP32 - portENTER_CRITICAL(&update_lock); - #elif MCU_VARIANT == MCU_NRF52 - portENTER_CRITICAL(); - #endif - last_rssi = selected_radio->packetRssi(); - last_snr_raw = selected_radio->packetSnrRaw(); - #if MCU_VARIANT == MCU_ESP32 - portEXIT_CRITICAL(&update_lock); - #elif MCU_VARIANT == MCU_NRF52 - portEXIT_CRITICAL(); - #endif - kiss_indicate_stat_rssi(); - kiss_indicate_stat_snr(); - kiss_write_packet(packet_interface); - } - for (int i = 0; i < INTERFACE_COUNT; i++) { selected_radio = interface_obj_sorted[i]; @@ -1321,23 +1321,13 @@ void poll_buffers() { } void packet_poll() { - #if MCU_VARIANT == MCU_ESP32 - portENTER_CRITICAL(&update_lock); - #elif MCU_VARIANT == MCU_NRF52 - portENTER_CRITICAL(); - #endif // If we have received a packet on an interface which needs to be processed - if (process_packet) { - selected_radio = interface_obj[packet_interface]; + while (!fifo_isempty(&packet_rdy_interfaces)) { + uint8_t packet_int = fifo_pop(&packet_rdy_interfaces); + selected_radio = interface_obj[packet_int]; selected_radio->clearIRQStatus(); selected_radio->handleDio0Rise(); - process_packet = false; } - #if MCU_VARIANT == MCU_ESP32 - portEXIT_CRITICAL(&update_lock); - #elif MCU_VARIANT == MCU_NRF52 - portEXIT_CRITICAL(); - #endif } volatile bool serial_polling = false; diff --git a/Radio.cpp b/Radio.cpp index cb949c2..6b2557f 100644 --- a/Radio.cpp +++ b/Radio.cpp @@ -88,8 +88,7 @@ #define FREQ_DIV_6X (double)pow(2.0, 25.0) #define FREQ_STEP_6X (double)(XTAL_FREQ_6X / FREQ_DIV_6X) -extern bool process_packet; -extern uint8_t packet_interface; +extern FIFOBuffer packet_rdy_interfaces; extern RadioInterface* interface_obj[]; // ISRs cannot provide parameters to the functions they call. Since we have @@ -99,9 +98,7 @@ extern RadioInterface* interface_obj[]; void ISR_VECT onDio0Rise() { for (int i = 0; i < INTERFACE_COUNT; i++) { if (digitalRead(interface_pins[i][5]) == HIGH) { - process_packet = true; - packet_interface = i; - break; + fifo_push(&packet_rdy_interfaces, i); } } } diff --git a/Radio.hpp b/Radio.hpp index fa42abd..44ce5a9 100644 --- a/Radio.hpp +++ b/Radio.hpp @@ -11,6 +11,7 @@ #include #include "Interfaces.h" #include "Boards.h" +#include "src/misc/FIFOBuffer.h" #define MAX_PKT_LENGTH 255