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?
I have fixed the problem. It was something real stupid.
I forgot that Keil cares little for lower and upper cases sometimes. I had other variables which were written with upper cases letters. Compiler does not see it, only the linker. But the linker does not say where the "other definations" were in my program.
-_-"
No, that's not true.
The 'C' language is, by definition, case-sensitive - so Keil C51 is case-sensitive.
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
I know very well that C is case sensitive and that Keil's compiler is also case sensitive. But the linker sure is not.
I cannot declare 2 variabeles like int a, A;. It compiles fine but the linker does not accept this and throws me error L104. This is why I said "Keil care little for upper and lower cases sometimes"
I didn't have this problem in Arduino or in SDCC
I had a memory of a command line switch to enable case sensitivity of the linker, but can't find it. I'm possibly wrong with that memory.
Worth you reading this old post:
http://www.keil.com/forum/551/case-sensitivity/
ah - OK.
But you could have been more specific - rather than just saying, "Keil".
"I didn't have this problem (sic) in Arduino or in SDCC"
There is no requirement that linkers must be case sensitive.
It's possible that it's a limitation of the OMF51 format ... ?
(Arduino uses GCC).