Pages: [1]   Go Down
Author Topic: noInterupts via "cli() + restore SREG" method  (Read 1242 times)
0 Members and 1 Guest are viewing this topic.
Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hi!

i have a concern about this code (for example in 0012's millis()):
Quote
uint8_t oldSREG = SREG;
// XXX
cli();
SREG = oldSREG;

what if at XXX an interupt happens, that changes SREG?
or is that impossible?

shouldn't we try to atomically manipulate the interrupt enabled bit?
maybe like this:
SREG &= oldSREG | (0xff ^ InteruptEnabledBitMask);

we just want to make sure, that we dont re-enable interrupts early, right?

bye
Logged

-Arne

Portland, OR, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 78
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
what if at XXX an interupt happens, that changes SREG?
Interrupt handlers are not supposed to change SREG bits.  Besides, C/C++ code generally doesn't care about most of the bits in SREG.  If you were writing assembly language code, you could use a macro like the one below to conditionally enable interrupts based on a saved SREG value.
Code:
.macro restInt _reg=r24
  sbrc \_reg, SREG_I
  sei
.endm
« Last Edit: November 25, 2008, 01:46:44 pm by dkinzer » Logged

Don

ZBasic Microcontrollers
http://www.zbasic.net

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

oh - ok...
Logged

-Arne

0
Offline Offline
God Member
*****
Karma: 0
Posts: 511
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I looked at the assembly dump of a "large" project and the only sreg reference was from delaymicroseconds (ver 0011).  So that corroborates  what you are saying Don.  

I think the only thing (generally speaking) we care about is the global interrupt flag in SREG, and being able to restore it to its previous value after ensuring interrupts are disabled for a critical operation.

I don't know if the general population needs to prepare for nested interrupts though.  

One other annoyance is the fact that the interrupt handlers use reti by default also complicates things in the reuse department.  If they pushed and popped sreg (you know what I mean smiley ), that might be better from a reuse, nesting perspective.

« Last Edit: November 26, 2008, 07:24:19 am by dcb » Logged

Portland, OR, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 78
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
One other annoyance is the fact that the interrupt handlers use reti by default also complicates things in the reuse department.
This is not an issue either.  Consider that in order for an interrupt handler to have executed (by normal means, that is), interrupts must have been enabled.  Consequently, the fact that RETI unconditionally enables interrupts is immaterial.

It might be a problem if your code disables interrupts and then performs a CALL to the ISR's starting address.  This would be an unusual programming technique, though.
Logged

Don

ZBasic Microcontrollers
http://www.zbasic.net

0
Offline Offline
God Member
*****
Karma: 0
Posts: 511
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

well from a reuse perspective, I cant use an interrupt handler function from "normal" code without poential SEI side effects.  minor annoyance smiley
Logged

Portland, OR, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 78
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I cant use an interrupt handler function from "normal" code without poential SEI side effects.
True.  However, you could factor out the code into a separate routine that is called from the ISR and otherwise.  Of course, that adds a bit of overhead to the ISR that wouldn't be incurred otherwise.
« Last Edit: November 26, 2008, 08:11:14 pm by dkinzer » Logged

Don

ZBasic Microcontrollers
http://www.zbasic.net

Pages: [1]   Go Up
Jump to: