avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] Interrupt vector redirection scheme


From: Michael Schulze
Subject: Re: [avr-libc-dev] Interrupt vector redirection scheme
Date: Wed, 05 Sep 2007 14:04:56 +0200
User-agent: Thunderbird 1.5.0.12 (X11/20070719)

Michael Schulze wrote:
Dmitry K. wrote:
On Tuesday 04 September 2007 18:20, Michael Schulze wrote:
Dmitry K. wrote:
On Monday 03 September 2007 19:59, Michael Schulze wrote:
Hi,

Very interesting idea. Though there is a discrepancy:
function redir_func() keeps the SREG already after it is
scratched (sbiw, eor).
I can't find the definition of that function. Where is it
defined?
Your file redirvec.S:

redir_func: sbiw ZL, 0 ; test for zero ... eor r1, r1 ; clear zero register, as assumed
 to ... in r0, _SFR_IO_ADDR(SREG)       ; load status. SREG is a
SFR macro push r0                         ; save loaded status.
Assumes irqs are
I can't see a discrepancy. I save the SREG and restore it at the
end of the function, because of the called function could it
change. However, the interrupt have to ensure that the state of all
registers is the same like before.

Check, please, the interrupt trace:

jmp TIMER1_OVR_vect

TIMER1_OVR_vect:        ; naked fuction push r31 push r30 lds  r30,
TIMER1_OVF_vect_REDIR lds  r31, TIMER1_OVF_vect_REDIR + 1 jmp
redir_func

redir_func: sbiw ZL, 0

So, the 'sbiw' instruction may change 5 bits of SREG before saving. Yes?
Yes, you are right.  I was blind. That is a bug in my implementation.
Thank you Dimitry.

Attached, you can find a corrected version of the redir_func. I tested
it and it works, how it shall.

Regards,
Michael
Oh, I saw there is still an error. The SREG has to be restored after the label redir_func_restore: This version is correct now, hopefully.

Michael

#include <avr/io.h>

; global redirection routine
; saves registers as needed and redirect to the
; address specified in redirection memory variable
.global redir_func
.func redir_func
redir_func:
        push r0                         ; save temporary register
                                        ; long names (__zero_reg__) 
                                        ; first avaiable in macros.inc
        in r0, _SFR_IO_ADDR(SREG)       ; load status. SREG is a SFR macro

        sbiw ZL, 0                      ; test for zero
        breq redir_func_restore         ; skip, if zero                         

                                        ; save used registers. Saves all 
                                        ; call-used registers. Called routines
                                        ; SHOULD do this by default. But 
                                        ; ignored for the sake of clarity and 
                                        ; in case of naked routines 
        push r0                         ; save loaded status. Assumes irqs are 
                                        ; disabled
        push r1                         ; save zero register
        eor r1, r1                      ; clear zero register, as assumed to
                                        ; always be zero
        push r18                        ; save other call-used registers
        push r19                        ;
        push r20                        ;
        push r21                        ;
        push r22                        ;
        push r23                        ;
        push r24                        ;
        push r25                        ;
        push XL                         ;
        push XH                         ;
                                
        
        icall                           ; jump to address pointed by Z pointer

                                        ; back from routine.
                                        ; restore used registers
        pop XH                          ; restore call-used registers
        pop XL                          ;
        pop r25                         ;
        pop r24                         ;
        pop r23                         ;
        pop r22                         ;
        pop r21                         ;
        pop r20                         ;
        pop r19                         ;
        pop r18                         ;
        pop r1                          ; restore zero register  
        pop r0                          ; restore status register into temporary
redir_func_restore:
        out _SFR_IO_ADDR(SREG), r0      ; load status register
        pop r0                          ; restore temporary register     
        pop ZL                          ; restore lower Z pointer        
        pop ZH                          ; restore higher Z pointer       
        reti                            ; return from redirection and so return
                                        ; from interrupt
.endfunc                                ; end of redirection routine    

.end            

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]