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

Const address in bank not "linked" by LX51

I am trying to locate const in a file into a particular bank and access it in the same bank but from a different file. From the map file const is located correctly at the specified address in the bank. However the compiled code to access this const references an address 0 instead of the const address.

Here is a simple banking application...

datafile.c contains

unsigned char const code  message0[] = {'a','b','c','\n'};

C_MESS0.c contains

extern unsigned char const code  message0[];
unsigned char const code  message7[] = {'d','e','f','\n'};

void mess0func()
{
 char x;
 x = message0[0];
 printf("%c", x);

 x = message7[0];
 printf("%c", x);
}

Both files are configured for bank 0 in the IDE. Code banking is selected with two banks and starting address 0x8000. User segment in the IDE is set to ?CO?datafile(B0:0x8000), ?CO?C_MESS0(B0:0x82f0).

The map file contains

      00808004H   CODE/B0  ---       mess0func
      00808000H   CONST/B0 ---       message0
      008082F3H   CODE/B0  ---       message7

When I see the .cod file generated by the linker...

   21:  x = message0[0];
B0:008004 900000            MOV     DPTR,#message0
B0:008007 E4                CLR     A
B0:008008 93                MOVC    A,@A+DPTR
B0:008009 F508              MOV     x,A
   22:  printf("%c", x);
B0:00800B 7BFF              MOV     R3,#0FFH
B0:00800D 7A82              MOV     R2,#HIGH 010082F0H
B0:00800F 79F0              MOV     R1,#LOW 010082F0H
B0:008011 85080C            MOV     ?_printf?BYTE+03H,x
B0:008014 1200A3            LCALL   _printf
   23:  x = message7[0];
B0:008017 9082F3            MOV     DPTR,#message7
B0:00801A E4                CLR     A
B0:00801B 93                MOVC    A,@A+DPTR
B0:00801C F508              MOV     x,A
   24:  printf("%c", x);

Notice that the first assembly line is 900000 instead of 908000

It appears that const is processed correctly in the same file but not in a different file.

I can't figure out what I am missing?

Build parameters:
C51 control string: OBJECTADVANCED OPTIMIZE (6,SPEED) BROWSE DEBUG CODE SYMBOLS
AX51 : GENONLY SET (SMALL) DEBUG XREF EP
LX51: TO "BANK_EX2" BankArea (0x008000, 0x0082FF) CODE IXREF SEGMENTS ( ?CO?datafile(B0:0x8000), ?CO?C_MESS0(B0:0x82f0) )

Here are the tools used..

IDE-Version:
µVision3 V3.72
Copyright (c) Keil Elektronik GmbH / Keil Software, Inc. 1995 - 2008

Tool Version Numbers:
Toolchain: PK51 Prof. Developers Kit Version: 8.06
Toolchain Path: C:\Keil\C51\BIN\
C Compiler: C51.Exe V8.06
Assembler: AX51.Exe V3.02
Linker/Locator: LX51.Exe V4.10a
Librarian: LIBX51.Exe V4.24
Hex Converter: OHX51.Exe V1.36b
CPU DLL: S8051.DLL V3.64
Dialog DLL: DP51.DLL V2.48f
Target DLL: BIN\MON51.DLL V2.41
Dialog DLL: TP51.DLL V2.48f

Parents
  • The issue here seems to me that the linker cannot tell from the declaration where to locate the const buffer. I would have expected it to end up in the common, unbanked area.

    As far as I understand XBANKING.A51 in the Cx51 documentation, "far const" is used to put global constants into the common area. I don't think forcing into a specific bank is actually supported. I.e. banked const should only be accessed from the same .c file, because others may be put into a different bank.

    As long as you don't run out of common, unbanked space, it seems to me "far const" is your best bet for working code.

    Note that this is purely speculative — I don't have banked code to test this.

Reply
  • The issue here seems to me that the linker cannot tell from the declaration where to locate the const buffer. I would have expected it to end up in the common, unbanked area.

    As far as I understand XBANKING.A51 in the Cx51 documentation, "far const" is used to put global constants into the common area. I don't think forcing into a specific bank is actually supported. I.e. banked const should only be accessed from the same .c file, because others may be put into a different bank.

    As long as you don't run out of common, unbanked space, it seems to me "far const" is your best bet for working code.

    Note that this is purely speculative — I don't have banked code to test this.

Children
  • From my understanding the linker has located the const (message0) in B0, as it appears from the map file. But is not able to link it correctly.

    By moving const data into a particular bank I am trying to ensure space for this data is utilized only when needed. The const data is never used outside the bank, so it would not be ideal to locate it in common area.
    I can include it in the C file that it is being used in (which solves the problem), but there may be multiple C files in the future and it makes it clunky.

    You can find example banking code in Keil\C51\Examples\CodeBanking

  • I think your only choice is to define your own memory class for each bank in which you want to share globals.