Example #1
0
/**
 * Main function of the timer task. This function is in charge of
 *    calling the callbacks associated with the timers.
 *
 *    This function is run in a high priority task on microkernel builds.
 *    This function is run in a high priority fiber on nanokernel builds.
 *    It implements an infinite loop that waits for any of the semaphores from
 *    g_TimerSem.
 *    When a semaphore is signaled, this function fetches the pointer to the
 *    associated callback in g_TimerDesc, then calls it.
 *
 * @param dummy1 not used (required by ZEPHYR API)
 * @param dummy2 not used (required by ZEPHYR API) *
 *
 */
void timer_task(int dummy1, int dummy2)
{
	int32_t timeout = UINT32_MAX;
	uint32_t now;

	UNUSED(dummy1);
	UNUSED(dummy2);

	while (1) { /* the Timer task shall never stop */
		/* Before waiting for next timeout, publish it to warn QUARK cpu */
		publish_cpu_timeout(timeout);
		/* block until g_TimerSem is signaled or until the next timeout expires */
#ifdef CONFIG_MICROKERNEL
		(void)task_sem_take(g_TimerSem, CONVERT_MS_TO_TICKS(timeout));
#else
		nano_sem_take(&g_TimerSem, CONVERT_MS_TO_TICKS(timeout));
#endif
		now = get_uptime_ms();
		/* task is unblocked: check for expired timers */
		while (g_CurrentTimerHead &&
		       is_after_expiration(now, &(g_CurrentTimerHead->desc))) {
			execute_callback(g_CurrentTimerHead);
			now = get_uptime_ms();
		}
		/* Compute timeout until the expiration of the next timer */
		if (g_CurrentTimerHead != NULL) {
			/* In micro kernel context, timeout = 0 or timeout < 0 works.
			 * In nano kernel context timeout must be a positive value.
			 */
			timeout = g_CurrentTimerHead->desc.expiration - now;
			if (timeout < 0) panic(E_OS_ERR_OVERFLOW);
		} else {
			timeout = UINT32_MAX;
		}

#ifdef __DEBUG_OS_ABSTRACTION_TIMER
		if (NULL != g_CurrentTimerHead)
			_log(
				"\nINFO : timer_task : now = %u, next timer expires at %u, timeout = %u",
				get_uptime_ms(),
				g_CurrentTimerHead->desc.expiration,
				timeout);
		else
			_log(
				"\nINFO : timer_task : now = %u, no next timer, timeout = OS_WAIT_FOREVER",
				get_uptime_ms());
#endif
	} /* end while(1) */
}
Example #2
0
/**
 * start the timer.
 *     This service may panic if err parameter is null and:
 *         no timer is available or timer is running .
 *
 * Authorized execution levels:  task, fiber, ISR
 *
 * @param tmr : handler on the timer (value returned by timer_create ).
 * @param err (out): execution status:
 */
void timer_start(T_TIMER tmr, uint32_t delay, OS_ERR_TYPE* err)
{
    T_TIMER_LIST_ELT* timer = (T_TIMER_LIST_ELT*) tmr;
    OS_ERR_TYPE localErr = E_OS_OK;

    /* if timer is created */
    if (NULL != timer)
    {
        if(timer->desc.status == E_TIMER_READY)
        {
            /* if timer parameter are valid */
            if ((NULL != timer->desc.callback) && (0 < delay))
            {
#ifdef __DEBUG_OS_ABSTRACTION_TIMER
                _log ("\nINFO : timer_start : starting  timer ");
#endif
                /* Update expiration time */
                timer->desc.delay = CONVERT_MS_TO_TICKS(delay);
                timer->desc.expiration = _GET_TICK() + timer->desc.delay;
                disable_scheduling();
                /* add the timer */
                add_timer(timer);

                /* new timer is the next to expire, unblock timer_task to assess the change */
                if (g_CurrentTimerHead == timer) {
                     signal_timer_task();
                }
                enable_scheduling();
            }
            else
            {
                 /* timer is not valid */
                 localErr = E_OS_ERR;
            }
        }
        else if(timer->desc.status == E_TIMER_RUNNING)
        {
            localErr = E_OS_ERR_BUSY;
        }
    }
    else
    { /* tmr is not a timer from g_TimerPool_elements */
        localErr = E_OS_ERR;
    }

    error_management(err, localErr);

}
Example #3
0
/**
 * Create  a timer object.
 *     This service may panic if err parameter is null and:
 *         callback parameter is null, or
 *         no timer is available.
 *
 * Authorized execution levels:  task, fiber, ISR
 *
 * @param callback: pointer to the function to be executed.
 * @param privData: pointer to data that shall be passed to the callback
 * @param delay: number of milliseconds between function executions
 * @param repeat: specifies if the timer shall be re-started after each execution of the callback
 * @param startup : specifies if the timer shall be start immediately
 * @param err (out): execution status:
 *         E_OS_OK : callback is programmed
 *         E_OS_ERR: no timer is available, or callback parameter is null
 *
 * @return Handler on the timer, NULL if the service fails (e.g. no available
 *         timer or callback is a null pointer).
 */
T_TIMER timer_create(T_ENTRY_POINT callback, void* privData, uint32_t delay, bool repeat, bool startup, OS_ERR_TYPE* err)
{
    T_TIMER_LIST_ELT* timer = NULL;
#ifdef CONFIG_NANOKERNEL /********************** NANO KERNEL SPECIFIC:  */
    if (delay> 0 && delay < NANO_TICK ) {
      delay= NANO_TICK;
    }
#endif
    /* check input parameters */
    if ((NULL != callback) && (OS_WAIT_FOREVER != delay))
    {
        /* delay should be set to 0 if startup flag is false
         * otherwise delay should be a positive value if startup flag is true */
        if (((0 < delay) && (true == startup)) || ((0 <= delay) && (false == startup)))
        {
            /* find and reserve a timer resource from g_TimerPool_elements */
            /* rem: timer points to an element from the global g_TimerPool_elements */
            timer = g_TimerPool_alloc();
            if (timer != NULL)
            {
                /* initialize timer descriptor */
                timer->desc.callback = callback;
                timer->desc.data = privData;
                timer->desc.delay =  CONVERT_MS_TO_TICKS ( delay );
                timer->desc.repeat = repeat;
                timer->desc.status = E_TIMER_READY;

                /* insert timer in the list of active timers */
                if (startup)
                {
                    timer->desc.expiration = _GET_TICK() + timer->desc.delay;
                    disable_scheduling();
                    add_timer(timer);
                    if ( g_CurrentTimerHead == timer )
                    {
                        /* new timer is the next to expire, unblock timer_task to assess the change */
                        signal_timer_task();
                    }
                    enable_scheduling();
                }

    #ifdef __DEBUG_OS_ABSTRACTION_TIMER
                _log ("\nINFO : timer_create : new timer will expire at %u (now = %u ) - addr = 0x%x",timer->desc.expiration,_GET_TICK(), (uint32) timer);
    #endif
                error_management (err, E_OS_OK);
            }
            else
            {
                /* all timers from the pool are already being used */
                error_management (err, E_OS_ERR_NO_MEMORY);
            }
        }
        else
        { /* delay and startup parameter are inconsistent */
            error_management (err, E_OS_ERR);
        }
    }
    else
    { /* callback == NULL or delay == 0 : at least one parameter is invalid */
        error_management (err, E_OS_ERR);
    }
    return ((T_TIMER) timer);
}