CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

out of rom

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

out of rom
PostPosted: Mon Nov 14, 2005 3:19 pm     Reply with quote

Using a pic16f877a with PCm 3.225

I can compile my code and the compiler says I'm using 54% ROM. Adding a line of code gives me an
"OUT of ROM, a segment or the program is too large"
error.
I'm assuming it is the segment it is talking about. How do I know how big a "segment" is and how would I fix the error?
the .lst file says largest free fragment = 2048
Is it because a function is too long?
Any thoughts?
Thanks
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 14, 2005 3:25 pm     Reply with quote

Quote:

The compiler says I'm using 54% ROM.
Adding a line of code gives me an "OUT of ROM, a segment or the
program is too large" error. Is it because a function is too long?


You probably have a function that's larger than 2KB. This can easily
happen if you're using floating point. I suggest that you break up the
function into two or more smaller functions.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Nov 14, 2005 3:35 pm     Reply with quote

Ok, that seems to work. How can I tell how big a function is though? Is there an easy way?
Thanks
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 14, 2005 4:33 pm     Reply with quote

Supposedly the command line compilers will generate a Statistics file
(.STA) if you specify the +A option. I've never been able to make this
work. I think it's really a PCW or PCWH option only.

You can study the .TRE file, but I've never liked that file. It just seems
like a mess.


If anybody has been able to make a .STA file with the command line
compilers, then please post how to do it.
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Mon Nov 14, 2005 5:23 pm     Reply with quote

This is what I use on pch 3.239 [[ But i have pcwh(the whole shebang)]]
ccsc +FH +T +A +DF +P4 "%f"
%f is repaced with the c file name test.c
top part of *.sta file

Code:

ROM used: 22104 (67%)
          22104 (67%) including unused fragments

          4 Average locations per line
          12 Average locations per statement

RAM used: 1000 (65%) at main() level
          1274 (83%) worst case

Is using this in command line mode different then the single command line compiler?
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Tue Nov 15, 2005 3:52 pm     Reply with quote

PCM programmer wrote:
Quote:

The compiler says I'm using 54% ROM.
Adding a line of code gives me an "OUT of ROM, a segment or the
program is too large" error. Is it because a function is too long?


You probably have a function that's larger than 2KB. This can easily
happen if you're using floating point. I suggest that you break up the
function into two or more smaller functions.


I'm still having issues. I had a pretty long function that parses the stream from the serial port. I have replaced lots of code with functions now but my problem remains the same. Even though I have taken out probably 200 lines of code out of this function if I try to add any code to it then I get the out of Rom error. Before trying to add code I'm at 52% rom used.

Here is the function I'm working on:

