From b1b896582ec696f235925c62d10ce7b726a61cfa Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 11 May 2025 20:21:39 +0200 Subject: [PATCH] #346 gpio wfidb command and unit test improvment --- gpio/gpio.c | 135 ++++++++++++++++++++++++++---------- gpio/test/gpio_test7_wfi.sh | 95 +++++++++++++++---------- 2 files changed, 158 insertions(+), 72 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 9ffb1b7..9fa5bf6 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -161,7 +161,7 @@ void LOAD_DEPRECATED(const char *progName) { ********************************************************************************* */ -static volatile int iterations ; +static volatile int globalIterations ; static volatile int globalCounter ; void printgpioflush(const char* text) { @@ -179,7 +179,7 @@ void printgpio(const char* text) { static void wfi (void) { globalCounter++; - if(globalCounter>=iterations) { + if(globalCounter>=globalIterations) { printgpio("finished\n"); exit (0) ; } else { @@ -187,40 +187,50 @@ static void wfi (void) { } } -void doWfi (int argc, char *argv []) -{ - int pin, mode; - int timeoutSec = 2147483647; - iterations = 1; +static void wfi2(struct WPIWfiStatus wfiStatus, void* userdata) { + (void)wfiStatus; + (void)userdata; + globalCounter++; + if (globalCounter>=globalIterations) { + printgpio("finished\n"); + exit(0); + } else { + printgpioflush("I"); + } +} + + +int get_wfi_edge(const char* arg_cmd, const char* arg_mode) { + if (strcasecmp (arg_mode, "rising") == 0) { + return INT_EDGE_RISING ; + } else if (strcasecmp (arg_mode, "falling") == 0) { + return INT_EDGE_FALLING ; + } else if (strcasecmp (arg_mode, "both") == 0) { + return INT_EDGE_BOTH ; + } else { + fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", arg_cmd, arg_mode) ; + exit (1); + } +} + + +void doWfiInternal(const char* cmd, int pin, int mode, int interations, int timeoutSec, int debounce) { + + globalIterations = interations; globalCounter = 0; - if (argc != 4 && argc != 5 && argc != 6) - { - fprintf (stderr, "Usage: %s wfi pin mode [interations] [timeout sec.]\n", argv [0]) ; - exit (1) ; - } - - pin = atoi (argv [2]) ; - - /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ; - else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ; - else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ; - else - { - fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ; - exit (1) ; - } - if (argc>=5) { - iterations = atoi(argv [4]); - } - if (argc>=6) { - timeoutSec = atoi(argv [5]); - } - - if (wiringPiISR (pin, mode, &wfi) < 0) - { - fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; - exit (1) ; + if (debounce>=0) { + // V2 function + if (wiringPiISR2(pin, mode, &wfi2, debounce, NULL) < 0) { + fprintf (stderr, "%s: Unable to setup ISR2: %s\n", cmd, strerror (errno)); + exit(1); + } + } else { + // classic function + if (wiringPiISR(pin, mode, &wfi) < 0) { + fprintf (stderr, "%s: Unable to setup ISR: %s\n", cmd, strerror (errno)); + exit(1); + } } printgpio("wait for interrupt function call\n"); @@ -229,7 +239,56 @@ void doWfi (int argc, char *argv []) delay (999); } printgpio("\nstopping wait for interrupt\n"); - wiringPiISRStop (pin); + wiringPiISRStop(pin); +} + + +void doWfi(int argc, char *argv []) +{ + int pin, mode, interations=1; + int timeoutSec = 2147483647; + + if (argc != 4 && argc != 5 && argc != 6) { + fprintf (stderr, "Usage: %s wfi pin mode [interations] [timeout sec.]\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv[2]) ; + mode = get_wfi_edge(argv[1], argv[3]); + if (argc>=5) { + interations = atoi(argv[4]); + } + if (argc>=6) { + timeoutSec = atoi(argv[5]); + } + + doWfiInternal(argv[1], pin, mode, interations, timeoutSec, -1); +} + + +void doWfi2(int argc, char *argv []) +{ + int pin, mode, interations=1, debounce=50000; + int timeoutSec = 2147483647; + + if (argc != 4 && argc != 5 && argc != 6 && argc != 7) { + fprintf (stderr, "Usage: %s wfidb pin mode [debounce period microsec.] [interations] [timeout sec.]\n", argv [0]) ; + exit(1); + } + + pin = atoi (argv[2]) ; + mode = get_wfi_edge(argv[1], argv[3]); + if (argc>=5) { + debounce = atoi(argv[4]); + } + if (argc>=6) { + interations = atoi(argv[5]); + } + if (argc>=7) { + timeoutSec = atoi(argv[6]); + } + + doWfiInternal(argv[1], pin, mode, interations, timeoutSec, debounce); } @@ -896,6 +955,10 @@ static void doVersion (char *argv []) } +static void doIs40Pin () +{ + exit(piBoard40Pin()); +} /* * main: @@ -1130,7 +1193,9 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ; else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ; else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ; + else if (strcasecmp (argv [1], "wfidb" ) == 0) doWfi2 (argc, argv) ; else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ; + else if (strcasecmp (argv [1], "is40pin" ) == 0) doIs40Pin () ; else { fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; diff --git a/gpio/test/gpio_test7_wfi.sh b/gpio/test/gpio_test7_wfi.sh index 7f4ef39..a5d2298 100755 --- a/gpio/test/gpio_test7_wfi.sh +++ b/gpio/test/gpio_test7_wfi.sh @@ -7,22 +7,26 @@ NC='\033[0m' # Reset color UNITTEST_OK=true TIMEOUT=8 iteration=0 +GPIOIN=26 +GPIOOUT=19 wait_with_timeout() { local pid=$1 local timeout=$2 iteration=0 + local toggle=0 while kill -0 "$pid" 2>/dev/null; do if [ $iteration -ge $timeout ]; then kill -9 "$pid" 2>/dev/null echo -e "${RED}ERROR: timeout ${timeout}s reached ${NC}" return -1 fi - gpio -g write 19 1 - sleep 1 echo -n . - gpio -g write 19 0 + sleep 1 + toggle=$((1 - toggle)) + gpio -g write $GPIOOUT $toggle + echo -n ${toggle} iteration=$((iteration + 1)) done @@ -30,51 +34,68 @@ wait_with_timeout() { return $? } +wfi_test() { + local edge=$1 + local set_iter=$2 + local set_iterOK=$3 + + #wfi test + if [ $iteration -eq 0 ]; then + gpio -g wfi $GPIOIN "$edge" & + else + gpio -g wfi $GPIOIN "$edge" "$set_iter" & + fi + GPIO_PID=$! + wait_with_timeout "$GPIO_PID" "$TIMEOUT" + EXIT_CODE=$? + echo + if [ $EXIT_CODE -eq 0 ]; then + if [ "$set_iter" -gt 0 ]; then + if [ "$iteration" -eq "$set_iterOK" ]; then + echo -e "${GREEN}wfi "$edge" $set_iter iteration passt (exit code 0)${NC}" + else + echo -e "${RED}wfi "$edge" failed, $iteration iterations of $set_iter is wrong${NC}" + UNITTEST_OK=false + fi + else + echo -e "${GREEN}wfi "$edge" passt (exit code 0)${NC}" + fi + else + echo -e "${RED}wfi "$edge" failed (exit code $EXIT_CODE)${NC}" + UNITTEST_OK=false + fi +} + echo -echo Unit test gpio GPIO19 and GPIO26 - functions: mode, write, wfi +echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfi echo ------------------------------------------------------------------ echo #prepare trigger out -gpio -g mode 19 out -gpio -g write 19 0 +gpio -g mode $GPIOOUT out -#wfi test -gpio -g wfi 26 rising & -GPIO_PID=$! -wait_with_timeout "$GPIO_PID" "$TIMEOUT" -EXIT_CODE=$? -echo -if [ $EXIT_CODE -eq 0 ]; then - echo -e "${GREEN}wfi passt (exit code 0)${NC}" -else - echo -e "${RED}wfi failed (exit code $EXIT_CODE)${NC}" - UNITTEST_OK=false -fi +gpio -g write $GPIOOUT 0 +wfi_test "rising" 0 0 + +gpio -g write $GPIOOUT 1 +wfi_test "falling" 0 0 #wfi iteration test -gpio -g wfi 26 rising 4 & -GPIO_PID=$! -wait_with_timeout "$GPIO_PID" "$TIMEOUT" -EXIT_CODE=$? -echo -if [ $EXIT_CODE -eq 0 ]; then - if [ "$iteration" -eq 5 ]; then - echo -e "${GREEN}wfi iteration passt (exit code 0)${NC}" - else - echo -e "${RED}wfi failed, iteration $iteration wrong${NC}" - UNITTEST_OK=false - fi -else - echo -e "${RED}wfi failed (exit code $EXIT_CODE)${NC}" - UNITTEST_OK=false -fi -gpio -g write 19 0 -gpio -g mode 19 in +gpio -g write $GPIOOUT 0 +wfi_test "rising" 4 7 + +gpio -g write $GPIOOUT 1 +wfi_test "falling" 4 8 + +gpio -g write $GPIOOUT 0 +wfi_test "both" 4 4 + +gpio -g write $GPIOOUT 0 +gpio -g mode $GPIOOUT in ### #wfi timeout test -gpio -g wfi 26 rising 2 4 & +gpio -g wfi $GPIOIN rising 2 4 & GPIO_PID=$! wait_with_timeout "$GPIO_PID" "$TIMEOUT" EXIT_CODE=$?