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

Linker problem L104 with a header file

I have a program which exists out of a few files. I have my main.c file, my own library .c and .h files, I have an I/O.h file which only contain #defines and lastly I have my register.h file for the uController. The register.h file is included in my own library.h file because the library needs to know most registers.

When I ported from sdcc to keil I experienced some difficulties and enlisted Keil's help. They made some minor modifications with those overcomplicated # statements. This helped me finishing my program. Now I am porting another program which uses a few registers and I am running against linker error L104 again and I can't get rid of it.

main.c includes librabry.h and library.h includes register.h

#ifndef AT89x51_H
#define AT89x51_H
/* BYTE addressable registers */
sfr P0 = 0x80;
sfr SP = 0x81;
sfr DPL = 0x82;
// many more


#ifdef _COMMUNICATION_FUNCTIONS

extern unsigned char xdata tpdoid = 0x8500;
extern unsigned char xdata tpdo0 = 0x8501;
extern unsigned char xdata tpdo1 = 0x8502;
extern unsigned char xdata tpdo2 = 0x8503;
extern unsigned char xdata tpdo3 = 0x8504;
extern unsigned char xdata tpdo4 = 0x8505;
extern unsigned char xdata tpdo5 = 0x8506;
extern unsigned char xdata tpdo6 = 0x8507;
extern unsigned char xdata tpdo7 = 0x8508;

extern unsigned char xdata rpdoid = 0x8510;
extern unsigned char xdata rpdo0 = 0x8511;
extern unsigned char xdata rpdo1 = 0x8512;
extern unsigned char xdata rpdo2 = 0x8513;
extern unsigned char xdata rpdo3 = 0x8514;
extern unsigned char xdata rpdo4 = 0x8515;
extern unsigned char xdata rpdo5 = 0x8516;
extern unsigned char xdata rpdo6 = 0x8517;
extern unsigned char xdata rpdo7 = 0x8518;

#else
unsigned char xdata tpdoid _at_ 0x8500;
unsigned char xdata tpdo0 _at_ 0x8501;
unsigned char xdata tpdo1 _at_ 0x8502;
unsigned char xdata tpdo2 _at_ 0x8503;
unsigned char xdata tpdo3 _at_ 0x8504;
unsigned char xdata tpdo4 _at_ 0x8505;
unsigned char xdata tpdo5 _at_ 0x8506;
unsigned char xdata tpdo6 _at_ 0x8507;
unsigned char xdata tpdo7 _at_ 0x8508;

unsigned char xdata rpdoid _at_ 0x8510;
unsigned char xdata rpdo0 _at_ 0x8511;
unsigned char xdata rpdo1 _at_ 0x8512;
unsigned char xdata rpdo2 _at_ 0x8513;
unsigned char xdata rpdo3 _at_ 0x8514;
unsigned char xdata rpdo4 _at_ 0x8515;
unsigned char xdata rpdo5 _at_ 0x8516;
unsigned char xdata rpdo6 _at_ 0x8517;
unsigned char xdata rpdo7 _at_ 0x8518;

#endif
sfr cogw = 0x94;
// many more


The Linker only complains about:

*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
    SYMBOL:  RPDO7
    MODULE:  .\Objects\preStresser.obj (PRESTRESSER)


Only the rpdo and tpdo give problems. If I out-comment the top ones (with extern) I get ' undefined identifier error in library.c and if I out-comment the bottem lines the same error appears in main.c. So I do need all of them. I did not think of this solution myself.

In SDCC I could simply include the register.h in main.c prior to including library.h like it should work IMHO. But unfortunately for me Keil is more complicated than that.

Why is my linker unhappy and how can I make it happy again?

Parents
  • #ifdef _COMMUNICATION_FUNCTIONS
    
    extern unsigned char xdata tpdoid = 0x8500;
    :
    :
    
    #else
    unsigned char xdata tpdoid _at_ 0x8500;
    :
    :
    
    #endif
    

    So your header file contains both a set of definitions and a set of 'extern' declarations - and which gets used is determined by the setting of _COMMUNICATION_FUNCTIONS

    Are you sure you are properly defining that symbol?

    This is standard 'C' stuff - nothing specifically to do with Keil.
    You would get exactly the same with SDCC - or any other compiler.


    c-faq.com/.../decldef.html

Reply
  • #ifdef _COMMUNICATION_FUNCTIONS
    
    extern unsigned char xdata tpdoid = 0x8500;
    :
    :
    
    #else
    unsigned char xdata tpdoid _at_ 0x8500;
    :
    :
    
    #endif
    

    So your header file contains both a set of definitions and a set of 'extern' declarations - and which gets used is determined by the setting of _COMMUNICATION_FUNCTIONS

    Are you sure you are properly defining that symbol?

    This is standard 'C' stuff - nothing specifically to do with Keil.
    You would get exactly the same with SDCC - or any other compiler.


    c-faq.com/.../decldef.html

Children