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

BL51: '*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL'

I am designing an application to run on the Si Labs
C8051F046 MCU with uVision 3. Yesterday I created a new
project, but forgot to include one of the source modules.
This produced a line during the link in the Output Window:

  *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL

I missed it, as this program generates many similar warnings:
  *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS

(in that tiny, little output window) which I must ignore.
Because L1 is only a warning; BL51 completed the build and
gave me a load module, which I attempted to debug. (It came
fairly close to working). I wasted an hour tracking the
cause back to this source.

I can't think of any scenario where I would want the build
to continue with missing source modules, yet I can find no
tool that would allow me to make L1 an error instead of a
warning. As best I can tell, this topic has never appeared
in the knowledge base or on this forum.

Does anybody have a differing opinion? A workaround?

Advance thanks for any insight.
============================================================
Gary Lynch            |     To send mail, change no$pam in
lynchg@no$pam.com     |     my domain name to stacoenergy

Parents
  • On 5/10/06 8:24:01; erik malund wrote:
    >
    > Many decide to ignore warnings, that may be OK during
    > development, but there is a difference between "ignore" and
    > "not read"
    >
    > I may ignore warnings during development, but I ALWAYS read
    > them
    >
    Ok, so oversimplified my process. I read ALL the warnings
    the first time I link a new module and take action as
    indicated. But some of them are not eliminatable.

    Thereafter I only read the body of the warnings if the
    NUMBER of warnings changes from the prior build. In the
    case cited, I went too fast and confused "UNRESOLVED" with
    "UNCALLED".

    Then at 5/10/06 8:23:07; A.W. Neil wrote:
    >
    > How about If you were doing some sort of "incremental
    > build", or you were building a Library that required some
    > call-backs to be provided by the user?
    >
    Ok, I'll grant you that scenario. It's just that I've never
    used it.

    >
    > Anyhow, if the functions in those modules are never called,
    > and the data is never accessed, what difference does it
    > make!
    >
    <snip>
    >
    > As soon as you actually try to reference one of the
    > undefined symbols, that most certainly will give you an
    > error.
    >
    Well, you want the dirty details, here they are. The source
    containing the main() function looks like (names have been
    changed to protect the guilty):

    while(1) {
      for(j=0; j<6; j++) {   | ?C0001: CLR     A        ;  1
                             |         MOV     j,A      ;  2
                             |         MOV     j+01H,A  ;  3
                             | ?C0003: CLR     C        ;  4
                             |         MOV     A,j+01H  ;  5
                             |         SUBB    A,#06H   ;  6
                             |         MOV     A,j      ;  7
                             |         SUBB    A,#00H   ;  8
                             |         JNC     ?C0001   ;  9
        doFoo(2, j);         |         MOV     R5,j+01H ; 10
                             |         MOV     R7,#02H  ; 11
                             |         LCALL   _doFoo   ; 12
        wait(4473);          |         MOV     R7,#079H ; 13
                             |         MOV     R6,#011H ; 14
                             |         LCALL   _wait    ; 15
      }                      |         INC     j+01H    ; 16
                             |         MOV     A,j+01H  ; 17
                             |         JNZ     ?C0007   ; 18
                             |         INC     j        ; 19
                             | ?C0007: SJMP    ?C0003   ; 20
                             |         RET              ; 21
    } /* END while(1) */     |                          ; 22
    

    I tacked the assembly produced by C51 onto the right side
    for reasons that will become apparent later. I also added
    line numbers to facilitate discussion. Variable j is an
    unsigned int.

    The module I forgot to add holds function wait() (which is a
    thumb-twiddling loop whose execution time I can control with
    the argument shown). The object module produced by the
    compiler sets wait()'s address to dummy value c:0x0000
    (a.k.a. your friendly neighborhood power-up vector).

    The linker issues its warning:

    *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
        SYMBOL:  _WAIT
        MODULE:  TestFoo.obj (TESTFOO)
        ADDRESS: 01BEH
    

    and the execution module gets built, assuming wait() is
    still at 0000.

    As compiled, the "j=0" part of the for-loop consists of the 3
    instructions beginning at line 1; the "j<6" code is in
    lines 4-9, while the "j++" term resides in lines 16-19.

    This baby executes exactly as I intended until we get to the
    call to wait(). At this point, it performs the moral
    equivalent of a power-on reset, putting control back at the
    top of the loop with j=0. Thus my program executes the
    infinite loop I had wanted, but j never deviates from 0.

    This is the scenario that prompted this post.
    ============================================================
    Gary Lynch            |     To send mail, change no$pam in
    lynchg@no$pam.com     |     my domain name to stacoenergy