void Process_Commands()
{
int dir;
int pinn;
int state;
int channel;
int servo_value;
long int ADC_Return_Value;
int i;
int data1,data2,data3;
int TEMP_STRING[SERIAL_BUFFER_SIZE];
int SRF08_STRING[SERIAL_BUFFER_SIZE];
int BLINK_STRING[SERIAL_BUFFER_SIZE];
int TEMP_STRING3[SERIAL_BUFFER_SIZE];
int TEMP_STRING4[SERIAL_BUFFER_SIZE];
int TEMP_STRING5[SERIAL_BUFFER_SIZE];

Int iresult;

/////////////////////////////////////////////////////////////////////////////////
*TEMP_STRING=STRLWR(SERIAL_BUFFER);
// STRLWR(SERIAL_BUFFER);
// strcpy(SRF08_string,"srf08");
// strcpy(BLINK_string,"blink");

// if(strncmp (temp_string, serial_buffer, 5))

// printf("comparing %s and %s\r\n",temp_string,serial_buffer);
if((SERIAL_BUFFER[0]=='s') &&
(SERIAL_BUFFER[1]=='r') &&
(SERIAL_BUFFER[2]=='f') &&
(SERIAL_BUFFER[3]=='0') &&
(SERIAL_BUFFER[4]=='8'))

{
read_srf08();
}

/*
else if((SERIAL_BUFFER[0]=='c') &&
(SERIAL_BUFFER[1]=='m') &&
(SERIAL_BUFFER[2]=='p') &&
(SERIAL_BUFFER[2]=='s') &&
(SERIAL_BUFFER[3]=='0') &&
(SERIAL_BUFFER[4]=='3'))
{
read_cmps03();
}
*/
else if((SERIAL_BUFFER[0]=='m') && //m or M
(SERIAL_BUFFER[1]=='o') &&//f or O
(SERIAL_BUFFER[2]=='g') && //g or G
(SERIAL_BUFFER[3]=='o') && //o or O
(SERIAL_BUFFER[4]==' ') &&
((SERIAL_BUFFER[5]=='0') ||(SERIAL_BUFFER[5]=='1') || (SERIAL_BUFFER[5]=='2')) &&
(SERIAL_BUFFER[6]==' '))

{
MOGO();
Return;
}



/*
// else if(!strncmp(BLINK_string, serial_buffer, 5))

else if((SERIAL_BUFFER[0]=='b') && //b or B
(SERIAL_BUFFER[1]=='l') &&//l or L
(SERIAL_BUFFER[2]=='i') && //i or I
(SERIAL_BUFFER[3]=='n') && //N or n
(SERIAL_BUFFER[4]=='k')) //K or k

{
printf("\r\n");
for(i=0;i<5;i++)
putc(serial_buffer[i]);
printf("\r\n");
printf("ACK");
BlinkLeds ();

Return;
}
*/
/////////////////////////////////////////////////////////////////////////////////
else if((SERIAL_BUFFER[0]=='g') &&
(SERIAL_BUFFER[1]=='p') &&//P
(SERIAL_BUFFER[2]=='i') && //I
(SERIAL_BUFFER[3]=='o')) //O
{

pinn=SERIAL_BUFFER[5]-0x30;

state=SERIAL_BUFFER[7]-0x30;
if(serial_buffer[6]=='\r')
state=2;
GPIO(pinn,state);


}//end if gpio

else if((SERIAL_BUFFER[0]=='s') &&
(SERIAL_BUFFER[1]=='e') &&
(SERIAL_BUFFER[2]=='n') &&
(SERIAL_BUFFER[3]=='s') &&
(SERIAL_BUFFER[4]=='o') &&
(SERIAL_BUFFER[5]=='r'))
{
channel=SERIAL_BUFFER[7]-0x30;
set_adc_channel( channel );
delay_ms(1);
ADC_Return_Value = Read_ADC();
printf("%ld",ADC_Return_Value);
Return;

}

else if((SERIAL_BUFFER[0]=='s') &&
(SERIAL_BUFFER[1]=='e') &&
(SERIAL_BUFFER[2]=='r') &&
(SERIAL_BUFFER[3]=='v') &&
(SERIAL_BUFFER[4]=='o') &&
(SERIAL_BUFFER[5]==' ') &&
((SERIAL_BUFFER[6]=='0') ||(SERIAL_BUFFER[6]=='1') || (SERIAL_BUFFER[6]=='2')) &&
(SERIAL_BUFFER[7]==' '))

{
set_servo();

}
else
printf("NACK");
Return;

}




If I try to uncomment anything I get the error, even though things like "set_servo()" used to have the code in this function. Moving the code out of the function did not help. Am I missing something here? any ideas?
Thanks
Ringo
_________________
Ringo Davis
teletype-guy



Joined: 11 Oct 2005
Posts: 8
Location: AZ

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 15, 2005 4:14 pm     Reply with quote

Hi Ringo:

When you uncomment lines, you are also adding the library function code (eg: strcmp) unless you have called it elsewhere. So you are adding much more code than just the call-and-pass-params stuff.

You are doing some rather large if comparisons. I parse serial strings a different way: the main loop constantly calls a parse function, which checks for a serial char (if no char avail it just exits, and the main loop continues). If a char is available, I drop into a switch statement based on a variable "rx_state" -- rx_state starts out as "IDLE," and in this switch case I check for the first char of the desired string. If I find the desired char, I update the rx_state (eg: GOT_1ST_CHAR) and exit. The next time through, if another char is available, it drops to the next state case to check for the second desired char. Yada, yada, so on and so forth.

