Hi, It seems as if the load and store library routines used by the C51 compiler (see http://www.keil.com/support/docs/1964.htm for a description of these routines) are the cause of an 'improper fixup' error I'm getting while linking. I'm using the ROM(SMALL) directive in conjunction with a customized linker command line: CODE(?CO?StateTest(0x4005), ?PR?*) OVERLAY(* ! ?PR?_UPDATE?StateTest, * ! ?CO StateTest) to link the following small program: ============================================= #pragma ROM(SMALL) unsigned int update(unsigned int arg0, unsigned int arg1); typedef struct ProcessFragmentState { unsigned int x; unsigned char a; } PFragState; unsigned int code StateSize = sizeof(PFragState); PFragState xdata * statePtr; unsigned int update(unsigned int arg0, unsigned int arg1) { (statePtr -> x) = (statePtr -> x) + 1; return arg0 + arg1; } ============================================= Shouldn't the linker be able to figure out where to place the load and store routines such that they satisfy the ROM(SMALL) requirements? Is there a way around this? Thanks, Slarti
Here's the error I'm getting: ========================================== *** ERROR L121: IMPROPER FIXUP MODULE: D:\PROJECTS\PUSHPIN\CODE\VERSION3\TESTCODEV3\STATETEST\STATETEST.OBJ (STATETEST) >> SEGMENT: ?PR?_UPDATE?STATETEST OFFSET: 000AH ========================================== And here's the part of the listing file of interest: =========================================== ; FUNCTION _update (BEGIN) ; SOURCE LINE # 23 ;---- Variable 'arg1' assigned to Register 'R4/R5' ---- ;---- Variable 'arg0' assigned to Register 'R6/R7' ---- ; SOURCE LINE # 24 0000 850082 R MOV DPL,statePtr+01H 0003 850083 R MOV DPH,statePtr 0006 E4 CLR A 0007 75F001 MOV B,#01H 000A 1100 E ACALL ?C?IILDX ; SOURCE LINE # 25 000C EF MOV A,R7 000D 2D ADD A,R5 000E FF MOV R7,A 000F EE MOV A,R6 0010 3C ADDC A,R4 0011 FE MOV R6,A ; SOURCE LINE # 26 0012 ?C0001: 0012 22 RET ; FUNCTION _update (END) ============================================ It's the ACALL to ?C?IILDX that seems to be causing the error. Cheers, Slarti
What version of the C compiler are you using? Jon
I'm using: C51 COMPILER V6.14 BL51 BANKED LINKER/LOCATER V4.14 -slarti-
The solution lies in changing the CODE linker directive from: CODE(?CO?StateTest(0x4005), ?PR?*) to: CODE(?CO?StateTest(0x4005), ?PR?*, ?C?*) so that the linker knows to put the library included by the compiler in the same 2Kbyte block as the rest of the code. Thanks, Slarti
I am using 8052 All Variants device. The following should work without worrying about wild carding all all the segments.
CODE( 0x4005, ?CO?StateTest(0x4005) )
CODE( 0x4005, ?CO?StateTest )
There is something wrong with the linker however, because the following should have also worked but fails. Nope. There is nothing wrong with the linker. If you take a look at the original posting, the ROM(SMALL) directive tells the linker that you will have all of your program code reside within one 2K block. So, the linker uses AJMPs and ACALLs. Since the CODE linker directive is used to change the starting address of the program, but only SOME segments are included, the linker locates all other segments starting at 0. The appropriate thing to do would have been to specify that the CODE area resides from 0x4000-0x47FF rather than manually locating segments in that range. Jon
I believe that StateTest (and maybe others) are required to be located at fixed locations. Setting code to 0x4005-0x47FF on the linker tab and adding
CODE(?CO?StateTest(0x4005))