We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I haven't received an answer that fixed my problem, so here is another example.
I have a simple printf statement that causes a L103 error. No variables declared. Includes "stdio.h" and links in C51FPL.LIB. Others LIBs don't seem to link correctly either. Code compiles fine. Anyone know what the linking problem could be?
#include "stdio.h"
main() { printf("12345"); }
BL51 BANKED LINKER/LOCATER V5.12 COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2004
*** ERROR L103: EXTERNAL ATTRIBUT DO NOT MATCH PUBLIC SYMBOL: ?_PRINTF?BYTE MODULE: C51FPL.LIB (PRINTF)
Program Size: data=15.1 xdata=48 code=2562 LINK/LOCATE RUN COMPLETE. 0 WARNING(S), 1 ERROR(S)
My simple code compiles and links properly with C51S.LIB (but not with other LIBs - L103 error). Still would like to know why that is.
However, with this code,
#include <stdio.h>
main() { unsigned char idata x, text[15];
x = 12; sprintf(text,"%d Volts",x); }
the value of text is '3072 Volts' in my variable watchbox. The value of x is always 12. There is something going on with the arguments that sprintf has in the Keil LIB. However, there is no source code in the Keil folders to look at. Anybody have any ideas why this simple Keil sprintf is not working? Using V7.50 of the compiler. Thanks.
Sutton
Do you have ANSI integer promotion enabled?
The format string in your printf is "%d", which is to say an integer, which means 2 bytes for C51. However, you pass it "x", which is declared as char -- 1 byte. This means the actual data passed to printf does not match what the format tells printf() to process, and you will not get the expected results.
Keil introduced a 'b' modifier for 1-byte integers, e.g. "%bd".
The alternative is to enable ANSI integer promotion, which means ALL single-byte parameters to ALL functions will be passed as two-byte integers instead of one byte. This usually means a fair amount of extra, unneeded code.
DOH....That was it. Should have figured that out myself.
"My simple code compiles and links properly with C51S.LIB (but not with other LIBs - L103 error). Still would like to know why that is."
The answer to that is in my very first reply in your original thread.
Hint: The 'S' in C51S.LIB indicates that it is for the Small memory model...
I know what the S,C, and L memory modules stand for. I've been using them for many years. But, that still doesn't answer the question of:
'sprintf' compiles and links fine with a Compact memory module but ONLY with the small libraries (C51S.LIB). It does NOT link properly with the compact or large LIBs (C51C.LIB or C51L.LIB). It gives L103 errors. Why? So, another question is what is the correlation between the memory modules and the LIBS? My first inclination is nothing. Sorry for being so long winded, but none of the postings have answered my question. Please try again.
And actually, if I compile and link a simple 'sprintf' statement with a small memory module with C51FPS.LIB, I get L121 (Invalid Fixup) errors. Why is that? All my variables are explicitly defined as IDATA (or XDATA or whatever). If I link it with C51S.LIB, no problems.
"I know what the S,C, and L memory modules stand for"
NB: It's model - not module.
OK. I was wrong on the terminology.
Also, I am using the command line for compiling and linking, when I get these linker errors. Seems to work OK in uVision. But, I still don't know why the command line linker errors are happening.
Are you MANUALLY forcing the library that the link should link with?
If so, that may be the problem.
The compiler tells the linker which Keil libraries to include so there is no need for you to do that.
For example, C51S.LIB is the small model library. C51FPS.LIB is the small model library floating-point extensions. To link a small model application with floating-point, you need both of these libraries linked in. Note that the compiler and linker do this automatically and there is no need for you to do anything.
If you get the problems you get when using the command line to compile and build but you don't get them when you use uVision, then you should tell uVision to create a batch file for building the project and you should review that to see what the differences are.
Jon
Jon,
You're a genius. That was the problem. I was manually linking a particular LIB. I used to have to do that with the old Keil software and just ported it over to the new project. If I take out the LIB from my link, all memory models link fine. Thanks.