Skip to content
Snippets Groups Projects
Commit d4a048c0 authored by Gregory Nutt's avatar Gregory Nutt
Browse files

Timer driver: Add hooks to support signal notification of timer expiration. ...

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.
parent ecb2d4cb
No related branches found
No related tags found
No related merge requests found
......@@ -65,8 +65,13 @@
struct timer_upperhalf_s
{
uint8_t crefs; /* The number of times the device has been opened */
FAR char *path; /* Registration path */
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
*
......@@ -120,10 +161,10 @@ static const struct file_operations g_timerops =
static int timer_open(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct inode *inode = filep->f_inode;
FAR struct timer_upperhalf_s *upper = inode->i_private;
uint8_t tmp;
int ret;
uint8_t tmp;
int ret;
tmrinfo("crefs: %d\n", upper->crefs);
......@@ -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:
......@@ -500,7 +571,7 @@ int timer_sethandler(FAR void *handle, tccb_t newhandler,
FAR struct timer_upperhalf_s *upper;
FAR struct timer_lowerhalf_s *lower;
tccb_t tmphandler;
/* Recover the pointer to the upper-half driver state */
upper = (FAR struct timer_upperhalf_s *)handle;
......
......@@ -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
......@@ -60,14 +66,18 @@
*
* These are detected and handled by the "upper half" timer driver.
*
* TCIOC_START - Start the timer
* Argument: Ignored
* TCIOC_STOP - Stop the timer
* Argument: Ignored
* TCIOC_GETSTATUS - Get the status of the timer.
* 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_START - Start the timer
* Argument: Ignored
* TCIOC_STOP - Stop the timer
* Argument: Ignored
* TCIOC_GETSTATUS - Get the status of the timer.
* 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.
......@@ -82,18 +92,20 @@
* range.
*/
#define TCIOC_START _TCIOC(0x0001)
#define TCIOC_STOP _TCIOC(0x0002)
#define TCIOC_GETSTATUS _TCIOC(0x0003)
#define TCIOC_SETTIMEOUT _TCIOC(0x0004)
#define TCIOC_SETHANDLER _TCIOC(0x0005)
#define TCIOC_START _TCIOC(0x0001)
#define TCIOC_STOP _TCIOC(0x0002)
#define TCIOC_GETSTATUS _TCIOC(0x0003)
#define TCIOC_SETTIMEOUT _TCIOC(0x0004)
#ifdef HAVE_NOTIFICATION
#define TCIOC_NOTIFICATION _TCIOC(0x0005)
#endif
/* Bit Settings *************************************************************/
/* Bit settings for the struct timer_status_s flags field */
#define TCFLAGS_ACTIVE (1 << 0) /* 1=The timer is running */
#define TCFLAGS_HANDLER (1 << 1) /* 1=Call the user function when the
* timer expires */
#define TCFLAGS_ACTIVE (1 << 0) /* 1=The timer is running */
#define TCFLAGS_HANDLER (1 << 1) /* 1=Call the user function when the
* timer expires */
/****************************************************************************
* Public Types
......@@ -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.
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment