Hi! i have use p89c669 microcontroller and am29f040b [512 kb] flash.When i using the external code memory i can't initialize the array that have more than 4 values.if i initialize more than that the program will not be executed.if i comment the array the program was executed.the code was
const char red [256] = {0x00,0x00...0x00,0x00};
please help me!
regrads, K.T.Venkatesan.
Hi! Actualy i use the p89c669 microcontroller and amd 512 kb flash.now i had write a program for led blinking.after that program was loaded in the flash [external code memory] and the EA pin in the microcontroller was grounded.when i power on the target pcb the led was blinking as the per code.when i add an array array [76800] ={0x00,..0xfd}; in code the compiler give the error error c249:'!':SEGMENT TOO LARGE .
Last time i use the array as array[255] = {0x00,...0xff}; and load it in target board the leds was not blinking.then i change the array format as extern unsigned char const far array [256] ={0x00,...0xff} the problem was solved.
Regards, K.T.Venkatesan.
I think a close inspection of the linker map file would be appropriate.
extern unsigned char const far array [256] ={0x00,...0xff}
You can't have an initialiser on an extern declaration, can you?
Why use the 'far'? I thought that was used on cores that support 24 bit addressing.
Are you beyond 64K? Don't cross the boundary!
Check the map file.
Why use the 'far'? I thought that was used on cores that support 24 bit addressing. which the (soon to be discontinued) '669 does
Erik
Yes. Well, yes on a "definition" but not on a "declaration", to be pedantic, but the syntax is legal, and from the code snippets above you can't really tell whether it was meant to be a declaration. The initializer makes it a definition, and you'll get some sort of "multiply defined" diagnostic message if the syntax shows up in a .h file included in several .c files (for example).
From the ANSI C89 spec:
3.7.2 External object definitions Semantics If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier. A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static , constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0. If the declaration of an identifier for an object is a tentative definition and has internal linkage, the declared type shall not be an incomplete type. Examples int i1 = 1; /* definition, external linkage */ static int i2 = 2; /* definition, internal linkage */ extern int i3 = 3; /* definition, external linkage */ int i4; /* tentative definition, external linkage */ static int i5; /* tentative definition, internal linkage */ int i1; /* valid tentative definition, refers to previous */ int i2; /* $3.1.2.2 renders undefined, linkage disagreement */ int i3; /* valid tentative definition, refers to previous */ int i4; /* valid tentative definition, refers to previous */ int i5; /* $3.1.2.2 renders undefined, linkage disagreement */ extern int i1; /* refers to previous, whose linkage is external */ extern int i2; /* refers to previous, whose linkage is internal */ extern int i3; /* refers to previous, whose linkage is external */ extern int i4; /* refers to previous, whose linkage is external */ extern int i5; /* refers to previous, whose linkage is internal */
Since I'm not a fan of programming languages doing much (if anything) implicitly, I prefer always to repeat the extern/static on the definition as well as the declarations. This at least earns me a diagnostic message when an object changes from external to internal, and serves as a useful reminder that "this object is accessible from outside", and keeps the syntax parallel with the "static" case.
Yes!i can initialize the array with extern i see this in keil web site http://www.keil.com/support/docs/3128.htm
K.T.V
The whole point of that article is that you do the initialisation in assembler - not in 'C'!
Have you examined the link map file ?
yes! here it is!
LX51 LINKER/LOCATER V4.02 03/11/2008 11:52:22 PAGE 1 LX51 LINKER/LOCATER V4.02, INVOKED BY: C:\KEIL\C51\BIN\LX51.EXE COMMON {START_MX.obj}, COMMON {main.obj}, BANK1 {code bank 1.obj}, BANK1 {.\L51_BANK.obj} TO LC >> color BANKAREA (0X008000, 0X00FFFF) CLASSES (EDATA (0X7F0000-0X7F04FF)) CPU MODE: PHILIPS 80C51MX (ROM HUGE) MEMORY MODEL: LARGE INPUT MODULES INCLUDED: START_MX.obj (?C_STARTUP) COMMENT TYPE 0: AX51 V3.01 main.obj (MAIN) COMMENT TYPE 0: CX51 V8.01 code bank 1.obj (CODE_BANK_1) COMMENT TYPE 0: CX51 V8.01 .\L51_BANK.obj (?BANK?SWITCHING) COMMENT TYPE 0: AX51 V3.01 C:\KEIL\C51\LIB\CH51L.LIB (MALLOC) COMMENT TYPE 0: CX51 V7.20f C:\KEIL\C51\LIB\CH51L.LIB (INIT_MEM) COMMENT TYPE 0: CX51 V7.20f ACTIVE MEMORY CLASSES OF MODULE: LC color (?C_STARTUP) BASE START END USED MEMORY CLASS ========================================================== 7F0000H 7F0000H 7F04FFH EDATA 800000H 800000H 80FFFFH 0001CCH CODE 7F0000H 7F0000H 7F00FFH 000001H IDATA 000000H 800000H FFFFFFH 0002FAH HCONST 000000H 800000H FFFFFFH 000453H ECODE 000000H 000000H 00FFFFH 000020H XDATA 000000H 000000H FFFFFFH 000042H HDATA 7F0000H 7F0000H 7F007FH 000008H DATA
Hmmm,
You said before that you didn't use banking??!!
yes! today only i try the banking!
'trying' is the bane of many projects. the result of a 'try' may come out right even if what you 'try' is the wrong approach.
the dead easy way to handle this is to do two things a) make an .a51 module that contain ALL xdata and make them accessible from C by extern, then you have full control of the locations b) access the biggie in an assembler routine
you will be home free
I have done the exact same as above
Hi! the array problem was solved, now i using the banking method.but the bank size was limitted to 32kb.i can't enter more than 32kb in the keil/options for target1/bank area .
my heartly thanks to all!