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

Error 71 Out of ROM problem

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



Joined: 12 Jun 2007
Posts: 68
Location: Poland, podlaskie district

View user's profile Send private message

Error 71 Out of ROM problem
PostPosted: Tue Oct 11, 2016 3:41 am     Reply with quote

Hello,

I am developing some code. Before small part of code is like below:
Code:

               switch (equaliser_menu_list[equaliser_submenu])
               {
                  #ifdef _USE_ACTIVE_ANTENA_
                  case EQUALISER_MENU_ACTIVE_ANTENA:
                       #ifdef _USE_LOGPORT_
                       disable_interrupts(GLOBAL);
                       fprintf(LOG_PORT,"DOWN AA ");
                       enable_interrupts(GLOBAL);
                       delay_ms(500);
                  #endif
                       break;
                  #endif
                  case EQUALISER_MENU_Treble:
                       #ifdef _USE_LOGPORT_
                           disable_interrupts(GLOBAL);                 
                           fprintf(LOG_PORT,"DOWN Treble ");
                            enable_interrupts(GLOBAL);
                       delay_ms(500);
                  #endif
                       break;
                  case EQUALISER_MENU_Middle:
                       #ifdef _USE_LOGPORT_
                           disable_interrupts(GLOBAL);
                           fprintf(LOG_PORT,"DOWN Middle ");
                           enable_interrupts(GLOBAL);
                           delay_ms(500);
                       #endif
                       break;
                  case EQUALISER_MENU_Bass:
                       #ifdef _USE_LOGPORT_
                           disable_interrupts(GLOBAL);
                           fprintf(LOG_PORT,"DOWN Bass ");
                           enable_interrupts(GLOBAL);
                           delay_ms(500);
                       #endif
                       break;
                  case EQUALISER_MENU_Low_HighBoost:
                       #ifdef _USE_LOGPORT_
                           disable_interrupts(GLOBAL);
                           fprintf(LOG_PORT,"DOWN L_H_Boost ");
                           enable_interrupts(GLOBAL);
                           delay_ms(500);
                       #endif
                       break;                                                                                 
                  case EQUALISER_MENU_Left_Right:
                       #ifdef _USE_LOGPORT_
                           disable_interrupts(GLOBAL);
                           fprintf(LOG_PORT,"DOWN Left_Right ");
                           enable_interrupts(GLOBAL);
                           delay_ms(500);
                       #endif
                       break;   
                  case EQUALISER_MENU_Front_Rear:
                       #ifdef _USE_LOGPORT_
                           disable_interrupts(GLOBAL);
                           fprintf(LOG_PORT,"DOWN Front_Rear ");
                           enable_interrupts(GLOBAL);
                           delay_ms(500);
                       #endif
                       break; 
                  case EQUALISER_MENU_ERROR:
                       #ifdef _USE_LOGPORT_
                           disable_interrupts(GLOBAL);
                           fprintf(LOG_PORT,"DOWN EQ !supported ");
                           enable_interrupts(GLOBAL);
                           delay_ms(500);
                       #endif
                       break;                       
               }

The compiler shows to me 39% ROM and 14% RAM of PIC16F877.

The code above "weight" circle about 3% of ROM (check it when cancel some previous code and make compilation).

When I compile program in total CCS return some errors. As I understand the problem is that segment is too large. How to solve that problem ?

The code is mostly if and switch in if/switch.
Code:

*** Error 71 "main.c" Line 1180(1,2): Out of ROM, A segment or the program is too large    MAIN
  Seg 00058-007FF, 02A5 left, need 00760
  Seg 00800-00FFF, 0800 left, need 008A0
  Seg 01000-017FF, 0800 left, need 008A0
  Seg 01800-01FFF, 0800 left, need 008A0
  Seg 00000-00003, 0000 left, need 008A0 Reserved
  Seg 00004-00057, 0000 left, need 008A0 Reserved
  Seg 00058-007FF, 02A5 left, need 008A0

      1 Errors,  0 Warnings.
Build Failed.


How to solve it?
jeremiah



Joined: 20 Jul 2010
Posts: 1328

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 6:21 am     Reply with quote

You most likely have a function that is too large to fit into a page of memory. Break up your bigger functions into smaller ones.
silelis



Joined: 12 Jun 2007
Posts: 68
Location: Poland, podlaskie district

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 6:52 am     Reply with quote

How to recognize which function.

Wkat does this data exactly means:
Code:
  Seg 00058-007FF, 02A5 left, need 00760
  Seg 00800-00FFF, 0800 left, need 008A0
  Seg 01000-017FF, 0800 left, need 008A0
  Seg 01800-01FFF, 0800 left, need 008A0
  Seg 00000-00003, 0000 left, need 008A0 Reserved
  Seg 00004-00057, 0000 left, need 008A0 Reserved
  Seg 00058-007FF, 02A5 left, need 008A0


