drivers/timers/timer.c: Support the signal notification through SIGEV_THREAD
This commit is contained in:
parent
b9c7a9a18f
commit
5a0f514615
@ -46,7 +46,6 @@
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
@ -67,13 +66,15 @@
|
||||
|
||||
struct timer_upperhalf_s
|
||||
{
|
||||
sem_t exclsem; /* Supports mutual exclusion */
|
||||
uint8_t crefs; /* The number of times the device has been opened */
|
||||
uint8_t signo; /* 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 */
|
||||
sem_t exclsem; /* Supports mutual exclusion */
|
||||
uint8_t crefs; /* The number of times the device has been opened */
|
||||
FAR char *path; /* Registration path */
|
||||
|
||||
/* The contained signal info */
|
||||
|
||||
struct timer_notify_s notify;
|
||||
struct sigwork_s work;
|
||||
|
||||
/* The contained lower-half driver */
|
||||
|
||||
FAR struct timer_lowerhalf_s *lower;
|
||||
@ -130,20 +131,14 @@ static const struct file_operations g_timerops =
|
||||
static bool timer_notifier(FAR uint32_t *next_interval_us, FAR void *arg)
|
||||
{
|
||||
FAR struct timer_upperhalf_s *upper = (FAR struct timer_upperhalf_s *)arg;
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
union sigval value;
|
||||
#endif
|
||||
FAR struct timer_notify_s *notify = &upper->notify;
|
||||
|
||||
DEBUGASSERT(upper != NULL);
|
||||
|
||||
/* Signal the waiter.. if there is one */
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
value.sival_ptr = upper->arg;
|
||||
(void)nxsig_queue(upper->pid, upper->signo, value);
|
||||
#else
|
||||
(void)nxsig_queue(upper->pid, upper->signo, upper->arg);
|
||||
#endif
|
||||
nxsig_notification(notify->pid, ¬ify->event,
|
||||
SI_QUEUE, &upper->work);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -328,14 +323,9 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
/* Stop the timer */
|
||||
|
||||
if (lower->ops->stop)
|
||||
{
|
||||
ret = lower->ops->stop(lower);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
DEBUGASSERT(lower->ops->stop != NULL); /* Required */
|
||||
ret = lower->ops->stop(lower);
|
||||
nxsig_cancel_notification(&upper->work);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -394,10 +384,7 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
/* 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.
|
||||
* Argument: signal information
|
||||
*/
|
||||
|
||||
case TCIOC_NOTIFICATION:
|
||||
@ -407,10 +394,7 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
if (notify != NULL)
|
||||
{
|
||||
upper->signo = notify->signo;
|
||||
upper->pid = notify->pid;
|
||||
upper->arg = notify->arg;
|
||||
|
||||
memcpy(&upper->notify, notify, sizeof(*notify));
|
||||
ret = timer_setcallback((FAR void *)upper, timer_notifier, upper);
|
||||
}
|
||||
else
|
||||
@ -586,6 +570,7 @@ void timer_unregister(FAR void *handle)
|
||||
|
||||
DEBUGASSERT(lower->ops->stop); /* Required */
|
||||
(void)lower->ops->stop(lower);
|
||||
nxsig_cancel_notification(&upper->work);
|
||||
|
||||
/* Unregister the timer device */
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -130,9 +131,8 @@ struct timer_status_s
|
||||
|
||||
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 signo; /* The signal number to use in the notification */
|
||||
struct sigevent event; /* Describe the way a task is to be notified */
|
||||
pid_t pid; /* The ID of the task/thread to receive the signal */
|
||||
};
|
||||
|
||||
/* This structure provides the "lower-half" driver operations available to
|
||||
|
Loading…
Reference in New Issue
Block a user