|
|
View previous topic :: View next topic |
Author |
Message |
HHoward
Joined: 29 Aug 2006 Posts: 9 Location: Silicon Valley, CA
|
Compiler reports an error but not enough information to... |
Posted: Wed Oct 04, 2006 1:15 pm |
|
|
Compiler reports an error. I have used #separate for all functions. Still, there is the error. I am guessing, it is because of an array or something. I have no clue which direction to work on. Please help. Thanks.
How to interpreter the following error message:
Error[71] C:\Development\OMC_Embedded\Main\Src\main.c 243 : Out of ROM, A segment or the program is too large @const246
Seg 000B4-03FFE, 3D34 left, need A018
0000
Seg 00000-00002, 0000 left, need A018
0000
Seg 00004-00006, 0004 left, need A018
0000
Seg 00008-000B2, 0000 left, need A018
0000
1 Errors, 0 Warnings. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Oct 04, 2006 1:24 pm |
|
|
One of your routines, most likely main(), is too large to fit into a page of memory. The memory is broken up into 'pages' like in a book. A routine needs to be able to fit into this page. If you have your entire code inside of main() then you may need to split part of it off and make it a routine. Then you can call that routine from main().
Ronald |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 04, 2006 1:28 pm |
|
|
Also, this segment size 'A018' is absolutely huge. I'm not even sure
if I could gin up a test program to do this. You must have, I suppose,
tons and tons of floating point operations, with trig functions, and
everything else thrown in. |
|
|
HHoward
Joined: 29 Aug 2006 Posts: 9 Location: Silicon Valley, CA
|
|
Posted: Wed Oct 04, 2006 1:39 pm |
|
|
Thanks for information.
Actually, I have 6 .c files and lots function calls in this project.
Almost all functions are applied with #separate.
I did some testing to comment out command interpreter, error will be gone. The total ROM usage without interpreter is:
ROM used: 3250 (20%)
3250 (20%) including unused fragments
I am not sure compiler reports correct information regarding to 'A018'. But it gives key words:
'@const246'
I am tiring to find what @const246 represented in my code.
Any thought?
Thanks.
Thanks.
PCM programmer wrote: | Also, this segment size 'A018' is absolutely huge. I'm not even sure
if I could gin up a test program to do this. You must have, I suppose,
tons and tons of floating point operations, with trig functions, and
everything else thrown in. |
|
|
|
HHoward
Joined: 29 Aug 2006 Posts: 9 Location: Silicon Valley, CA
|
Problem identified! |
Posted: Wed Oct 04, 2006 4:02 pm |
|
|
PCM programmer:
I have declared a global array with error messages predefined here.
The size is 100 (10 modules and each may have 10 error msgs) x 64 (letters). In error routine, if I am trying to index the array to get specific message, the error will be reported. The size of array is 6400 bytes.
If I use char, the array will be placed in ROM. the demo code will take up to 46% ROM with 10 lines of code. PIC has 16k ROM and 6400 BYTE is exactly 46% of it.
If I use const char, the array will be placed in RAM (768 byte only), compiler will report "Not enough RAM" which is true.
I temporally report error code instead of error message even I have to do so.
Thanks.
Here is an example code:
Code: |
#include <18F442.h>
#use delay(clock=80000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
//definition of name of SW module:
#define State_Mod_name "State Machine"
#define Network_Mod_Name "NetWork"
#define Cmd_Mod_Name "Command Interpreter"
#define DataBlock_Mod_Name "Data Block"
#define Diag_Mod_Name "Diagnotic"
#define Status_Mod_Name "Status"
#define Setup_Mod_Name "Setup"
#define Recipe_Mod_Name "Recipe"
#define CtlMon_Mod_Name "Control Monitor"
//const Char cErrMsgTbl[100][64] =
Char cErrMsgTbl[100][64] =
{ //network module
/*1*/ {"Recieve Buffer Overflow"},
/*2*/ {"Network Connection Timeout"},
/*3*/ {" "},
/*4*/ {" "},
/*6*/ {" "},
/*7*/ {" "},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
//Command module
/*1*/ {"System is busy"},
/*2*/ {"Wrong Command was received"},
/*3*/ {"Wrong Parameter was received"},
/*4*/ {" "},
/*6*/ {" "},
/*7*/ {" "},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
//Data block module
/*1*/ {"Recieve Buffer Overflow"},
/*2*/ {"Network Connection Timeout"},
/*3*/ {"Data Transimition Fail"},
/*4*/ {" "},
/*6*/ {" "},
/*7*/ {" "},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
//Diag module
/*1*/ {"System is busy"},
/*2*/ {"Communication lost"},
/*3*/ {"data is over limitation"},
/*4*/ {" "},
/*6*/ {" "},
/*7*/ {" "},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
//Status module
/*1*/ {"Recieve Buffer Overflow"},
/*2*/ {"Network Connection Timeout"},
/*3*/ {" "},
/*4*/ {" "},
/*6*/ {" "},
/*7*/ {" "},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
//Setup module
/*1*/ {"Flush Memory is full, new setup is not saved"},
/*2*/ {"Wrong setup. Parameter is over limitation"},
/*3*/ {" "},
/*4*/ {" "},
/*6*/ {" "},
/*7*/ {" "},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
//Recipe module
/*1*/ {"Flush Memory is full, new recipe is not saved"},
/*2*/ {"Wrong recipe. Parameter is over limitation"},
/*3*/ {" "},
/*4*/ {" "},
/*6*/ {" "},
/*7*/ {" "},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
//Control module
/*1*/ {"Flush Memory is full. No log saved"},
/*2*/ {"data is over limination"},
/*3*/ {"Temperature is over limitation"},
/*4*/ {"data Generator is failed"},
/*5*/ {"Air Pump is failed"},
/*6*/ {"PID control is over limitation"},
/*7*/ {"Date/Time is lost"},
/*8*/ {" "},
/*9*/ {" "},
/*10*/ {" "},
};
//const Char cModNameTbl[10][64] =
Char cModNameTbl[10][64] =
{
{Network_Mod_Name},
{Cmd_Mod_Name},
{DataBlock_Mod_Name},
{Diag_Mod_Name},
{Status_Mod_Name},
{Setup_Mod_Name},
{Recipe_Mod_Name},
{CtlMon_Mod_Name}
};
char gSendBuf[128];
#separate
void Error(int modError, int errMsg)
{
int errIndex = 0;
int errTableIndx = 0, length = 0;
char cmdOutBuf[128], theChar;
errTableIndx = modError * 10;
errIndex = errTableIndx + errMsg;
strcpy(cmdOutBuf, cModNameTbl[errTableIndx]),
sprintf(gSendBuf, "%s%s", cmdOutBuf, ";");
printf("%s", gSendBuf);
strcpy(cmdOutBuf, cErrMsgTbl[errIndex]),
sprintf(gSendBuf, "%s%s", cmdOutBuf, "\r");
printf("%s", gSendBuf);
}
void main ( )
{
error(0, 1);
}
|
|
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Oct 05, 2006 8:19 am |
|
|
Quote: | Char cErrMsgTbl[100][64] = |
That is one HUGE declaration and the PIC has no where near the space for it. I'm not sure if Microchip makes a PIC that can store that size internally. That's why your compiler is puking.
Ronald |
|
|
Ttelmah Guest
|
|
Posted: Thu Oct 05, 2006 8:53 am |
|
|
It is 'only' 6.4KB.
The 18F442, has got 16K of ROM, but it won't fit in the RAM (768 bytes).
It is a wasteful way to store the data.
It is perhaps typical of a 'PC programmer', trying to move code over into a microcontroller, and not realising that this declaration inherently 'wastes' well over half the size involved, with 64 characters of storage being used to store single spaces on several lines as shown...
The declaration is also even more wasteful, in that there are 80 lines as shown, but space declared for 100).
This is where you have to think for yourself, and use a bit of ingenuity.
Given the huge amount of wasted space, I'd suggest generating just the actual strings as a ROM declaration, with nulls between the strings. Leaving no gaps (except the nulls, and single spaces for the lines containing nothing). Then declaring a 80 element array of long integers, and on boot up, storing the address of the ROM declaration in the first element. Then scanning through the data, using the 'read_program_memory' function, and whenever a null is found, store the next address into the next element of the array. Then when you want to 'use' element 25 (for example), simply perform the same operation, taking the address from entry 25 in the array (number 24), and reading characters until you find the null. This way the array can stay in ROM, and will use only the number of total used characters, plus a single extra for each line. Less than 1000 characters ar shown...
Best Wishes |
|
|
HHoward
Joined: 29 Aug 2006 Posts: 9 Location: Silicon Valley, CA
|
|
Posted: Thu Oct 05, 2006 1:59 pm |
|
|
Thanks for information and suggestion.
Originally, the question is regarding to the error message from compiler. The key word gives a hint but not enough to find out what was wrong.
I got the answer and share it with everyone. It is not because the mistake in my code, it is about how to interpret the error message from compiler.
It would be better if one who likes to provide help and focus on the topic instead of making a personal comments. Remember the words, never say never. |
|
|
Ttelmah Guest
|
|
Posted: Thu Oct 05, 2006 2:38 pm |
|
|
What the error message means has already been answered. Memory on the PIC's is segmented, and you are trying to create in just the example you give, a declaration, that will not fit in any page of the ROM, and has even less chance of fitting in the RAM.
Your code, _is_ fundamentally faulty, in the approach used, for a small embedded architecture chip.
Best Wishes |
|
|
HHoward
Joined: 29 Aug 2006 Posts: 9 Location: Silicon Valley, CA
|
|
Posted: Thu Oct 05, 2006 3:10 pm |
|
|
Ttelmah,
Since you insist into this kind of style, I have to answer you one more time.
1. "What the error message means has already been answered."
That is not you or you are not first one to interpret the error message in right way. All the replies suggested to check the length of main not variables been used.
2. To start a project from nothing, it is important to reserve and architect the infrastructure first. This is fundamentally correct and has been used on almost all of "rapid" sw development. In terms of which way could save more memory space with small PIC chip, your suggestion is NOT the best for following reasons:
(1). Add/remove/edit error message become difficult.
(2). Memory space is saved but the problem is not fixed. Eventfully, more space will be used.
(3). Maintainability and readability is low - more like a homework from a freshman at college.
(4). To answer a compiler question related with a error message, and expend the topic to "architecture", "fundamental", "PC Programmer". Your show off has wasted lots time of readers.
I wish you have had a chance to pick up more this kind of lessons from school. I must stop at here.
Take care. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Thu Oct 05, 2006 3:47 pm |
|
|
Whoa HHoward!!
You just made a BIG mistake "picking a fight" with the wrong folks here... If that's how you feel maybe you should go to another board where you don't consider folks idiots or simpletons and all the members think on your higher plane of knowledge.
The large portion of help provided on this board is from TTelmah and PCM and they are highly regarded here (except by you apparently). I would strongly suggest you reconsider your approach. What he/they said was correct and an attempt to be helpful, instead of taking it constructively, you attacked. Bad move!! |
|
|
CCS PIC Guest
|
CCS Forum Policy and Guidelines |
Posted: Thu Oct 05, 2006 6:36 pm |
|
|
...
6. Stay on topic
This forum's sole purpose is to help people with programming Microchip's in CCS PIC C. Also, generally any discussion about Microchip's, firmware designing and electronic components in embedded systems is considered on topic.
7. No vulgarity
Please keep the conversation civil and respectful.
... |
|
|
bsodmike
Joined: 05 Aug 2006 Posts: 52
|
|
Posted: Fri Oct 06, 2006 12:28 am |
|
|
Thanks for the long explanation Ttelmah, quite useful
Over the past couple weeks, I find my self browsing through random posts and practically 99% are answered by your's truly and PCM - lots of insightful info and knowledge by these guys it's great, and I think we should appreciate their help more!
That said I've noticed quite a few people wanting their hands held through the process of getting the code to work, but I like PCMs approach of nudging people in the right way giving them 'just enough' to get it sorted but without *really* solving it for you (well that's not true, he gives you what you need, or what needs to be done, but the coding has to be done by yourself!), which is a good exercise...
Cheers,
Mike |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 06, 2006 2:42 am |
|
|
There is one little 'confusion', which has led to HHoward's thinking about this, and is worth saying, possibly to clear things up.
The PIC, unlike 'mainstream' processors, has a Harvard architecture. As such permanent storage (programs and constants), sit in one block of memory, and then the variables sit elsewhere. Now the 'problem', is that one (or more) of the blocks needed in the 'program' memory, is much too large, hence the comments to look at the program size.
What is not so 'obvious', is that variable initialisations, are _part_ of your program. There is not a magic solution, where values appear in the RAM from nowhere. The following declarations are almost identical:
Code: |
int8 fred=10;
and
int8 fred;
fred=10;
|
The key is that in the latter case, it is 'obvious', that loading the '10', is part of the program, but in the former, the same code is being generated, as part of the variable declaration. The only difference, is that in the former case the initialisation code gets put into the 'wakeup' code for the system, and in the latter, it is inside the particular function call. This in fact, makes things worse, in regard to the 'segment too large' problem!.
The reason is this. If you declare:
Code: |
int8 fred[10]={1,2,3,4,5,6,7,8,9,10};
and then in another subroutine,
int8 dick[10]={1,2,3,4,5,6,7,8,9,10};
|
The initilalisations of _both_, are done in the single 'wakeup' routine at the start of 'main'.
Effectively, the sizes of all the initialisations, have to be added together, and are added to the size of main.
Now the reason we all got a little 'amused', was primarily the idea that you could have a 100*64 array in the processor!. Ignoring this though, the 'point' is that ignoring the limits of RAM, if you initialise an array, then the code to do this all gets added to the size of main. That initialisations generate code, is 'obvious' to anyone who has worked with processors at a lower level than this, but has not been pointed out (recently) here, and hence the poster could not 'see' this connection.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|