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

Variable corruption

Hello,

I have developed an application using the 8051 and c51, there is a external memory 93c46 which contains the control variables for the applcations, these variables are read at the start of the application and are used further in the application.

The values read from the memory are stored in the global variables and are used in the different routiens for the control purpose

These variable get corrupted in the middle of the application causing unpridictable results.

How can i say these variable get Corrupted?

There is a ruotien to update these variables. The value of variables are displayed on screen and can be changed, after all the values are scaned and the values are stored back in the memory and application runs with the updated variables.

so if a variable gets corupted it is visible in the routien which updates these variables

More over if we switch off the application after seeing the corrupted variables in the the updation routien, before saving the corrupted variables, then after switching on the variables are read from the external memory perfectely well and can be seen quite well in the updation routien

I am using AT89c51 micro

which means the global variables get corrupted, which gets displayed in the updation rouotien

Any help will be highly appericiated

Thanks in advance
Kapil

Parents
  • Prime suspect for data corruption in 'C' is pointers.

    In Keil C51, you also need to check that you don't have OVERLAY problems - particularly if you're using function pointers.

    In embedded systems, interrupts could cause problems.

    Maybe you have a hardware fault.

    Can you reproduce this on the Simulator?

Reply
  • Prime suspect for data corruption in 'C' is pointers.

    In Keil C51, you also need to check that you don't have OVERLAY problems - particularly if you're using function pointers.

    In embedded systems, interrupts could cause problems.

    Maybe you have a hardware fault.

    Can you reproduce this on the Simulator?

