|
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:
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.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 assumedto ... in r0, _SFR_IO_ADDR(SREG) ; load status. SREG is a SFR macro push r0 ; save loaded status. Assumes irqs areI 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
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
smime.p7s
Description: S/MIME Cryptographic Signature
[Prev in Thread] | Current Thread | [Next in Thread] |