Fix race condition on multiple interfaces receiving at once

This commit is contained in:
jacob.eva 2024-09-04 17:37:09 +01:00
parent 6035e1a2c2
commit 81aff16c2d
No known key found for this signature in database
GPG Key ID: 0B92E083BBCCAA1E
4 changed files with 36 additions and 41 deletions

View File

@ -28,6 +28,8 @@
#define CABLE_STATE_DISCONNECTED 0x00 #define CABLE_STATE_DISCONNECTED 0x00
#define CABLE_STATE_CONNECTED 0x01 #define CABLE_STATE_CONNECTED 0x01
uint8_t cable_state = CABLE_STATE_DISCONNECTED; uint8_t cable_state = CABLE_STATE_DISCONNECTED;
#define MAX_INTERFACES 12
#define BT_STATE_NA 0xff #define BT_STATE_NA 0xff
#define BT_STATE_OFF 0x00 #define BT_STATE_OFF 0x00
@ -88,6 +90,11 @@
uint8_t seq = 0xFF; uint8_t seq = 0xFF;
uint16_t read_len = 0; uint16_t read_len = 0;
FIFOBuffer packet_rdy_interfaces;
uint8_t packet_rdy_interfaces_buf[MAX_INTERFACES];
// Incoming packet buffer // Incoming packet buffer
uint8_t pbuf[MTU]; uint8_t pbuf[MTU];

View File

@ -66,9 +66,6 @@ char sbuf[128];
bool packet_ready = false; bool packet_ready = false;
volatile bool process_packet = false;
volatile uint8_t packet_interface = 0;
uint8_t *packet_queue[INTERFACE_COUNT]; uint8_t *packet_queue[INTERFACE_COUNT];
void setup() { void setup() {
@ -140,6 +137,10 @@ void setup() {
packet_queue[i] = (uint8_t*)malloc(getQueueSize(i)+1); 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 // Create and configure interface objects
for (uint8_t i = 0; i < INTERFACE_COUNT; i++) { for (uint8_t i = 0; i < INTERFACE_COUNT; i++) {
switch (interfaces[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) { if (!promisc) {
selected_radio = interface_obj[index]; 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); getPacketData(selected_radio, packet_size);
packet_ready = true; 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(); last_rx = millis();
} }
@ -1170,25 +1189,6 @@ void loop() {
// If at least one radio is online then we can continue // If at least one radio is online then we can continue
if (ready) { 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++) { for (int i = 0; i < INTERFACE_COUNT; i++) {
selected_radio = interface_obj_sorted[i]; selected_radio = interface_obj_sorted[i];
@ -1321,23 +1321,13 @@ void poll_buffers() {
} }
void packet_poll() { 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 we have received a packet on an interface which needs to be processed
if (process_packet) { while (!fifo_isempty(&packet_rdy_interfaces)) {
selected_radio = interface_obj[packet_interface]; uint8_t packet_int = fifo_pop(&packet_rdy_interfaces);
selected_radio = interface_obj[packet_int];
selected_radio->clearIRQStatus(); selected_radio->clearIRQStatus();
selected_radio->handleDio0Rise(); 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; volatile bool serial_polling = false;

View File

@ -88,8 +88,7 @@
#define FREQ_DIV_6X (double)pow(2.0, 25.0) #define FREQ_DIV_6X (double)pow(2.0, 25.0)
#define FREQ_STEP_6X (double)(XTAL_FREQ_6X / FREQ_DIV_6X) #define FREQ_STEP_6X (double)(XTAL_FREQ_6X / FREQ_DIV_6X)
extern bool process_packet; extern FIFOBuffer packet_rdy_interfaces;
extern uint8_t packet_interface;
extern RadioInterface* interface_obj[]; extern RadioInterface* interface_obj[];
// ISRs cannot provide parameters to the functions they call. Since we have // ISRs cannot provide parameters to the functions they call. Since we have
@ -99,9 +98,7 @@ extern RadioInterface* interface_obj[];
void ISR_VECT onDio0Rise() { void ISR_VECT onDio0Rise() {
for (int i = 0; i < INTERFACE_COUNT; i++) { for (int i = 0; i < INTERFACE_COUNT; i++) {
if (digitalRead(interface_pins[i][5]) == HIGH) { if (digitalRead(interface_pins[i][5]) == HIGH) {
process_packet = true; fifo_push(&packet_rdy_interfaces, i);
packet_interface = i;
break;
} }
} }
} }

View File

@ -11,6 +11,7 @@
#include <SPI.h> #include <SPI.h>
#include "Interfaces.h" #include "Interfaces.h"
#include "Boards.h" #include "Boards.h"
#include "src/misc/FIFOBuffer.h"
#define MAX_PKT_LENGTH 255 #define MAX_PKT_LENGTH 255