| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| edbfmi1 
 
 
 Joined: 18 Jul 2006
 Posts: 110
 
 
 
			    
 
 | 
			
				| 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: 110
 
 
 
			    
 
 | 
			
				|  |  
				|  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: 9589
 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  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
 
 |