Merge pull request #398 from naokiiwakami/issue-396
Add gtest cases for ISR
This commit is contained in:
2
wiringPi/gtest/.gitignore
vendored
Normal file
2
wiringPi/gtest/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
bin
|
||||
googletest-main
|
||||
92
wiringPi/gtest/Makefile
Normal file
92
wiringPi/gtest/Makefile
Normal file
@@ -0,0 +1,92 @@
|
||||
CXX := g++
|
||||
CXXFLAGS := -std=c++17 -Wall -Wextra -Werror -g \
|
||||
-Igoogletest-main/googletest/include -Igoogletest-main/googlemock/include
|
||||
LDFLAGS := -pthread
|
||||
WIRING_PI_LIBS := -lwiringPi
|
||||
|
||||
# Where to download googletest
|
||||
GTEST_URL := https://github.com/google/googletest/archive/refs/heads/main.zip
|
||||
GTEST_ZIP := googletest.zip
|
||||
GTEST_DIR := googletest-main
|
||||
|
||||
# Output directory
|
||||
BIN_DIR := bin
|
||||
|
||||
# Helper program
|
||||
RUN_ISR_SRC := run_isr.cpp
|
||||
RUN_ISR_BIN := $(BIN_DIR)/run_isr
|
||||
|
||||
# Need BCM1 <-> BCM12 connection
|
||||
TEST_SRCS := \
|
||||
test_isr_both.cpp \
|
||||
test_isr_conflict_between_processes.cpp \
|
||||
test_isr_falling.cpp \
|
||||
test_isr_restart.cpp \
|
||||
test_isr_restart2.cpp \
|
||||
test_isr_rising.cpp \
|
||||
test_isr_rising2.cpp
|
||||
|
||||
# Derive test binaries (in bin/)
|
||||
TEST_BINS := $(addprefix $(BIN_DIR)/, $(TEST_SRCS:.cpp=))
|
||||
|
||||
# gtest/gmock sources
|
||||
GTEST_SRCS := $(GTEST_DIR)/googletest/src/gtest-all.cc
|
||||
GMOCK_SRCS := $(GTEST_DIR)/googlemock/src/gmock-all.cc
|
||||
GTEST_MAIN := $(GTEST_DIR)/googletest/src/gtest_main.cc
|
||||
GTEST_INCLUDES := -I$(GTEST_DIR)/googletest/include -I$(GTEST_DIR)/googlemock/include
|
||||
|
||||
GTEST_OBJS := $(GTEST_SRCS:.cc=.o)
|
||||
GMOCK_OBJS := $(GMOCK_SRCS:.cc=.o)
|
||||
GTEST_MAIN_OBJ := $(GTEST_MAIN:.cc=.o)
|
||||
|
||||
# Default: build everything
|
||||
all: $(GTEST_DIR) $(BIN_DIR) $(TEST_BINS) $(RUN_ISR_BIN)
|
||||
|
||||
# Rule: build normal test binaries
|
||||
$(filter-out $(BIN_DIR)/test_conflict_between_processes,$(TEST_BINS)): $(BIN_DIR)/%: %.cpp $(GTEST_OBJS) $(GMOCK_OBJS) $(GTEST_MAIN_OBJ)
|
||||
$(CXX) $(CXXFLAGS) $< $(GTEST_OBJS) $(GMOCK_OBJS) $(GTEST_MAIN_OBJ) -o $@ $(LDFLAGS) $(WIRING_PI_LIBS)
|
||||
|
||||
# Special case: test_conflict_between_processes depends on run_isr
|
||||
$(BIN_DIR)/test_conflict_between_processes: test_conflict_between_processes.cpp $(GTEST_OBJS) $(GMOCK_OBJS) $(GTEST_MAIN_OBJ) $(RUN_ISR_BIN)
|
||||
$(CXX) $(CXXFLAGS) $< $(GTEST_OBJS) $(GMOCK_OBJS) $(GTEST_MAIN_OBJ) -o $@ $(LDFLAGS) $(WIRING_PI_LIBS)
|
||||
|
||||
# Build run_isr
|
||||
$(RUN_ISR_BIN): $(RUN_ISR_SRC) | $(BIN_DIR)
|
||||
$(CXX) $(CXXFLAGS) $< -o $@ $(WIRING_PI_LIBS)
|
||||
|
||||
# Ensure bin directory exists
|
||||
$(BIN_DIR):
|
||||
mkdir -p $(BIN_DIR)
|
||||
|
||||
# Download googletest if not already present
|
||||
$(GTEST_DIR):
|
||||
@echo "Downloading GoogleTest..."
|
||||
curl -L $(GTEST_URL) -o $(GTEST_ZIP)
|
||||
unzip -q $(GTEST_ZIP)
|
||||
rm -f $(GTEST_ZIP)
|
||||
|
||||
# Generic rules for compiling gtest/gmock sources
|
||||
%.o: %.cc
|
||||
$(CXX) $(CXXFLAGS) $(GTEST_INCLUDES) -I$(GTEST_DIR)/googletest -I$(GTEST_DIR)/googlemock -c $< -o $@
|
||||
|
||||
# Run all tests
|
||||
test: all
|
||||
@failed=0; \
|
||||
for t in $(TEST_BINS); do \
|
||||
echo "Running $$t..."; \
|
||||
./$$t || failed=1; \
|
||||
done; \
|
||||
if [ $$failed -eq 0 ]; then \
|
||||
echo "✅ All tests passed."; \
|
||||
else \
|
||||
echo "❌ Some tests failed."; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
rm -f $(TEST_BINS) $(RUN_ISR_BIN)
|
||||
|
||||
distclean: clean
|
||||
rm -rf $(GTEST_DIR) $(BIN_DIR)
|
||||
|
||||
.PHONY: all clean distclean test
|
||||
26
wiringPi/gtest/README.md
Normal file
26
wiringPi/gtest/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
## Quick Start
|
||||
|
||||
g++ is required to build the test cases.
|
||||
|
||||
Connect wPi pin 31 (BCM 1) and wPi pin 26 (BCM 12) to run ISR tests.
|
||||
Also, wPi pin 28 (BCM 20) should be unconnected.
|
||||
|
||||
Run `make test` or do following to run the test:
|
||||
|
||||
```
|
||||
make googletest-main
|
||||
make -j 4
|
||||
make test
|
||||
```
|
||||
|
||||
To clean up the environment:
|
||||
|
||||
```
|
||||
make clean
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
Googletest is downloaded during
|
||||
the build for the first time. The downloaded items are in directory `googletest-main`. `make clean` keeps this directory. Run `make distclean`
|
||||
to erase all built images including googletest.
|
||||
31
wiringPi/gtest/run_isr.cpp
Normal file
31
wiringPi/gtest/run_isr.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Helper program of test_conflict_between_processes.
|
||||
*
|
||||
* The program configures ISR on pin 31 (BCM 1) and polls for a termination request.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
|
||||
static uint8_t ok_to_stop = 0;
|
||||
static void noop() {
|
||||
fprintf(stderr, "interrupted\n");
|
||||
ok_to_stop = 1;
|
||||
}
|
||||
|
||||
int main(int, char *[]) {
|
||||
fprintf(stderr, "start\n");
|
||||
wiringPiSetup();
|
||||
if (wiringPiISR(LISTENER_PIN, INT_EDGE_RISING, noop)) {
|
||||
fprintf(stderr, "failed to start listener\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "start listening\n");
|
||||
|
||||
while (!ok_to_stop) {
|
||||
delay(1000);
|
||||
}
|
||||
fprintf(stderr, "bye\n");
|
||||
}
|
||||
51
wiringPi/gtest/test_isr_both.cpp
Normal file
51
wiringPi/gtest/test_isr_both.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <time.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define TRIGGER_PIN 26 // BCM 12
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
|
||||
/**
|
||||
* Tests ISR for both edges.
|
||||
*/
|
||||
class ISRBoth : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
wiringPiSetup();
|
||||
pinMode(TRIGGER_PIN, OUTPUT);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
wiringPiISR(LISTENER_PIN, INT_EDGE_BOTH, ISRBoth::TriggerCount);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static uint32_t count;
|
||||
static void TriggerCount() { ++count; }
|
||||
|
||||
protected:
|
||||
virtual void SetUp() { count = 0; }
|
||||
|
||||
virtual void TearDown() {
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t ISRBoth::count = 0;
|
||||
|
||||
TEST_F(ISRBoth, Fundamental) {
|
||||
EXPECT_EQ(count, 0u);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 2u);
|
||||
}
|
||||
|
||||
TEST_F(ISRBoth, ThreeTriggers) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
digitalWrite(TRIGGER_PIN, (i + 1) % 2);
|
||||
delay(10);
|
||||
}
|
||||
EXPECT_EQ(count, 5u);
|
||||
}
|
||||
68
wiringPi/gtest/test_isr_conflict_between_processes.cpp
Normal file
68
wiringPi/gtest/test_isr_conflict_between_processes.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define TRIGGER_PIN 26 // BCM 12
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
#define ANOTHER_LISTENER_PIN 28 // BCM 20
|
||||
|
||||
static void *remote_isr(void *) {
|
||||
std::system("./bin/run_isr");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests ISR setup conflict between two processes.
|
||||
*
|
||||
* Another program 'run_isr' starts first that occupies the pin 31 for an ISR.
|
||||
* This program should fail to start ISR on the same pin.
|
||||
*/
|
||||
class ISRConflict : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
wiringPiSetup();
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, remote_isr, NULL);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
static void TearDownTestSuite() {
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
static uint32_t count;
|
||||
|
||||
static void TriggerCount() { ++count; }
|
||||
static void TriggerCount2(WPIWfiStatus, void *userdata) {
|
||||
++*(uint32_t *)userdata;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() { count = 0; }
|
||||
|
||||
virtual void TearDown() {
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t ISRConflict::count = 0;
|
||||
|
||||
TEST_F(ISRConflict, TestConflictBetweenProcesses) {
|
||||
// The ISRs should fail to start because run_isr is listening on the
|
||||
// same port
|
||||
EXPECT_EQ(
|
||||
wiringPiISR(LISTENER_PIN, INT_EDGE_FALLING, ISRConflict::TriggerCount),
|
||||
-1);
|
||||
EXPECT_EQ(wiringPiISR2(LISTENER_PIN, INT_EDGE_FALLING,
|
||||
ISRConflict::TriggerCount2, 0, &ISRConflict::count),
|
||||
-1);
|
||||
|
||||
// to exit run_isr
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
}
|
||||
57
wiringPi/gtest/test_isr_falling.cpp
Normal file
57
wiringPi/gtest/test_isr_falling.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <time.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define TRIGGER_PIN 26 // BCM 12
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
|
||||
/**
|
||||
* Tests ISR for falling edges.
|
||||
*/
|
||||
class ISRFalling : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
wiringPiSetup();
|
||||
pinMode(TRIGGER_PIN, OUTPUT);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
wiringPiISR(LISTENER_PIN, INT_EDGE_FALLING, ISRFalling::TriggerCount);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static void TearDownTestSuite() { digitalWrite(TRIGGER_PIN, LOW); }
|
||||
|
||||
static uint32_t count;
|
||||
static void TriggerCount() { ++count; }
|
||||
|
||||
protected:
|
||||
virtual void SetUp() { count = 0; }
|
||||
|
||||
virtual void TearDown() {
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t ISRFalling::count = 0;
|
||||
|
||||
TEST_F(ISRFalling, Fundamental) {
|
||||
EXPECT_EQ(count, 0u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
}
|
||||
|
||||
TEST_F(ISRFalling, ThreeTriggers) {
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
count = 0;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
delay(10);
|
||||
digitalWrite(TRIGGER_PIN, (i + 1) % 2);
|
||||
}
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 3u);
|
||||
}
|
||||
67
wiringPi/gtest/test_isr_restart.cpp
Normal file
67
wiringPi/gtest/test_isr_restart.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <time.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define TRIGGER_PIN 26 // BCM 12
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
#define ANOTHER_LISTENER_PIN 28 // BCM 20
|
||||
|
||||
/**
|
||||
* Tests restarting ISR.
|
||||
*/
|
||||
class ISRRestart : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
wiringPiSetup();
|
||||
pinMode(TRIGGER_PIN, OUTPUT);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
wiringPiISR(LISTENER_PIN, INT_EDGE_RISING, ISRRestart::TriggerCount);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static uint32_t count;
|
||||
|
||||
static void TriggerCount() { ++count; }
|
||||
|
||||
static void TriggerCountDown() { --count; }
|
||||
|
||||
protected:
|
||||
virtual void SetUp() { count = 0; }
|
||||
|
||||
virtual void TearDown() {
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t ISRRestart::count = 0;
|
||||
|
||||
TEST_F(ISRRestart, RestartISR) {
|
||||
// fundamental ISR test
|
||||
EXPECT_EQ(count, 0u);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
|
||||
// stop the ISR
|
||||
EXPECT_EQ(wiringPiISRStop(LISTENER_PIN), 0);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
|
||||
// start another ISR on the same pin
|
||||
EXPECT_EQ(
|
||||
wiringPiISR(LISTENER_PIN, INT_EDGE_FALLING, ISRRestart::TriggerCountDown),
|
||||
0);
|
||||
delay(100);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 0u);
|
||||
}
|
||||
109
wiringPi/gtest/test_isr_restart2.cpp
Normal file
109
wiringPi/gtest/test_isr_restart2.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <time.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define TRIGGER_PIN 26 // BCM 12
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
#define ANOTHER_LISTENER_PIN 28 // BCM 20
|
||||
|
||||
struct counters {
|
||||
int32_t *primary;
|
||||
int32_t *secondary;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests restarting ISR using function wiringPiISR2().
|
||||
*/
|
||||
class ISRRestart2 : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
wiringPiSetup();
|
||||
pinMode(TRIGGER_PIN, OUTPUT);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
counters_a.primary = &count;
|
||||
counters_a.secondary = &count2;
|
||||
counters_b.primary = &count;
|
||||
counters_b.secondary = &count3;
|
||||
wiringPiISR2(LISTENER_PIN, INT_EDGE_RISING, ISRRestart2::TriggerCount, 1000,
|
||||
&counters_a);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static int32_t count;
|
||||
static int32_t count2;
|
||||
static int32_t count3;
|
||||
|
||||
static counters counters_a;
|
||||
static counters counters_b;
|
||||
|
||||
static void TriggerCount(WPIWfiStatus, void *userdata) {
|
||||
struct counters *counters = (struct counters *)userdata;
|
||||
++*counters->primary;
|
||||
++*counters->secondary;
|
||||
}
|
||||
|
||||
static void TriggerCountDown(WPIWfiStatus, void *userdata) {
|
||||
struct counters *counters = (struct counters *)userdata;
|
||||
++*counters->primary;
|
||||
--*counters->secondary;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
count = 0;
|
||||
count2 = 0;
|
||||
count3 = 0;
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
}
|
||||
};
|
||||
|
||||
int32_t ISRRestart2::count = 0;
|
||||
int32_t ISRRestart2::count2 = 0;
|
||||
int32_t ISRRestart2::count3 = 0;
|
||||
struct counters ISRRestart2::counters_a;
|
||||
struct counters ISRRestart2::counters_b;
|
||||
|
||||
TEST_F(ISRRestart2, RestartISR2) {
|
||||
// fundamental ISR2 test
|
||||
EXPECT_EQ(count, 0);
|
||||
EXPECT_EQ(count2, 0);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_EQ(count2, 1);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_EQ(count2, 1);
|
||||
|
||||
// stop the ISR
|
||||
EXPECT_EQ(wiringPiISRStop(LISTENER_PIN), 0);
|
||||
delay(100);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_EQ(count2, 1);
|
||||
EXPECT_EQ(count3, 0);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
|
||||
// start another ISR2 on the same pin
|
||||
EXPECT_EQ(wiringPiISR2(LISTENER_PIN, INT_EDGE_FALLING,
|
||||
ISRRestart2::TriggerCountDown, 0, &counters_b),
|
||||
0);
|
||||
delay(100);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_EQ(count2, 1);
|
||||
EXPECT_EQ(count3, 0);
|
||||
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 2);
|
||||
EXPECT_EQ(count2, 1);
|
||||
EXPECT_EQ(count3, -1);
|
||||
}
|
||||
80
wiringPi/gtest/test_isr_rising.cpp
Normal file
80
wiringPi/gtest/test_isr_rising.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <time.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define TRIGGER_PIN 26 // BCM 12
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
#define ANOTHER_LISTENER_PIN 28 // BCM 20
|
||||
|
||||
/**
|
||||
* Tests ISR for rising edges.
|
||||
*/
|
||||
class ISRRising : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
wiringPiSetup();
|
||||
pinMode(TRIGGER_PIN, OUTPUT);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
wiringPiISR(LISTENER_PIN, INT_EDGE_RISING, ISRRising::TriggerCount);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static uint32_t count;
|
||||
|
||||
static void TriggerCount() { ++count; }
|
||||
|
||||
static void TriggerCountDown() { --count; }
|
||||
|
||||
protected:
|
||||
virtual void SetUp() { count = 0; }
|
||||
|
||||
virtual void TearDown() {
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t ISRRising::count = 0;
|
||||
|
||||
TEST_F(ISRRising, Fundamental) {
|
||||
EXPECT_EQ(count, 0u);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
}
|
||||
|
||||
TEST_F(ISRRising, ThreeTriggers) {
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
count = 0;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
delay(10);
|
||||
digitalWrite(TRIGGER_PIN, i % 2);
|
||||
}
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 3u);
|
||||
}
|
||||
|
||||
TEST_F(ISRRising, ISRInitConflict) {
|
||||
// this initialization should fail for ISR conflict
|
||||
EXPECT_EQ(
|
||||
wiringPiISR(LISTENER_PIN, INT_EDGE_FALLING, ISRRising::TriggerCountDown),
|
||||
-1);
|
||||
// ensure the initialization above has released the mutex lock
|
||||
EXPECT_EQ(wiringPiISR(ANOTHER_LISTENER_PIN, INT_EDGE_RISING,
|
||||
ISRRising::TriggerCountDown),
|
||||
0);
|
||||
delay(100);
|
||||
|
||||
// ensure the existing ISR has not broken
|
||||
EXPECT_EQ(count, 0u);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
}
|
||||
135
wiringPi/gtest/test_isr_rising2.cpp
Normal file
135
wiringPi/gtest/test_isr_rising2.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <time.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
#define TRIGGER_PIN 26 // BCM 12
|
||||
#define LISTENER_PIN 31 // BCM 1
|
||||
#define ANOTHER_LISTENER_PIN 28 // BCM 20
|
||||
|
||||
struct counters {
|
||||
uint32_t *primary;
|
||||
uint32_t *secondary;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests ISR for rising edges.
|
||||
* Function wiringPiISR2 is used for the configuraiton.
|
||||
*/
|
||||
class ISRRising2 : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
wiringPiSetup();
|
||||
pinMode(TRIGGER_PIN, OUTPUT);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
counters_a.primary = &count;
|
||||
counters_a.secondary = &count2;
|
||||
counters_b.primary = &count;
|
||||
counters_b.secondary = &count3;
|
||||
wiringPiISR2(LISTENER_PIN, INT_EDGE_RISING, ISRRising2::TriggerCount, 1000,
|
||||
&counters_a);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static uint32_t count;
|
||||
static uint32_t count2;
|
||||
static uint32_t count3;
|
||||
|
||||
static counters counters_a;
|
||||
static counters counters_b;
|
||||
|
||||
static void TriggerCount(WPIWfiStatus, void *userdata) {
|
||||
struct counters *counters = (struct counters *)userdata;
|
||||
++*counters->primary;
|
||||
++*counters->secondary;
|
||||
}
|
||||
|
||||
static void TriggerCountDown(WPIWfiStatus, void *userdata) {
|
||||
struct counters *counters = (struct counters *)userdata;
|
||||
++*counters->primary;
|
||||
--*counters->secondary;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
count = 0;
|
||||
count2 = 0;
|
||||
count3 = 0;
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t ISRRising2::count = 0;
|
||||
uint32_t ISRRising2::count2 = 0;
|
||||
uint32_t ISRRising2::count3 = 0;
|
||||
struct counters ISRRising2::counters_a;
|
||||
struct counters ISRRising2::counters_b;
|
||||
|
||||
TEST_F(ISRRising2, Fundamental) {
|
||||
EXPECT_EQ(count, 0u);
|
||||
EXPECT_EQ(count2, 0u);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
EXPECT_EQ(count2, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
EXPECT_EQ(count2, 1u);
|
||||
}
|
||||
|
||||
TEST_F(ISRRising2, ThreeTriggers) {
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
count = 0;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
delay(10);
|
||||
digitalWrite(TRIGGER_PIN, i % 2);
|
||||
}
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 3u);
|
||||
}
|
||||
|
||||
TEST_F(ISRRising2, Debounce) {
|
||||
delay(10);
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
digitalWrite(TRIGGER_PIN, (i + 1) % 2);
|
||||
}
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
}
|
||||
|
||||
TEST_F(ISRRising2, ISRInitConflict) {
|
||||
// this initialization should fail for ISR conflict
|
||||
EXPECT_EQ(wiringPiISR2(LISTENER_PIN, INT_EDGE_FALLING,
|
||||
ISRRising2::TriggerCountDown, 0, &counters_b),
|
||||
-1);
|
||||
// ensure the initialization above has released the mutex lock
|
||||
EXPECT_EQ(wiringPiISR2(ANOTHER_LISTENER_PIN, INT_EDGE_BOTH,
|
||||
ISRRising2::TriggerCountDown, 0, &counters_b),
|
||||
0);
|
||||
delay(100);
|
||||
|
||||
// ensure the existing ISR has not broken
|
||||
EXPECT_EQ(count, 0u);
|
||||
EXPECT_EQ(count2, 0u);
|
||||
digitalWrite(TRIGGER_PIN, HIGH);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
EXPECT_EQ(count2, 1u);
|
||||
digitalWrite(TRIGGER_PIN, LOW);
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
EXPECT_EQ(count2, 1u);
|
||||
|
||||
delay(10);
|
||||
count = 0;
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
digitalWrite(TRIGGER_PIN, (i + 1) % 2);
|
||||
}
|
||||
delay(10);
|
||||
EXPECT_EQ(count, 1u);
|
||||
}
|
||||
Reference in New Issue
Block a user