edward0429 / arduino

Automatically exported from code.google.com/p/arduino
0 stars 0 forks source link

Improve SIG_OVERFLOW (timer0, millis, etc) code efficiency & hooking vectors/API. #674

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What change would like to see?

Improve SIG_OVERFLOW (timer0, millis, etc) code efficiency.
Per this discussion
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1216294585

DON'T hook timer0 interrupt or create ANY code if no timer functions are used. 
e.g. delay, millis, micros, etc., so user can create ones own handler.

Provide a means to hook onto timer0 vectors with one's own ISRs and let them 
then pass overflows on to SIG_OVERFLOW as appropriate.

Have a means to control the Timer0 interrupt rate and mode with an API.
One way to do this is to use output compare to create an interrupt, but update 
the OCxx reg with a DELTA for each interrupt (like done for 6811 timers). That 
way you get a custom interrupt rate for the user, (within a range) and overflow 
ints still happen as needed.

Why?

Because Sig_overflow takes a LONG time and so blocks interrupts introducing 
variable latency. e.g. pinchange. Improving ISR code efficiency is always a 
good thing, isn't it?

I need to create a bit banged stream at 100kHz, snd since Timer0 is already 
running, I figured I could hook it for myself and then pass on SIG_OVERFLOW at 
the required update rate (967.xxx usec).
But I can't hook the vector because the compiler already has taken it for 
Sig_overflow in Wired.c, which is ALWAYS used.

Some of these issues are discussed here.
http://code.google.com/p/arduino/issues/detail?id=169&q=timer0

Would this cause any incompatibilities with previous versions?  If so, how can 
these be mitigated?

None that I can think of.

There were some patches posted that would update millis, etc.

http://code.google.com/p/arduino/issues/detail?id=187&q=timer0

while Ints were disabled, by checking for overflow flag inside millis.
If one has repgrogrammed Timer0 to do autoreload, there won't BE any overflow 
flag, but the private routine should be able to keep mills etc. happy by 
passing on to Sig_overflow at the required rate.

If one has a 100 khz base timer rate, (16 MHz/8/20) you get 10 usec tic, which 
is high, but serviceable, and very granular. And the compiler can choose a 
suitable reload constant for other clock rates.

Currently Timer0 uses 16 MHz/64/256 =976 Hz, which is a base tic of 4 usec 
counted to 256 to get 1.024 msec overflows.

Registered listeners would have to specify how many tics they wanted to wait 
between calls, and the compiler could lower the interrupt rate to the lowest 
common denominator to reduce ISR overhead while still providing calls to the 
functions as desired.

Thoughts?

If one takes too long in one's 'listener' functions, tics will be lost, but 
thats life. Beats having to code it all in ASM.

Functions would have to be responsible for saving/restoring their used 
registers (or the complier could figure that out?) so
ISR overhead is only incurred WHEN the functions are called.

Robert

Original issue reported on code.google.com by RCR...@gmail.com on 9 Oct 2011 at 5:29

GoogleCodeExporter commented 9 years ago
That should say  "976 Hz" not "967.xxx usec"

I can get my bit banging done over 85 10 usec tics (850) (distributed in 2 usec 
slices) so there is still lots of time left for background and other ints. And 
I don't do anything again for 10s of milliseconds, but the inability to hook 
the vector is frustrating. I now have to hack wiring.c and put my code in there 
to minimize the jiggery pokery that would otherwise need to be done.

And 'listner' functions would have to be short, since they are being called 
WITHIN an interrupt. And other ISR's should be non blocking if possible 
(notably serial).

I suppose one could write a 'prioritizer' ISR that traps ALL activated ints, 
and then dispatched them in priority order. Unfortunate that the AVR has no 
'execution priority' register that would block lower priority interrupts.

Original comment by RCR...@gmail.com on 9 Oct 2011 at 5:42

GoogleCodeExporter commented 9 years ago
This sounds like a duplicate of the issues you're linking to.  Or is there 
another suggestion here that isn't covered there?  

Original comment by dmel...@gmail.com on 10 Oct 2011 at 4:44

GoogleCodeExporter commented 9 years ago
I referenced the other discussion to put this request into context.

"DON'T hook timer0 interrupt or create ANY code if no timer functions are used. 
e.g. delay, millis, micros, etc., so user can more easily create ones own 
timer0 handler."
And so one doesn't have 400 some bytes of UNNEEDED code if timers are not used.

As long as you are looking at timer0, it would be good to address the other 
issues I referenced since they are all closely interrelated.

Original comment by RCR...@gmail.com on 11 Oct 2011 at 3:57