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

how to easily locate constant in bank easily?

Hi folk

I am developing a huge application of 64K * 4 using 4 banks on Keil 7.01

Consider the following scenerio:

I have over 20 modules (over 20 c source files) in each of the banks. And in each module, I use quite a bit of constant data, for example, in bank1:

void test1(void)
{ unsigned char code array[] + { 1, 2, 3} ;
doThis() ;
....
}

and test2() in other module of the same bank, so on and so forth.

Now the constant arrays will be linked into common bank but not in bank1. As you can see, the constant array has local function scope, and no way it can be accessed for outside the function, and surely it can be located in bank1 by default, but this is not the case.

I understand that I can use linker to specify location such that bank1(?CO?test1,(0xc000),?CO?test2,...). For the 20 odd modules, it seems that is not the nice way to do.

Also for the linker, can I just specific to locate the constant arrays starting to the end of the common bank, and how to do it. I understand that I can found out the length of common bank and then specifies the starting address of the constant, but as commonbank grows and shrinks, you do not expect one to keep on monitor its length and adjusted manually.


It would be best if my wish can be done automatically. That is function scope constant should be linked to the relevent bank instead of common bank.

Rgds

Calvin

Parents
  • The linker BL51 locates all constant code data in the common area. Because I use a single EPROM (with 2 copies of the common area) I want the common area to be as small as possible. Knowledgebase article 1615 promised just what I needed. After a lot of puzzling I came up with the following linker command-file:

    COMMON{&
    qv47_com.obj,&
    comm.obj,&
    tis1.obj,&
    tis1drv.obj,&
    L51_bank.obj,&
    \apps\c51\v6.10\c51s.lib,&
    clck1215.obj,&
    qereset.obj,&
    showmess.obj,&
    time.obj,&
    utils.obj,&
    assure.obj},&
    BANK0{&
    qv47.obj,&
    blackli.obj,&
    cardbuf.obj,&
    coin.obj,&
    curcy.obj,&
    dispens.obj,&
    hopper.obj,&
    key.obj,&
    lcd.obj,&
    l2money.obj,&
    log.obj,&
    note.obj,&
    mfc_smrt.obj,&
    mfc_std.obj,&
    mfccmd.obj,&
    nedap.obj,&
    nedapcmd.obj,&
    reset.obj,&
    sle4442.obj,&
    slecard.obj,&
    sound.obj,&
    tclist.obj,&
    tglist.obj,&
    astro.obj,&
    pushmat.obj,&
    mifare.obj,&
    omron.obj,&
    saf2_des.obj,&
    mifcmd.obj},&
    BANK1{&
    menu.obj,&
    kmenu.obj,&
    configbt.obj,&
    servremo.obj,&
    serport.obj}&
    TO qv47 RAMSIZE (256) CODE (0H) XDATA (0-7FFFh,?XD?CLCK1215(0h)) NLIB IXREF PW(132)&
    BANKAREA(03000h,0FFFFh)&
    BANK0(?CO?SAF2_DES,?CO?QV47,?CO?LOG)
    

    Indeed, the three code-segments (?CO?SAF2_DES, ?CO?QV47 and?CO?LOG) were located in BANK0. However, the end-address of the common code area was the same as before. A closer look at the map-file revealed the trick that the linker used. There is a large gap in the common area. As you can see below the gap is exactly the size of the three moved blocks. So the constants are still in the common area, only the name is changed to BANK0. There is no gain in the available codesize.

                * * * * * * *   C O D E   M E M O R Y   * * * * * * *
                CODE    002BH     0003H     ABSOLUTE
                        002EH     10A2H                  *** GAP ***
                CODE    10D0H     0B50H     UNIT         ?C?LIB_CODE
    ..............
                * * * * * * *   C O D E   B A N K   0   * * * * * * *
                        0000H     002EH                  *** GAP ***
                BANK0   002EH     02ECH     UNIT         ?CO?SAF2_DES
                BANK0   031AH     0AC8H     UNIT         ?CO?QV47
                BANK0   0DE2H     02EEH     UNIT         ?CO?LOG
                        10D0H     2EA3H                  *** GAP ***
    
    
    
    Is the linker trying to fool me, or am I feeding it the wrong input?
    
    Regards,
    Nelis
    

