forked from Imagelibrary/rtems
rtems: Add more clock tick functions
Add rtems_clock_tick_later(), rtems_clock_tick_later_usec() and rtems_clock_tick_before().
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
#include <rtems/score/tod.h>
|
||||
#include <rtems/rtems/status.h>
|
||||
#include <rtems/rtems/types.h>
|
||||
#include <rtems/config.h>
|
||||
|
||||
#include <sys/time.h> /* struct timeval */
|
||||
|
||||
@@ -159,6 +160,76 @@ RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_get_ticks_since_boot(void)
|
||||
return _Watchdog_Ticks_since_boot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the ticks counter value delta ticks in the future.
|
||||
*
|
||||
* @param[in] delta The ticks delta value.
|
||||
*
|
||||
* @return The tick counter value delta ticks in the future.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_tick_later(
|
||||
rtems_interval delta
|
||||
)
|
||||
{
|
||||
return _Watchdog_Ticks_since_boot + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the ticks counter value at least delta microseconds in the
|
||||
* future.
|
||||
*
|
||||
* @param[in] delta_in_usec The delta value in microseconds.
|
||||
*
|
||||
* @return The tick counter value at least delta microseconds in the future.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_tick_later_usec(
|
||||
rtems_interval delta_in_usec
|
||||
)
|
||||
{
|
||||
rtems_interval us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
||||
|
||||
/*
|
||||
* Add one additional tick, since we don't know the time to the clock next
|
||||
* tick.
|
||||
*/
|
||||
return _Watchdog_Ticks_since_boot
|
||||
+ (delta_in_usec + us_per_tick - 1) / us_per_tick + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the current ticks counter value indicates a time
|
||||
* before the time specified by the tick value and false otherwise.
|
||||
*
|
||||
* @param[in] tick The tick value.
|
||||
*
|
||||
* This can be used to write busy loops with a timeout.
|
||||
*
|
||||
* @code
|
||||
* status busy( void )
|
||||
* {
|
||||
* rtems_interval timeout = rtems_clock_tick_later_usec( 10000 );
|
||||
*
|
||||
* do {
|
||||
* if ( ok() ) {
|
||||
* return success;
|
||||
* }
|
||||
* } while ( rtems_clock_tick_before( timeout ) );
|
||||
*
|
||||
* return timeout;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @retval true The current ticks counter value indicates a time before the
|
||||
* time specified by the tick value.
|
||||
* @retval false Otherwise.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool rtems_clock_tick_before(
|
||||
rtems_interval tick
|
||||
)
|
||||
{
|
||||
return (int32_t) ( tick - _Watchdog_Ticks_since_boot ) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Obtain Ticks Per Seconds
|
||||
*
|
||||
|
||||
104
doc/user/clock.t
104
doc/user/clock.t
@@ -21,6 +21,9 @@ the clock manager are:
|
||||
@item @code{@value{DIRPREFIX}clock_get_seconds_since_epoch} - Get seconds since epoch
|
||||
@item @code{@value{DIRPREFIX}clock_get_ticks_per_second} - Get ticks per second
|
||||
@item @code{@value{DIRPREFIX}clock_get_ticks_since_boot} - Get current ticks counter value
|
||||
@item @code{@value{DIRPREFIX}clock_tick_later} - Get tick value in the future
|
||||
@item @code{@value{DIRPREFIX}clock_tick_later_usec} - Get tick value in the future in microseconds
|
||||
@item @code{@value{DIRPREFIX}clock_tick_before} - Is tick value is before a point in time
|
||||
@item @code{@value{DIRPREFIX}clock_get_uptime} - Get time since boot
|
||||
@item @code{@value{DIRPREFIX}clock_get_uptime_timeval} - Get time since boot in timeval format
|
||||
@item @code{@value{DIRPREFIX}clock_get_uptime_seconds} - Get seconds since boot
|
||||
@@ -613,6 +616,107 @@ This directive is callable from an ISR.
|
||||
|
||||
This directive will not cause the running task to be preempted.
|
||||
|
||||
@c
|
||||
@c
|
||||
@c
|
||||
@page
|
||||
@subsection CLOCK_TICK_LATER - Get tick value in the future
|
||||
|
||||
@subheading CALLING SEQUENCE:
|
||||
|
||||
@ifset is-C
|
||||
@findex rtems_clock_tick_later
|
||||
@example
|
||||
rtems_interval rtems_clock_tick_later(
|
||||
rtems_interval delta
|
||||
);
|
||||
@end example
|
||||
@end ifset
|
||||
|
||||
@subheading DESCRIPTION:
|
||||
|
||||
Returns the ticks counter value delta ticks in the future.
|
||||
|
||||
@subheading NOTES:
|
||||
|
||||
This directive is callable from an ISR.
|
||||
|
||||
This directive will not cause the running task to be preempted.
|
||||
|
||||
@c
|
||||
@c
|
||||
@c
|
||||
@page
|
||||
@subsection CLOCK_TICK_LATER_USEC - Get tick value in the future in microseconds
|
||||
|
||||
@subheading CALLING SEQUENCE:
|
||||
|
||||
@ifset is-C
|
||||
@findex rtems_clock_tick_later_usec
|
||||
@example
|
||||
rtems_interval rtems_clock_tick_later_usec(
|
||||
rtems_interval delta_in_usec
|
||||
);
|
||||
@end example
|
||||
@end ifset
|
||||
|
||||
@subheading DESCRIPTION:
|
||||
|
||||
Returns the ticks counter value at least delta microseconds in the future.
|
||||
|
||||
@subheading NOTES:
|
||||
|
||||
This directive is callable from an ISR.
|
||||
|
||||
This directive will not cause the running task to be preempted.
|
||||
|
||||
@c
|
||||
@c
|
||||
@c
|
||||
@page
|
||||
@subsection CLOCK_TICK_BEFORE - Is tick value is before a point in time
|
||||
|
||||
@subheading CALLING SEQUENCE:
|
||||
|
||||
@ifset is-C
|
||||
@findex rtems_clock_tick_before
|
||||
@example
|
||||
rtems_interval rtems_clock_tick_before(
|
||||
rtems_interval tick
|
||||
);
|
||||
@end example
|
||||
@end ifset
|
||||
|
||||
@subheading DESCRIPTION:
|
||||
|
||||
Returns true if the current ticks counter value indicates a time before the
|
||||
time specified by the tick value and false otherwise.
|
||||
|
||||
@subheading NOTES:
|
||||
|
||||
This directive is callable from an ISR.
|
||||
|
||||
This directive will not cause the running task to be preempted.
|
||||
|
||||
@subheading EXAMPLE:
|
||||
|
||||
@example
|
||||
@group
|
||||
status busy( void )
|
||||
@{
|
||||
rtems_interval timeout = rtems_clock_tick_later_usec( 10000 );
|
||||
|
||||
do @{
|
||||
if ( ok() ) @{
|
||||
return success;
|
||||
@}
|
||||
@} while ( rtems_clock_tick_before( timeout ) );
|
||||
|
||||
return timeout;
|
||||
@}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@c
|
||||
@c
|
||||
@c
|
||||
|
||||
@@ -230,6 +230,59 @@ static void test_interrupt_locks( void )
|
||||
rtems_interrupt_lock_destroy( &initialized );
|
||||
}
|
||||
|
||||
static void test_clock_tick_functions( void )
|
||||
{
|
||||
rtems_interrupt_level level;
|
||||
Watchdog_Interval saved_ticks;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
rtems_interrupt_disable( level );
|
||||
|
||||
saved_ticks = _Watchdog_Ticks_since_boot;
|
||||
|
||||
_Watchdog_Ticks_since_boot = 0xdeadbeef;
|
||||
rtems_test_assert( rtems_clock_get_ticks_since_boot() == 0xdeadbeef );
|
||||
|
||||
rtems_test_assert( rtems_clock_tick_later( 0 ) == 0xdeadbeef );
|
||||
rtems_test_assert( rtems_clock_tick_later( 0x8160311e ) == 0x600df00d );
|
||||
|
||||
_Watchdog_Ticks_since_boot = 0;
|
||||
rtems_test_assert( rtems_clock_tick_later_usec( 0 ) == 1 );
|
||||
rtems_test_assert( rtems_clock_tick_later_usec( 1 ) == 2 );
|
||||
rtems_test_assert( rtems_clock_tick_later_usec( US_PER_TICK ) == 2 );
|
||||
rtems_test_assert( rtems_clock_tick_later_usec( US_PER_TICK + 1 ) == 3 );
|
||||
|
||||
_Watchdog_Ticks_since_boot = 0;
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0xffffffff ) );
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0 ) );
|
||||
rtems_test_assert( rtems_clock_tick_before( 1 ) );
|
||||
|
||||
_Watchdog_Ticks_since_boot = 1;
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0 ) );
|
||||
rtems_test_assert( !rtems_clock_tick_before( 1 ) );
|
||||
rtems_test_assert( rtems_clock_tick_before( 2 ) );
|
||||
|
||||
_Watchdog_Ticks_since_boot = 0x7fffffff;
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0x7ffffffe ) );
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0x7fffffff ) );
|
||||
rtems_test_assert( rtems_clock_tick_before( 0x80000000 ) );
|
||||
|
||||
_Watchdog_Ticks_since_boot = 0x80000000;
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0x7fffffff ) );
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0x80000000 ) );
|
||||
rtems_test_assert( rtems_clock_tick_before( 0x80000001 ) );
|
||||
|
||||
_Watchdog_Ticks_since_boot = 0xffffffff;
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0xfffffffe ) );
|
||||
rtems_test_assert( !rtems_clock_tick_before( 0xffffffff ) );
|
||||
rtems_test_assert( rtems_clock_tick_before( 0 ) );
|
||||
|
||||
_Watchdog_Ticks_since_boot = saved_ticks;
|
||||
|
||||
rtems_interrupt_enable( level );
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
void test_interrupt_inline(void)
|
||||
{
|
||||
rtems_interrupt_level level;
|
||||
@@ -413,6 +466,8 @@ rtems_task Init(
|
||||
directive_failed( status, "rtems_clock_tick" );
|
||||
puts( "clock_tick from task level" );
|
||||
|
||||
test_clock_tick_functions();
|
||||
|
||||
/*
|
||||
* Now do a dispatch directly out of a clock tick that is
|
||||
* called from a task. We need to create a task that will
|
||||
|
||||
@@ -13,6 +13,9 @@ test set name: sp37
|
||||
directives:
|
||||
|
||||
rtems_clock_tick
|
||||
rtems_clock_tick_later()
|
||||
rtems_clock_tick_later_usec()
|
||||
rtems_clock_tick_before()
|
||||
rtems_interrupt_disable (inline/body)
|
||||
rtems_interrupt_enable (inline/body)
|
||||
rtems_interrupt_flash (inline/body)
|
||||
@@ -24,6 +27,8 @@ concepts:
|
||||
+ Ensure that rtems_clock_tick operates properly when invoked from a task
|
||||
rather than an ISR.
|
||||
|
||||
+ Ensure that clock tick counter functions work properly.
|
||||
|
||||
+ Ensure that the interrupt disable, enable, and flash directives operate
|
||||
as expected.
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#include <tmacros.h>
|
||||
|
||||
#define US_PER_TICK 10000
|
||||
|
||||
/* functions */
|
||||
|
||||
rtems_task Init(
|
||||
@@ -28,6 +30,8 @@ rtems_task Init(
|
||||
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_MICROSECONDS_PER_TICK US_PER_TICK
|
||||
|
||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||
#define CONFIGURE_INIT_TASK_PRIORITY 2
|
||||
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_PREEMPT
|
||||
|
||||
Reference in New Issue
Block a user