Ben S.
Ben S.

Reputation: 1143

Understanding AVR code for disabling and restoring SREG interrupt state

I'm somewhat confused by the examples of how to disable and restore the interrupt state that I've found for 8-bit AVR processors.

8-bit AVR processors like the ATmega 2560 have a Global Interrupt Enable bit (labelled 'I') in the Status Register (SREG). The CLI instruction disables all interrupts by clearing that bit. From the AVR Instruction Set Manual:

CLI - Clear Global Interrupt Enable Bit

Description

Clears the Global Interrupt Enable (I) bit in SREG (Status Register). The interrupts will be immediately disabled. No interrupt will be executed after the CLI instruction, even if it occurs simultaneously with the CLI instruction. (Equivalent to instruction BCLR 7.)

The AVR Instruction Set Manual also shows the following example:

1   in temp, SREG      ; Store SREG value (temp must be defined by user)
2   cli                ; Disable interrupts during timed sequence
3   sbi EECR, EEMWE    ; Start EEPROM write
4   sbi EECR, EEWE
5   out SREG, temp     ; Restore SREG value (I-flag)

The intent of line 5 seems to be to restore SREG's I-flag to the value that it had just before line 2 was executed. In fact, this code stores the state of all of SREG's flags - it just seems to assume that the values of SREG's other flags won't change between lines 1 and 5. However, if an interrupt occurred between lines 1 and 2, couldn't it cause some of SREG's other flags to be "restored" incorrect?

1   in temp, SREG      ; Store SREG value (temp must be defined by user)
    ; <------- interrupt occurs here
2   cli                ; Disable interrupts during timed sequence
3   sbi EECR, EEMWE    ; Start EEPROM write
4   sbi EECR, EEWE
5   out SREG, temp     ; Restore SREG value (I-flag)

Upvotes: 0

Views: 1251

Answers (1)

Ibram Reda
Ibram Reda

Reputation: 2820

  • When interrupt happen the CPU will switch to interrupt service routine but before switching the CPU will remember the location of the program (by push Program counter in the stack)
  • CPU will execute ISR
  • after execute ISR It's very important and crucial to restore CPU environment (SERG, GPR, SP, PC) as before interrupt this will be done by your code(if you did not restore CPU environment after interrupt your program will crush With High probability)
  • CPU will Return to the same location (by restore PC from Stack)
1   in temp, SREG      ; Store SREG value (temp must be defined by user)
    ; <------- interrupt occurs here
    ; <-------------go to interupt  handler
    ; <--------Rutern from interupt with same value of temp, SREG, and all GPR are same value 

2   cli                ; Disable interrupts during timed sequence
3   sbi EECR, EEMWE    ; Start EEPROM write
4   sbi EECR, EEWE
5   out SREG, temp     ; Restore SREG value (I-flag)

the above code simply telling you "Make sure that the line 3,4 will execute after each other with no interrupt"

if an interrupt occurred between lines 1 and 2, couldn't it cause some of SREG's other flags to be "restored" incorrect?

if an interrupt occurred between lines 1 and 2,the interrupt will be handled and return before the line 2 and Any interrupt code Must preserve CPU Environment

Upvotes: 0

Related Questions