Children
  • Thanks For quick reply Andrew,

    Well i am not using any function pointers and i dont see any hardware faults as the application runs fine for some time and this thing start happning after some time.

    I was not able to reproduce this problem on simulator, i can try again but any specific thing in mind to check with.

    Is it possible to have a breakpoint or check when a particular variable is accesed or changed?

    I am using interrupts (Timer interrupt every 10 mS) but the issue like saving important variables on stack(Acc e.t.c) and other issues are taken care of by C51. IS it not like that? i assumed it to be like that.
    may be i am wrong

    Thanks and Regards
    Kapil

  • i dont see any hardware faults as the application runs fine for some time and this thing start happning after some time.

    You're misleading yourself there, I think. Things that work fine for quite some time, then suddenly become unstable, is exactly the kind of behaviour that is a lot more easily caused by flaky hardware than by software.

    Is it possible to have a breakpoint or check when a particular variable is accesed or changed?
    Yes. See "Debug->Breakpoints", then notice the 'read' and 'write' checkboxes towards the lower right of the dialog box. Doing this with the in-system debugger (ISD51) is likely to completely throw off your timing though, so better restrict this to the simulator.

  • i dont see any hardware faults as the application runs fine for some time and this thing start happning after some time.
    Not a guarantee of no "hardware faults", but very likely a confluence problem.

    I have seen such things happen only when an interrupt happened while 7 lines of code in main were executed and other such cases.

    Check your stack!!!

    Erik

  • I have seen such things happen only when an interrupt happened while 7 lines of code in main were executed and other such cases.

    Erik could very well be right about your problem here. He might be suggesting that you have a "race condition." In general, it is dangerous to use a variable in both main code and an interrupt, unless all the actions on it can be "atomic" (completed in one assembly instruction that is not interruptible).

    For instance, imagine you had the following:

    unsigned int baduse;
    
    void sometimerint(void) interrupt X {
      baduse = baduse + someoffset;
    }
    
    void main(void) {
      while(1) {
        delay(sometime);
        printf("%i",baduse);
        baduse++;
      }
    }
    

    Here, a variable is being used in main, but being modified in an interrupt. Imagine that the value baduse contains 0x00FF and the system is just about to fetch it and print it out. It might fetch half the value (the LSB) and then be interrupted. The interrupt would increment the variable and return. Then the main code would fetch the OTHER half and the variable would be 0x00FF larger than it should. To make matters worse, unless the variable is declared as volatile, the next line (baduse++) might very well use the incorrect value for the operation and permanently munge the data as opposed to just displaying a "glitch" in the value.

    I don't know if that was clear enough. Race conditions are a difficult thing to explain. When this problem occurrs for you, is it just some values that are corrupted, or all of them? Do they seem to happen one at a time? If so, race conditions might be something to look for.

  • The variable which gets corrupted are not at all used in the interrupt(timer interrupt)service routien

    Which 7 lines of code while being executed can cause this problem? and WHY? is this a compiler bug or what?

    About stack overflow i dont know? i will check. the major problem on my end is that i dont have an emulator and i havent seen this problem on the simulator. i am trying to see it

    I see it only when the application runs

  • The variable which gets corrupted are not at all used in the interrupt(timer interrupt)service routien
    That is totally irrelevant

    Which 7 lines of code while being executed can cause this problem? and WHY? is this a compiler bug or what?
    7 lines in a program I fixed and NO it is not a compiler bug, it was missing stack control.

    About stack overflow i dont know? i will check. the major problem on my end is that i dont have an emulator and i havent seen this problem on the simulator. i am trying to see it
    set a breakpoint in the simulator at the deepest subroutine level you have. check SP. then set the bit that activates your heaviest interrupt and let it enter, then check sp.
    I think this might work as a check using the ineffective method of simulating.

    Erik

  • Jay when i see this problem it happens to the first 2 varibles i mean if we have 10 variables of type unsigned int (starting address of first variable is 0x28 in ram and all athe variables are placed one after other)then first 2 gets corrupted everytime

  • I have just checked the stack values when the programe runs but the stack is placed at 0x58 and maximum it goes up to 0x62

    but the varibles which gets corrupted are placed at 0x2B to 0x2E

  • Can you post the smallest complete compilable program that shows the problem. Please cut and paste this from your editor to ensure that the code you post is exactly the same as the code you are using.

  • This is interrupt file

    /* ADC.C */
    #include <reg51.h>

    #define HIGH 1
    #define LOW 0

    #define ON 1
    #define OFF 0

    extern unsigned char Nibble[5];
    extern unsigned char nibble_reference;


    sbit Mode_sw = 0xB7;
    sbit Down_sw = 0xB7;
    sbit Up_sw = 0xB6;
    sbit STOP_sw = 0xB6;
    sbit D5 = 0x94;
    sfr In_Data = 0x90;

    extern unsigned int COUNTER;
    unsigned char Temp_Counter=0;
    unsigned char Temp_Counter1=0;

    extern bit STOP_SW_bit ;
    extern bit Screen_Flag ;

    void Enable_Interrupts(){

    // Enable the Timer/Counter 0 Interrupt No 1
    TR0 = 0;
    TMOD &= ~0x0F; /* clear timer 0 mode bits */
    TMOD |= 0x01; /* put timer 0 into 16-bit no prescale */
    TL0 = 00;
    TH0 = 200;
    PT0 = 0; /* set low priority for timer 0 */
    ET0 = 1; /* enable timer 0 interrupt */
    TR0 = 1; /* start timer 0 */

    // Enable the Timer/Counter 1 Interrupt No 4

    // Enable the External 0 Interrupt No 0

    // Enable the External 1 Interrupt No 2
    EX1 = 1;
    // Enable the SCI Interrupt No 5

    // Enable Global
    EA = 1;
    }


    External_1() interrupt 2 using 3
    {
    if(D5)
    nibble_reference = 0; // this is the starting, MSB is sent after this

    Nibble[nibble_reference] = In_Data;
    Nibble[nibble_reference] &= 0x0F;
    ++nibble_reference;

    }


    Timer0 () interrupt 1 using 2
    {
    TL0 = 55;
    TH0 = 248;
    Temp_Counter++;

    if(Temp_Counter >= 100){
    Temp_Counter =0;
    Temp_Counter1++;
    COUNTER++; }


    }

  • variable used first 2 gets corrupted


    volatile unsigned int STAGE_1_CNT = 10;
    volatile unsigned int STAGE_2_CNT = 10;
    volatile unsigned int STAGE_30_CNT_L = 10;
    volatile unsigned int STAGE_30_CNT_H = 10;
    volatile unsigned int STAGE_31_CNT_L = 10;
    volatile unsigned int STAGE_31_CNT_H = 10;
    volatile unsigned int STAGE_32_CNT_L = 10;
    volatile unsigned int STAGE_32_CNT_H = 10;
    volatile unsigned int STAGE_33_CNT_L = 10;
    volatile unsigned int STAGE_33_CNT_H = 10;
    volatile unsigned int STAGE_4_CNT = 10;
    volatile unsigned int STAGE_5_CNT = 10;
    volatile unsigned int COUNTER = 0;
    volatile unsigned int Cycle_Count = 0;
    volatile unsigned int OP3_MF = 1;
    volatile unsigned char OP3_MF_CNT = 0;
    volatile unsigned int Bottel_Counter= 0;
    volatile unsigned int Set_Temp1 = 30;


    void main(void){
    CS=0;SK=0;DI=1;DO=1;

    En_Write_93cxx(); // Enable the Memory
    Read_Variables(); // Read the Process v

    CS=0;SK=0;DI=0;DO=0;
    LED_1 = OUTPUT_LOW;
    LED_2 = OUTPUT_LOW;
    LED_3 = OUTPUT_LOW;
    LED_4 = OUTPUT_LOW;
    Initialize_LCD();
    Clear_LCD();
    Enable_Interrupts();
    Welcomw_Note();

    Delay_S();
    Delay_S();

    COUNTER = 0;
    // Display_Cycle_Count(Cycle_Count);


    while(1){
    if(START_sw == LOW)
    {LED_1 = OUTPUT_LOW;
    LED_2 = OUTPUT_LOW;
    LED_3 = OUTPUT_LOW;
    LED_4 = OUTPUT_LOW;

    while(START_sw == LOW) Delay_MS(100);

    STAGE_1_Flag = HIGH;
    OP3_MF_CNT = 0;
    COUNTER = 0;}

    Stage_1();

    if(Mode_sw == LOW)Switch_Control();
    if(Temp_Counter1 == 25)Get_Temperature();
    if(Temp_Counter1 == 50){Temp_Counter1 = 0;}
    }

    void Get_Temperature(){

    unsigned char nib0,nib1,nib2,nib3,nib4;
    unsigned int temp;

    temp = Bottel_Counter;
    nib0 = temp%10;temp = temp/10;
    nib1 = temp%10;temp = temp/10;
    nib2 = temp%10;temp = temp/10;
    nib3 = temp%10;temp = temp/10;
    // nib4 = temp%10;
    Clear_LCD();
    Display_String_LCD1(String_16,11);
    Write_LCD(' ');
    Write_LCD(nib3 + 0x30);
    Write_LCD(nib2 + 0x30);
    Write_LCD(nib1 + 0x30);
    Write_LCD(nib0 + 0x30);
    Next_Line_LCD();
    Display_String_LCD1(String_18,10);

    Present_Value = 0;
    Present_Value += Nibble[4];
    Present_Value += 10 * Nibble[3];
    Present_Value += 100 * Nibble[2];
    Present_Value += 1000 * Nibble[1];
    Present_Value += 10000 * Nibble[0];
    Present_Value = Present_Value/200;

    temp = Present_Value;
    nib0 = temp%10;temp = temp/10;
    nib1 = temp%10;temp = temp/10;
    nib2 = temp%10;temp = temp/10;
    // nib3 = temp%10;temp = temp/10;
    // nib4 = temp%10;

    Write_LCD(' ');
    // Write_LCD(nib4 + 0x30);
    // Write_LCD(nib3 + 0x30);
    Write_LCD(nib2 + 0x30);
    Write_LCD(nib1 + 0x30);
    Write_LCD(nib0 + 0x30);
    Write_LCD(' ');
    Write_LCD(' ');
    }


    void Stage_1(){

    if(STAGE_1_Flag == HIGH){
    LED_1 = OUTPUT_HIGH;
    if(COUNTER >= STAGE_1_CNT)
    {STAGE_2_Flag = HIGH;
    STAGE_1_Flag = LOW;
    COUNTER = 0;}}


    if(STAGE_2_Flag == HIGH){
    LED_2 = OUTPUT_HIGH;
    if(COUNTER >= STAGE_2_CNT)
    {STAGE_30_Flag_H = HIGH;
    STAGE_2_Flag = LOW;
    COUNTER = 0;}}





    if(STAGE_30_Flag_H == HIGH){
    LED_3 = OUTPUT_HIGH;
    if(COUNTER >= STAGE_30_CNT_H)
    {STAGE_30_Flag_H = LOW;
    STAGE_30_Flag_L = HIGH;
    COUNTER = 0;}}
    if(STAGE_30_Flag_L == HIGH){
    LED_3 = OUTPUT_LOW;
    if(COUNTER >= STAGE_30_CNT_H)
    {STAGE_30_Flag_L = LOW;
    STAGE_31_Flag_H = HIGH;
    COUNTER = 0;}}


    if(STAGE_31_Flag_H == HIGH){
    LED_3 = OUTPUT_HIGH;
    if(COUNTER >= STAGE_31_CNT_H)
    {STAGE_31_Flag_H = LOW;
    STAGE_31_Flag_L = HIGH;
    COUNTER = 0;}}
    if(STAGE_31_Flag_L == HIGH){
    LED_3 = OUTPUT_LOW;
    if(COUNTER >= STAGE_31_CNT_H)
    {STAGE_31_Flag_L = LOW;
    STAGE_32_Flag_H = HIGH;
    COUNTER = 0;}}

    if(STAGE_32_Flag_H == HIGH){
    LED_3 = OUTPUT_HIGH;
    if(COUNTER >= STAGE_32_CNT_H)
    {STAGE_32_Flag_H = LOW;
    STAGE_32_Flag_L = HIGH;
    COUNTER = 0;}}
    if(STAGE_32_Flag_L == HIGH){
    LED_3 = OUTPUT_LOW;
    if(COUNTER >= STAGE_32_CNT_H)
    {STAGE_32_Flag_L = LOW;
    STAGE_33_Flag_H = HIGH;
    COUNTER = 0;}}

    if(STAGE_33_Flag_H == HIGH){
    LED_3 = OUTPUT_HIGH;
    if(COUNTER >= STAGE_33_CNT_H)
    {STAGE_33_Flag_H = LOW;
    STAGE_33_Flag_L = HIGH;
    COUNTER = 0;}}
    if(STAGE_33_Flag_L == HIGH){
    LED_3 = OUTPUT_LOW;
    if(COUNTER >= STAGE_33_CNT_H)
    {STAGE_33_Flag_L = LOW;
    OP3_MF_CNT++;
    if(OP3_MF == OP3_MF_CNT){STAGE_4_Flag = HIGH;OP3_MF_CNT =0;}
    else{STAGE_30_Flag_H = HIGH;}
    COUNTER = 0;}}




    if(STAGE_4_Flag == HIGH){
    LED_2 = OUTPUT_LOW;
    if(COUNTER >= STAGE_4_CNT)
    {STAGE_4_Flag = LOW;
    STAGE_5_Flag = HIGH;
    Bottel_Counter = Read_93cxx_16bit(28);
    Bottel_Counter = Bottel_Counter + OP3_MF;
    Write_93cxx_16bit(28,Bottel_Counter);
    COUNTER = 0;}}



    if(STAGE_5_Flag == HIGH){
    LED_4 = OUTPUT_HIGH;
    if(COUNTER >= STAGE_5_CNT)
    {STAGE_5_Flag = LOW;
    STAGE_6_Flag = HIGH;
    COUNTER = 0;}}



    if(STAGE_6_Flag == HIGH){
    LED_4 = OUTPUT_LOW;
    LED_1 = OUTPUT_LOW;
    STAGE_6_Flag = LOW;
    Cycle_Count = Read_93cxx_16bit(30);
    Cycle_Count++;
    Write_93cxx_16bit(30,Cycle_Count);
    Get_Temperature();
    // Display_Cycle_Count(Cycle_Count);
    }
    }

  • kapil,

    Please repost those message with formatting intact. Put a tag

     BEFORE copying in your source, and then put 
    after it. Thanks. It's almost completely unreadable as it is.

  • I think something got lost, so here we go
    where you in the below see [ use <
    where you in the below see ] use >
    kapil,

    Please repost those message with formatting intact. Put a tag [pre]
    BEFORE copying in your source, and then put [/pre] after it. Thanks. It's almost completely unreadable as it is.

  • Hehehe... That's what I get for not hitting preview first.

  • When you make a post, immediately above the 'Message:' box where you type are some 'Notes' which explain how to post code.

    A link is also given for "Tips for Posting Messages" which gives further details & examples.
    The link is: http://www.keil.com/forum/tips.asp