ARM Technical Support Knowledge Articles

HARDWARE TIMER INTERRUPT FAILS

Applies to: RTX51 Tiny Real-time Kernel

Answer


Information in this article applies to:


QUESTION

I'm using the RTX Tiny kernel on an Analog Devices ADuC834 MicroConverter. I have added the following hardware timer interrupt code to the CONF_TNY.A51 configuration file:

;------------------------------------------------------------------------------
;
;  USER CODE FOR 8051 HARDWARE TIMER INTERRUPT
;  ===========================================
;
;  The following macro defines the code executed on a hardware timer interrupt.
;
;  Define instructions executed on a hardware timer interrupt.
EXTRN           XDATA (us_value)
HW_TIMER_CODE   MACRO
                USING   0       ; Registerbank 0 for following code

                PUSH    AR6
                PUSH    ACC
                        ; test if null
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                MOV     R6,A
                INC     DPTR
                MOVX    A,@DPTR
                ORL     A,R6
                JZ      HW_TIMER_CODE_END
                        ; us_value --;
                MOVX    A,@DPTR
                ADD     A,#0FFH
                MOVX    @DPTR,A
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                ADDC    A,#0FFH
                MOVX    @DPTR,A
HW_TIMER_CODE_END:
                                ; End of Macro by default
                POP     ACC
                POP     AR6
                RETI
                ENDM

I am using the simulator to verify my code behavior. Everything seems to work correctly (several timer interruption calls with the correct behavior) however, from time to time, the value of us_value is changed when the program exits for RTX_TNY call.

What can be the reason for this problem?

ANSWER

The hardware interrupt code needs to save all modified registers. You need to PUSH and POP the following registers that are altered in your code: DPL, DPH (=DPTR), PSW (required for Carry flag that is modified by ADDC). When you change your code as follows everything should work fine:

HW_TIMER_CODE   MACRO
                USING   0       ; Registerbank 0 for following code

                PUSH    DPL
                PUSH    DPH
                PUSH    PSW
                PUSH    AR6
                PUSH    ACC
                        ; test if null
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                MOV     R6,A
                INC     DPTR
                MOVX    A,@DPTR
                ORL     A,R6
                JZ      HW_TIMER_CODE_END
                        ; us_value --;
                MOVX    A,@DPTR
                ADD     A,#0FFH
                MOVX    @DPTR,A
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                ADDC    A,#0FFH
                MOVX    @DPTR,A
HW_TIMER_CODE_END:
                                ; End of Macro by default
                POP     ACC
                POP     AR6
                POP     PSW
                POP     DPH
                POP     DPL
                RETI
                ENDM

If you are in doubt, you should write the interrupt service routine with the C51 Compiler and copy the generated assembler instructions (i.e. generated with the SRC directive) to the CONF_TNY.A51 file.

MORE INFORMATION

SEE ALSO

Article last edited on: 2006-10-29 19:01:38

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential