From 3adcae8ffbf247f1038bbb3b8281ea811799031e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 18 May 2015 08:53:42 -0600 Subject: [PATCH] Update the type passed to watchdog timer handlers. Using uint32_t is a problem for 64-bit machines. --- Documentation/NuttxUserGuide.html | 34 +++++++++++++++---------------- include/nuttx/wdog.h | 24 +++++++++++++--------- sched/mqueue/mq_timedreceive.c | 4 ++-- sched/mqueue/mq_timedsend.c | 2 +- sched/semaphore/sem_timedwait.c | 4 ++-- sched/signal/sig_timedwait.c | 10 ++++----- sched/timer/timer_settime.c | 25 ++++++++++------------- sched/wdog/wd_start.c | 14 ++++++------- 8 files changed, 59 insertions(+), 58 deletions(-) diff --git a/Documentation/NuttxUserGuide.html b/Documentation/NuttxUserGuide.html index 8eecc9052b2..26079b5752e 100644 --- a/Documentation/NuttxUserGuide.html +++ b/Documentation/NuttxUserGuide.html @@ -9743,25 +9743,25 @@ notify a task when a message is available on a queue.

Where argc is the number of uint32_t type arguments that follow.

- The arguments are passed as uint32_t values. - For systems where the sizeof(pointer) < sizeof(uint32_t), the - following union defines the alignment of the pointer within the - uint32_t. For example, the SDCC MCS51 general pointer is - 24-bits, but uint32_t is 32-bits (of course). -

-
-    union wdparm_u
-    {
-      void   *pvarg;
-      uint32_t *dwarg;
-    };
-    typedef union wdparm_u wdparm_t;
-

- For most 32-bit systems, pointers and uint32_t are the same size - For systems where sizeof(pointer) > sizeof(uint32_t), we will - have to do some redesign. + The arguments are passed as wdparm_t values. For systems where the sizeof(pointer) < sizeof(uint32_t), the following union defines the alignment of the pointer within the uint32_t. For example, the SDCC MCS51 general pointer is 24-bits, but uint32_t is 32-bits (of course).

+ We always have sizeof(pointer) <= sizeof(uintptr_t) by definitions. +

