Pumpkin, Inc.

Pumpkin User Forums

Cyclic timers

Have an idea on how to make Salvo better? Post it here!

Cyclic timers

Postby aek » Mon Aug 26, 2002 1:58 am

Hello.

What would the API look like?

It's an interesting idea -- I have to figure out how to incorporate these cyclic timers into the existing delay queue structure.

Also, how to tie each timer to an event flag (or other event). This is probably the bigger problem, as this will require more RAM, which goes against Salvo's core design philosophy. But it should certainly be less than 20 tasks' worth of RAM ...

For the time being, why not use a spare timer and call OSSignalEFlag() from inside its ISR? Is it that you want to take advantage of Salvo's built-in timing features instead of using a timer + interrupts? I suspect that a well-written cyclic timer routine could signal multiple event flags and still be very compact ...

Regards,

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Cyclic timers

Postby jtemples » Mon Aug 26, 2002 7:36 am

OSCreateCyclicTimer(initial_ticks, repeat_ticks, timer_count, event_flag, event);

initial_ticks: The number of timer ticks before the timer first triggers.

repeat_ticks: The number of timer ticks between subsequent triggers.

timer_count: The number of times the timer triggers before it stops. A magic value (e.g., 0) would indicate the timer runs forever.

event_flag: Pointer to the event flag's ecb.

event: Mask indicating the event flag to set when the timer triggers.

E.g.:

OSCreateCyclicTimer(50, 0, 1, OSECBP(1), 0x80);

Creates a one-shot timer that sets event flag 0x80 in ecb 1 in 50 ticks.

OSCreateCyclicTimer(50, 100, 0, OSECBP(1), 0x80);

Creates a timer on the same event as above that runs forever, triggering initially after 50 ticks, then every 100 ticks thereafter.

There would also be an OSDestroyCyclicTimer.

jtemples
 
Posts: 45
Joined: Tue Jul 16, 2002 11:00 pm

Re: Cyclic timers

Postby jtemples » Mon Aug 26, 2002 7:46 am

quote:
For the time being, why not use a spare timer and call OSSignalEFlag() from inside its ISR? Is it that you want to take advantage of Salvo's built-in timing features instead of using a timer + interrupts? I suspect that a well-written cyclic timer routine could signal multiple event flags and still be very compact ...

Yes, I want this to be running within the Salvo context. I've considering writing a dedicated "cyclic timer task" that receives requests through a message queue with a varying timeout on the OS_WaitMsgQ depending on when the next timer is going to trigger.
But of course I'd rather just use an OS call...

jtemples
 
Posts: 45
Joined: Tue Jul 16, 2002 11:00 pm

Re: Cyclic timers

Postby aek » Mon Aug 26, 2002 8:31 am

Hello.

I've given this some thought as to how it can be made to fit inside the current Salvo framework.

First, some observations: a simple, basic cyclic timer will take 5 bytes per timer (assuming 16-bit function pointers and 8-bit delays):

2 bytes for function pointer
1 byte for initial delay
1 byte for repeat interval (0 = one-shot)
1 byte to identify the timer

IIRC, this is the same size as a tcb for a-variant libraries. So, we can conclude that if we allow the "cyclic timer control blocks" to get bigger than this, we're gonna be inefficient in terms of RAM utilization.

2) If we could "overlay" the ctcb with the tcbs, then we can take advantage of the existing code to handle delays, etc. This would represent a decent ROM savings in OSSched().

3) I always want to create stuff for the general case, so I think it would be better not to tie the cyclic timers specifically to event flags, but rather simply to a specified function. That function can in turn signal event flags, etc.

So, I think we could do the following quite easily and look good on RAM and ROM utilization, and on speed:

code:
OSCreateCyclicTimer(initial_ticks, repeat_ticks, function);

along with OSDestroyCyclicTimer().

The function specified can be any function, but of course it must be void fn (void). But, there is context within the framework of calling that function: OScTcbP points to the tcb that is the ctcb of the cyclic timer when the function is called. So inside the called function, if you wanted only one called function to signal any of 20 different event flags, you could do something like

code:
void Fn(void)
{
switch(OSctcbP) {
case OSTCBP(7):
...
break;
case OSTCBP(8):
...
break;
default:
break;
}
}

