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
If you are using DK51 or CA51, you must use the BL51 linker to locate the constant code segments as shown in the following knowledgebase article: http://www.keil.com/support/docs/1615.htm If you have the PK51, you can use the LX51 Linker to locate the constant segments as shown in http://www.keil.com/support/docs/2307.htm Jon
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)
* * * * * * * 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
Is the linker trying to fool me, or am I feeding it the wrong input? Regards, Nelis
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))
"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"
"I am developing a huge application of 64K * 4 using 4 banks ... 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..." Have you stopped to consider the fundamental question here: Is the application really suited to an 8051? Is the effort of trying to force this huge application onto a classic 8051 really worth the effort? Would the effort be better spent in moving to a more appropriate processor - maybe one of the 8051 derivates with >64K addressing (as Erik has already mentioned), or an ARM, or something completely different?
I use Cygnal C8051F124 with 128K flash memory (4 banks*32K). It is enough for the application. And other processor's features agree to the task. So I can't understand what for there is so much memory space if I can't use it?! It seems that I can use only 64K of code memory (linker creates the gaps in parallel with the constant data).
"So I can't understand what for there is so much memory space if I can't use it?!" One reason may be to support In-Application software updates - where you need space to save a whole download so that you don't trash the old code before you know for sure that the download has worked...!! (dunno if this applies to the C8051F124 specifically)