This is an automated email from the ASF dual-hosted git repository. gnutt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push: new b15e78b examples: Adds Timer gpout example b15e78b is described below commit b15e78b9fa771085e0c965746f841895f3bf116d Author: Sara Souza <sara.so...@espressif.com> AuthorDate: Mon May 17 09:08:40 2021 -0300 examples: Adds Timer gpout example --- examples/README.md | 38 ++++ examples/timer_gpout/Kconfig | 67 +++++++ examples/timer_gpout/Make.defs | 23 +++ examples/timer_gpout/Makefile | 34 ++++ examples/timer_gpout/timer_gpout_main.c | 306 ++++++++++++++++++++++++++++++++ 5 files changed, 468 insertions(+) diff --git a/examples/README.md b/examples/README.md index 2de025c..789f3ed 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1712,6 +1712,44 @@ Example configuration: - `CONFIG_EXAMPLES_TIMER_PROGNAME` – This is the name of the program that will be used when the NSH ELF program is installed. Default: `timer`. +## `timer_gpout` + +This example uses the timer interrupt to periodically +change the state of a digital output. +The digital output may be a relay, a led or anything else. +This example can be very useful to validate timer drivers +by using a logic analyzer connected to the digital output. +This example, mainly differs from the timer example because it +waits on a sigwaitinfo() instead of using a signal handler. +This approach ensures a deterministic wake-up time when +the signal occurs. + +Dependencies: + +- `CONFIG_TIMER` – The timer driver must be selected. +- `CONFIG_DEV_GPIO` – The GPIO driver must be selected. + +Note: You should also select one timer instance and have gpout +proper configured in your board logic. + +Example configuration: + +- `EXAMPLES_TIMER_GPOUT_TIM_DEVNAME` – This is the name of the timer device that will be used. + Default: `/dev/timer0`. +- `EXAMPLES_TIMER_GPOUT_GPOUT_DEVNAME` – This is the name of the gpout device that will be used. + Default: `/dev/gpout0`. +- `EXAMPLES_TIMER_GPOUT_INTERVAL` – This is the timer interval in microseconds. + Default: `1000000`. +- `EXAMPLES_TIMER_GPOUT_SIGNO` – This is the signal number that is used to notify that a timer + interrupt occurred. + Default: `17`. +- `EXAMPLES_TIMER_GPOUT_STACKSIZE` – This is the stack size allocated when the timer task runs. + Default: `2048`. +- `EXAMPLES_TIMER_GPOUT_PRIORITY` – This is the priority of the timer task. + Default: `255`. +- `EXAMPLES_TIMER_GPOUT_PROGNAME` – This is the name of the program that will be used from the nsh. + Default: `timer_gpout`. + ## `touchscreen` Touchscreen Events This configuration implements a simple touchscreen test at diff --git a/examples/timer_gpout/Kconfig b/examples/timer_gpout/Kconfig new file mode 100644 index 0000000..ff7eb26 --- /dev/null +++ b/examples/timer_gpout/Kconfig @@ -0,0 +1,67 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_TIMER_GPOUT + tristate "Timer GPOUT example" + default n + depends on TIMER && DEV_GPIO + ---help--- + Enable the timer-gpout example. + This example uses the timer interrupt to periodically + change the state of a digital output. + The digital output may be a relay, a led or anything else. + This example can be very useful to validate timer drivers + by using a logic analyzer connected to the digital output. + This example, differs from the timer example because it + waits on a sigwaitinfo() instead of using a signal handler. + This approach ensures a deterministic wake-up time when + the signal occurs. + +if EXAMPLES_TIMER_GPOUT + +config EXAMPLES_TIMER_GPOUT_TIM_DEVNAME + string "Timer device name" + default "/dev/timer0" + ---help--- + This is the name of the timer device that will be used. + +config EXAMPLES_TIMER_GPOUT_GPOUT_DEVNAME + string "GPOUT device name" + default "/dev/gpout0" + ---help--- + This is the name of the gpout device that will be used. + +config EXAMPLES_TIMER_GPOUT_INTERVAL + int "Timer interval (microseconds)" + default 1000000 + ---help--- + This is the timer interval in microseconds. + +config EXAMPLES_TIMER_GPOUT_SIGNO + int "Notification signal number" + default 17 + ---help--- + This is the signal number that is used to notify that a timer + interrupt occurred. + +config EXAMPLES_TIMER_GPOUT_STACKSIZE + int "Timer stack size" + default DEFAULT_TASK_STACKSIZE + ---help--- + This is the stack size allocated when the timer task runs. + +config EXAMPLES_TIMER_GPOUT_PRIORITY + int "Timer task priority" + default 255 + ---help--- + This is the priority of the timer task. + +config EXAMPLES_TIMER_GPOUT_PROGNAME + string "Timer GPOUT program name" + default "timer_gpout" + ---help--- + This is the name of the program that will be used from the nsh. + +endif diff --git a/examples/timer_gpout/Make.defs b/examples/timer_gpout/Make.defs new file mode 100644 index 0000000..4b742ff --- /dev/null +++ b/examples/timer_gpout/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/examples/timer_gpout/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifeq ($(CONFIG_EXAMPLES_TIMER_GPOUT),y) +CONFIGURED_APPS += $(APPDIR)/examples/timer_gpout +endif diff --git a/examples/timer_gpout/Makefile b/examples/timer_gpout/Makefile new file mode 100644 index 0000000..7ec4b57 --- /dev/null +++ b/examples/timer_gpout/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# apps/examples/timer_gpout/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# Timer built-in application info + +PROGNAME = $(CONFIG_EXAMPLES_TIMER_GPOUT_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_TIMER_GPOUT_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_TIMER_GPOUT_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_TIMER_GPOUT) + +# Timer example + +MAINSRC = timer_gpout_main.c + +include $(APPDIR)/Application.mk diff --git a/examples/timer_gpout/timer_gpout_main.c b/examples/timer_gpout/timer_gpout_main.c new file mode 100644 index 0000000..7a64975 --- /dev/null +++ b/examples/timer_gpout/timer_gpout_main.c @@ -0,0 +1,306 @@ +/**************************************************************************** + * apps/examples/timer_gpout/timer_gpout_main.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <nuttx/timers/timer.h> +#include <nuttx/ioexpander/gpio.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEVNAME_SIZE 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static char g_devtim[DEVNAME_SIZE]; +static char g_devgpout[DEVNAME_SIZE]; +static bool g_timer_gpout_daemon_started = false; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: timer_status + * + * Description: + * Auxiliar function to get the timer status and print it. + * + * Parameters: + * fd - Timer file descriptor to access the timer. + * + ****************************************************************************/ + +static void timer_status(int fd) +{ + struct timer_status_s status; + int ret; + + /* Get timer status */ + + ret = ioctl(fd, TCIOC_GETSTATUS, (unsigned long)((uintptr_t)&status)); + if (ret < 0) + { + fprintf(stderr, "ERROR: Failed to get timer status: %d\n", errno); + close(fd); + exit(EXIT_FAILURE); + } + + /* Print the timer status */ + + printf(" flags: %08lx timeout: %lu timeleft: %lu\n", + (unsigned long)status.flags, (unsigned long)status.timeout, + (unsigned long)status.timeleft); +} + +/**************************************************************************** + * Name: timer_gpout_daemon + * + * Description: + * Deamon that will be active waiting on a signal to change the digital + * output state. + * + ****************************************************************************/ + +static int timer_gpout_daemon(int argc, char *argv[]) +{ + struct timer_notify_s notify; + sigset_t set; + struct siginfo value; + int fd_timer; + int fd_gpout; + int ret; + bool state = false; + + /* Indicate that the deamon is running */ + + g_timer_gpout_daemon_started = true; + printf("timer_gpout_daemon: timer_gpout_daemon started\n"); + + /* Open the timer device */ + + printf("Open %s\n", g_devtim); + + fd_timer = open(g_devtim, O_RDONLY); + if (fd_timer < 0) + { + int errcode = errno; + printf("timer_gpout_daemon: Failed to open %s: %d\n", + g_devtim, errcode); + return EXIT_FAILURE; + } + + /* Open the GPIO driver */ + + printf("Open %s\n", g_devgpout); + + fd_gpout = open(g_devgpout, O_RDWR); + if (fd_gpout < 0) + { + int errcode = errno; + printf("timer_gpout_daemon: Failed to open %s: %d\n", + g_devgpout, errcode); + close(fd_timer); + return EXIT_FAILURE; + } + + /* Show the timer status before setting the timer interval */ + + timer_status(fd_timer); + + /* Set the timer interval */ + + printf("Set timer interval to %lu\n", + (unsigned long)CONFIG_EXAMPLES_TIMER_GPOUT_INTERVAL); + + ret = ioctl(fd_timer, TCIOC_SETTIMEOUT, + CONFIG_EXAMPLES_TIMER_GPOUT_INTERVAL); + if (ret < 0) + { + int errcode = errno; + printf("timer_gpout_daemon: Failed to set the timer interval: %d\n", + errcode); + goto errout; + } + + /* Show the timer status before attaching the timer handler */ + + timer_status(fd_timer); + + /* Configure the signal set for this task */ + + sigemptyset(&set); + sigaddset(&set, CONFIG_EXAMPLES_TIMER_GPOUT_SIGNO); + + /* Configure the timer notifier to receive a signal when timeout occurs. + * Inform the PID of the process that will be notified by the internal + * timer callback, and configure the event to describe the way this + * task will be notified. In this case, through a signal. + */ + + printf("Configure the timer notification.\n"); + + notify.pid = getpid(); + notify.event.sigev_notify = SIGEV_SIGNAL; + notify.event.sigev_signo = CONFIG_EXAMPLES_TIMER_GPOUT_SIGNO; + notify.event.sigev_value.sival_ptr = NULL; + + ret = ioctl(fd_timer, TCIOC_NOTIFICATION, + (unsigned long)((uintptr_t)¬ify)); + if (ret < 0) + { + int errcode = errno; + printf("timer_gpout_daemon: Failed to set the timer handler: %d\n", + errcode); + goto errout; + } + + /* Start the timer */ + + printf("Start the timer\n"); + + ret = ioctl(fd_timer, TCIOC_START, 0); + if (ret < 0) + { + int errcode = errno; + printf("timer_gpout_daemon: Failed to start the timer: %d\n", errcode); + goto errout; + } + + while (1) + { + ret = sigwaitinfo(&set, &value); + if (ret < 0) + { + int errcode = errno; + printf("timer_gpout_daemon: ERROR: sigwaitinfo() failed: %d\n", + errcode); + goto errout; + } + + /* Change the gpout state */ + + state = !state; + + /* Write the pin value */ + + ret = ioctl(fd_gpout, GPIOC_WRITE, (unsigned long)state); + if (ret < 0) + { + int errcode = errno; + printf("timer_gpout_daemon: Failed to write value" + " %u from %s: %d\n", + (unsigned int)state, g_devgpout, errcode); + goto errout; + } + } + +errout: + close(fd_timer); + close(fd_gpout); + g_timer_gpout_daemon_started = false; + + printf("timer_gpout_daemon: Terminating!\n"); + return EXIT_FAILURE; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * timer_gpout main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + int ret; + int opt; + + if (g_timer_gpout_daemon_started) + { + printf("timer_gpout_main: timer_gpout daemon already running\n"); + return EXIT_SUCCESS; + } + + /* Retrieve the arguments */ + + /* Use the ones configured on menuconfig */ + + strcpy(g_devtim, CONFIG_EXAMPLES_TIMER_GPOUT_TIM_DEVNAME); + strcpy(g_devgpout, CONFIG_EXAMPLES_TIMER_GPOUT_GPOUT_DEVNAME); + + /* Or the ones passed as arguments */ + + while ((opt = getopt(argc, argv, ":t:g:")) != -1) + { + switch (opt) + { + case 't': + strcpy(g_devtim, optarg); + break; + case 'g': + strcpy(g_devgpout, optarg); + break; + case ':': + fprintf(stderr, "ERROR: Option needs a value\n"); + exit(EXIT_FAILURE); + default: /* '?' */ + fprintf(stderr, "Usage: %s [-d /dev/timerx] [-d /dev/gpoutx]\n", + argv[0]); + exit(EXIT_FAILURE); + } + } + + printf("timer_gpout_main: Starting the timer_gpout daemon\n"); + ret = task_create("timer_gpout_daemon", + CONFIG_EXAMPLES_TIMER_GPOUT_PRIORITY, + CONFIG_EXAMPLES_TIMER_GPOUT_STACKSIZE, + timer_gpout_daemon, + NULL); + if (ret < 0) + { + int errcode = errno; + printf("timer_gpout_main: Failed to start timer_gpout_daemon: %d\n", + errcode); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +}