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

Uncalled segment due to external variable?

I know you have many discussions about warning L16 but I couldn't find one that would match with my problem below.

I got a warning L16: uncalled segment - SEGMENT: ?PR?API_module2?MODULE2 which my app had nothing to do with. See code below:

in test.c:  ---> app code built with lib1.lib
main {
 api_module1();
}

in module1.c: ----> part of lib1.lib
volatile char var1
api_module1( void ) {
   var1 = ...
}

in module2.c: ----> part of lib1.lib
extern volatile char var1
api_module2 ( void ) {
 if (var1 == ...)
}

I suspect the reason I got this warning was because of the global variable var1 (can't find any other link between these two modules except for this global variable).

Question:
If this variable is actually causing this problem, how do I get rid of it as it is increasing my app's code size unnecessary (by also include module2).
If this variable could not possible be causing this warning, where else should I look?

Also, in module2.c I have another API which does NOT use this var1 global variable but I also got the same warning. Any idea?

  • "I got a warning L16: uncalled segment - SEGMENT: ?PR?API_module2?MODULE2 which my app had nothing to do with."

    What do you mean by that?

    If your application has nothing to do with it, why is it in your Project?

    If it's in your project but never used, then you will obviously get an "uncalled segment" warning - because it is not called!

  • Sorry for being unclear. What I meant is my app linked to a library called lib1.lib. Lib1.lib was built with two .c files called module1.c and module2.c. My app only used the function defined in module1.c and nothing in module2.c. There is one variable I found that is used between these two c files. The warnings were for the functions defined in module2.c which my app does not call.

    I can't simply get rid of this variable because my other apps used module1 and module2 extensively.

  • in module1.c: ----> part of lib1.lib
    volatile char var1
    api_module1( void ) {
       var1 = ...
    }
    
    in module2.c: ----> part of lib1.lib
    extern volatile char var1
    api_module2 ( void ) {
     if (var1 == ...)
    }
    

    Are you 100% sure it's this way round, i.e. the 'extern' declaration of var1 is in module2.c, and not in module1.c? I ask because if it were the other way round, you should get exactly the behaviour you observe.

    Either way, the solution is quite simple: you're violating the basic design principles for libraries to be used by a traditional C linker: every non-splittable group of objects gets its own source file. Where object means either variable or function. I.e.: move the definition of var1 to a separate file, and put an extern declaration of it into a header file which you #include from both your existing source files.

  • It was the way I described originally. Nevertheless, I appreciate your advice about moving the global variable to a common file. I fixed it and still got this unwanted warning so it must be something else. I have to continue searching for the culprit.

    Thank you very much for your help!

  • Have you looked in the map file to see what modules are included from the library (and why)?

    Jon

  • I created a simple project and linked it and I do not get the same problem you do.

    Here is the linker MAP file.

    BL51 BANKED LINKER/LOCATER V5.03
    
    
    BL51 BANKED LINKER/LOCATER V5.03, INVOKED BY:
    C:\KEIL\C51\BIN\BL51.EXE main.obj, .\libprj.LIB TO codeprj RAMSIZE (256)
    
    
    MEMORY MODEL: SMALL
    
    
    INPUT MODULES INCLUDED:
      main.obj (MAIN)
      .\libprj.LIB (FUNC1)
      C:\KEIL\C51\LIB\C51S.LIB (?C_STARTUP)
    
    
    LINK MAP OF MODULE:  codeprj (MAIN)
    
    
                TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
                -----------------------------------------------------
    
                * * * * * * *   D A T A   M E M O R Y   * * * * * * *
                REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
                DATA    0008H     0001H     UNIT         ?DT?FUNC1
                IDATA   0009H     0001H     UNIT         ?STACK
    
                * * * * * * *   C O D E   M E M O R Y   * * * * * * *
                CODE    0000H     0003H     ABSOLUTE
                CODE    0003H     000CH     UNIT         ?C_C51STARTUP
                CODE    000FH     0005H     UNIT         ?PR?MAIN?MAIN
                CODE    0014H     0004H     UNIT         ?PR?FUNC1?FUNC1
    
    
    
    OVERLAY MAP OF MODULE:   codeprj (MAIN)
    
    
    SEGMENT
      +--> CALLED SEGMENT
    ---------------------
    ?C_C51STARTUP
      +--> ?PR?MAIN?MAIN
    
    ?PR?MAIN?MAIN
      +--> ?PR?FUNC1?FUNC1
    
    
    
    SYMBOL TABLE OF MODULE:  codeprj (MAIN)
    
      VALUE           TYPE          NAME
      ----------------------------------
    
      -------         MODULE        MAIN
      C:0000H         SYMBOL        _ICE_DUMMY_
      C:000FH         PUBLIC        main
      -------         PROC          MAIN
      C:000FH         LINE#         3
      C:000FH         LINE#         4
      C:000FH         LINE#         5
      C:0012H         LINE#         7
      -------         ENDPROC       MAIN
      -------         ENDMOD        MAIN
    
      -------         MODULE        FUNC1
      C:0000H         SYMBOL        _ICE_DUMMY_
      D:0008H         PUBLIC        libvar
      C:0014H         PUBLIC        func1
      -------         PROC          FUNC1
      C:0014H         LINE#         3
      C:0014H         LINE#         4
      C:0014H         LINE#         5
      C:0017H         LINE#         6
      -------         ENDPROC       FUNC1
      -------         ENDMOD        FUNC1
    
    Program Size: data=10.0 xdata=0 code=24
    LINK/LOCATE RUN COMPLETE.  0 WARNING(S),  0 ERROR(S)
    

    Jon

  • Hi Jon,
    Thanks for the responses.
    Yes, the app's map file showed the functions in module2. The 'Why' is what I'm looking for.

  • You may want to start by looking in the call tree in the MAP file:

    OVERLAY MAP OF MODULE:   codeprj (MAIN)
    
    SEGMENT
      +--> CALLED SEGMENT
    ---------------------
    ?C_C51STARTUP
      +--> ?PR?MAIN?MAIN
    
    ?PR?MAIN?MAIN
      +--> ?PR?FUNC1?FUNC1
    

    This shows that the ?PR?MAIN?MAIN segment references (calls) the ?PR?FUNC1?FUNC1 segment.

    Maybe you should look in the MAP file for references to ?PR?*?FUNC2 or to variables defined in FUNC2.

    Jon

  • Hello Jon,
    I rebuilt with 'Cross Reference' option and the map file is much more clear to read. As you pointed it out, I found the culprit. I found the ?PR?MODULE2 under a ?CO? of another/init module name, which is used by the app. It looks like I have a lot of cleaning up work to do but at least I know where to look now.

    THank you so much for your help.

  • Just out of curiosity: In uVision2, when bringing up 'options for library lib1.lib', the menu will show a list of 'Select module to always include' module (all .c files) available to the application from this lib1.lib. I'm wondering if there is such option to select 'Always exclude' module.