|
|
View previous topic :: View next topic |
Author |
Message |
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
Out of ROM, A segment or the program is too large: main |
Posted: Thu Sep 07, 2006 1:14 pm |
|
|
When I add the function call - WriteEeprom(preset1, 1); - to my program I get the following compiler message:
"Out of ROM, A segment or the program is too large main"
But without it I have plenty of ROM.
The first list shows the results with the function remarked out of the program. The second list shows the results with the function call inserted.
Does anyone know what would cause this to happen?
P.S. I have removed a lot of the code for ease of posting. If anyone needs to see the whole program please let me know.
Thanks!
List 1:
Result of compile with - WriteEeprom(preset1, 1); - Remarked out
CCS PCB C Compiler, Version 3.249, 34349 07-Sep-06 13:29
Filename: C:\A_TEST\TCP91.lst
ROM used: 1150 words (56%)
Largest free fragment is 512
RAM used: 37 (51%) at main() level
42 (58%) worst case
Stack: 1 locations
Lsit 2:
Results of compile with - WriteEeprom(preset1, 1); - inserted
Building TCP91.HEX...
Compiling TCP91.C:
Command line: "C:\PROGRA~1\PICC\CCSC.EXE +FB +T C:\A_TEST\TCP91.C"
Error[71] C:\A_TEST\TCP91.C 642 : Out of ROM, A segment or the program is too large main
Seg 00200-003FF, 0118 left, need 0242
0000
Seg 00400-005FF, 0200 left, need 0242
0000
Seg 00600-007FF, 0200 left, need 0242
0000
Seg 00000-001FF, 001D left, need 0242
0000
1 Errors, 0 Warnings.
MPLAB is unable to find output file "TCP91.HEX". This may be due to a compile, assemble, or link process failure.
Build failed.
Here is the code:
Code: |
#include <16C57.h>
#device *=8
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=40000000)
#use I2C(master, SDA=PIN_B7, SCL=PIN_B6)
#define EEPROM_SDA PIN_B7
#define EEPROM_SCL PIN_B6
. .
. .
. .
. . (Rest of program is here - deleted to reduce posting size)
. .
. .
void main()
{
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++ Inititalization everything +++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
while (1==1)
{
SETUP_TIMER_0(RTCC_DIV_8|RTCC_INTERNAL);
output_float(PB1);
output_float(PB2);
output_float(PB3);
preset1 = 0;
digit_select = 0x00;
set_tris_a(0b1111);
set_tris_b(0b00000000);
set_tris_c(0b10000000);
temp = 122;
PB_Test_New = 0;
PB_Test_Old = 0;
PB_Deb = 0;
debounce = 0;
PB1_Pressed = False;
while (digit_select < 6)
{
/*
if (led_value < 32)
{
Delay_Cycles(1);
led_value = led_value<<2;
}
else
{
Delay_Cycles(1);
led_value = 1;
}
output_toggle(PIN_B5);
if (debounce == 100)
{
debounce = 0;
}
*/
GetDigits(preset1, msd_code, lsd2_code, lsd1_code, lsd_code);
display_update();
switch(digit_select)
{
case 0:
output_c(0x00);
output_b(0b00000001);
output_c(lsd_value);
break;
case 1:
output_c(0x00);
output_b(0b00000010);
output_c(lsd1_value);
break;
case 2:
output_c(0x00);
output_b(0b00000100);
output_c(lsd2_value);
break;
case 3:
output_c(0x00);
if (msd_value == 10)
{
output_b(0b00000000);
}
else
{
output_b(0b00001000);
output_c(msd_value);
}
break;
case 4:
output_c(0x00);
output_b(0b00010000);
output_c(led_value);
}
if (digit_select < 4)
{
digit_select++;
}
else
{
digit_select = 0;
}
if (CheckButtons() == true)
{
delay_cycles(1);
switch(Buttons)
{
case 1:
delay_cycles(1);
preset1 = 1;
break;
case 2:
delay_cycles(1);
preset1 = 2;
break;
case 3:
delay_cycles(1);
preset1 = 3;
break;
case 4:
delay_cycles(1);
preset1 = 4;
break;
case 5:
delay_cycles(1);
preset1 = 5;
}
delay_cycles(1);
// WriteEeprom(preset1, 1);
delay_cycles(1);
preset1 = 100;
delay_cycles(1);
ReadEeprom(preset1, 1);
delay_cycles(1);
}
if (CheckButtons() == false)
{
delay_cycles(1);
delay_cycles(1);
}
#asm
loop1:
movf rtcc,w
subwf temp,w
btfss status,z
goto loop1
clrf rtcc
#endasm
debounce++;
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 07, 2006 2:42 pm |
|
|
In CCS, a function must fit into a single ROM page. This includes the
main() function. The 16C57 has fairly small ROM pages -- only 512
words (0x200) per page. The compiler reports that your main() function
uses 0x242 words. So it's too big, by 0x42 words. To fix this, you
need to break up the code in main() into two or more functions.
Look at the code in main() and pick a suitable section of code that can
be turned into a function. Then call it from main(). |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Thu Sep 07, 2006 3:08 pm |
|
|
Hello PCM Programmer,
You are here to bail me out again I see.
I understand what you are saying but my question is how can adding one function call send it over the 512 word limit when the compilation without this call shows I have the largest free fragment of 512 available?
I guess I need a quick primer on memory allocation :-)
Quote: |
ROM used: 1150 words (56%)
Largest free fragment is 512
|
Also I used the #separate before all of my functions and it compiled with the following results.
ROM used: 1354 words (66%)
Largest free fragment is 512
RAM used: 37 (51%) at main() level
43 (60%) worst case
Stack: 2 locations
Thanks for looking |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 07, 2006 4:07 pm |
|
|
Your main() function was probably close to the 512-word ROM page
limit. Based on the error messages you posted, it looks like the
compiler tried to place the WriteEeprom() function inline and this
caused main() to expand to 0x242 ROM words.
The 16C57 only has two stack levels. The compiler probably used up
those two levels on other functions that you call more than once, such
as CheckButtons(). Normally, if the compiler doesn't have enough
stack levels, it will do a pseudo "call" by jumping to the function and
returning from it with GOTO statements (in ASM code). I don't know
why it didn't automatically do this in your case. But by using #separate
you have told it to do that.
However, make sure that you watch the stack level usage reported
at the top of your .LST file. When you use #separate, the compiler
won't automatically limit the hardware stack usage to the number
given in the data sheet. It can exceed the levels, and thus cause
the program to crash. At least, this is true for the PCM compiler.
I have very little experience with the PCB compiler. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Sep 07, 2006 4:17 pm |
|
|
Your program is only using 56% of your _Total_ memory. Adding one more thing, whether it's a function call or an input() command or something else, that one statement can cause your code to over run the boundery limits. Like PCM said, take a portion of your main() code and make a function out of it. I've had to do this same thing several times when I've run out of space in main().
Ronald |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Sep 08, 2006 10:25 pm |
|
|
Writeeeprom() is always coded inline. PCM gave you the correct answer but if you use writeeeprom() frequently in a program then it might pay to wrap the function inside another function. |
|
|
anjlena1
Joined: 23 May 2013 Posts: 1
|
|
Posted: Thu May 23, 2013 12:33 am |
|
|
Hola a todos. Lo que no termino de entender es si es muy largo el programa en cantidad de lineas o si se refiere
al contenido del main, o de una funcion especifica ??
El mensaje que me aparece es
Out of ROM, a segment or the program is too large funcion_1
y si veo el contenido de funcion_1 son dos lineas dentro de una interrupcion, no creo que sea ese el problema
ya que me sale ese error cuando coloco en el main la llamada a otra funcion función, si la dejo comentada funciona
todo bien, es mas, solo usa un 41% de la ROM, es como que es medio raro porque no modifico nada en funcion_1..
Agradeceria que alguien explique bien el objetivo de este mensaje, a que hace referencia,
Saludos y gracias por la colaboracion
Last edited by anjlena1 on Sat May 25, 2013 2:40 am; edited 1 time in total |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu May 23, 2013 8:40 am |
|
|
Este es un foro de habla Inglés. Utilice Inglés al introducir comentarios.
This is an English speaking forum. Please use english when entering comments.
One thing that causes Out of Rom errors is if you have too much code in one function, including main(). The PIC's memory space is like a book. You have several pages in the book but your code(function) has to fit on each page and cannot carry over to the next page. Even though your compiler says you are only using 41% of the available ROM the code that's in your Main() is too large. Try breaking your program into smaller functions that can be called individually and have the same effect.
Ronald |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu May 23, 2013 3:09 pm |
|
|
not that this is causing your 'too big' problem but...
#use delay(clock=40000000)
appears to be 40 MHZ !
Is this right?
I'm thinking that PICs good for 4 MHz...
hth
jay |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu May 23, 2013 3:22 pm |
|
|
heck of a lot of attention for a
7 year old thread......
lord help anybody designing in a 16c57 in 2013
especially when an 16f883 has more prog ram AND eeprom INSIDE
and cost 1/4 the $$ !!!!
|
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Fri May 24, 2013 12:19 pm |
|
|
True, this is a VERY old thread but the person that replied to it is in need of help today. That's why I replied to his post.
Doesn't matter how old we are/look/smell, we all need a little help now and then.
Ronald |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri May 24, 2013 1:22 pm |
|
|
Quote: |
Try breaking your program into smaller functions that can be called individually
|
this implies having BOTH enough memory pages and a
STACK that enables potential nesting of called functions.
BUT- no matter how much you break down a tangle of code
on a single 16cxxx memory page, which may be structurally
divided into unwieldy blocks - like the original poster - way back when -
( did not comprehend) - trying to break down a complex nest of code in main() can be pretty badly impaired with a part like the 16c57
since you still have only a 2 level STACK to handle those calls.
if you are starting at 40% plus code usage - the implications
for satisfying the one pass CCS approach with a measly 2 level stack -
"stack" the deck against getting the traction that is hoped
for by breaking up the main() in the first place .
newer parts address this sort of problem from both higher prog memory page counts AND stack depth.
Updating the choice of PIC, is both an economic and code space victory win-win of the purest sort.
just my 2 cents |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Fri May 24, 2013 2:30 pm |
|
|
Not totally.
If you have subroutines, that are not 'called' more than once, then the compiler can still split them into multiple pages, and use jumps, rather than calls. So splitting can still work.
Best Wishes |
|
|
io_Joe
Joined: 20 Nov 2013 Posts: 5
|
|
Posted: Wed Nov 20, 2013 12:07 pm |
|
|
I am getting a similar error:
Quote: |
*** Error 71 "main.c" Line 302(1,2): Out of ROM, A segment or the program is too large main
Seg 00036-007FF, 0214 left, need 0088C
Seg 00800-00FFF,
Seg 00004-00035, 0000 left, need 0088C 0800 left, need 0088C
Seg 01000-017FF, 0800 left, need 0088C
Seg 01800-01FFF, 0800 left, need 0088C
Seg 00000-00003, 0000 left, need 0088C |
Any ideas?
My main is relatively small..
Code: | void main(void)
{
initializePIC(); // default settings (initial register states)
restart_wdt(); // initialization complete, reset watchdog
delay_ms(5000); // Start up delay: battery voltage stability
restart_wdt();
start_up(); // Tool status checks / variable settings
delay_ms(1000);
while(1)
{
ready_sleep(); // Sets external interrupt, other misc. settings
sleep(); // Wake on external change interrupt B0
//WATCH_DOG_ENABLED(); // WDT enabled after wake up
battery_monitor(SLEEP_AH);
wireless_tx(1,5); // Wake up response.
do // Receive / execute commands until 3 consecutive timeouts are reached.
{
wireless_rx();
}while(wireless_timeout < 3);
battery_monitor(COMMUNICATION_AH);
}
} |
|
|
|
io_Joe
Joined: 20 Nov 2013 Posts: 5
|
|
Posted: Wed Nov 20, 2013 12:19 pm |
|
|
Appears my do while loop is eating my ROM.
When you say split up your main(), does it matter if its in the same .c file or does it need to be a separate .c ?
Adding #separate prior to main() seems to compile, but not sure if I'm overloading the stack <yet>.
Last edited by io_Joe on Wed Nov 20, 2013 1:44 pm; edited 1 time in total |
|
|
|
|
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
|