Go Down

Topic: Detecting when interrupts are enabled (Read 488 times) previous topic - next topic

TanHadron

Quote
Except that the two actions (pushing onto the stack and then clearing the interrupt) need to be atomic


Why is that?  If the interrupts were already disabled, there is no way the two actions could be separated by an interrupt.  If the interrupts are already enabled, what is the difference between an interrupt firing before the push, or an interrupt firing between the push and the cli?  I don't see how it could be a problem.

In any case, ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) isn't atomic at that point, either.  The compiler implements it by saving the __SREG__ in a general purpose register.  In my case, it was r24.  Then it executes the cli.
Code: [Select]

in r24,__SREG__
cli

;        ...    My block of code that can't be interrupted

out __SREG__,r24

stowite


Quote
Except that the two actions (pushing onto the stack and then clearing the interrupt) need to be atomic


Why is that? 


Having thought about this for a short while you are right - the two actions do not need to be atomic since there is no way that anything should be able to change the interrupt bit between the two operations. To my mind using ATOMIC_BLOCK is still the way to go.

TanHadron

I agree.  I looked at the C code in the atomic.h file, and I don't understand how the heck it works.  But I can't argue with the assembly code it spits out.

holmes4

In a chunk of code which has interrupts turned off you should never call anything but the simplest/shortest functions/methods.

Any time you have interrupts turned off you risk other problems such as serial missing data and messing you the timers making a hash of servo/mills/micros/pwm etc. The time spent in ISR's or with interrupts turned off must always be kept as short as possible. So you don't run off and play with LCDs and the like.

Mark

Robin2


In a chunk of code which has interrupts turned off you should never call anything but the simplest/shortest functions/methods.

Any time you have interrupts turned off you risk other problems such as serial missing data and messing you the timers making a hash of servo/mills/micros/pwm etc. The time spent in ISR's or with interrupts turned off must always be kept as short as possible. So you don't run off and play with LCDs and the like.


That's exactly why I think this whole question is chasing a will-o'-the-wisp.

In my code I shouldn't have to worry that some other guy did his coding badly - especially on a tiny thing like an Arduino.

I just can't envisage a situation where my code could find itself called by code from the middle of somebody else's CLI / SEI block.

And if you find yourself caught by a badly written Library the solution is to correct the library code.

...R

stowite

#20
Aug 09, 2014, 10:04 am Last Edit: Aug 09, 2014, 10:05 am by stowite Reason: 1


In a chunk of code which has interrupts turned off you should never call anything but the simplest/shortest functions/methods.

Any time you have interrupts turned off you risk other problems such as serial missing data and messing you the timers making a hash of servo/mills/micros/pwm etc. The time spent in ISR's or with interrupts turned off must always be kept as short as possible. So you don't run off and play with LCDs and the like.


That's exactly why I think this whole question is chasing a will-o'-the-wisp.

In my code I shouldn't have to worry that some other guy did his coding badly - especially on a tiny thing like an Arduino.

I just can't envisage a situation where my code could find itself called by code from the middle of somebody else's CLI / SEI block.


You are both missing the point of my original post! The third party library seems to be failing because it has very time critical code  and even though my interrupt handlers have been pared down to the very minimum the fact that I am handling about 5000 per second seems to cause the problem with the library. I am not calling somebody else's code from within a CLI / SEI block and this this whole question is most definitely not chasing a will-o'-the-wisp. My solution to the problem is to modify the third party library so that it puts a CLI / SEI block round the critical code sections in the library; something that should have been done by the writers of the library.

The 5000 per second interrupt handler is just incrementing a counter and then once a second or so it sets a flag. I can't make it any shorter than that. My code happily deals with the interrupt latency caused by the CLI / SEI block so I am not affected by it. The third party library now works without problems though before publishing the changes I do need to try to minimise the library code that needs to be placed within the CLI / SEI block(s).
Quote

And if you find yourself caught by a badly written Library the solution is to correct the library code.

...R


Which is exactly what I am doing!!!!!!!!

holmes4

@stowite we are not missing the point - the bug was NOT in the lib it was in your code when it called the part of the lib!

You do not call fuctions/methods from with ISR's or critical sections of code. The fault was with you. You tried to do to much with in the sei/cli block or ISR!

Mark

stowite


@stowite we are not missing the point - the bug was NOT in the lib it was in your code when it called the part of the lib!

You do not call fuctions/methods from with ISR's or critical sections of code. The fault was with you. You tried to do to much with in the sei/cli block or ISR!

Mark


One last time - I am not calling functions/methods from within  ISR's or critical sections of code. I am only calling the Liquid Crustal library methods from outside of the ISR. My ISR do very very little just enough to set flags which are processed in the loop() method.


MarkT

If the critical section is only called from outside of an ISR, cli/sei is fine.
If the critical section is only called from inside an ISR, nothing is needed
If the critical section can be called from both an ISR and from outside an ISR,
then you need the code that saves and restores SREG - look at the implementation
of digitalWrite().

Also if a critical section can be called from within another critical section, the save/restore
SREG method is needed.

Interrupts are enabled unless you are in an ISR or a critical section (though it is
possible to re-enable interrupts halfway through an ISR, this requires the ISR
to be coded as re-entrant, using critical sections).
[ I won't respond to messages, use the forum please ]

Robin2


You are both missing the point of my original post! The third party library seems to be failing because it has very time critical code  and even though my interrupt handlers have been pared down to the very minimum the fact that I am handling about 5000 per second seems to cause the problem with the library.


I don't see how we can be missing the point when you have never said what you are actually trying to do.

Post your code so that we have the same information in front of us as you have.

Maybe the code (library) that you would like to include in your sketch just isn't fast enough for 5000 per second?

...R

Go Up