I'm evaluating C51 & uVision v2.30 and have trouble accessing IDATA RAM. The target is an Atmel AT89C51AC2 that has 128 bytes of DATA ram, a further 128 bytes of IDATA ram and 1024 bytes of XRAM. I've completely exhausted both the XRAM and DATA spaces. I need to be able to use the IDATA space for globals etc, but can't seem to access it? I seem to think that the linker would automatically start using IDATA RAM as DATA RAM is used up. The linker bails with ADDRESS SPACE OVERFLOW as follows: . . . *** ERROR L107: ADDRESS SPACE OVERFLOW SPACE: DATA SEGMENT: ?DT?KBOARD LENGTH: 0020H *** ERROR L105: PUBLIC REFERS TO IGNORED SEGMENT . . . Target not created The .M51 file has the link map as follows: LINK MAP OF MODULE: FileIO (FILEIO) TYPE BASE LENGTH RELOCATION SEGMENT NAME ----------------------------------------------------- * * * * * * * D A T A M E M O R Y * * * * * * * REG 0000H 0008H ABSOLUTE "REG BANK 0" DATA 0008H 0001H UNIT ?DT?GETCHAR IDATA 0009H 0002H UNIT ?ID?FILEIO 000BH 0015H *** GAP *** BIT 0020H.0 0001H.2 UNIT _BIT_GROUP_ BIT 0021H.2 0000H.3 UNIT ?BI?FILEIO BIT 0021H.5 0000H.1 UNIT ?BI?GETCHAR 0021H.6 0000H.2 *** GAP *** DATA 0022H 0027H UNIT _DATA_GROUP_ DATA 0049H 0024H UNIT ?DT?FILEIO IDATA 006DH 0001H UNIT ?STACK * * * * * * * X D A T A M E M O R Y * * * * * * * XDATA 0000H 0400H UNIT ?XD?FILEIO BL51 BANKED LINKER/LOCATER V5.00 The Target Options dialog has 2 tabbed dialogs with the following Linker Control String: TO "FileIO" RAMSIZE(256) If I try to type cast some variables with an IDATA prefix, they seem to end up in the DATA space of the link map! Any assistance would be greatly appreciated. Regards, Murray R.Van Luyn
"If I try to type cast some variables with an IDATA prefix, they seem to end up in the DATA space of the link map!" You need to use a memory space specifier: idata unsigned char x; data unsigned char y; If I remember correctly it works like this: y will be placed in the low 128 bytes of RAM. If there is insufficient space you will get address space overflow. x will be placed in the low 128 bytes. If there is insufficient space it will be quietly placed in the high 128 bytes. Don't forget to leave room for the stack!
"You need to use a memory space specifier:" Hi Stefan, Yes, memory space specifier. That seems to be what I mean when I say type casting to IDATA. This is all quite new to me still. Well I gave that a shot and the variables still ended up in DATA memory. I changed from Small to Compact memory model, and everything now works. I imagine that you had expected I would have already done that. I'll have to go over the manual again to see exactly what I have done! Thanks for the input. Regards, Murray.
"Well I gave that a shot and the variables still ended up in DATA memory." If this made your "Address space overflow" message disappear, some of them must have wound up in the high 128 bytes. If not, you didn't declare enough of them as idata. "I changed from Small to Compact memory model" Having done that all variables declared without a memory space specifier will have gone into the pdata area which is one 256 byte page of the external memory. I don't know your derivative but is may have internal 'external' memory. This is RAM that behaves exactly as though it were connected to the address/data bus on ports 0 and 2. "I imagine that you had expected I would have already done that." Not at all, I always use the small model and declare variables as idata when I have used up the low 128 bytes. There is a lot of confusion about data and idata because of the way the 8051 accesses these memory areas. With direct addressing (which is what you get if you use the data specifier) accesses to addresses below 0x80 go to the internal RAM, above that address range they go to the SFR space (0x80 through 0xff). With indirect addressing (which is what you get if you use the idata specifier) all accesses go to the internal RAM (0x00 through 0xff). That's why a variable declared as idata can still wind up in the low 128 bytes.
"There is a lot of confusion about data and idata because of the way the 8051 accesses these memory areas. With direct addressing (which is what you get if you use the data specifier) accesses to addresses below 0x80 go to the internal RAM, above that address range they go to the SFR space (0x80 through 0xff). With indirect addressing (which is what you get if you use the idata specifier) all accesses go to the internal RAM (0x00 through 0xff). That's why a variable declared as idata can still wind up in the low 128 bytes." Ah, that explains everything. Even the compiler's report when compiling in Compact model: Program Size: data=15.6 xdata=1138 Thanks Stefan. Tremendous! Regards, Murray.
Yep, that's fixed everything. Lots of variables in IDATA when compiled for small memory model. The generated code seems to be a lot smaller than for compact model too. Thanks again Stefan. Regards, Murray.
Accessing xdata requires more bytes of instructions than accessing idata/data. You have to set up the DPTR, MOVX to the accumulator, move the accumulator to where you really wanted the byte. So just relocating a variable can increase code size noticably. (This is one reason I sometimes wish for a "medium" memory model, where auto variables and temps are allocated in data by default, rather than xdata, while statics go in xdata. You can of course explicitly declare the memory qualifiers -- which is perhaps even a preferable method just to prevent problems if you do switch memory models, or for the sake of documentation. The location of temps and register overflow can be controlled only with the memory model selection, unfortunately.)
"Accessing xdata requires more bytes of instructions than accessing idata/data. You have to set up the DPTR, MOVX to the accumulator, move the accumulator to where you really wanted the byte." Indeed, but note that the OP used the compact model where the external RAM is accessed as pdata which doesn't require DPTR.
"note that the OP used the compact model where the external RAM is accessed as pdata which doesn't require DPTR." Indeed - it uses R0 or R1 instead with MOVX @Rn. Hence the full story is: Accessing PDATA requires more bytes of instructions than accessing IDATA/DATA. You have to set up the Rn, MOVX to the accumulator, move the accumulator to where you really wanted the byte; Accessing XDATA requires more bytes still, as you have to set up a 16-bit DPTR.
Accessing PDATA requires more bytes of instructions than accessing IDATA/DATA. Is that quite the full story? Accessing variables in idata is no quicker than acessing variables in pdata. Both addressing modes make use of a pointer value in R0 or R1. Of course, accessing variables in data memory is faster than either idata or pdata because direct addressing modes can be used.