|
|
View previous topic :: View next topic |
Author |
Message |
silelis
Joined: 12 Jun 2007 Posts: 68 Location: Poland, podlaskie district
|
Error 71 Out of ROM problem |
Posted: Tue Oct 11, 2016 3:41 am |
|
|
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: 1358
|
|
Posted: Tue Oct 11, 2016 6:21 am |
|
|
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
|
|
Posted: Tue Oct 11, 2016 6:52 am |
|
|
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: 1358
|
|
Posted: Tue Oct 11, 2016 8:19 am |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Oct 11, 2016 8:45 am |
|
|
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: 19552
|
|
Posted: Tue Oct 11, 2016 9:20 am |
|
|
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
|
|
Posted: Tue Oct 11, 2016 5:40 pm |
|
|
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
|
|
Posted: Tue Oct 11, 2016 11:52 pm |
|
|
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. . |
|
|
|
|
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
|