Is this function in code position or something?
jeremiah



Joined: 20 Jul 2010
Posts: 1328

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 8:19 am     Reply with quote

Try disabling your logging and see if that lets it compile. If so, it is one of the functions with your logging. My gut tells me it is the one with the case statements, but I don't know what other code you have.
temtronic



Joined: 01 Jul 2010
Posts: 9169
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 8:45 am     Reply with quote

this....
Seg 00058-007FF, 02A5 left, need 00760

means
your program needs 760 memory locations but the segment from 0058 to 7ff only has 2A5 spaces left, so the compiler can't put 760 where only 2A5 are.

The same is true for the other 'segments' of memory.

You need to 'breakup' or 'reorganise' some of your code to make it fit. Sometimes putting your 'functions' in a different order will help depending on how smart the compiler version you have. other times taking a 'large' function and breaking it into 2 or more 'sub functions' will allow the program to compile.

It's just the way the 877 was designed 20+ years ago, memory is in 'banks' or 'segments'. Today, the 'new' PICS have huge, contiguous memory,so 'creative coding' isn't required.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19358

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 9:20 am     Reply with quote

I'm guessing he is using the USB PIC16 he is talking about in another thread?.
If so the physical page size is 0x800 (0 to 7FF). He has one code routine wanting 0x8A0, so this is never going to fit. The 0x760 one, is presumably interrupt handling, or his main, which the compiler needs to put in the bottom page. The USB code already nearly fills the bottom page on these chips, so it is vital when adding your own code to the demo, to put this as subroutines that can then be moved into later pages.
This is the problem of the PIC16 architecture versus the PIC18. Though there are limitations on the PIC18 for some things, for most code these chips are 'pageless'.
A search here will find dozens of threads about this error, and a read of some will explain what has to be done. Jeremiah's comment is basically a summary of what has to happen.
You need to think in term of structuring the code in little pieces, not as monolithic lumps.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 5:40 pm     Reply with quote

Also, your code is not written in the most efficient way. I was able to
reduce the ROM usage for the following test program from initially 411
words down to 317 words.

First, I noticed you are disabling/enabling ints when you do an fprintf. So
you're probably using a software UART. But you can disable ints during
transmission by adding DISABLE_INTS to the #use rs232() statement as
shown in bold below. That allows you to remove all the disable/enable ints
in the routine.

Then, I notice you do delay_ms(500) in every section. Well, why not
get rid of all those individual delays and just put one line at the end ?

I did these changes and saved 94 bytes. Go through your whole
program and re-write it for code efficiency.
Quote:
#include <16F1455.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C0, stream=LOG_PORT, DISABLE_INTS)

#define _USE_LOGPORT_ TRUE

void print_log(int8 c)
{
switch(c)
{
case 1:
#ifdef _USE_LOGPORT_
//disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN AA ");
//enable_interrupts(GLOBAL);
//delay_ms(500);
#endif
break;

case 2:
#ifdef _USE_LOGPORT_
// disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN Treble ");
// enable_interrupts(GLOBAL);
// delay_ms(500);
#endif
break;

case 3:
#ifdef _USE_LOGPORT_
// disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN Middle ");
// enable_interrupts(GLOBAL);
// delay_ms(500);
#endif
break;

case 4:
#ifdef _USE_LOGPORT_
// disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN Bass ");
// enable_interrupts(GLOBAL);
// delay_ms(500);
#endif
break;

case 5:
#ifdef _USE_LOGPORT_
// disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN L_H_Boost ");
// enable_interrupts(GLOBAL);
// delay_ms(500);
#endif
break;

case 6:
#ifdef _USE_LOGPORT_
// disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN Left_Right ");
// enable_interrupts(GLOBAL);
// delay_ms(500);
#endif
break;

case 7:
#ifdef _USE_LOGPORT_
// disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN Front_Rear ");
// enable_interrupts(GLOBAL);
// delay_ms(500);
#endif
break;

case 8:
#ifdef _USE_LOGPORT_
// disable_interrupts(GLOBAL);
fprintf(LOG_PORT,"DOWN EQ !supported ");
// enable_interrupts(GLOBAL);
// delay_ms(500);
#endif
break;
}

delay_ms(500);
}
silelis



Joined: 12 Jun 2007
Posts: 68
Location: Poland, podlaskie district

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 11:52 pm     Reply with quote

I have divided the code and really it helps to avoid the compilation error.

Also I want to thank for DISABLE_INTS idea. It will save my ROM space and saves 5% of ROM. Smile.
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