From 1bee723a7d4cfe2af52bd49b7da2b963ded6efea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sun, 2 Oct 2016 00:11:09 +0000 Subject: [PATCH 1/2] Use ring buffer and semaphore to eliminate busy wait in sniffer tool. Apply relevant changes from this fork: https://github.com/UrbaneChimp/433Utils/commit/3f2517efffd870d571302231380410f3ad431ff1?w=0 --- RCSwitch.cpp | 33 +++++++++++++++++++++++++++++++++ RCSwitch.h | 17 +++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/RCSwitch.cpp b/RCSwitch.cpp index 3ff7374..941f425 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -96,6 +96,11 @@ const unsigned int RCSwitch::nSeparationLimit = 4600; // according to discussion on issue #14 it might be more suitable to set the separation // limit to the same time as the 'low' part of the sync signal for the current protocol. unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; + +unsigned long RCSwitch::events[RCSWITCH_MAX_EVENTS]; +int RCSwitch::eventsHead = 0; +int RCSwitch::eventsTail = 0; +sem_t RCSwitch::eventSem; #endif RCSwitch::RCSwitch() { @@ -106,6 +111,8 @@ RCSwitch::RCSwitch() { this->nReceiverInterrupt = -1; this->setReceiveTolerance(60); RCSwitch::nReceivedValue = 0; + + ::sem_init(&eventSem, 0, 0); #endif } @@ -647,6 +654,8 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun RCSwitch::nReceivedBitlength = (changeCount - 1) / 2; RCSwitch::nReceivedDelay = delay; RCSwitch::nReceivedProtocol = p; + + RCSwitch::pushEvent(code); } return true; @@ -693,4 +702,28 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() { RCSwitch::timings[changeCount++] = duration; lastTime = time; } + +/** + * Pushes an event onto the end of the events ring. + */ +void RCSwitch::pushEvent(unsigned long event) { + RCSwitch::events[RCSwitch::eventsTail++] = event; + if (RCSwitch::eventsTail >= RCSWITCH_MAX_EVENTS) { + RCSwitch::eventsTail = 0; + } + ::sem_post(&eventSem); +} + +/** + * Blocks until the events ring contains at least one event then pops + * an event from the head of the events ring and returns it. + */ +unsigned long RCSwitch::popEvent() { + ::sem_wait(&eventSem); + unsigned long event = RCSwitch::events[RCSwitch::eventsHead++]; + if (RCSwitch::eventsHead >= RCSWITCH_MAX_EVENTS) { + RCSwitch::eventsHead = 0; + } + return event; +} #endif diff --git a/RCSwitch.h b/RCSwitch.h index 9424e12..acd1564 100644 --- a/RCSwitch.h +++ b/RCSwitch.h @@ -47,6 +47,10 @@ #include +#if not defined( RCSwitchDisableReceiving ) + #include +#endif + // At least for the ATTiny X4/X5, receiving has to be disabled due to // missing libm depencies (udivmodhi4) @@ -58,6 +62,10 @@ // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync #define RCSWITCH_MAX_CHANGES 67 +#if not defined( RCSwitchDisableReceiving ) + #define RCSWITCH_MAX_EVENTS 100 +#endif + class RCSwitch { public: @@ -85,6 +93,8 @@ class RCSwitch { bool available(); void resetAvailable(); + unsigned long popEvent(); + unsigned long getReceivedValue(); unsigned int getReceivedBitlength(); unsigned int getReceivedDelay(); @@ -146,6 +156,13 @@ class RCSwitch { * timings[0] contains sync timing, followed by a number of bits */ static unsigned int timings[RCSWITCH_MAX_CHANGES]; + + static void pushEvent(unsigned long); + + static unsigned long events[RCSWITCH_MAX_EVENTS]; + static int eventsHead; + static int eventsTail; + static sem_t eventSem; #endif From 63a7dcf7b0c316133e9b422d5befa36d45e0e7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sun, 2 Oct 2016 11:34:27 +0000 Subject: [PATCH 2/2] add RCSwitchEnableBlockingReceive flag --- RCSwitch.cpp | 8 ++++++++ RCSwitch.h | 17 +++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/RCSwitch.cpp b/RCSwitch.cpp index 941f425..59f3e1d 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -97,11 +97,13 @@ const unsigned int RCSwitch::nSeparationLimit = 4600; // limit to the same time as the 'low' part of the sync signal for the current protocol. unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; +#if defined( RCSwitchEnableBlockingReceive ) unsigned long RCSwitch::events[RCSWITCH_MAX_EVENTS]; int RCSwitch::eventsHead = 0; int RCSwitch::eventsTail = 0; sem_t RCSwitch::eventSem; #endif +#endif RCSwitch::RCSwitch() { this->nTransmitterPin = -1; @@ -112,8 +114,10 @@ RCSwitch::RCSwitch() { this->setReceiveTolerance(60); RCSwitch::nReceivedValue = 0; + #if defined( RCSwitchEnableBlockingReceive ) ::sem_init(&eventSem, 0, 0); #endif + #endif } /** @@ -655,7 +659,9 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun RCSwitch::nReceivedDelay = delay; RCSwitch::nReceivedProtocol = p; + #if defined( RCSwitchEnableBlockingReceive ) RCSwitch::pushEvent(code); + #endif } return true; @@ -703,6 +709,7 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() { lastTime = time; } +#if defined( RCSwitchEnableBlockingReceive ) /** * Pushes an event onto the end of the events ring. */ @@ -727,3 +734,4 @@ unsigned long RCSwitch::popEvent() { return event; } #endif +#endif diff --git a/RCSwitch.h b/RCSwitch.h index acd1564..10f918b 100644 --- a/RCSwitch.h +++ b/RCSwitch.h @@ -41,28 +41,29 @@ #include /* memcpy */ #include /* abs */ #include + + #if not defined ( RCSwitchDisableReceiving ) + #define RCSwitchEnableBlockingReceive + #include + #endif #else #include "WProgram.h" #endif #include -#if not defined( RCSwitchDisableReceiving ) - #include -#endif - // At least for the ATTiny X4/X5, receiving has to be disabled due to // missing libm depencies (udivmodhi4) #if defined( __AVR_ATtinyX5__ ) or defined ( __AVR_ATtinyX4__ ) -#define RCSwitchDisableReceiving + #define RCSwitchDisableReceiving #endif // Number of maximum High/Low changes per packet. // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync #define RCSWITCH_MAX_CHANGES 67 -#if not defined( RCSwitchDisableReceiving ) +#if defined( RCSwitchEnableBlockingReceive ) #define RCSWITCH_MAX_EVENTS 100 #endif @@ -93,7 +94,9 @@ class RCSwitch { bool available(); void resetAvailable(); + #if defined( RCSwitchEnableBlockingReceive ) unsigned long popEvent(); + #endif unsigned long getReceivedValue(); unsigned int getReceivedBitlength(); @@ -157,6 +160,7 @@ class RCSwitch { */ static unsigned int timings[RCSWITCH_MAX_CHANGES]; + #if defined( RCSwitchEnableBlockingReceive ) static void pushEvent(unsigned long); static unsigned long events[RCSWITCH_MAX_EVENTS]; @@ -164,6 +168,7 @@ class RCSwitch { static int eventsTail; static sem_t eventSem; #endif + #endif };