diff --git a/TODO b/TODO index aa048fde33..3d54ecf7f7 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated November 2, 2016) +NuttX TODO List (Last updated November 17, 2016) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -15,7 +15,7 @@ nuttx/: (3) Signals (sched/signal, arch/) (2) pthreads (sched/pthread) (0) Message Queues (sched/mqueue) - (9) Kernel/Protected Build + (8) Kernel/Protected Build (3) C++ Support (6) Binary loaders (binfmt/) (12) Network (net/, drivers/net) @@ -683,14 +683,6 @@ o Kernel/Protected Build improvement. However, there is no strong motivation now do do that partitioning work. - Title: TIMER INTERRUPT CALLBACK - Description: The timer upper half driver at drivers/timers/timer.c performs - interrupt level callbacks into applications. This, of course, - will never work in anything but a non-secure, flat build. - Status: Open - Priority: Medium. The driver is only usable with all of its features - in a FLAT build. - Title: USER MODE TASKS CAN MODIFY PRIVILEGED TASKS Description: Certain interfaces, such as sched_setparam(), sched_setscheduler(), etc. can be used by user mode tasks to diff --git a/drivers/timers/timer.c b/drivers/timers/timer.c index 0186e9977f..ebe58dcd2f 100644 --- a/drivers/timers/timer.c +++ b/drivers/timers/timer.c @@ -322,46 +322,6 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; - /* cmd: TCIOC_SETHANDLER - * Description: Call this handler on timeout - * Argument: A pointer to struct timer_sethandler_s. - * - * NOTE: This ioctl cannot be support in the kernel build mode. In that - * case direct callbacks from kernel space into user space is forbidden. - */ - -#if !defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_BUILD_KERNEL) - case TCIOC_SETHANDLER: - { - FAR struct timer_sethandler_s *sethandler; - - /* Don't reset on timer timeout; instead, call this user - * provider timeout handler. NOTE: Providing handler==NULL will - * restore the reset behavior. - */ - - if (lower->ops->sethandler) /* Optional */ - { - sethandler = (FAR struct timer_sethandler_s *)((uintptr_t)arg); - if (sethandler) - { - sethandler->oldhandler = - lower->ops->sethandler(lower, sethandler->newhandler); - ret = OK; - } - else - { - ret = -EINVAL; - } - } - else - { - ret = -ENOSYS; - } - } - break; -#endif - /* Any unrecognized IOCTL commands might be platform-specific ioctl commands */ default: @@ -496,8 +456,8 @@ void timer_unregister(FAR void *handle) /* Recover the pointer to the upper-half driver state */ upper = (FAR struct timer_upperhalf_s *)handle; + DEBUGASSERT(upper != NULL && upper->lower != NULL); lower = upper->lower; - DEBUGASSERT(upper && lower); tmrinfo("Unregistering: %s\n", upper->path); @@ -516,4 +476,57 @@ void timer_unregister(FAR void *handle) kmm_free(upper); } +/**************************************************************************** + * Name: timer_sethandler + * + * Description: + * This function can be called to add a callback into driver-related code + * to handle timer expirations. This is a strictly OS internal interface + * and may NOT be used by appliction code. + * + * Input parameters: + * handle - This is the handle that was returned by timer_register() + * newhandler - The new timer interrupt handler + * oldhandler - The previous timer interrupt handler (if any) + * + * Returned Value: + * None + * + ****************************************************************************/ + +int timer_sethandler(FAR void *handle, tccb_t newhandler, + FAR tccb_t *oldhandler) +{ + 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; + DEBUGASSERT(upper != NULL && upper->lower != NULL); + lower = upper->lower; + DEBUGASSERT(lower->ops != NULL); + + /* Check if the lower half driver supports the sethandler method */ + + if (lower->ops->sethandler != NULL) /* Optional */ + { + /* Yes.. Defer the hander attachment to the lower half driver */ + + tmphandler = lower->ops->sethandler(lower, newhandler); + + /* Return the oldhandler if a location to return it was provided */ + + if (oldhandler != NULL) + { + *oldhandler = tmphandler; + } + + return OK; + } + + return -ENOSYS; +} + #endif /* CONFIG_TIMER */ diff --git a/include/nuttx/timers/timer.h b/include/nuttx/timers/timer.h index 8df658376a..77946327fc 100644 --- a/include/nuttx/timers/timer.h +++ b/include/nuttx/timers/timer.h @@ -68,8 +68,6 @@ * 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_SETHANDLER - Call this handler on timer expiration - * Argument: A pointer to struct timer_sethandler_s. * * WARNING: May change TCIOC_SETTIMEOUT to pass pointer to 64bit nanoseconds * or timespec structure. @@ -105,15 +103,7 @@ * function can modify the next interval if desired. */ -typedef bool (*tccb_t)(FAR uint32_t *next_interval_us); - -/* This is the type of the argument passed to the TCIOC_SETHANDLER ioctl */ - -struct timer_sethandler_s -{ - CODE tccb_t newhandler; /* The new timer interrupt handler */ - CODE tccb_t oldhandler; /* The previous timer interrupt handler (if any) */ -}; +typedef CODE bool (*tccb_t)(FAR uint32_t *next_interval_us); /* This is the type of the argument passed to the TCIOC_GETSTATUS ioctl and * and returned by the "lower half" getstatus() method. @@ -254,6 +244,33 @@ FAR void *timer_register(FAR const char *path, void timer_unregister(FAR void *handle); +/**************************************************************************** + * Kernal internal interfaces. Thse may not be used by application logic + ****************************************************************************/ + +/**************************************************************************** + * Name: timer_sethandler + * + * Description: + * This function can be called to add a callback into driver-related code + * to handle timer expirations. This is a strictly OS internal interface + * and may NOT be used by appliction code. + * + * Input parameters: + * handle - This is the handle that was returned by timer_register() + * newhandler - The new timer interrupt handler + * oldhandler - The previous timer interrupt handler (if any) + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef __KERNEL__ +int timer_sethandler(FAR void *handle, tccb_t newhandler, + FAR tccb_t *oldhandler); +#endif + /**************************************************************************** * Platform-Independent "Lower-Half" Timer Driver Interfaces ****************************************************************************/