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

Automatic RESET during operation

i am facing a wierd problem.. My MCU P89V51RD2BN resets during Execution...
i am a college student and a beginner Here so i dont know the Advanced Programming methods
i would also inform that..

i have a recursive function , a warning is issued by the compiler for the same. but....

earlier this was not a problem but since i have modified some of the Sub-Routines for 16Bit Data this Problem has come up, i need those functions to be 16 bit because of the limitation of the ALU i was earlier using 8bit and leaving most of the Task to Assumption which i cannot do so now..

i would also state that the Problem occurs in a fumction at a point when i call 2 functions in the same code, these themselves call around 5 sub-routines each but that wasnt a problem earlier (before i used the 16bit return type sub-routines).

now i found something in the manual stating reentrant Functions, but i really dont know how to use it

i used it like this

void Home_Screen_Instance() reentrant
{ ------------
} Do i need to use the keyword "reentrant" in the Function Decleration too?
but that didnt help either
but the compilers shows an error Home_Screen_Instance : redefinition.
Target Not Created

this was the first of a kind problem that i encountered, my MCU is resetting itself for sure(i checked that with a dummy subroutine of blinking LED) and it is not because of the watchdog timer, i am sure about that too..

so whats the Problem here?

is the Stack overflowing???
or there is any other reason behind this?
should i revert back to the 8bit versions of my subroutine (without any other choice)?
is it because of the recursive nature of the function H0me_screen_instance?

Related Data:

The Program is Display intensive, i mean there are a lot of Strings to be displayed and they are stored beforehand in XDATA,
message shown during sucessfull compilation, (still resets)
Program Size: data 9.4 xdata 252 code 9514
creating hex-----blah blah blah----
0 Error(s) 65 Warning(s)

Parents
  • thanks neil!!
    i was ignoring the uncalled segments as the warning states that it was "ignored for overlay Process"

    and another thing, my recursive function has no local DATA, it just Prints Text on an LCD, and calls another sub-routine depending upon the input from a keypad,

    again its a student Project and i am completely new to embedded C Programming.

Reply
  • thanks neil!!
    i was ignoring the uncalled segments as the warning states that it was "ignored for overlay Process"

    and another thing, my recursive function has no local DATA, it just Prints Text on an LCD, and calls another sub-routine depending upon the input from a keypad,

    again its a student Project and i am completely new to embedded C Programming.

