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

Why some functions got WARNING L15, while others not!

Hi,
I have several functions called in T0 isr. The outline of call tree like this:

void T0_isr() interrupt 1 {
    getkey();
}

void getkey() {
    char c;
    c = filterGetKeyCode();
}

char filterGetKeyCode() {
    char c;
    c = getKeyCode();
    return c;
}

char getKeyCode() {
    char c;
    char cd;
    // c be assigned somehow
    cd = encodeFlex(c);
    c = decode(cd);
    return c;
}

char encodeFlex(char c) {
    return encode(c);
}

char encode(char);

char decode(char);
Now linker reports (simplified):
Warning 15: multiple call to segment
segment: getKeyCode
caller1: T0_isr
caller2: c_c51stratup

Warning 15: multiple call to segment
segment: encodeFlex
caller1: T0_isr
caller2: c_c51startup

My question is: why getKeyCode and encodeFlex incur warnings, while others, like decode, passed by linker.
When I disoverlay getKeyCode, and declare encodeFlex with reentrant, the warnings all disappear. But I still worry about other functions called in isr. Is it safe now?

Thanks in advance.

d.curie

Parents
  • It's not a matter of whether the code is in the same position in the routine that you show. It's a matter of whether either of those routines is called from some other context elsewhere in the program.

    In the snippet posted, the only calling context shown is the ISR.

    T0_isr
        getkey
            filterGetKeyCode
                getKeyCode
                    decode
                    encodeFlex
                        encode
    

    As it stands, that bit of code is fine. There's only one path to call to either decode or encodeFlex.

    But if there's code somewhere else that we can't see -- descended from main(), or another ISR -- that calls encodeFlex() but not decode(), you would get exactly the warnings you reported: a "multiple call to segment" for encodeFlex(), and no warning for decode() since there wasn't a multiple call. The warning means that two independent call trees both call the same routine at some point.

    The map file shows you the call tree for the program (one level at a time, at any rate).

Reply
  • It's not a matter of whether the code is in the same position in the routine that you show. It's a matter of whether either of those routines is called from some other context elsewhere in the program.

    In the snippet posted, the only calling context shown is the ISR.

    T0_isr
        getkey
            filterGetKeyCode
                getKeyCode
                    decode
                    encodeFlex
                        encode
    

    As it stands, that bit of code is fine. There's only one path to call to either decode or encodeFlex.

    But if there's code somewhere else that we can't see -- descended from main(), or another ISR -- that calls encodeFlex() but not decode(), you would get exactly the warnings you reported: a "multiple call to segment" for encodeFlex(), and no warning for decode() since there wasn't a multiple call. The warning means that two independent call trees both call the same routine at some point.

    The map file shows you the call tree for the program (one level at a time, at any rate).

Children
  • "The map file shows you the call tree for the program (one level at a time, at any rate)."

    The uVision Code Browser shows you the full call tree.
    It can also show its converse - the Caller Tree.

    So, just take a look at the Caller Tree (or "Caller Graph") for those functions...

  • Ok, I'll check the map to make sure that the rest of my program did not call those routines mentioned above.

    d.curie

  • "Ok, I'll check the map..."

    I think you'll find the Browser easier!

  • When checking the call map, I eventually found where the multiply calls occurred. There are two callers to _getkey, a function implemented in a project-specific way to override the library function with the same name in stdio.lib. I explicitly called _getkey in T0_isr, and again I implicitly called _getkey in scrollDigit since it calls sscanf, which in turn calls getchar, which then call _getkey. All related call branches are listed as follows.

    ?PR?GETKEYCODE?KEYBOARD_P
      +--> ?PR?_DECODE38?FUNC
      +--> ?PR?_ENCODE83FLEX?FUNC
    
    ?PR?_ENCODE83FLEX?FUNC
      +--> ?PR?_ENCODE83?FUNC
    
    ?PR?FILTERKEYCODE?KEYBOARD_P
      +--> ?PR?GETKEYCODE?KEYBOARD_P
    
    ?PR?_GETKEY?KEYBOARD_P
      +--> ?PR?FILTERKEYCODE?KEYBOARD_P
      +--> ?PR?_TOASCII?KEYBOARD_P
      +--> ?PR?_LOADKEYQUEUE?KEYBOARD_P
    
    ?PR?T0_ISR?T0_ISR
      +--> ?PR?_GETKEY?KEYBOARD_P
    
    ?PR?_SCROLLDIGIT?GUI
      +--> ?CO?GUI
      +--> ?PR?PRINTF?PRINTF
      +--> ?PR?SCANF?SCANF
      +--> ?PR?_TEXTOUT?GUI
    
    ?PR?SCANF?SCANF
      +--> ?PR?GETCHAR?UNGETCHAR
      +--> ?PR?_ISSPACE?ISSPACE
      +--> ?PR?GETCHAR?GETCHAR
      +--> ?PR??C?ATOF??C?ATOF
    
    ?PR?GETCHAR?GETCHAR
      +--> ?PR?_GETKEY?KEYBOARD_P
      +--> ?PR?PUTCHAR?PUTCHAR
    
    But my original question is still there! Why encode83flex get warning, whereas decode38 not?
    And a new question arises: I invoke sscanf in scrollDigit, but the call map above shows scanf is called instead! In my opinion, sscanf should not call getchar (in turn _getkey) even though scanf does.