How to run multiple timers at the same time ?
I need to use 3 timers.
Mark
How to run multiple timers at the same time ?
I need to use 3 timers.
Mark
Hi Mark,
I don’t see a problem here… Why not just call adl_tmrSubscribe() three times?
Best Regards,
Jan
Yes, limitation is around 30 timers at the same time… no problem with 3 timers !!
…and if you do need >30 (or whatever) timers, just use the standard approach of having one “real” ADL timer to generate your timebase “tick”, and maintain a number of counters clocked by that “tick” to implement your other timed requirements…
Another good reason is the need of retriggerable timers.
My app is “presetting” the counter to its initial val - unfortunately the ADL timers do not provide this funcionality.
Heinz
Absolutely!
It is a very major omission that Open-AT does not provide retrigerable timers!!
The retrigerable timer is such a fundamental requirement for any comms protocol work (ie, timeouts), that it is quite incredible that Open-AT doesn’t provide them!!
So there’s a new functionality request: wavecom.com/modules/movie/sc … php?p=4902
Since it is quite simple, but lot of work to write I’m going to share 8)
/****************************************************************************
*
* File: timer.h
*
* Object: header file for timer system
*
****************************************************************************
*
* ----------+--------+----------------+-------------------------------------
* 06/11/05 | HLI | 1.0 | Initial revision.
* ----------+--------+----------------+-------------------------------------
*
***************************************************************************/
#ifndef __TIMER_H__
#define __TIMER_H__
#include "adl_global.h"
#define MAX_TIMERS 40
typedef enum TimerStatus_e
{
TIMER_FREE = 0,
TIMER_RUNNING,
TIMER_EXPIRED,
TIMER_STOPPED
} TimerStatus_e;
typedef enum TimerType_e
{
TIMER_NONE = 0,
TIMER_ONESHOT,
TIMER_CYCLIC
} TimerType_e;
typedef struct //sw_timers_t
{
s8 timer;
TimerStatus_e state;
TimerType_e type;
u32 reload;
void (*callback)( s8 timer );
u32 count;
} sw_timers_t;
void timer_init ( void );
void timer_remove ( void );
// sw realized timer system
void SwTmr_Init ( void );
s8 SwTmr_StartTimer ( s8 timer, TimerType_e type, u32 timeout, void (*callback)( s8 timer ) );
void SwTmr_SetStatus ( s8 timer, TimerStatus_e status );
void SwTmr_StopTimer ( s8 timer );
void SwTmr_ContinueTimer ( s8 timer );
void SwTmr_KillTimer ( s8 timer );
void SwTmr_RetriggerTimer( s8 timer );
void SwTmr_SetInterval ( s8 timer, u16 new_interval );
#endif
and
/****************************************************************************
*
* File: timer.c
*
* Object: functions related to the timer subsystem
*
****************************************************************************
*
* ----------+--------+----------------+-------------------------------------
* 06/11/05 | HLI | 1.0 | Initial revision.
* ----------+--------+----------------+-------------------------------------
*
***************************************************************************/
#include "adl_global.h"
#include "timer.h"
#include "tcp_all.h"
#include "dtl_all.h"
#include "grl_all.h"
/*===========================================================================
* some global var's for timing issues
*=========================================================================*/
adl_tmr_t * myHWTimer; // wavecom system timer 100ms
sw_timers_t TIMERS[ MAX_TIMERS ]; // SW timer system
/*===========================================================================
* Function: Tmr_FindTimer
* Descr.: find the correct timer in array list
*=========================================================================*/
s8 SwTmr_FindTimer( s8 timer )
{
u8 i;
for( i = 0; i < MAX_TIMERS; i++ )
{
if ( TIMERS[ i ].timer == timer )
{
return ( i );
}
}
return ( -1 );
}
/*===========================================================================
* Function: SwTmr_KillTimer
* Descr.: cancel a running timer
*=========================================================================*/
void SwTmr_KillTimer( s8 timer )
{
s8 i = SwTmr_FindTimer( timer );
if ( i != -1 )
{
TIMERS[ i ].timer = -1;
TIMERS[ i ].reload = 0L;
TIMERS[ i ].state = TIMER_FREE;
TIMERS[ i ].callback = 0;
TIMERS[ i ].count = 0L;
}
}
/*===========================================================================
* Function: SwTmr_StopTimer
* Descr.: suspend a running sw timer
*=========================================================================*/
void SwTmr_StopTimer( s8 timer )
{
s8 i = SwTmr_FindTimer( timer );
if ( i != -1 )
{
TIMERS[ i ].state = TIMER_STOPPED;
}
}
/*===========================================================================
* Function: SwTmr_ContinueTimer
* Descr.: continue a previous suspended timer
*=========================================================================*/
void SwTmr_ContinueTimer( s8 timer )
{
s8 i = SwTmr_FindTimer( timer );
if ( i != -1 )
{
TIMERS[ i ].state = TIMER_RUNNING;
}
}
/*===========================================================================
* Function: SwTmr_RetriggerTimer
* Descr.: refresh the time of a running timer
*=========================================================================*/
void SwTmr_RetriggerTimer( s8 timer )
{
s8 i = SwTmr_FindTimer( timer );
if ( i != -1 )
{
TIMERS[ i ].count = TIMERS[ i ].reload;
}
}
/*===========================================================================
* Function: SwTmr_Init
* Descr.: initialize the software timer system
*=========================================================================*/
void SwTmr_Init( void )
{
u8 i;
for( i = 0; i < MAX_TIMERS; i++ )
{
TIMERS[ i ].timer = -1;
TIMERS[ i ].count = 0L;
TIMERS[ i ].state = TIMER_FREE;
TIMERS[ i ].type = TIMER_NONE;
TIMERS[ i ].callback = NULL;
TIMERS[ i ].reload = 0L;
}
}
/*===========================================================================
* Function: SwTmr_SetStatus
* Descr.: set the status of an existing timer
*=========================================================================*/
void SwTmr_SetStatus( s8 timer, TimerStatus_e status )
{
s8 i = SwTmr_FindTimer( timer );
if ( i != -1 )
{
TIMERS[ i ].state = status;
return;
}
}
/*===========================================================================
* Function: SwTmr_Control
* Descr.: function which is called by OS timing system to provide
* retriggerable sw timer system
*=========================================================================*/
void SwTmr_Control( u8 hwtmr )
{
// ignore hwtmr cause there is only one
u8 i;
if ( hwtmr == myHWTimer->TimerId )
{
for( i = 0; i < MAX_TIMERS; i++ )
{
if ( TIMERS[ i ].state == TIMER_RUNNING )
{
if ( TIMERS[ i ].count-- == 0 )
{
TIMERS[ i ].state = TIMER_EXPIRED;
TIMERS[ i ].callback ( TIMERS[ i ].timer );
if ( TIMERS[ i ].type == TIMER_CYCLIC )
{
TIMERS[ i ].count = TIMERS[ i ].reload;
TIMERS[ i ].state = TIMER_RUNNING;
break;
}
else
{
SwTmr_KillTimer ( i );
}
}
}
}
}
}
/*===========================================================================
* Function: SwTmr_Status
* Descr.: read the status of a sw defined timer
*=========================================================================*/
TimerStatus_e SwTmr_Status( u8 timer )
{
s8 i = SwTmr_FindTimer( timer );
if ( i != -1 )
{
return ( TIMERS[ timer ].state );
}
return ( TIMER_FREE );
}
/*===========================================================================
* Function: SwTmr_StartTimer
* Descr.: start a sw defined n*1s timer
*=========================================================================*/
s8 SwTmr_StartTimer( s8 timer, TimerType_e type, u32 timeout, void (*callback)( s8 timer ) )
{
s8 i = SwTmr_FindTimer( timer );
if ( i == -1 )
{
i = SwTmr_FindTimer( -1 );
if ( i == -1 )
{
TRACE ((1, "##### PANIC: No more sw timers! #####" ));
return ( -1 );
}
}
TIMERS[ i ].timer = timer;
TIMERS[ i ].type = type;
TIMERS[ i ].count = timeout;
TIMERS[ i ].callback = callback;
TIMERS[ i ].reload = TIMERS[ i ].count = timeout;
TIMERS[ i ].state = TIMER_RUNNING;
return ( i );
}
/*===========================================================================
* Function: SwTmr_SetInterval
* Descr.: set a new timer interval
*=========================================================================*/
void SwTmr_SetInterval ( s8 timer, u16 new_interval )
{
s8 i = SwTmr_FindTimer( timer );
if ( i != -1 )
{
TIMERS[ i ].reload = new_interval;
return;
}
}
/*===========================================================================
* Function: timer_init
* Descr.: initialize timer handling
*=========================================================================*/
void timer_init ( void )
{
SwTmr_Init();
// subscribe a OS timer every 10*100ms for the SW defined timing funcs
myHWTimer = adl_tmrSubscribe ( TRUE, (u32)10, ADL_TMR_TYPE_100MS, (void*) SwTmr_Control );
}
/*===========================================================================
* Function: timer_remove
* Descr.: remove the OS driven timing feature, therefore also
* the driven timing system stops!
*=========================================================================*/
void timer_remove ( void )
{
adl_tmrUnSubscribe ( myHWTimer, (void*) SwTmr_Control, ADL_TMR_TYPE_100MS );
}
I’m using typically 1sec intervals, but it simply can be changed by changing the values in timer_init.
Regards,
Heinz