/*--------------------------------------------------------------------- * Generate delayed event to the application. * Deactivate fired timer. *-------------------------------------------------------------------*/ static void timer_fire( ETimer_t * const t ) { t->expiration = ( t->recurrence == 0 ) ? 0 : t->expiration + t->recurrence; Escher_SendEvent( t->event ); if ( 0 != t->recurrence ) { Escher_xtUMLEvent_t * e = Escher_AllocatextUMLEvent(); Escher_memmove( e, t->event, sizeof( Escher_xtUMLEvent_t ) ); t->event = e; #ifdef ESCHER_TASKING_POSIX Escher_mutex_lock( SEMAPHORE_FLAVOR_TIMER ); #endif animate = animate->next; /* Remove from front of list. */ timer_insert_sorted( t ); #ifdef ESCHER_TASKING_POSIX Escher_mutex_unlock( SEMAPHORE_FLAVOR_TIMER ); #endif } else { #ifdef ESCHER_TASKING_POSIX Escher_mutex_lock( SEMAPHORE_FLAVOR_TIMER ); #endif animate = animate->next; /* Remove from active list. */ t->next = inanimate; /* Connect to inactive list. */ inanimate = t; #ifdef ESCHER_TASKING_POSIX Escher_mutex_unlock( SEMAPHORE_FLAVOR_TIMER ); #endif } }
/*--------------------------------------------------------------------- * Get a timer instance from the inanimate list, provide the * expiration time and insert it into its proper location among * the currently ticking timers. *-------------------------------------------------------------------*/ static ETimer_t * timer_start( const ETimer_time_t duration, Escher_xtUMLEvent_t * const event ) { ETimer_t * t; #ifdef ESCHER_TASKING_SystemC Escher_mutex_lock( SEMAPHORE_FLAVOR_TIMER ); #endif t = inanimate; if ( t != 0 ) { inanimate = inanimate->next; t->event = event; /*---------------------------------------------------------------*/ /* Calculate the timer expiration time. */ /* Note: Add one to the duration to make sure that delay is */ /* at least as long as duration. */ /*---------------------------------------------------------------*/ t->expiration = ETimer_msec_time() + duration + 1UL; timer_insert_sorted( t ); } #ifdef ESCHER_TASKING_SystemC Escher_mutex_unlock( SEMAPHORE_FLAVOR_TIMER ); Escher_nonbusy_wake( 0 ); /* Wake default task to service timers. */ #endif return ( t ); }
/*--------------------------------------------------------------------- * This is the repetitively invoked timer poller. * This routine needs to be run periodically. *-------------------------------------------------------------------*/ void TIM_tick( void ) { #if ESCHER_SYS_MAX_XTUML_TIMERS > 0 /*-----------------------------------------------------------------*/ /* Check to see if there are timers in the ticking timers list. */ /*-----------------------------------------------------------------*/ #ifdef ESCHER_TASKING_SystemC Escher_mutex_lock( SEMAPHORE_FLAVOR_TIMER ); #endif if ( animate != 0 ) { if ( animate->expiration <= ETimer_msec_time() ) { timer_fire( animate ); } } #ifdef ESCHER_TASKING_SystemC Escher_mutex_unlock( SEMAPHORE_FLAVOR_TIMER ); #endif #endif /* if ESCHER_SYS_MAX_XTUML_TIMERS > 0 */ }
/*--------------------------------------------------------------------- * Cancel the given timer if possible. *-------------------------------------------------------------------*/ static bool timer_cancel( ETimer_t * const t ) { bool rc = false; #ifdef ESCHER_TASKING_SystemC Escher_mutex_lock( SEMAPHORE_FLAVOR_TIMER ); #endif if ( timer_find_and_delete( t ) == true ) { if ( t->event != 0 ) { Escher_DeletextUMLEvent( t->event ); rc = true; } } #ifdef ESCHER_TASKING_SystemC Escher_mutex_unlock( SEMAPHORE_FLAVOR_TIMER ); #endif return ( rc ); }