diff --git a/arch/arm/src/sam34/Kconfig b/arch/arm/src/sam34/Kconfig index 2613d7441a..f9286a30ca 100644 --- a/arch/arm/src/sam34/Kconfig +++ b/arch/arm/src/sam34/Kconfig @@ -930,7 +930,7 @@ endif # SAM34_GPIO_IRQ endmenu # AT91SAM3/4 GPIO Interrupt Configuration menu "AT91SAM3/4 Timer/Counter Configuration" - depends on SAM34_TC + depends on SAM34_TC && ARCH_CHIP_SAM4CM config SAM34_TC0_CLK bool "Enable TC channel 0 clock input pin" @@ -1058,8 +1058,7 @@ config SAM34_TICKLESS_FREERUN If the Tickless OS feature is enabled, the one clock must be assigned to provided the free-running timer needed by the OS. -endif - +endif # SCHED_TICKLESS endmenu # AT91SAM3/4 Timer/Counter Configuration if SAM34_SPI0 || SAM34_SPI1 diff --git a/arch/arm/src/sam34/sam4cm_tickless.c b/arch/arm/src/sam34/sam4cm_tickless.c index 0c86c671eb..cf20e5e9eb 100644 --- a/arch/arm/src/sam34/sam4cm_tickless.c +++ b/arch/arm/src/sam34/sam4cm_tickless.c @@ -231,6 +231,9 @@ static void sam_oneshot_handler(void *arg) void up_timer_initialize(void) { +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP + uint64_t max_delay; +#endif int ret; /* Initialize the one-shot timer */ @@ -245,12 +248,26 @@ void up_timer_initialize(void) } #ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP - ret = sam_oneshot_max_delay(&g_tickless.oneshot, &g_oneshot_max_delay_usec); + /* Get the maximum delay of the one-shot timer in microseconds */ + + ret = sam_oneshot_max_delay(&g_tickless.oneshot, &max_delay); if (ret < 0) { tclldbg("ERROR: sam_oneshot_max_delay failed\n"); PANIC(); } + + /* Convert this to configured clock ticks for use by the OS timer logic */ + + max_delay /= CONFIG_USEC_PER_TICK; + if (max_delay > UINT32_MAX) + { + g_oneshot_maxticks = UINT32_MAX + } + else + { + g_oneshot_maxticks = max_delay; + } #endif /* Initialize the free-running timer */ diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 10f195ed39..836407c204 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -119,6 +119,15 @@ typedef CODE void (*phy_enable_t)(bool enable); * Public Variables ****************************************************************************/ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + #ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP /* By default, the RTOS tickless logic assumes that range of times that can * be represented by the underlying hardware time is so large that no special @@ -126,25 +135,20 @@ typedef CODE void (*phy_enable_t)(bool enable); * limit to the maximum timing interval that be represented by the timer, * then that limit must be respected. * - * If CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP is defined, then a 64-bit global - * variable called g_oneshot_max_delay_usec variable is enabled. The variable + * If CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP is defined, then use a 32-bit + * global variable called g_oneshot_maxticks variable is enabled. This variable * is initialized by platform-specific logic at runtime to the maximum delay - * that the timer can wait (in microseconds). The RTOS tickless logic will - * then limit all requested delays to this value (in ticks). + * that the timer can wait (in configured clock ticks). The RTOS tickless + * logic will then limit all requested delays to this value (in ticks). */ -extern uint64_t g_oneshot_max_delay_usec; +EXTERN uint32_t g_oneshot_maxticks; #endif /**************************************************************************** * Public Function Prototypes ****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - /**************************************************************************** * These are standard interfaces that must be exported to the base RTOS * logic from architecture-specific code. @@ -1946,6 +1950,7 @@ int up_getc(void); void up_puts(FAR const char *str); +#undef EXTERN #ifdef __cplusplus } #endif diff --git a/sched/Kconfig b/sched/Kconfig index a82466d320..a6df4fedab 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -85,10 +85,11 @@ config SCHED_TICKLESS_LIMIT_MAX_SLEEP bool "Max sleep period (in microseconds)" default n ---help--- - Enables g_oneshot_max_delay_usec variable. The variable is + Enables use of the g_oneshot_maxticks variable. This variable is initialized by platform-specific logic at runtime to the maximum - delay that the timer can wait (in microseconds). The RTOS tickless - logic will then limit all requested delays to this value (in ticks). + delay that the timer can wait (in configured clock ticks). The + RTOS tickless logic will then limit all requested delays to this + value. endif diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index b1ed1833f4..e990f0b571 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -94,14 +94,14 @@ * limit to the maximum timing interval that be represented by the timer, * then that limit must be respected. * - * If CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP is defined, then a 64-bit global - * variable called g_oneshot_max_delay_usec variable is enabled. The variable + * If CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP is defined, then a 32-bit global + * variable called g_oneshot_maxticks variable is enabled. The variable * is initialized by platform-specific logic at runtime to the maximum delay * that the timer can wait (in microseconds). The RTOS tickless logic will * then limit all requested delays to this value (in ticks). */ -uint64_t g_oneshot_max_delay_usec; +uint32_t g_oneshot_maxticks = UINT32_MAX; #endif /************************************************************************ @@ -445,9 +445,9 @@ static void sched_timer_start(unsigned int ticks) struct timespec ts; #if CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP - if (ticks > (g_oneshot_max_delay_usec / CONFIG_USEC_PER_TICK)) + if (ticks > g_oneshot_maxticks) { - ticks = (g_oneshot_max_delay_usec / CONFIG_USEC_PER_TICK); + ticks = g_oneshot_maxticks; } #endif