This is the error message I get. The projext is for the NXP P80C51MC2. The code size is around 400K bytes. This occurs after I add another instance of a structure to the code. I have about 450 instances of this structure. I can take out one of them and the problem goes away. This project is several years old and we add code to it on occasion. The error occurs during the compile of the C file that includes the header file with the structures. I have tried splitting the header file up, but that did not help. Any ideas?
I am using Keil 8.05a on Win2000.
450 instances of a struct? That does not sound so good.
Doesn't the code use one or a few array variables, where the variable can contain multiple entries?
It sounds like you are running out of namespace in the compiler, when it processes the code.
Each structure represents a screen on an LCD. The structure holds the text for the screen, where each keystroke can take you, entry method for data, etc.
Namespace? How do I fix that? I searched Keil and can not find anything on namespace.
I did not mean namespace as the keyword namespace used in C++, but namespace as a general concept for the number of symbols a compiler can keep track of while compiling code.
Global variables, data types, ... all reside in namespaces in the compiler.
But back to your problem: Do you really mean that you have 450+ individual variables of a specific data type?
Somehow, it seems that you should be able to better declare your menu information.
Another thing that can bother a compiler is if you have a complex data type and have to populate it with thousands of individual strings, where the compiler has to wait with either emitting the string data, or the struct contents until a huge array of initialized data reaches the end. An array must be continuous, so a large array containing initialized string pointers can result in overflows depending on how the compiler is implemented, and amount of memory on the build machine.
Care to show what your data structures - and sample initializations - looks like?
Yes, I have over 450 individual variables of a specific data type. Now I have been using this data type for a long time. Nothing new there.
Some of the complexity is from supporting multiple languages and controling the data entry method by the TERM_STRUCT.
I did not include the defines starting with KEY_ or NUM_LEN_ and others.
typedef unsigned short MODE_TYPE; typedef struct { char const far *lang[NUM_LANGS]; } LANG_STRUCT; typedef struct { MODE_TYPE mode; LANG_STRUCT const far *string_1; // first string to be displayed LANG_STRUCT const far *string_2; // second string to be displayed LANG_STRUCT const far *string_3; // third string to be displayed LANG_STRUCT const far *string_4; // fourth string to be displayed LANG_STRUCT const far *string_help; /* string to be displayed for help */ uchar type_1; void *entry_1; uchar type_2; void *entry_2; uchar type_3; void *entry_3; uchar type_4; void *entry_4; MODE_TYPE key_right; /* action if Right > is pressed */ MODE_TYPE key_down; /* action if Down V is pressed */ MODE_TYPE key_left; /* action if Left < is pressed */ MODE_TYPE key_yes; /* action if Yes is pressed */ MODE_TYPE key_no; /* action if No is pressed */ MODE_TYPE key_clear; MODE_TYPE key_help; /* action if HELP key is pressed */ MODE_TYPE key_exit; /* action if Exit key is pressed */ MODE_TYPE key_reset; /* action if Reset key is pressed */ MODE_TYPE key_up; /* action if Up ^ arrow is pressed */ MODE_TYPE key_SCM; /* action if SCM logo is pressed */ uchar rotate_top:1; uchar rotate_bot:1; uchar top_just:2; // 0-left just, 1-right just, 2-center uchar bot_just:2; uchar not_used:2; void *num_entry; // not used uchar num_use; // which entry (above) has the number to change uchar num_dig; // number of digits that can be entered ushort min_number; // the minimum the number can be ushort max_number; // the maximum the number can be } TERM_STRUCT; // sample /*************************************************************************/ // top number 1, string 1, number 2, string 2 // bot number 3, string 3, number 4, string 4 static TERM_STRUCT const far start = { KEY_START, // mode NULL, // first string NULL, // second string NULL, // third string NULL, // fourth string start_help, // help string NUM_LEN_STRING, // type 1 top_string, // entry 1 NUM_LEN_NONE, // type 2 NULL, // entry 2 NUM_LEN_STRING, // type 3 bot_string, // entry 3 NUM_LEN_UCHAR_HIDDEN, // type 4 &temp_uchar, // entry 4 KEY_LOG_ACCEPT_HISTORY_START, // right KEY_DIAG_VERSIONS_START, // down KEY_DIAG_VERSIONS_START, // left KEY_NONE, // yes KEY_NONE, // no KEY_NONE, // clear KEY_HELP, // help KEY_START_AGAIN, // Exit KEY_START_RESET, // Reset KEY_LOG_ACCEPT_HISTORY, // up KEY_NONE, // SCM FALSE, // 1 bit FALSE, // 1 bit CENTER_JUST, // 2 bits - top justificatiom CENTER_JUST, // 2 bits - bot justification 0, // 2 bits NULL, 4, // which entry (above) has the number to change 1, // number of digits that can be entered 0, // the minimum the number can be -1 // the maximum the number can be };
1) it seems you have the old worn "work around the 'no globals rule' structure". Elements in a structure, a pointer to which is passed to everything, are just as global as global variables. 2) why not suck the LANG_STRUCTs out of your catchall struct and put them in an array, that will give a much better program flow
Erik
Oh, I suppose I could, but LANG_STRUCT is used in other places. The reason we use it is kind of lost. I think we tried arrays but the text was lost when another language was selected besides index zero. That really isn't the point is it? The code works. Why go back and change that? Why do I get the error?
Why do I get the error? many have surmised as to why, What I suggested was to get rid of it regardless of the why.
That may be a moot point if I can not resolve the other problem. It would be a big task to change the LANG_STRUCTs. Thanks anyway.
not change the structs, change the access to them
The code works. Why go back and change that?
Because, right now, it doesn't work. It's as simple as that.
You've hit some internal limit of the compiler. It'd be nice to find out what that limit is and devise a perfect solution. But what if you can't achieve that? What would you prefer: a program that works (although you may not totally understand why it didn't work before), or a program that fails, but gives you the satisfaction that it's not your fault?
It'd be nice to find out what that limit is and devise a perfect solution.
In the olden days when (PC) resources were limited I ran into a similar problem with a different compiler (C86?) and the solution was to abbreviate some variable names.
And you have 400K of code - all on a poor little 8-bit controller.
Hopefully you will manage to work around this - but I think you should take it as a very big hint that it's time to start thinking about moving this to a more appropriate architecture...
I have worked on a project that was on the very edge of its compiler's limits (not C51), and it is definitely not a Good Thing - for a start, your project plan for even the tiniest wafer-thin modification have to have at least a 2-week contingency in case your break the compiler again...! That's no way to run a project!
On the other hand, if you're on an hourly rate, this could be your meal ticket for life...!!
:-)
BTW: the C51 compiler limits are detailed here: http://www.keil.com/support/man/docs/c51/c51_xd.htm Do you recognise any of them...?
The 400K must just be just source code. That would be a lot of banks.
In the end it is a support question. They may be able to identify the reason, and if the is an easy way aroud it.
Nope, 400K bytes of compiled code. This processor is unique (P87C51MC2). 23 bits of program memory space and 23 bits of data memory space. No banking either. I admit with that much code it is getting a little slow at 24MHz.
We are thinking of moving to a more powerful processor. We just have a lot of time and code written for this one. The current project is a decendent of an earlier one. We are definitely considering an ARM in 16 bit mode. We don't need 16 bit really, just the speed. Any suggestions?
Is this the compilers limits? Wish I knew. Keil will not tell me if I am not paying for support. If I pay for support will they change the compiler to accomadate a limitation I have run into? I am not saying it is their fault. I don't know.
I looked at the limits. The one I do not understand is. Keep in mind that I have 450 instances of this structure already.
A maximum of 19 levels of indirection (access modifiers) to any standard data type are supported. This includes array descriptors, indirection operators, and function descriptors.