This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Retaining global variable value after resetting device


$NOMOD51
;------------------------------------------------------------------------------
;  This file is part of the C51 Compiler package
;  Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
;------------------------------------------------------------------------------
;  STARTUP.A51:  This code is executed after processor reset.
;
;  To translate this file use A51 with the following invocation:
;
;     A51 STARTUP.A51
;
;  To link the modified STARTUP.OBJ file to your application use the following
;  BL51 invocation:
;
;     BL51 <your object file list>, STARTUP.OBJ <controls>
;
;------------------------------------------------------------------------------
;
;  User-defined Power-On Initialization of Memory
;
;  With the following EQU statements the initialization of memory
;  at processor reset can be defined:
;
;               ; the absolute start-address of IDATA memory is always 0
IDATALEN        EQU     80H     ; the length of IDATA memory in bytes.
;
XDATASTART      EQU   100H      ; the absolute start-address of XDATA memory
XDATALEN        EQU  7F00H      ; the length of XDATA memory in bytes.
;
PDATASTART      EQU     0H      ; the absolute start-address of PDATA memory
PDATALEN        EQU   100H      ; the length of PDATA memory in bytes.
;
;  Notes:  The IDATA space overlaps physically the DATA and BIT areas of the
;          8051 CPU. At minimum the memory space occupied from the C51
;          run-time routines must be set to zero.
;------------------------------------------------------------------------------
;
;  Reentrant Stack Initilization
;
;  The following EQU statements define the stack pointer for reentrant
;  functions and initialized it:
;
;  Stack Space for reentrant functions in the SMALL model.
IBPSTACK        EQU     0       ; set to 1 if small reentrant is used.
IBPSTACKTOP     EQU     0FFH+1  ; set top of stack to highest location+1.
;
;  Stack Space for reentrant functions in the LARGE model.
XBPSTACK        EQU     1       ; set to 1 if large reentrant is used.
XBPSTACKTOP     EQU     3FFFH+1 ; set top of stack to highest location+1.
;
;  Stack Space for reentrant functions in the COMPACT model.
PBPSTACK        EQU     0       ; set to 1 if compact reentrant is used.
PBPSTACKTOP     EQU     0FFFFH+1; set top of stack to highest location+1.
;
;------------------------------------------------------------------------------
;
;  Page Definition for Using the Compact Model with 64 KByte xdata RAM
;
;  The following EQU statements define the xdata page used for pdata
;  variables. The EQU PPAGE must conform with the PPAGE control used
;  in the linker invocation.
;
PPAGEENABLE     EQU     0       ; set to 1 if pdata object are used.
;
PPAGE           EQU     0       ; define PPAGE number.
;
PPAGE_SFR       DATA    0A0H    ; SFR that supplies uppermost address byte
;               (most 8051 variants use P2 as uppermost address byte)
;
;------------------------------------------------------------------------------

; Standard SFR Symbols
ACC     DATA    0E0H
B       DATA    0F0H
SP      DATA    81H
DPL     DATA    82H
DPH     DATA    83H

                NAME    ?C_STARTUP


?C_C51STARTUP   SEGMENT   CODE
?STACK          SEGMENT   IDATA

                RSEG    ?STACK
                DS      1

                EXTRN CODE (?C_START)
                PUBLIC  ?C_STARTUP

                CSEG    AT      0
?C_STARTUP:     LJMP    STARTUP1

                RSEG    ?C_C51STARTUP

STARTUP1:

IF IDATALEN <> 0
                MOV     R0,#IDATALEN - 1
                CLR     A
IDATALOOP:      MOV     @R0,A
                DJNZ    R0,IDATALOOP
ENDIF

IF XDATALEN <> 0
                MOV     DPTR,#XDATASTART
                MOV     R7,#LOW (XDATALEN)
  IF (LOW (XDATALEN)) <> 0
                MOV     R6,#(HIGH (XDATALEN)) +1
  ELSE
                MOV     R6,#HIGH (XDATALEN)
  ENDIF
                CLR     A
XDATALOOP:      MOVX    @DPTR,A
                INC     DPTR
                DJNZ    R7,XDATALOOP
                DJNZ    R6,XDATALOOP
ENDIF

IF PPAGEENABLE <> 0
                MOV     PPAGE_SFR,#PPAGE
ENDIF

IF PDATALEN <> 0
                MOV     R0,#LOW (PDATASTART)
                MOV     R7,#LOW (PDATALEN)
                CLR     A
PDATALOOP:      MOVX    @R0,A
                INC     R0
                DJNZ    R7,PDATALOOP
ENDIF

IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)

                MOV     ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)

                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF

IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
                MOV     ?C_PBP,#LOW PBPSTACKTOP
ENDIF

                MOV     SP,#?STACK-1
; This code is required if you use L51_BANK.A51 with Banking Mode 4
; EXTRN CODE (?B_SWITCH0)
;               CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
                LJMP    ?C_START

                END

I am using above startup.a51 in my project. I want to use one global variable as a flag, so that its value should be retained after resetting device.
I set one global variable at memory location 8000 and I changed in startup.a51 initialization from XDATALEN EQU 7F00H to
XDATALEN EQU 7EFFH
But still it is intializing this variable to 0 after resetting. Please give me the solution for this problem.

  • "But still it is intializing this variable to 0 after resetting"

    Is that in the Simulator, or a real target?

  • What kind of target ?

    The internal memory does not get zeroed during a reset, but what the external memory does is pretty much implementation-defined.

  • If this variable is truly defined as "global" or static somewhere, then the initialization to zero might well be occurring in a place other than startup.A51.

    One of the things that C compilers have to guarantee is that any variable defined with static storage class is automatically initialized to zero if you don't specify an initial value explicitly. The location where xdata memory is initialized to zero isn't necessarily what does this, if I remember correctly.

    C51 uses some magic like C_INITSEG to keep a list of all the static/global variables and then runs through there and initializes all those to zero (or whatever value you've explicitly specified). That might be where you have to turn your sights.

    To take a look at what happens, check out the file INIT.A51. I'm guessing that would be the next good place to take a look.

  • What kind of reset are you using?

    If it is a complete board reset, you may well find that the memory device in which the variable is mapped is being resetted as well.

    Jose

  • yes, I am resetting entire board. Is there any other way to retain the value of that variable?

  • "C51 uses some magic like C_INITSEG to keep a list of all the static/global variables and then runs through there and initializes all those to zero (or whatever value you've explicitly specified). That might be where you have to turn your sights."

    My recollection is that C_INITSEG just does non-zero initialisations; the rest is done by startup.A51.

    However, I wouldn't like to bet on my recollection being better than yours - so the OP is just going to have to do his own research to be sure!

    At least he now has some good Keywords to start his searching: "C_INITSEG", "startup.A51", "INIT.A51"...

  • use any debugger (preferably an ICE)

    at the beginning of statup, patch the variable to nonzero, set a breakpoint at the end of statup, if sti;ll nonzero, set abreakpoint...

    standard debugging technique.