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

code banking

I am using a uVision2 and C51 compiler. I want to use code banking as my code exceeds 64K limit. how do I specify which part of the code will be in which bank(means which files to assign what bank) and which will go into the common area.

Suppose I have assigned two files of the code to be in bank0. How will I know the size occupied by the files in that bank?

Does the linker take care of the function calls if we specify some files in one bank and some files in another bank randomly?

  • In uVision, a file group has a pulldown list that lets you set a bank for all files in that group. So, if you have no other structure in your project, you might just create groups "Common", "Bank 1", etc.

    The SEGMENTS directive is the corresponding directive for the linker. You can specify a bank without specifying a specific address. E.g., SEGMENTS (?PR?MyModule (B1:)) puts MyModule someplace in bank 1, while SEGMENTS (?PR?MyModule (B1:A000H)) puts MyModule exactly at address A000.

    The map file shows the actual locations of all the segments once they've been located. You can scan down the lists of segments located in CODE, CODE/B1, etc, to find the highest address used. Unfortunately, there's no handy summary of this information. It would be a nice feature if the linker summarized bank usage along with the other memory usage generated by the compiler (data/xdata/const/code, but with "code" being broken down by banks when building a banked application.) A little work with perl or awk to process the map file can get you by, though.

    The linker will create the inter-bank calls correctly if you randomly scatter files around. Keep in mind, though, that any inter-bank call requires a stub to exist in the common bank, so the flow of control can jump down to common, flip in a new bank, jump up to the new bank, and return the same way. In addition to being slow, these stubs take up space in the common bank. I'd recommend considering your program call tree, and trying to group modules with high interdependence together in the same bank.

  • Hi,

    I am also new to the code banking concept and would like to try it. Drew, Can u plz elaborate on how the whole process is going on. I have read the manuals but i need something which is more enlightening.

    How and where to use directives i.e. in the code or somewhere else.

    What if we do not specify any common area i.e i want to use two 64K banks 0000h to ffffh. instead of one common 32K area and four 32K banks

  • What if we do not specify any common area i.e i want to use two 64K banks 0000h to ffffh.

    Then you're asking for trouble.

    A common area is necessary because the operation (switch to bank X and jump to address X) is not atomic. After executing (switch to bank X), the next command is already read from bank X.

  • The dual 64KB bank scheme is also supported by Keil tools. The disadvantage is that you have to locate all common code in each bank, so that it is always present when needed. All the common routines, interrupt handlers, and so on will exist twice and take up twice as much room.

    The choice between the two is up to your address decoding hardware. Either way, you need a register with high-order bits of the code address. The address decoder either makes these bits N:16, concatenating with bits 15:0 from the CPU, to produce 64KB banks. Or, the address decoder checks bit 15 from the CPU, and replaces bits N:15 with the high-order register to produce 32KB banks.

    Given the hardware, you have to produce an L51_BANK.A51 that updates your banking hardware correctly. Some of the most common hardware designs are built in as options; you can also code completely custom routines.

    The Keil manuals and app notes are a place to start.
    http://www.keil.com/c51/codebanking.asp