Timer driver: Add hooks to support signal notification of timer expiration. Commented out because invasive interface changes would also be required to complete the implementation.

This commit is contained in:
Gregory Nutt
2016-11-17 12:41:11 -06:00
parent ecb2d4cbc1
commit d4a048c0c6
2 changed files with 116 additions and 22 deletions
+71
View File
@@ -66,6 +66,11 @@
struct timer_upperhalf_s
{
uint8_t crefs; /* The number of times the device has been opened */
#ifdef HAVE_NOTIFICATION
uint8_t signal; /* The signal number to use in the notification */
pid_t pid; /* The ID of the task/thread to receive the signal */
FAR void *arg; /* An argument to pass with the signal */
#endif
FAR char *path; /* Registration path */
/* The contained lower-half driver */
@@ -77,6 +82,12 @@ struct timer_upperhalf_s
* Private Function Prototypes
****************************************************************************/
#ifdef HAVE_NOTIFICATION
/* REVISIT: This function prototype is insufficient to support signaling */
static bool timer_notifier(FAR uint32_t *next_interval_us);
#endif
static int timer_open(FAR struct file *filep);
static int timer_close(FAR struct file *filep);
static ssize_t timer_read(FAR struct file *filep, FAR char *buffer,
@@ -110,6 +121,36 @@ static const struct file_operations g_timerops =
* Private Functions
****************************************************************************/
/************************************************************************************
* Name: timer_notifier
*
* Description:
* Notify the application via a signal when the timer interrupt occurs
*
* REVISIT: This function prototype is insufficient to support signaling
*
************************************************************************************/
#ifdef HAVE_NOTIFICATION
static bool timer_notifier(FAR uint32_t *next_interval_us)
{
FAR struct timer_upperhalf_s *upper = HOW?;
#ifdef CONFIG_CAN_PASS_STRUCTS
union sigval value;
#endif
int ret;
#ifdef CONFIG_CAN_PASS_STRUCTS
value.sival_ptr = upper->arg;
ret = sigqueue(upper->pid, upper->signo, value);
#else
ret = sigqueue(upper->pid, upper->signo, upper->arg);
#endif
return ret == OK;
}
#endif
/************************************************************************************
* Name: timer_open
*
@@ -322,6 +363,36 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break;
#ifdef HAVE_NOTIFICATION
/* cmd: TCIOC_NOTIFICATION
* Description: Notify application via a signal when the timer expires.
* Argument: signal number
*
* NOTE: This ioctl cannot be support in the kernel build mode. In that
* case direct callbacks from kernel space into user space is forbidden.
*/
case TCIOC_NOTIFICATION:
{
FAR struct timer_notify_s *notify =
(FAR struct timer_notify_s *)((uintptr_t)arg)
if (notify != NULL)
{
upper->signo = notify->signal;
upper->get = notify->signal;
upper->arg = noify->arg;
ret = timer_sethandler((FAR void *handle)upper, timer_notifier, NULL);
}
else
{
ret = -EINVAL;
}
}
break;
#endif
/* Any unrecognized IOCTL commands might be platform-specific ioctl commands */
default:
+24 -1
View File
@@ -52,6 +52,12 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* It would require some interface modifcations in order to support
* notifications.
*/
#undef HAVE_NOTIFICATION
/* IOCTL Commands ***********************************************************/
/* The timer driver uses a standard character driver framework. However,
* since the timer driver is a device control interface and not a data
@@ -68,6 +74,10 @@
* Argument: A writeable pointer to struct timer_status_s.
* TCIOC_SETTIMEOUT - Reset the timer timeout to this value
* Argument: A 32-bit timeout value in microseconds.
* TCIOC_NOTIFICATION - Set up to notify an application via a signal when
* the timer expires.
* Argument: A read-only pointer to an instance of
* stuct timer_notify_s.
*
* WARNING: May change TCIOC_SETTIMEOUT to pass pointer to 64bit nanoseconds
* or timespec structure.
@@ -86,7 +96,9 @@
#define TCIOC_STOP _TCIOC(0x0002)
#define TCIOC_GETSTATUS _TCIOC(0x0003)
#define TCIOC_SETTIMEOUT _TCIOC(0x0004)
#define TCIOC_SETHANDLER _TCIOC(0x0005)
#ifdef HAVE_NOTIFICATION
#define TCIOC_NOTIFICATION _TCIOC(0x0005)
#endif
/* Bit Settings *************************************************************/
/* Bit settings for the struct timer_status_s flags field */
@@ -117,6 +129,17 @@ struct timer_status_s
* (in microseconds) */
};
#ifdef HAVE_NOTIFICATION
/* This is the type of the argument passed to the TCIOC_NOTIFICATION ioctl */
struct timer_notify_s
{
FAR void *arg; /* An argument to pass with the signal */
pid_t pid; /* The ID of the task/thread to receive the signal */
uint8_t signal; /* The signal number to use in the notification */
};
#endif
/* This structure provides the "lower-half" driver operations available to
* the "upper-half" driver.
*/