program restarting itself

Discussion in 'Embedded Systems and Microcontrollers' started by Macabra, Dec 28, 2008.

  1. Macabra

    Thread Starter Active Member

    May 31, 2008
    49
    0
    Hi, I have a problem in which for some unknown reason, my program resets itself when it is running (after flashing the code into the PIC). I'm using PIC24H. The program works fine, It receives input from user and stores it into a character array. After a while, the program does not do anything with that buffer but the values which were stored in that array just dissappear. It just looks like the program restarts for some reason. I have nothing that would call the main to re-initialize the system.

    thanks
     
  2. futz

    Member

    Dec 14, 2008
    23
    0
    Yes I know it's obvious, but I'll ask anyway. Did you disable the WDT?
     
  3. mik3

    Senior Member

    Feb 4, 2008
    4,846
    63
    Also, there is a MCLR pin (pin 13). You have to pull up it to positive supply voltage via a 1K resistor otherwise the pin will float and make arbitrary decisions about its logical state (1 or 0).
     
  4. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    You may be encountering stack-pointer overflow.

    hgmjr
     
  5. futz

    Member

    Dec 14, 2008
    23
    0
    1K is pretty low. That's a very strong pullup. Will his programmer be able to overcome it? I'm only asking because I don't really know. :p

    I use a 33K, but anything between 10K and 33K is fine.
     
  6. Macabra

    Thread Starter Active Member

    May 31, 2008
    49
    0
    thanks everyone who replied to me, I really appreciate it.

    Futz, I'm turning off the WDT, the code that does this is this:

    _FWDT( FWDTEN_OFF & WINDIS_OFF & WDTPOST_PS32768 );

    I also put this through one of the functions:
    RCONbits.WDTO=0; //watchdog timer time-out flag bit
    RCONbits.SWDTEN=0; //disables WDT

    Mik3, I do have the MCLR pin pulled to 3.3V with a pull-up resistor :). Thanks for your suggestion.

    hgmjr, it's not the first time that I've heard something like this, however, I don't know how to make sure that it is that let alone how to fix that. How can I determine if it is a stack pointer overflow? Since the code goes through a while loop all the time, it makes perfect sense that it could be this.

    Thanks everyone for your ideas :)
     
  7. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    You have not mentioned whether you are using C or Assembly Language. Which one are you using?

    hgmjr
     
  8. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    The stack lives in ram along with all of the program variables.

    Two possible problems can arise with this arrangement.

    One source of a stack-pointer overflow is too many nested subroutine calls when C-language is used. Another problem is the number of program ram variables exceeds the portion of memory available and collides with the area of ram allocated to the stack. This over-writes the return from subtroutine pointers that have been stored in stack memory and the program crashes.

    In the case of Assembly language, the key is to make sure that the stack pointer is initialized with adequate stack memory capacity. Too many nested subroutine calls can also cause the stack pointer to be incremented passed the end of the stack and then the program execution flow is thrown into chaos. Eventually the program counter execution ends up pointing to the program memory location containing the jump to the start of your program.

    hgmjr
     
  9. Macabra

    Thread Starter Active Member

    May 31, 2008
    49
    0
    thanks

    I'm sorry for not mentioning this before, I am using C. I think my function is doing a whole lot of stuff and maybe i need to break it up a bit ..especially since it's got several loops. Something that you mentioned could be the source of the problem :rolleyes:

    Thanks again for your help, I'll fix these problems and post here again if I found some problem :)
     
  10. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Good Luck with your software debugging.

    I can't promise anything but if you can attach your source code file, I or one of the other more PIC knowledgeable members might be able to spot a weakness.

    hgmjr
     
  11. Macabra

    Thread Starter Active Member

    May 31, 2008
    49
    0
    ok, I'd reckon it'll be quite an eyesore, but I'll give it a kick..
    Here is a cropped out version of the Menu() which is the recursive function.

    void Menu(void)
    {
    if(cellnum[0] == NULL) //checks if character buffer is empty if it is then set flags
    {
    ...
    }
    //***********CHECKS FOR INPUTS HERE******************//

    while(PORTBbits.RB2) //If this input pin gets a high then do this
    {
    //Goes to some function here
    //turns on LEDs
    //counter here..for a loop
    if(counter == 12) //120 seconds (2 minutes) each text message sent
    {
    SMS_send('P'); //SEND P to Telit (every 2 minutes)
    counter = 0; //resets counter
    }
    if(PORTBbits.RB2 == 0) //if this pin gets a low signal
    {
    //Turns off LEDs
    SMS_send('D'); //function send to display normal status
    Menu(); //exits loop ;refresh screen to show current temperature recursive function here
    }
    y = inputx(); //HERE looks for user input from a 4x4 keypad
    if(y == 'D') //if it's a "D"
    {
    //turns off LED's and other stuff
    Menu(); //Go to Menu function to exit loop; refresh screen
    }
    }//close while(portBbits.rb2)

    if(s == 0)
    {
    while((PORTAbits.RA0) &&(y!='D')) //if smoke is detected
    {
    ...
    ... //Here it does the same thing as above, except it checks a different pin
    ...
    }//end while
    }//end if(s=0)

    if(c == 0)
    {
    while((PORTAbits.RA1)&&(y!='D')) //Here same thing..it is just checking to see if the pin is "high" and if so then it does the following
    {
    y = inputx();
    if(y == 'D') //breaks out of the while loop when someone presses D on keypad
    {
    Menu(); //goes to Menu
    }
    }//end while
    }//end if(c == 0)

    if(t == 0)
    {
    while(((_temper > max) || (_temper < min)) && (y!= 'D') && (PORTBbits.RB2 == 0)) //does the same thing ..checks for this input
    {
    ...
    ...
    ...
    if((PORTBbits.RB2)&&(p == 0)) //checks for this pin and does stuff
    {
    }
    if((PORTAbits.RA0)&&(s == 0)) //checks for this pin
    {
    }
    if((PORTAbits.RA1)&&(c == 0)) //checks for this pin
    {
    }
    }//end while
    }//end if (t = 0)

    //*********STOPS CHECKING INPUT PINS*****************//

    DELAY_US(500);
    y = inputx();

    switch(y)
    {
    case '1': phone(); //goes to this function then back to Menu ..this is where inputs are stored in cellnum[].
    break;
    case '2': temp(); //goes to this then back to Menu
    break;
    case '3': phonebook(); //goes to this then goes to Menu
    break;
    case '*': //RESET
    {
    ...
    ...
    ...
    }
    default: //if user didnt press 1,2,3, or * then it just goes to Menu
    {
    Menu(); //recursive function, return to menu and loops
    }
    }//End Case Statement
    } //END MENU FUNCTION

    ///////////////////////////////////////////////////////////////////
    int main ()
    {
    init(); // initalize register pins and the UART
    initA2D(); // initialize A2D converter
    U1STAbits.UTXBF = 1; // sets the TX ON
    i2cInit(); // sets the I2C

    Menu(); //Here goes to Menu();

    return 0;
    }//Main

    So hopefully, if it was not too much code which was unbearable to look at, the menu loops to itself because on the case statement by default if none of the required buttons are pressed the function calls itself and so the whole thing repeats itself.

    I hope that helps, I'm re-organizing it this moment. Much thanks hgmjr and everyone.
     
  12. futz

    Member

    Dec 14, 2008
    23
    0
    Here's a nice tip for you Macabra. When posting code, always use Code tags. You do this by clicking on the # icon just before pasting your code. Alternately you can type [code] before your code and [/code] after it. This holds the formatting (indentation) on your code so it's still readable after posting.

    Here's your code reformatted and posted with tags:
    Code ( (Unknown Language)):
    1. void Menu(void)
    2. {
    3.     if(cellnum[0] == NULL) //checks if character buffer is empty if it is then set flags
    4.     {
    5.         ...
    6.     }
    7.     //***********CHECKS FOR INPUTS HERE******************//
    8.  
    9.     while(PORTBbits.RB2) //If this input pin gets a high then do this
    10.     {
    11.         //Goes to some function here
    12.         //turns on LEDs
    13.         //counter here..for a loop
    14.         if(counter == 12) //120 seconds (2 minutes) each text message sent
    15.         {
    16.             SMS_send('P'); //SEND P to Telit (every 2 minutes)
    17.             counter = 0; //resets counter
    18.         }
    19.         if(PORTBbits.RB2 == 0) //if this pin gets a low signal
    20.         {
    21.             //Turns off LEDs
    22.             SMS_send('D'); //function send to display normal status
    23.             Menu(); //exits loop ;refresh screen to show current temperature recursive function here
    24.         }
    25.         y = inputx(); //HERE looks for user input from a 4x4 keypad
    26.         if(y == 'D') //if it's a "D"
    27.         {
    28.             //turns off LED's and other stuff
    29.             Menu(); //Go to Menu function to exit loop; refresh screen
    30.         }
    31.     }//close while(portBbits.rb2)
    32.  
    33.     if(s == 0)
    34.     {
    35.         while((PORTAbits.RA0) &&(y!='D')) //if smoke is detected
    36.         {
    37.             ...
    38.             ... //Here it does the same thing as above, except it checks a different pin
    39.             ...
    40.         }//end while
    41.     }//end if(s=0)
    42.  
    43.     if(c == 0)
    44.     {
    45.         while((PORTAbits.RA1)&&(y!='D')) //Here same thing..it is just checking to see if the pin is "high" and if so then it does the following
    46.         {
    47.             y = inputx();
    48.             if(y == 'D') //breaks out of the while loop when someone presses D on keypad
    49.             {
    50.                 Menu(); //goes to Menu
    51.             }
    52.         }//end while
    53.     }//end if(c == 0)
    54.  
    55.     if(t == 0)
    56.     {
    57.         while(((_temper > max) || (_temper < min)) && (y!= 'D') && (PORTBbits.RB2 == 0)) //does the same thing ..checks for this input
    58.         {
    59.             ...
    60.             ...
    61.             ...
    62.             if((PORTBbits.RB2)&&(p == 0)) //checks for this pin and does stuff
    63.             {
    64.             }
    65.             if((PORTAbits.RA0)&&(s == 0)) //checks for this pin
    66.             {
    67.             }
    68.             if((PORTAbits.RA1)&&(c == 0)) //checks for this pin
    69.             {
    70.             }
    71.         }//end while
    72.     }//end if (t = 0)
    73.  
    74.     //*********STOPS CHECKING INPUT PINS*****************//
    75.  
    76.     DELAY_US(500);
    77.     y = inputx();
    78.  
    79.     switch(y)
    80.     {
    81.         case '1': phone(); //goes to this function then back to Menu ..this is where inputs are stored in cellnum[].
    82.             break;
    83.         case '2': temp(); //goes to this then back to Menu
    84.             break;
    85.         case '3': phonebook(); //goes to this then goes to Menu
    86.             break;
    87.         case '*': //RESET
    88.         {
    89.             ...
    90.             ...
    91.             ...
    92.         }
    93.         default: //if user didnt press 1,2,3, or * then it just goes to Menu
    94.         {
    95.             Menu(); //recursive function, return to menu and loops
    96.         }
    97.     }//End Case Statement
    98. } //END MENU FUNCTION
    99.  
    100. ///////////////////////////////////////////////////////////////////
    101. int main ()
    102. {
    103.     init(); // initalize register pins and the UART
    104.     initA2D(); // initialize A2D converter
    105.     U1STAbits.UTXBF = 1; // sets the TX ON
    106.     i2cInit(); // sets the I2C
    107.  
    108.     Menu(); //Here goes to Menu();
    109.  
    110.     return 0;
    111. }//Main
    112.  
     
  13. Macabra

    Thread Starter Active Member

    May 31, 2008
    49
    0
    Thank you for the tip futz :)

    From now on, I'll make sure to do that:)
     
  14. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    The use of recursive functions is a good way to blow through the finite stack size in the microcontroller.

    hgmjr
     
Loading...