In my code, I'm looking for a specific header string, and then grabbing comma-delimited ascii-encoded-decimal numbers, until I hit a CR or LF to terminate the command -- at this point the rx_state goes back to the IDLE state, waiting for the next command. If any error occurs during command parsing (bogus chars, etc), you can flag the error and return to IDLE state.

It's all pretty fast and compact, and can be extended to multiple strings. Just a thought.

gil
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 15, 2005 4:29 pm     Reply with quote

You probably could fix the problem by putting #separate on all the
routines that are called by Process_Commands(), but I dislike doing that.
That's because the compiler will no longer automatically limit the stack
usage to the hardware limit of the PIC. For 16F PICs, this is only 8.
You have to check the .LST file, each time after you compile.

Here's another option:
Break up your Process_Commands() function into two pieces.
The first one could be called "Parse_Commands()". It would look
at the incoming command string and decide which one it is, and return
a number indicating which command was received. A 2nd function,
"Do_Command()" would perform the command. Example:


cmd_code = Parse_Commands();

Do_Command(cmd_code);


void Do_Command(int8 cmd)
{
if(cmd == 0) // Null command ?
return;

if(cmd > MAX_CMD_CODE)
return;

switch(cmd)
{
case CMD_RD_SRF:
read_srf08();
break;

case CMD_RD_CMPS03:
read_cmps03();
break;

default:
}

}

I don't guarantee this will fix the problem, but it might work.
Also it's possible that using "if-else if" might work better than
switch-case.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Tue Nov 15, 2005 4:29 pm     Reply with quote

In my #int_rda function I grab all the bytes until I get a CR, then I call the function I listed before. I was trying to get the strcmp in there to get it working so I could replace all those letter by letter comparisons with 1 strcmp and hope it is smaller that way. I still have several commands I would to add. I guess I could just check the first letter then call another function (based on that letter) to check the rest.

But I guess the question still remains, is there a way to tell how big a function is without adding stuff to it until it will not compile?

Thanks
RIngo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 15, 2005 5:05 pm     Reply with quote

I just emailed CCS and asked them to enable the Statistics file option
for the command line compilers. If they reply, I'll post the answer to
this thread.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 12:01 am     Reply with quote

PCM programmer wrote:
You probably could fix the problem by putting #separate on all the
routines that are called by Process_Commands(), but I dislike doing that.
That's because the compiler will no longer automatically limit the stack
usage to the hardware limit of the PIC. For 16F PICs, this is only 8.
You have to check the .LST file, each time after you compile.



I really reduced the function to almost nothing:

void Process_Commands()
{
read_cmps03();
GPIO();
MOGO();
set_sensor();
set_servo();
//read_srf08();
Return;
}

but I guess it is still trying to compile everything inline so I still get the out of rom error if I uncomment the last function (or any 1 of the functions).

I was able to get rid of the error by using the #separate in front of some of the functions called above. You said I need to check the .lst file after I compile can you describe what I need to be looking for? I saw in the help file that this could cause stack overflow, but what am I looking for to see if this could happen? I assume that the fewer functions I #separate the better?
Thanks
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 12:53 am     Reply with quote

Quote:
You said I need to check the .lst file after I compile.
Can you describe what I need to be looking for ?

Look at my post at the end of the following thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=20422
In that post, you'll see the top portion of the .LST file for the program.
Notice that the number of stack locations = 9. That's the part
you have to watch. The number of locations used must be no
more than 8 for the 16F-series PICs. If it's greater than 8, you
need to remove the #separate directive from one or more functions
until the problem is corrected.

You should also put a very prominent comment at the start of your
main source file to remind yourself to do this, in case you ever
have to modify the program in the future.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 8:32 am     Reply with quote

Thank you very much for the help. I'll definitely put the comment you suggested in the code.
Thanks again
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 17, 2005 3:31 pm     Reply with quote

Quote:

I just emailed CCS and asked them to enable the Statistics file option
for the command line compilers. If they reply, I'll post the answer to
this thread.

CCS says the "+A" option only works if you have PCW (or PCWH).
So, you can't make the statistics file for the command line compilers.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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