+ diff --git a/include/nuttx/wdog.h b/include/nuttx/wdog.h index c249b850588..44774cd8507 100644 --- a/include/nuttx/wdog.h +++ b/include/nuttx/wdog.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/wdog.h * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -101,28 +101,32 @@ /**************************************************************************** * Public Type Declarations ****************************************************************************/ -/* The arguments are passed as uint32_t values. For systems where the - * sizeof(pointer) < sizeof(uint32_t), the following union defines the +/* The arguments are passed as scalar wdparm_t values. For systems where + * the sizeof(pointer) < sizeof(uint32_t), the following union defines the * alignment of the pointer within the uint32_t. For example, the SDCC * MCS51 general pointer is 24-bits, but uint32_t is 32-bits (of course). * - * For systems where sizeof(pointer) > sizeof(uint32_t), we will have to do - * some redesign. + * We always have sizeof(pointer) <= sizeof(uintptr_t) by definitions. */ union wdparm_u { - FAR void *pvarg; - FAR uint32_t *dwarg; + FAR void *pvarg; /* The size one generic point */ + uint32_t dwarg; /* Big enough for a 32-bit value in any case */ + uintptr_t uiarg; /* sizeof(uintptr_t) >= sizeof(pointer) */ }; -typedef union wdparm_u wdparm_t; +#if UINTPTR_MAX >= UINT32_MAX +typedef uintptr_t wdparm_t; +#else +typedef uint32_t wdparm_t; +#endif /* This is the form of the function that is called when the * watchdog function expires. Up to four parameters may be passed. */ -typedef CODE void (*wdentry_t)(int argc, uint32_t arg1, ...); +typedef CODE void (*wdentry_t)(int argc, wdparm_t arg1, ...); /* This is the internal representation of the watchdog timer structure. The * WDOG_ID is a pointer to a watchdog structure. @@ -138,7 +142,7 @@ struct wdog_s int lag; /* Timer associated with the delay */ uint8_t flags; /* See WDOGF_* definitions above */ uint8_t argc; /* The number of parameters to pass */ - uint32_t parm[CONFIG_MAX_WDOGPARMS]; + wdparm_t parm[CONFIG_MAX_WDOGPARMS]; }; /* Watchdog 'handle' */ diff --git a/sched/mqueue/mq_timedreceive.c b/sched/mqueue/mq_timedreceive.c index 858d9a3bf47..1d1c71aded5 100644 --- a/sched/mqueue/mq_timedreceive.c +++ b/sched/mqueue/mq_timedreceive.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_timedreceive.c * - * Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -92,7 +92,7 @@ * ****************************************************************************/ -static void mq_rcvtimeout(int argc, uint32_t pid) +static void mq_rcvtimeout(int argc, wdparm_t pid) { FAR struct tcb_s *wtcb; irqstate_t saved_state; diff --git a/sched/mqueue/mq_timedsend.c b/sched/mqueue/mq_timedsend.c index 134f04484e4..31855e6401f 100644 --- a/sched/mqueue/mq_timedsend.c +++ b/sched/mqueue/mq_timedsend.c @@ -92,7 +92,7 @@ * ****************************************************************************/ -static void mq_sndtimeout(int argc, uint32_t pid) +static void mq_sndtimeout(int argc, wdparm_t pid) { FAR struct tcb_s *wtcb; irqstate_t saved_state; diff --git a/sched/semaphore/sem_timedwait.c b/sched/semaphore/sem_timedwait.c index 4d5e583422b..a73e278051b 100644 --- a/sched/semaphore/sem_timedwait.c +++ b/sched/semaphore/sem_timedwait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_timedwait.c * - * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -91,7 +91,7 @@ * ****************************************************************************/ -static void sem_timeout(int argc, uint32_t pid) +static void sem_timeout(int argc, wdparm_t pid) { FAR struct tcb_s *wtcb; irqstate_t flags; diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c index 66d4ccd05e9..a0abc47d933 100644 --- a/sched/signal/sig_timedwait.c +++ b/sched/signal/sig_timedwait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_timedwait.c * - * Copyright (C) 2007-2009, 2012-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -90,7 +90,7 @@ * ****************************************************************************/ -static void sig_timeout(int argc, uint32_t itcb) +static void sig_timeout(int argc, wdparm_t itcb) { /* On many small machines, pointers are encoded and cannot be simply cast * from uint32_t to struct tcb_s*. The following union works around this @@ -101,7 +101,7 @@ static void sig_timeout(int argc, uint32_t itcb) union { FAR struct tcb_s *wtcb; - uint32_t itcb; + wdparm_t itcb; } u; u.itcb = itcb; @@ -269,13 +269,13 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info, * see wdog.h. */ - wdparm_t wdparm; + union wdparm_u wdparm; wdparm.pvarg = (FAR void *)rtcb; /* Start the watchdog */ wd_start(rtcb->waitdog, waitticks, (wdentry_t)sig_timeout, 1, - wdparm.dwarg); + wdparm.pvarg); /* Now wait for either the signal or the watchdog */ diff --git a/sched/timer/timer_settime.c b/sched/timer/timer_settime.c index 308240b88cb..432b6d20680 100644 --- a/sched/timer/timer_settime.c +++ b/sched/timer/timer_settime.c @@ -1,7 +1,7 @@ /******************************************************************************** * sched/timer/timer_settime.c * - * Copyright (C) 2007-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2013-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -67,8 +67,8 @@ ********************************************************************************/ static inline void timer_sigqueue(FAR struct posix_timer_s *timer); -static inline void timer_restart(FAR struct posix_timer_s *timer, uint32_t itimer); -static void timer_timeout(int argc, uint32_t itimer); +static inline void timer_restart(FAR struct posix_timer_s *timer, wdparm_t itimer); +static void timer_timeout(int argc, wdparm_t itimer); /******************************************************************************** * Private Functions @@ -128,11 +128,12 @@ static inline void timer_sigqueue(FAR struct posix_timer_s *timer) * None * * Assumptions: - * This function executes in the context of the watchod timer interrupt. + * This function executes in the context of the watchdog timer interrupt. * ********************************************************************************/ -static inline void timer_restart(FAR struct posix_timer_s *timer, uint32_t itimer) +static inline void timer_restart(FAR struct posix_timer_s *timer, + wdparm_t itimer) { /* If this is a repetitive timer, then restart the watchdog */ @@ -164,17 +165,17 @@ static inline void timer_restart(FAR struct posix_timer_s *timer, uint32_t itime * ********************************************************************************/ -static void timer_timeout(int argc, uint32_t itimer) +static void timer_timeout(int argc, wdparm_t itimer) { #ifndef CONFIG_CAN_PASS_STRUCTS /* On many small machines, pointers are encoded and cannot be simply cast from - * uint32_t to struct tcb_s*. The following union works around this (see wdogparm_t). + * wdparm_t to struct tcb_s*. The following union works around this (see wdogparm_t). */ union { FAR struct posix_timer_s *timer; - uint32_t itimer; + wdparm_t itimer; } u; u.itimer = itimer; @@ -198,11 +199,7 @@ static void timer_timeout(int argc, uint32_t itimer) timer_restart(u.timer, itimer); } #else - /* (casting to uintptr_t first eliminates complaints on some architectures - * where the sizeof uint32_t is different from the size of a pointer). - */ - - FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)((uintptr_t)itimer); + FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)itimer; /* Send the specified signal to the specified task. Increment the reference * count on the timer first so that will not be deleted until after the @@ -375,7 +372,7 @@ int timer_settime(timer_t timerid, int flags, FAR const struct itimerspec *value { timer->pt_last = delay; ret = wd_start(timer->pt_wdog, delay, (wdentry_t)timer_timeout, - 1, (uint32_t)((uintptr_t)timer)); + 1, (uint32_t)((wdparm_t)timer)); } irqrestore(state); diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c index 6faf0e6dfcc..ba7cc06aa28 100644 --- a/sched/wdog/wd_start.c +++ b/sched/wdog/wd_start.c @@ -71,18 +71,18 @@ typedef void (*wdentry0_t)(int argc); #if CONFIG_MAX_WDOGPARMS > 0 -typedef void (*wdentry1_t)(int argc, uint32_t arg1); +typedef void (*wdentry1_t)(int argc, wdparm_t arg1); #endif #if CONFIG_MAX_WDOGPARMS > 1 -typedef void (*wdentry2_t)(int argc, uint32_t arg1, uint32_t arg2); +typedef void (*wdentry2_t)(int argc, wdparm_t arg1, wdparm_t arg2); #endif #if CONFIG_MAX_WDOGPARMS > 2 -typedef void (*wdentry3_t)(int argc, uint32_t arg1, uint32_t arg2, - uint32_t arg3); +typedef void (*wdentry3_t)(int argc, wdparm_t arg1, wdparm_t arg2, + wdparm_t arg3); #endif #if CONFIG_MAX_WDOGPARMS > 3 -typedef void (*wdentry4_t)(int argc, uint32_t arg1, uint32_t arg2, - uint32_t arg3, uint32_t arg4); +typedef void (*wdentry4_t)(int argc, wdparm_t arg1, wdparm_t arg2, + wdparm_t arg3, wdparm_t arg4); #endif /**************************************************************************** @@ -264,7 +264,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...) va_start(ap, argc); for (i = 0; i < argc; i++) { - wdog->parm[i] = va_arg(ap, uint32_t); + wdog->parm[i] = va_arg(ap, wdparm_t); } #ifdef CONFIG_DEBUG for (; i < CONFIG_MAX_WDOGPARMS; i++)