Reply
  • On 5/10/06 8:24:01; erik malund wrote:
    >
    > Many decide to ignore warnings, that may be OK during
    > development, but there is a difference between "ignore" and
    > "not read"
    >
    > I may ignore warnings during development, but I ALWAYS read
    > them
    >
    Ok, so oversimplified my process. I read ALL the warnings
    the first time I link a new module and take action as
    indicated. But some of them are not eliminatable.

    Thereafter I only read the body of the warnings if the
    NUMBER of warnings changes from the prior build. In the
    case cited, I went too fast and confused "UNRESOLVED" with
    "UNCALLED".

    Then at 5/10/06 8:23:07; A.W. Neil wrote:
    >
    > How about If you were doing some sort of "incremental
    > build", or you were building a Library that required some
    > call-backs to be provided by the user?
    >
    Ok, I'll grant you that scenario. It's just that I've never
    used it.

    >
    > Anyhow, if the functions in those modules are never called,
    > and the data is never accessed, what difference does it
    > make!
    >
    <snip>
    >
    > As soon as you actually try to reference one of the
    > undefined symbols, that most certainly will give you an
    > error.
    >
    Well, you want the dirty details, here they are. The source
    containing the main() function looks like (names have been
    changed to protect the guilty):

    while(1) {
      for(j=0; j<6; j++) {   | ?C0001: CLR     A        ;  1
                             |         MOV     j,A      ;  2
                             |         MOV     j+01H,A  ;  3
                             | ?C0003: CLR     C        ;  4
                             |         MOV     A,j+01H  ;  5
                             |         SUBB    A,#06H   ;  6
                             |         MOV     A,j      ;  7
                             |         SUBB    A,#00H   ;  8
                             |         JNC     ?C0001   ;  9
        doFoo(2, j);         |         MOV     R5,j+01H ; 10
                             |         MOV     R7,#02H  ; 11
                             |         LCALL   _doFoo   ; 12
        wait(4473);          |         MOV     R7,#079H ; 13
                             |         MOV     R6,#011H ; 14
                             |         LCALL   _wait    ; 15
      }                      |         INC     j+01H    ; 16
                             |         MOV     A,j+01H  ; 17
                             |         JNZ     ?C0007   ; 18
                             |         INC     j        ; 19
                             | ?C0007: SJMP    ?C0003   ; 20
                             |         RET              ; 21
    } /* END while(1) */     |                          ; 22
    

    I tacked the assembly produced by C51 onto the right side
    for reasons that will become apparent later. I also added
    line numbers to facilitate discussion. Variable j is an
    unsigned int.

    The module I forgot to add holds function wait() (which is a
    thumb-twiddling loop whose execution time I can control with
    the argument shown). The object module produced by the
    compiler sets wait()'s address to dummy value c:0x0000
    (a.k.a. your friendly neighborhood power-up vector).

    The linker issues its warning:

    *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
        SYMBOL:  _WAIT
        MODULE:  TestFoo.obj (TESTFOO)
        ADDRESS: 01BEH
    

    and the execution module gets built, assuming wait() is
    still at 0000.

    As compiled, the "j=0" part of the for-loop consists of the 3
    instructions beginning at line 1; the "j<6" code is in
    lines 4-9, while the "j++" term resides in lines 16-19.

    This baby executes exactly as I intended until we get to the
    call to wait(). At this point, it performs the moral
    equivalent of a power-on reset, putting control back at the
    top of the loop with j=0. Thus my program executes the
    infinite loop I had wanted, but j never deviates from 0.

    This is the scenario that prompted this post.
    ============================================================
    Gary Lynch            |     To send mail, change no$pam in
    lynchg@no$pam.com     |     my domain name to stacoenergy

Children
No data