Maybe I have some setting wrong in my project. At the beginning of my main source file, I include a header that declares several variables as externs. Then I declare and initialize them after the #include.
Main Source:
#include <header.h> ... const char DEVICE_NAME[] = "ELC"; const char VERSION_NUMBER[] = "F1.0M1.0"; const char CONTROL_PANEL = 1; ... void main(void) { ... }
Header (header.h):
#ifndef _HEADER_H #define _HEADER_H ... extern char DEVICE_NAME[],VERSION_NUMBER[],CONTROL_PANEL; ... #endif
The variables are then used in implementation code in another file. This other file and the header are common to several projects that I'm working. (I have restructured my projects per our last discussion.)
The problem that I'm experiencing is that all of the data is initialized to 0 at the beginning of main() rather than the specified values. I don't have any of the .A51 initialization files in my project, so what could be causing this?
Thanks.
I don't have any of the .A51 initialization files in my project, so what could be causing this?
That very thing might just be causing it. INIT.A51 does the job that's not being done in your project. So how about you try putting it into your project and see if that makes a change?
If you don't explicitly put them in your project, C51 will use defaults.
I guess the defaults are not (quite) suitable to your project's requirements...
So how about you try putting it into your project and see if that makes a change?
No change. All of my preset string variables are still zeroed out. Is there anything more that I need to do than just add it to my project?
From the documentation, it seems like INIT.A51 clears all of the memory at device startup. I don't want it cleared; I want it to initialize properly.
Is there anything more that I need to do than just add it to my project?
It has to be the last entry in your project. Otherwise it won't work.
From the documentation, it seems like INIT.A51 clears all of the memory at device startup.
I don't know which documentation you're referring to, but no, that's not what INIT.A51 does. It initializes explicitly initialized variables.
Okay. New information. In the implementation of my header file, I have a large (5000) char array in xdata that I initialize to 0. When I reduce the size to 250, the other variables initialize as they're supposed to. It appears that the array is initializing over the other variables.
#ifndef _HEADER_H #define _HEADER_H ... extern char DEVICE_NAME[],VERSION_NUMBER[],CONTROL_PANEL; extern char output_buffer[]; ... #endif
Implementation (header.c):
#ifndef _HEADER_C #define _HEADER_C #include <header.h> ... char output_buffer[5000] = {0}; ... #endif
If I move the declaration to the main source file, the code works, even with the larger array.
#include <header.h> ... char output_buffer[5000] = {0}; const char DEVICE_NAME[] = "ELC"; const char VERSION_NUMBER[] = "F1.0M1.0"; const char CONTROL_PANEL = 1; ... void main(void) { ... }
#ifndef _HEADER_C #define _HEADER_C #include <header.h> ... #endif
Why would the compiler overlap memory allocation in the first case, but not the second?
[edit] All of the
char output_buffer
should be
char xdata output_buffer
Because it didn't. There's really no way it even could do that, according to your latest update of the incomplete sample program: output_buffer is in a completely different memory space from the rest of your variables.
Your problem presentation here has suffered greatly from being different from the actual code you had the problem with. Enough of that! So, before you go on asking questions, please create an example case that actually fails with exactly the source as posted.
Sorry for the confusion. We think we found a solution. There appears to be an upper limit for the large array (about 2500). For anything larger than that amount, the memory wipes. We think the limit (or just shy of it) will be sufficient for our application.
However, for the sake of completeness (and supposing I might face this problem in the future), I would like to figure out why this isn't working. All of the global variables are in xdata. Below is the most complete version of my code that I can post. I apologize, but I have to be generic enough so as not to infringe on my company's proprietary information policies.
Main Source (main.c):
#include <header.h> ... char xdata DEVICE_NAME[] = "ELC"; char xdata VERSION_NUMBER[] = "F1.0M1.0"; char xdata CONTROL_PANEL = 1; ... void main(void) { ... }
#ifndef _HEADER_H #define _HEADER_H ... extern char xdata DEVICE_NAME[],VERSION_NUMBER[],CONTROL_PANEL; extern char xdata output_buffer[]; ... #endif
#ifndef _HEADER_C #define _HEADER_C #include <header.h> ... char xdata output_buffer[5000] = {0}; ... #endif
I have main.c, header.c, and INIT.A51 listed in the target's only source group. Again, the program works just fine by moving the declaration of output_buffer to main.c. I'd like to avoid this because I use the header on many different units. Also, if I declare output_buffer in header.h (without extern) rather than one of the .c files, I get a 'multiple definition' linker error.
You might be better off not explicitly initializing that buffer at all. An initialization to an explict {0} serves no particular purpose anyway --- the result is the same as if you hadn't initialized it all, since the implicit default initialization to all-zeroes would have done the same job, and without wasting several kilobytes of zero bytes in the code image.
... how much xdata do you actually have?
Erik
You might be better off not explicitly initializing that buffer at all.
I see your point. I thought it was better to be safe.
I'm using the SciLabs C8051F020, which has 64K each of program and data memory. My programs are building to about 12K for the largest program. Other devices requires significantly smaller builds.
I'm using the SciLabs C8051F020, which has 64K each of program and data memory
www.silabs.com/.../C8051F020_Short.pdf clearly states it has 4k of xdata + the usual 256 of (I)DATA
That might likely be my problem then. I misread the 64K external memory addressing note.