Skip to content

Commit 2de08f2

Browse files
authored
Merge pull request WiringPi#311 from WiringPi/test
Unit Test Bench
2 parents f524fdf + 3639bd3 commit 2de08f2

File tree

4 files changed

+198
-6
lines changed

4 files changed

+198
-6
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.13
1+
3.14

version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
#define VERSION "3.13"
1+
#define VERSION "3.14"
22
#define VERSION_MAJOR 3
3-
#define VERSION_MINOR 13
3+
#define VERSION_MINOR 14

wiringPi/test/Makefile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ CFLAGS = -Wall
33
LDFLAGS =
44

55
# Need BCM19 <-> BCM26, +PWM: BCM12 <-> BCM13, BCM18 <-> BCM17 connected (1kOhm)
6-
tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test8_pwm wiringpi_test9_pwm
6+
tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm
77

88
# Need XO hardware
99
xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pwm wiringpi_test9_pwm
@@ -13,6 +13,9 @@ pifacetests = wiringpi_piface_test1 wiringpi_test8_pwm wiringpi_test9_pwm
1313

1414
all: $(tests) $(xotests) $(pifacetests)
1515

16+
wiringpi_test0_version:
17+
${CC} ${CFLAGS} wiringpi_test0_version.c -o wiringpi_test0_version -lwiringPi
18+
1619
wiringpi_test1_sysfs:
1720
${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi
1821

@@ -31,8 +34,8 @@ wiringpi_test5_default:
3134
wiringpi_test6_isr:
3235
${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi
3336

34-
wiringpi_test0_version:
35-
${CC} ${CFLAGS} wiringpi_test0_version.c -o wiringpi_test0_version -lwiringPi
37+
wiringpi_test7_bench:
38+
${CC} ${CFLAGS} wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi
3639

3740
wiringpi_test8_pwm:
3841
${CC} ${CFLAGS} wiringpi_test8_pwm.c -o wiringpi_test8_pwm -lwiringPi
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// WiringPi test program: benchmark
2+
// Compile: gcc -Wall wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi
3+
4+
#include "wpi_test.h"
5+
//#include <stdio.h>
6+
//#include <stdlib.h>
7+
//#include <signal.h>
8+
#include <string.h>
9+
#include <time.h>
10+
#include <sys/time.h>
11+
12+
13+
int ToggleValue = 240000000;
14+
float fExpectTimedigitalWrite = 0.1;
15+
float fExpectTimedigitalRead = 0.1;
16+
float fExpectTimepinMode = 0.1;
17+
float fWriteReadDelayFactor = 1.0;
18+
float fWriteReadFactor = 1.0;
19+
float fPi4ExpectTimedigitalWrite = 0.020;
20+
int GPIO = 19;
21+
int GPIOIN = 26;
22+
int RaspberryPiModel = -1;
23+
24+
25+
double ReportElapedTime(const char* msg, int multiop, const float fExpectTime, struct timeval t1, struct timeval t2) {
26+
double elapsedTime, fTimePerOperation, fFreq;
27+
28+
elapsedTime = (t2.tv_sec-t1.tv_sec)+(t2.tv_usec-t1.tv_usec)/1000000.0;
29+
fTimePerOperation = elapsedTime*1000000.0/ToggleValue/multiop;
30+
fFreq = 1.0f/(fTimePerOperation*2); //ToggleValue/elapsedTime/1000000.0;
31+
printf(" % 9d took %.3f s, Time per operation %.3f us (toggle Freq %.3f MHz) \n",
32+
ToggleValue, elapsedTime, fTimePerOperation, fFreq);
33+
CheckSameFloat(msg, fTimePerOperation, fExpectTime, fExpectTime*0.2f);
34+
35+
return fTimePerOperation;
36+
}
37+
38+
39+
int main (void) {
40+
struct timeval t1, t2;
41+
42+
if (wiringPiSetupGpio() == -1) {
43+
printf("wiringPiSetupGpio failed\n\n");
44+
exit(EXIT_FAILURE);
45+
}
46+
47+
int rev, mem, maker, overVolted;
48+
piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted);
49+
CheckNotSame("Model: ", RaspberryPiModel, -1);
50+
if (!piBoard40Pin()) {
51+
GPIO = 23;
52+
GPIOIN = 24;
53+
}
54+
55+
switch(RaspberryPiModel) {
56+
case PI_MODEL_A:
57+
case PI_MODEL_B: //ARM=800MHz
58+
case PI_MODEL_BP:
59+
case PI_MODEL_AP:
60+
case PI_MODEL_CM:
61+
fExpectTimedigitalWrite = 0.132; //us;
62+
fExpectTimedigitalRead = 0.171; //us
63+
fExpectTimepinMode = 0.334; //us
64+
break;
65+
case PI_MODEL_ZERO:
66+
case PI_MODEL_ZERO_W: //ARM=1000MHz
67+
fExpectTimedigitalWrite = 0.104; //us;
68+
fExpectTimedigitalRead = 0.135; //us
69+
fExpectTimepinMode = 0.250; //us
70+
break;
71+
case PI_MODEL_2:
72+
ToggleValue /= 4;
73+
break;
74+
case PI_MODEL_3B:
75+
case PI_MODEL_CM3:
76+
case PI_MODEL_3BP:
77+
case PI_MODEL_3AP:
78+
case PI_MODEL_CM3P:
79+
case PI_MODEL_ZERO_2W:
80+
ToggleValue /= 2;
81+
break;
82+
case PI_MODEL_4B: //ARM=1500MHz
83+
case PI_MODEL_400:
84+
case PI_MODEL_CM4:
85+
case PI_MODEL_CM4S:
86+
fExpectTimedigitalWrite = 0.020; //us
87+
fExpectTimedigitalRead = 0.038; //us
88+
fExpectTimepinMode = 0.121; //us
89+
fWriteReadDelayFactor = 1.86;
90+
break;
91+
default:
92+
if (piRP1Model()) {
93+
// So far expect all Pi5 / RP1 hardware has same performance
94+
printf("Raspberry Pi with RP1 chip found\n");
95+
fExpectTimedigitalWrite = 0.025; //us
96+
fExpectTimedigitalRead = 0.323; //us
97+
fExpectTimepinMode = 0.200; //us
98+
fWriteReadDelayFactor = 3.2;
99+
} else {
100+
printf("Unknown Raspberry Pi found, exit\n");
101+
return(EXIT_FAILURE);
102+
}
103+
break;
104+
}
105+
fWriteReadFactor = fExpectTimedigitalRead/fExpectTimedigitalWrite;
106+
ToggleValue /= (fExpectTimedigitalWrite/fPi4ExpectTimedigitalWrite);
107+
108+
printf("WiringPi GPIO operation time test program (using GPIO %d/%d)\n", GPIO, GPIOIN);
109+
pinMode(GPIO, OUTPUT);
110+
111+
printf("\n% 3d million times digitalWrite ...\n", ToggleValue/1000000);
112+
gettimeofday(&t1, NULL);
113+
for (int loop=1; loop<ToggleValue; loop++) {
114+
digitalWrite(GPIO, HIGH);
115+
digitalWrite(GPIO, LOW);
116+
}
117+
gettimeofday(&t2, NULL);
118+
double OpTimeWrite = ReportElapedTime("digitalWrite", 2, fExpectTimedigitalWrite, t1, t2);
119+
120+
digitalWrite(GPIO, LOW);
121+
pinMode(GPIOIN, INPUT);
122+
123+
ToggleValue /=(fExpectTimedigitalRead/fExpectTimedigitalWrite);
124+
printf("\n% 3d million times digitalRead ...\n", ToggleValue/1000000);
125+
gettimeofday(&t1, NULL);
126+
for (int loop=1; loop<ToggleValue; loop++) {
127+
digitalRead(GPIOIN);
128+
digitalRead(GPIOIN);
129+
}
130+
gettimeofday(&t2, NULL);
131+
double OpTimeRead = ReportElapedTime("digitalRead", 2, fExpectTimedigitalRead, t1, t2);
132+
133+
if (!piRP1Model()) {
134+
ToggleValue /= 4;
135+
} else {
136+
ToggleValue *= 1.5;
137+
}
138+
printf("\n% 3d million times pinMode...\n", ToggleValue/1000000);
139+
gettimeofday(&t1, NULL);
140+
for (int loop=1; loop<ToggleValue; loop++) {
141+
pinMode(GPIO, OUTPUT);
142+
pinMode(GPIOIN, INPUT);
143+
}
144+
gettimeofday(&t2, NULL);
145+
ReportElapedTime("pinMode", 2, fExpectTimepinMode, t1, t2);
146+
147+
printf("\nToggle % 3d million times pinMode and digitalWrite ..\n", ToggleValue/1000000);
148+
gettimeofday(&t1, NULL);
149+
for (int loop=1; loop<ToggleValue; loop++) {
150+
pinMode(GPIO, OUTPUT);
151+
digitalWrite(GPIO, LOW);
152+
digitalWrite(GPIO, HIGH);
153+
pinMode(GPIO, INPUT);
154+
}
155+
gettimeofday(&t2, NULL);
156+
ReportElapedTime("pinMode and digitalWrite", 2, fExpectTimepinMode+fExpectTimedigitalWrite, t1, t2);
157+
158+
if (!piRP1Model()) {
159+
ToggleValue *= 1.5;
160+
} else {
161+
ToggleValue /= 5;
162+
}
163+
pinMode(GPIO, OUTPUT);
164+
printf("\nToggle % 3d million times digitalRead and digitalWrite ..\n", ToggleValue/1000000);
165+
gettimeofday(&t1, NULL);
166+
for (int loop=1; loop<ToggleValue; loop++) {
167+
digitalWrite(GPIO, HIGH);
168+
digitalRead(GPIOIN);
169+
digitalWrite(GPIO, LOW);
170+
digitalRead(GPIOIN);
171+
}
172+
gettimeofday(&t2, NULL);
173+
double fTimePerOperation = ReportElapedTime("digitalRead and digitalWrite", 2, (fExpectTimedigitalWrite+fExpectTimedigitalRead)*fWriteReadDelayFactor, t1, t2);
174+
175+
printf("\n");
176+
CheckSameFloat("digitalWrite vs. digitalRead factor", OpTimeRead/OpTimeWrite, fWriteReadFactor, 0.3);
177+
CheckSameFloat("digitalWrite and digitalRead alternating factor", fTimePerOperation/(fExpectTimedigitalWrite+fExpectTimedigitalRead), fWriteReadDelayFactor, 0.2);
178+
if (piRP1Model()) {
179+
printf("\nRasperry Pi with RP1 chip:\n");
180+
printf(" * digitalRead has very slow speed, much slower then digitalWrite, factor %.1f (typical Pi4 ~1.9)\n", fWriteReadFactor);
181+
printf(" * Alternating read/write operation has slow speed, factor %.2f (typical Pi4 ~1.86) to single operation time\n", fWriteReadDelayFactor);
182+
}
183+
184+
digitalWrite(GPIO, LOW);
185+
pinMode(GPIO, INPUT);
186+
187+
return(EXIT_SUCCESS);
188+
}
189+

0 commit comments

Comments
 (0)