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?
As was noted in your previous thread:
http://www.keil.com/forum/63381/
Links to the Manuals, App Notes, and Examples are there.
There always used to be a "Getting Started" guide. It isn't on the website any more, but try searching your installation folders for "GS51" (it used to be a PDF, but was more recently a Windows Help File - .CHM, IIRC).
See also: http://www.keil.com/books/
Specifically: http://www.keil.com/books/8051books.asp