Children
  • "my recursive function has no local DATA, it just Prints Text on an LCD, and calls another sub-routine depending upon the input from a keypad,"

    I'm not sure we are using the same definition of "recursive function".

    A recursive function is a function that calls itself, or calls other functions in a call chain where one of the directly or indirectly called functions will call the original function again.

    So recursion means that the call chain forms a loop.
    With a non-recursive design, you can still call several levels deep, but the call sequences just forms trees.

    The compiler/linker explicitly analyses the call sequences by the code, to figure out the branches of the call tree - functions that are never part of same path from root (main) to leaf of the call tree can use the same memory locations for storing local data or parameters. So the variables/parameters gets overlayed in global data space because the 8051 don't have a real stack powerful enough.

    With more general processor architectures, the compiler don't need to perform this optimization. It's enough to just push parameters and local (auto) variables on the stack, and pop when the function returns.

  • we are using the same definition of recursive function

    i have got a "chain" in which one function calls another and so on till one another function in the chain calls the initial function... so let me put the code here

    home_Screen()
    { ---------
    Lock_Screen();
    -------
    --------
    }

    Lock Screen() //Checks the Password
    { if(yes)
    Main_Menu();
    else return;
    }

    main_menu()
    { ---------
    ---------
    switch()
    { ----
    ---
    - -
    - --
    case 4:Home_Screen(); //when user presses the "Home" Button

    // Here is the recursion. this is just one of the recursion,s there are other functions too
    } }

    i am working on getting this code into a non-recursive format...
    and once more
    im just a beginner in embedded C, i am not as learned as you guys !!

  • Your issue is that you mix the code for displaying a menu with the code that processes it.

    So you handle one menu, then jump to screen-lock then have the screen-lock once more call the function to handle the same menu, after unlock. That is wrong.

    With the draw function separated, you don't need a recursive call to redraw the main menu after unlock.

    current_display = x;
    wanted_display = y;
    locked = false;
    pwd_input_state = 0;
    
    void handle_display() {
        if (idle_time > AUTO_LOCK) {
            locked = true;
            pwd_input_state = 0;
        }
        if (locked) wanted_display = DISP_LOCKED;
        if (current_display != wanted_display) {
            switch (wanted_display) {
                ...
                case DISP_LOCKED:
                    saved_display = current_display;
                    draw_screen_lock();
                    break;
                case DISP_MAIN:
                    draw_screen_main();
                    break;
                case DISP_SUBMENU_1:
                     draw_submenu_1();
                     break;
                default:
                    ; // should not happen - do some repair
            }
            current_display = wanted_display;
        }
        input = check_input();
        if (input) {
            clear_idle_time();
            switch (current_display) {
                ...
                case DISP_LOCKED:
                    if (is_unlock(input)) {
                        wanted_display = saved_display;
                    }
                    break;
                case DISP_MAIN:
                    switch (input) {
                        case BUTTON_1: do_main_1(); break;
                        case BUTTON_2: do_main_2(); break;
                        ...
                     }
                     break;
                 case DISP_SUBMENU_1:
                     switch (input) {
                         ...
                     }
                     break;
                 default:
                     ; // should not happen - do some repair
            }
        }
    }
    
    void main() {
        for (;;) {
            ...
            handle_display();
        }
    }
    

  • So you handle one menu, then jump to screen-lock then have the screen-lock once more call the function to handle the same menu, after unlock. That is wrong.
    wrong whether embedded or not, it is just bad design

    Erik

  • "wrong whether embedded or not, it is just bad design"

    It's more interesting than that. What if the second stacked main menu also gets a timeout and locks the screen. Or the 100th nested call to the main menu? Then we have the situation:
    menu -> lock -> menu -> lock -> menu -> lock -> ....

    Any processor with a finite state storage area would run out of state space (wither a hw stack or a software-implemented stack) for such a design.

  • Any processor with a finite state storage area would run out of state space (wither a hw stack or a software-implemented stack) for such a design.
    I have actually seen that one, a frustrated used pressing the button umpteen times and SPLASH!

    Erik

  • i am completely new to embedded C Programming.

    You're still evading the real issue. You're quite clearly new not just to embedded programming, nor just to C programming, much less embedded C programming. It's becoming increasingly clear that you're completely new to programming, period.

    In other words: you're clearly in way over your head. So stop right there, take several steps back and re-think your strategy from there. Learn some fundamentals, e.g.: "What is unbounded recursion, and why should one never allow it to occur in a program?" or "What is a finite state machine?" before you come back to this project.

  • Thanks for your Advice.... I'll seriously consider implementing them...
    i know i am not good at programming... thanks for your comments, i shall now have a new approach towards programming

  • i shall now have a new approach towards programming
    the while thing: Keep It Simple, Stupid
    processing interrupts: Keep ISRs Short and Simple

    Erik

  • All Recursions Gone now !!! Thanks erik and others..
    i just couldnt come up with such a thing..

    now i have different "Draw Functions" and input Functions and they are not Recursive or forming any kind of chain...

    one question though..

    at one point i need the user to enter a number whose length (number of Digits) would be decided by me during the coding phase, i am thinking of implementing it in the form of a stack, so that i would know if he entered all the digits or not..
    am i doing it right?

    Ex:
    i need the user to enter a 4 digit number, so i am using a stack but if the user enters a three digit number, i break out of the Keypad_Input function and based on the position of the "StackTop" i find the final values.
    if user enters 999 Stack top is at 3 so the number is 9*10^2+9*10^1+9*10^0
    if user enters just 9 stack top will be at 1 so the number is 9*10^0

    void Keypad_Instance(ubit_8 Size,ubit_8 line,ubit_8 pos,bit show,ubit_8 BreakC)
    {
    ubit_8 Keypress; //Temproary variable to store the key pressed
    Stack_Initialize(); //initialize the stack, makes all character NULL
    Keypress= False;
    LCD_Cursor_XY(line,pos); //Move cursor to desired position
    
    while(!Check_Overflow(Size)) // when  Function return False i.e no Overflow
    {
    
         while (!Keypress)  //Show a Blank Character if nothing is pressed
                    {
                                    LCD_Cursor_XY(line,pos);
                                    LCD_Data(0xFF);
                                    Keypress = Keypad_Input();
                    }
    
                    if(Keypress != False)
                    {
                            if(Keypress >= '0' && Keypress <='9')//if a number is pressed
                            {
                                    Stack[Stack_Top] = Keypress;
                                    ++Stack_Top;
    
                                    if(show == 1)//when not using this function for password
                                     {
                                                    LCD_Cursor_XY(line,pos);
                                                    LCD_Data(Keypress);
                                                    pos=pos+1;
                                      }
                                     else     //when using this function for password
                                     {
                                                    LCD_Cursor_XY(line,pos);
                                                    LCD_Data(0xFF);
                                                    pos=pos+1;
                                      }
                            }
    
                    else if(Keypress == BreakC) // Character to break out the "Cancel" Button
                            {
                                       Break =1; // Notifies that user cancelled the procedure
                                       return;
                            }
    
                            else if (Keypress == 'B') //Backspace key
                            {
                               if(Stack_Top == 0) //Underflow Condition, cannot pop out more
                             {
                                    continue;
                              }
                            else
                            {
                                    LCD_Cursor_XY(line,pos); //Move Cursor From Curent Position
                                    LCD_Data('\0');
                                    pos=pos-1;
                                    LCD_Cursor_XY(line,pos);        // delete Previous Character;
                                    LCD_Data(0xFF);
                                    --Stack_Top;                    // POP Character from Stack.
                            }
                       }
    
    /*  when user enters less characters than the maximum limit 'A' is placed at stack top, this is used when calulating the final numerical value from the Character inputs obtained from the user*/
                       else if (Keypress == 'A')
                       {
                            Stack[Stack_Top] =Keypress;
                            ++Stack_Top;
                            break;
                       }
    
                       Keypress = False; // Get Keypress ready for the next character.
                       Delay200ms(); //Give a delay for the user to enter the character (Debounce)
                    }
    
            }
            --Stack_Top; //To point at the last stored position
    }
    
    

    need comment about the code... any improvements on this?

  • ubit_8 is unsigned char
    and the Stack_Initialize() function gets the stack ready for input..

    the Size of the stack is 10Bytes, and i initialize each location with a 'Null Chracter" while initializing it, i have now changed the function to initialize only desired number of characters with a "null character" before getting the input from the user.

  • You take as parameter what character that represents a break?

    But you use a global parameter for telling that your function was exited by a press of a break character.

    I would have thought that the break character was a constant.

    And that the return value from function would tell if data entered or cancel.

  • The Character 'C' on my Keypad is the Break Character
    Character 'B' Behaves as Backspace Key
    Character 'A' is used when the user is done entering the values less than the maximum limit
    ex: i have set a limit of 4 characters so maximum value is 9999 but he user wishes to enter just 99 then he presses 9->9->'A'

    a global bit variable 'Break' is used to notify that a user initiated break has occured and the system comes back to a state before the user input was requested.

  • Yes, but my question is why you used it as a configurable key - why a parameter to the function.

    When designing a user interface, it is normally very consistent which key is escape and which key is enter.

    Next thing - why a stack?

    You can just compute a numeric value as you go - only keep track of number of digits.

    if (num_digit < 4) {
        num *= 10;
        num + digit;
        num_digits++;
    }
    

    or for delete:

    if (num_digits) {
        num /= 10; // integer division strips last (least significant) digit.
        --num_digits;
    }
    

    Then return a value 0..9999 for valid input, and -1 if user cancels the input.

  • i was passing Parameters to the function because at some places
    The Space available at the LCD is limited its like XXXXXW 'X'is the available space for user input while the rest has been occupied by other text, so if the input is unbound in terms of number of digits it may overwrite, other strings on the LCD.

    Secondly, one of the parameters is "bit show" which is used to control if the characters being typed need to be visible at the LCD.

    i had doubts implementing it as a stack...but my main reason was the unknown Size(number of Characters) for the input, that's why i let it be a stack of 10 Characters, so that the same stack can be used if i made some other Sub-Routine which required Stack implementation.

    and one more question...
    i was searching for books on Programming both general Programming and Embedded Programming and of these the best i found was
    Embedded C by Micheal J Pont
    The art of Programming by Knuth

    can you suggest any other reads apart from these..
    the book by muhaamad ali mazidi is one of my textbook