Reply
  • The linker BL51 locates all constant code data in the common area. Because I use a single EPROM (with 2 copies of the common area) I want the common area to be as small as possible. Knowledgebase article 1615 promised just what I needed. After a lot of puzzling I came up with the following linker command-file:

    COMMON{&
    qv47_com.obj,&
    comm.obj,&
    tis1.obj,&
    tis1drv.obj,&
    L51_bank.obj,&
    \apps\c51\v6.10\c51s.lib,&
    clck1215.obj,&
    qereset.obj,&
    showmess.obj,&
    time.obj,&
    utils.obj,&
    assure.obj},&
    BANK0{&
    qv47.obj,&
    blackli.obj,&
    cardbuf.obj,&
    coin.obj,&
    curcy.obj,&
    dispens.obj,&
    hopper.obj,&
    key.obj,&
    lcd.obj,&
    l2money.obj,&
    log.obj,&
    note.obj,&
    mfc_smrt.obj,&
    mfc_std.obj,&
    mfccmd.obj,&
    nedap.obj,&
    nedapcmd.obj,&
    reset.obj,&
    sle4442.obj,&
    slecard.obj,&
    sound.obj,&
    tclist.obj,&
    tglist.obj,&
    astro.obj,&
    pushmat.obj,&
    mifare.obj,&
    omron.obj,&
    saf2_des.obj,&
    mifcmd.obj},&
    BANK1{&
    menu.obj,&
    kmenu.obj,&
    configbt.obj,&
    servremo.obj,&
    serport.obj}&
    TO qv47 RAMSIZE (256) CODE (0H) XDATA (0-7FFFh,?XD?CLCK1215(0h)) NLIB IXREF PW(132)&
    BANKAREA(03000h,0FFFFh)&
    BANK0(?CO?SAF2_DES,?CO?QV47,?CO?LOG)
    

    Indeed, the three code-segments (?CO?SAF2_DES, ?CO?QV47 and?CO?LOG) were located in BANK0. However, the end-address of the common code area was the same as before. A closer look at the map-file revealed the trick that the linker used. There is a large gap in the common area. As you can see below the gap is exactly the size of the three moved blocks. So the constants are still in the common area, only the name is changed to BANK0. There is no gain in the available codesize.

                * * * * * * *   C O D E   M E M O R Y   * * * * * * *
                CODE    002BH     0003H     ABSOLUTE
                        002EH     10A2H                  *** GAP ***
                CODE    10D0H     0B50H     UNIT         ?C?LIB_CODE
    ..............
                * * * * * * *   C O D E   B A N K   0   * * * * * * *
                        0000H     002EH                  *** GAP ***
                BANK0   002EH     02ECH     UNIT         ?CO?SAF2_DES
                BANK0   031AH     0AC8H     UNIT         ?CO?QV47
                BANK0   0DE2H     02EEH     UNIT         ?CO?LOG
                        10D0H     2EA3H                  *** GAP ***
    
    
    
    Is the linker trying to fool me, or am I feeding it the wrong input?
    
    Regards,
    Nelis
    

Children
  • Banking is, at best, a kluge.
    Once it was the only way to do it and thus "necessary", but no more.

    Today there is no excuse for using the kluge since several derivatives, including Philips Mx and 669, are available that will linearly address megabytes.

    Erik

  • I faced the same problem. I have a large project (>64K) and a large segment of constant data (fonts for LCD), which I want to download to the banked area (to BANK2). So I use the following string

    BANK2 (?co?fonts(0x8000))
    And as a result I do have the fonts in BANK2, but I also have the gap of the same size as fonts in the CODE area (and at the same address).

    Has anybody solved such problem?

  • "I have a large project (>64K) and a large segment of constant data (fonts for LCD)"

    Note that LX51 allows you to put constant data (such as strings) into XDATA - you just need a memory architecture that places some ROM in XDATA space.

    Search for "XCONST" and "XCROM"