1.2.11.2 Using The Library

The Time System Service provides alarm and delay functionalities to multiple clients. In addition, it also provides APIs to read the counter value which can be used to measure the time period between two events.

Alarm

  • For single/one-shot alarms, the application must register a callback. Once the requested time period elapses, the application is notified by calling the registered callback. After the callback is given, the internal timer object is destroyed by Time System Service, making it available for application to request new alarms/delays.

  • For periodic alarms, the application can either register a callback or can choose to poll the status of the alarm. Once the requested time period elapses, the application is notified by calling the callback if registered by the application. In case the application wants to poll the status of the alarm it can do so by calling the status API provided by the library.

  • Application can use the delay functionality by using the delay related APIs and then polling the status of the requested delay. Calling the status API after the delay has expired will destroy the internal timer object making it available for new alarms/delays.

  • The library also provides counter functionality, that can be used by the application to measure the time elapsed between the two events. The counter functionality does not require a dedicated timer object and is always available.

Example application demonstrating the multi-client system timer functionality

This application demonstrates timer functionality (with two clients to the Time System Service) by periodically printing a message on console every two seconds and blinking an LED every one second

#define LED_BLINK_RATE_MS         1000
#define CONSOLE_PRINT_RATE_MS     2000
#define SINGLE_SHOT_TIMER_MS      100
#define SWITCH_DELAY_MS           500

typedef struct
{
    /* The application's current state */
    APP_STATES state;

    SYS_TIME_HANDLE tmr1Handle;
    volatile bool tmr1Expired;

    SYS_TIME_HANDLE tmr2Handle;
    volatile bool tmr2Expired;

    SYS_TIME_HANDLE tmr3Handle;
    volatile bool tmr3Expired;

    SYS_TIME_HANDLE tmr4Handle;
    uint64_t prevCounterVal;

} APP_DATA;

APP_DATA appData;

void Timer1_Callback ( uintptr_t context )
{
    appData.tmr1Expired = true;
}

void Timer2_Callback ( uintptr_t context )
{
    appData.tmr2Expired = true;
}

void Timer3_Callback ( uintptr_t context )
{
    appData.tmr3Expired = true;
}

void APP_Initialize ( void )
{
    /* Place the App state machine in its initial state. */
    appData.state = APP_STATE_INIT;
    appData.state = APP_STATE_INIT;
    appData.tmr1Handle = SYS_TIME_HANDLE_INVALID;
    appData.tmr2Handle = SYS_TIME_HANDLE_INVALID;
    appData.tmr3Handle = SYS_TIME_HANDLE_INVALID;
    appData.tmr4Handle = SYS_TIME_HANDLE_INVALID;
    appData.tmr1Expired = false;
    appData.tmr2Expired = false;
    appData.tmr3Expired = false;
}

void APP_Tasks ( void )
{
    uint64_t diffCount = 0;

    /* Check the application's current state. */
    switch ( appData.state )
    {
        /* Application's initial state. */
        case APP_STATE_INIT:
        {
            appData.tmr1Handle = SYS_TIME_CallbackRegisterMS(Timer1_Callback, 0, LED_BLINK_RATE_MS, SYS_TIME_PERIODIC);
            appData.tmr2Handle = SYS_TIME_CallbackRegisterMS(Timer2_Callback, 0, CONSOLE_PRINT_RATE_MS, SYS_TIME_PERIODIC);

            if ((appData.tmr1Handle != SYS_TIME_HANDLE_INVALID) && (appData.tmr2Handle != SYS_TIME_HANDLE_INVALID))
            {

                appData.state = APP_STATE_SERVICE_TASKS;
            }
            break;
        }

        case APP_STATE_SERVICE_TASKS:
        {
            if(appData.tmr1Expired == true)
            {
                /* Toggle LED periodically */
                appData.tmr1Expired = false;
                LED_TOGGLE();
            }
            if(appData.tmr2Expired == true)
            {
                printf("Message printed every %d ms \r\n", CONSOLE_PRINT_RATE_MS);
                appData.tmr2Expired = false;
            }
            if(appData.tmr3Expired == true)
            {
                printf("Single shot timer of %d ms expired \r\n", SINGLE_SHOT_TIMER_MS);
                appData.tmr3Expired = false;
            }
            if(SWITCH_GET() == SWITCH_STATUS_PRESSED)
            {
                /* Wait on delay */
                appData.prevCounterVal = SYS_TIME_Counter64Get();

                SYS_TIME_DelayMS(SWITCH_DELAY_MS, &appData.tmr4Handle);
                while(SYS_TIME_DelayIsComplete(appData.tmr4Handle) == false);

                diffCount = (SYS_TIME_Counter64Get() - appData.prevCounterVal);
                printf("Delay time = %d ms\r\n", (int)SYS_TIME_CountToMS(diffCount));

                appData.tmr3Handle = SYS_TIME_CallbackRegisterMS(Timer3_Callback, 0, SINGLE_SHOT_TIMER_MS, SYS_TIME_SINGLE);
            }
            break;
        }

        /* The default state should never be executed. */
        default:
        {
            break;
        }

    }
}