Clock

Features Supported

  • Provide system tick functionality using a single timer to periodically interrupt the CPU

  • Default tick period is 1000 usecs

  • Using this system tick,

    • Users can create arbitrary number of clock objects

    • When a clock object expires, a user specified callback is called

    • Clock expiry time is specified in units of clock ticks

    • Each clock can be started in one-shot callback or periodic callback mode

  • Provides APIs to wait ‘n’ clock ticks, get current clock ticks

  • Provides APIs to convert clock ticks to time in usecs and vica versa

  • API to get current time in units of usecs

Features NOT Supported

NA

Important Usage Guidelines

  • The user specific callback can be called in interrupt, SWI or task context depending on the underlying RTOS that is used

    • In no-RTOS case, the callback is called in interrupt context

    • It is recommended to assume that the callback is called in ISR context and not block within the callback.

    • Typically one should do very limited work within the callback itself and defer the larger part of the work to a task via a semaphore post.

  • ClockP_usleep and ClockP_sleep will block until the user specified time is expired.

    • In no-RTOS case, there is only a single main task and that will block or spin until the ticks have elasped

    • In RTOS case, the current executing task will ‘pend’ and schedular will switch to another ready task

    • In both cases ISR’s are still active

    • In RTOS case, actual sleep will be in the range of sleep time - ClockP_ticksToUsec(1) to sleep time. If you need to guarantee atleast minimum sleep of sleep time, you need to sleep for sleep time + ClockP_ticksToUsec(1), i.e there will be a error on 1 OS tick at max.

  • When using multiple CPUs, make sure each CPU uses a different HW timer else the tick ISR will not trigger as expected.

  • Recommended value of tick period is 1ms or 1000us

  • Adding any module in SysConfig, automatically adds a clock module with a timer configured for 1ms. The default timer is chosen such that it does not overlap with a timer from another CPU.

  • In R5F, one of the many SOC level timer is used.

Example Usage

Include the below file to access the APIs,

Example callback that increments a global counter based on the clock that invoked the callback:

Example usage to create a clock in one shot mode with timer expiry of 10ms:

Example usage to create a clock in periodic mode with timer period of 100ms:

Example usage to measure time and profile a function:

API Reference

Defines

ClockP_OBJECT_SIZE_MAX

Max size of clock object across no-RTOS and all OS’s.

Typedefs

typedef void (*ClockP_FxnCallback)(ClockP_Object *obj, void *args)

Callback that is called when the clock expires.

Param obj:

[in] Clock object associated with this callback

Param args:

[in] user specific argument pointer that was passed via ClockP_Params

Functions

void ClockP_init(void)

Initialize the clock module.

The API is called during system init to setup a timer to run at a periodic time internval of ‘n’ micro seconds.

‘n’ can be configued by the user via SysConfig, default value for ‘n’ is typically 1000 us

Using this single timer, the clock API can be used to start multiple ‘clock’s in units of clock ticks.

void ClockP_deinit()

De-initialize the clock module.

This API is called at the end of the application to stop timers and destroy interrupt handlers

void ClockP_Params_init(ClockP_Params *params)

Set default values to ClockP_Params.

Strongly recommended to be called before seting values in ClockP_Params

Parameters:

params – [out] parameter structure to set to default

int32_t ClockP_construct(ClockP_Object *obj, ClockP_Params *params)

Create a clock object.

when ClockP_Params.start = 1, this also starts the clock object

Parameters:
  • obj – [out] created object

  • params – [in] parameter structure

Returns:

SystemP_SUCCESS on success, SystemP_FAILURE on error

void ClockP_destruct(ClockP_Object *obj)

Cleanup, delete, destruct a clock object.

Parameters:

obj – [in] object

void ClockP_start(ClockP_Object *obj)

Start the clock, if not already started.

If clock is already started, then this restarts it with updated timeout and period, if any.

Parameters:

obj – [in] object

void ClockP_stop(ClockP_Object *obj)

Stop the clock, if not already stopped. No effect if clock is already stopped.

Parameters:

obj – [in] object

uint32_t ClockP_isActive(ClockP_Object *obj)

Check if clock is active i.e not expired.

For clock setup in periodic mode, clock will always be active after it is started and before it is stopped.

For clock setup in one-shot mode , clock will be active after it is started and will be inactive after clock expires or it is stopped.

Parameters:

obj – [in] object

Returns:

0: clock is not-active or expired,

1: clock is active or not expired

void ClockP_setTimeout(ClockP_Object *obj, uint32_t timeout)

Set clock timeout value, takes effect for next clock start.

Parameters:
  • obj – [in] object

  • timeout – [in] clock expiry period of first clock execution, in units of clock ticks

uint32_t ClockP_getTimeout(ClockP_Object *obj)

Get current remaining time in units of ticks.

Parameters:

obj – [in] object

Returns:

clock expiry period of next clock execution, in units of clock ticks

uint32_t ClockP_getTicks(void)

Get current clock ticks.

Returns:

number of clock ticks that have elasped since ClockP_init()

uint64_t ClockP_usecToTicks(uint64_t usecs)

Convert usecs to clock ticks.

Parameters:

usecs – [in] time in micro seconds

Returns:

nearest integer clock ticks

uint64_t ClockP_ticksToUsec(uint32_t ticks)

Convert clock ticks to usecs.

Parameters:

ticks – [in] number of clocks ticks

Returns:

nearest integer micro seconds

uint64_t ClockP_getTimeUsec(void)

Get current time in units of usecs.

void ClockP_usleep(uint64_t usec)

Sleep for user specified usecs.

Note

Actual sleep will be in the range of usec - ClockP_ticksToUsec(1) to usec. If you need to guarantee atleast minimum sleep of usec, you need to sleep for usec + ClockP_ticksToUsec(1).

Parameters:

usec – [in] Time to sleep in units of usecs

void ClockP_sleep(uint32_t sec)

Sleep for user specified seconds.

Note

Actual sleep will be in the range of sec - ClockP_ticksToUsec(1) to sec. If you need to guarantee atleast minimum sleep of sec, you need to sleep for sec + ClockP_ticksToUsec(1).

Parameters:

sec – [in] Time to sleep in units of secs

struct ClockP_Object
#include <ClockP.h>

Opaque clock object used with the clock APIs.

Public Members

uintptr_t rsv[ClockP_OBJECT_SIZE_MAX / sizeof(uint32_t)]

reserved, should NOT be modified by end users

struct ClockP_Config
#include <ClockP.h>

ClockP module config, set as part of SysConfig, not to be set by end-users directly.

Public Members

uint32_t timerBaseAddr

HW Timer MMR base address

uint32_t timerHwiIntNum

CPU interrupt number for this timer

uint32_t eventId
uint32_t timerInputClkHz

Timer clock in units of Hz

uint32_t timerInputPreScaler

Timer divider to apply to the input clock

uint32_t usecPerTick

period of one timer tick in units of usecs

struct ClockP_Params
#include <ClockP.h>

Parameters passed during ClockP_construct.

Public Members

uint32_t start

0: do not start the clock after construct,

1: start the clock after construct

uint32_t timeout

clock period for first execution, in units of clock ticks

uint32_t period

clock period for subsequent periodic execution, in units of clock ticks.

Set to 0 for one-shot mode of operation

ClockP_FxnCallback callback

User callback to invoke when timer expires.

Note

Callback could be called in ISR context, so user should not block within the ISR

void *args

User argument that is available inside the callback

const char *name

Name to associate with this object