or you could just dedicate a single function per cyclic timer (doesn't cost much ROM), like:
code:
void Fn (void) 
{
OSSignalEFlag(OSECBP(7),...);
}

The point being that you might want to do other things like signal a semaphore or do something completely outside the OS with a cyclic timer, and this would enable you to do that.

Your timer_count is the only carryover that will not fit into the tcb struct -- that would require extending tcb sizes, which I'm somewhat loathe to do. But I recognize the utility -- I'm still thinking about that one.

Comments?

------------------

[This message has been edited by aek (edited August 26, 2002).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Cyclic timers

Postby jtemples » Mon Aug 26, 2002 9:07 am

quote:
Your timer_count is the only carryover that will not fit into the tcb struct -- that would require extending tcb sizes, which I'm somewhat loathe to do. But I recognize the utility -- I'm still thinking about that one.

Such timers are typically used as one-shot, or "infinite-shot" (run until explicitly stopped). The timer_count is useful in relatively few cases, so if one feature had to go, I would think that would be it.

quote:
I think it would be better not to tie the cyclic timers specifically to event flags, but rather simply to a specified function. That function can in turn signal event flags, etc.

I would agree this is a better and more general implementation. (ThreadX handles cyclic timers this way.)

jtemples
 
Posts: 45
Joined: Tue Jul 16, 2002 11:00 pm

Re: Cyclic timers

Postby jtemples » Mon Aug 26, 2002 11:30 am

One feature I'd like to see is the ability to signal an event flag after a timeout. The timeout could be one-shot, or repeating.

For example, if I have 20 LEDs that each need to blink at different frequencies, I'd rather not create 20 led_blink tasks, but a single task that waits on 20 event flags, with each flag being triggered by a cyclic timer expiring.

jtemples
 
Posts: 45
Joined: Tue Jul 16, 2002 11:00 pm

Re: Cyclic timers

Postby luben » Tue Sep 03, 2002 9:01 am

Hello,

I read the article and I wish to share my experience in this area. In fact you don't need a new function in SALVO to do the following:

--------------
One feature I'd like to see is the ability to signal an event flag after a timeout. The timeout could be one-shot, or repeating.
For example, if I have 20 LEDs that each need to blink at different frequencies, I'd rather not create 20 led_blink tasks, but a single task that waits on 20 event flags, with each flag being triggered by a cyclic timer expiring.
------------

The timing in SALVO is strictly connected with the OSTimer() - I mean, other timings are possible only if you use event flags and other hardware timing circit.

It's not big deal to make a 20 different LED to blink with any frequency and delays into a single task. I mean - all functionality described above for the new service is possible to be done with the current SALVO services. Even I have clear vision how should look like the C code.

Anyway, if SALVO supports this new service it's OK.

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Cyclic timers

Postby aek » Fri Jan 31, 2003 10:49 am

I am in the process of adding cyclic timers to the upcoming v3.1.2 release.

So far, I have just one service in the API:

code:
OStypeErr OSCreateCycTmr ( OStypeTFP     tFP, 
OStypeTcbP tcbP,
OStypeCTMode mode,
OStypeDelay reloadDelay );

where mode is either ONE_SHOT or CONTINUOUS, and reloadDelay (this needs a better name) is the interval in ticks at which the cyclic timer calls the function tFP.

A Cyclic timer occupies one tcb.

A CycTmr's function is called from within OSSched() with interrupts enabled.

What other CycTmr API services would you like? I figure OSStopCycTmr() and OSDestroyCycTmr() would be useful ...

The utility of cyclic timers can be seen in salvoexex1main.c -- Task3() is easily replaced with a cyclic timer via

code:
void CyclicTimer1( void )
{
PORT ^= 0x08;
OSSignalBinSem(BINSEM1_P);
}

OSCreateCycTmr(CyclicTimer1, CT1_P, OSCT_CONTINUOUS, 40);


The overhead for running a cyclic timer is slightly lower than that of a task ... it still has to be reenqueued into the delay queue, etc. But it doesn't have to be enqueued into the eligible queue, like a task does when its delay expires. So it probably has, on average, half the overhead of a task w/delays.

------------------

[This message has been edited by aek (edited January 31, 2003).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Cyclic timers

Postby jtemples » Sun Feb 02, 2003 9:35 am

quote:

reloadDelay (this needs a better name) is the interval in ticks at which the cyclic timer calls the function tFP


How about "period"?
quote:

What other CycTmr API services would you like? I figure OSStopCycTmr() and OSDestroyCycTmr() would be useful ...


OSStartCycTmr() (for timers that have been stopped, or timers that are created in a stopped condition [with a mode flag?])

OsChangeCycTmrPeriod() to change the period of an existing timer (without having to destroy and create it).

OSResetCycTmr() to reset a currently running timer to zero.

[This message has been edited by jtemples (edited February 02, 2003).]

jtemples
 
Posts: 45
Joined: Tue Jul 16, 2002 11:00 pm

Re: Cyclic timers

Postby aek » Mon Feb 03, 2003 8:27 am

quote:
OSResetCycTmr() to reset a currently running timer to zero.
Does this result in the timer's function being called immediately, or not at all?

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Next

Return to Feature Requests

Who is online

Users browsing this forum: No registered users and 1 guest

cron