View previous topic :: View next topic |
Author |
Message |
jackmicro
Joined: 07 May 2013 Posts: 23
|
Error 71 - Out of Rom for different devices? |
Posted: Mon Sep 07, 2015 3:26 pm |
|
|
Hello,
I compile my code for a PIC16F1825 device and all goes well.
When I try the same code for a PIC16F877A I get:
*** Error 71 "RC-Expander.c" Line 1748(0,5): Out of ROM, A segment or the program is too large display_program
Seg 00800-00FFF, 01ED left, need 005EE
Seg 01000-017FF, 0326 left, need 005EE
Seg 01800-01FFF, 008E left, need 005EE
Seg 00000-00003, 0000 left, need 005EE
Seg 00004-0003E, 0000 left, need 005EE
Seg 0003F-007FF, 0071 left, need 005EE
I can't really see what is different and the code used to work for both devices.
There are some device specific definitions, but no extra code on either.
Any ideas other than breaking the display_program function into two?
Thx |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Mon Sep 07, 2015 4:21 pm |
|
|
you could try to resequence the functions( put into a different order). That might work. Use a newer PIC( that one is 20+ years old) that has bigger program space....
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 07, 2015 6:27 pm |
|
|
Quote: | I compile my code for a PIC16F1825 device and all goes well. |
When you compile for the 16F1825, what does the .LST file say at the top,
about how much ROM was used ? Also what does it say about the
largest free fragment ? |
|
|
jackmicro
Joined: 07 May 2013 Posts: 23
|
|
Posted: Mon Sep 07, 2015 9:32 pm |
|
|
Memory for the 1825 is at 6800. For the 877 it ends at 7285. Very weird.
I broke the routine in two and now it compiles. It's very weird how one device takes a lot more ROM than the other.
The 877a is part of my breadboard. Just convenient to use. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Sep 08, 2015 12:40 am |
|
|
The later chip has quite a few little 'extras' that might be saving space.
One (for instance), is having the RETFIE 1, like the PIC18, that allows several of the registers to be automatically handled on interrupts. Fourteen extra instructions.... |
|
|
jackmicro
Joined: 07 May 2013 Posts: 23
|
|
Posted: Tue Sep 08, 2015 1:56 pm |
|
|
I was thinking if the extra debugging code inserted for the ICD3 could be the culprit.
I'm glad I managed to find a workaround.
Many thx |
|
|
aerodactyl
Joined: 22 Feb 2008 Posts: 14 Location: Germany
|
|
Posted: Sun Oct 18, 2015 11:13 am |
|
|
Dear all,
I pull up this old thread as I encounter basically the same problem, but I do not understand how to overcome this issue.
The PIC I use is a 16F1829 and I got more or less the same compiler message as the thread starter.
The *.lst file tellsCCS PCM C Compiler, Version 5.027, xxxxx 18-Okt-15 18:45
Filename: E:\TEST.lst
ROM used: 3446 words (42%)
Largest free fragment is 2048
RAM used: 271 (26%) at main() level
302 (29%) worst case
Stack used: 2 locations (1 in main + 1 for interrupts)
Stack size: 16
This is the status before adding some code and the error message appears.
In main {} I read some variables from the EEPROM and in the loop I write same variables into the EEPROM.
This all works fine until I add the code for 1 more variable to read/write.
I know the PIC has different ROM banks and it looks like 1 of them is overloaded but how can I resolve this?
The program works with serveral interrupt routines and 1 main {} function. I do not call any subs in the main loop.
The code I used to read the EEPROM
Code: |
address = 128;
EE_low_byte = Read_EEPROM (address);
address = 129;
EE_high_byte = Read_EEPROM (address);
EE_high_byte = EE_high_byte << 8;
EE_total = EE_high_byte + EE_low_byte;
value = EE_total;
|
These kind of code blocks I have 5 time using the same wording but with different address and different value names.
When I insert 1 more of these blocks for reading a new variable the compiler failed.
Anybody out there who can help me?
Best regards
Uwe |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sun Oct 18, 2015 3:07 pm |
|
|
This has been answered here hundreds of times.
Problem is that the memory on most PIC's is paged. On these a 'routine', must fit completely inside a page. So if you write a single large 'main' for example, it cannot be split up to fit into the available pages. So you have to learn to split your code up. Use subroutines, rather than embedding more code into the single block, and you may have to declare these as #separate, which then forces the compiler to not 'inline' them.
Think sectional code, rather than monolithic code. |
|
|
jackmicro
Joined: 07 May 2013 Posts: 23
|
|
Posted: Mon Oct 19, 2015 10:41 am |
|
|
Basically speaking, break your large subroutines into several smaller ones. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 19, 2015 12:43 pm |
|
|
To explain more, suppose your current program looks like this:
You have one big main().
Code: |
void main()
{
// Inline code to read parameters from eeprom.
.
.
.
// Inline code to initialize a sensor chip.
.
.
.
// Inline code to get readings from a sensor chip.
.
.
.
// Inline code to do some math functions.
.
.
.
// A while() loop to wait for interrupts
.
.
.
}
|
This creates a huge block of code for main(). The compiler can't fit it
into one code page on PIC and you get an out-of-ROM error.
To fix this problem, you need to move all the inline code into multiple
sub-routines and call the routines from main(). Example:
Code: |
void main()
{
int32 current_parameters;
int16 data;
int16 result;
current_parameters = read_parameters();
init_sensor();
data = read_sensor();
result = process_sensor_data(data);
while(TRUE)
{
// Put code here to handle flags set in interrupt routines.
}
}
// Put your routines here, as shown below. Note, you will
// need to place function prototypes above main().
//-----------------------------------------------
int32 void read_parameters(int8 index)
{
.
.
.
}
//------------------------------------
void init_sensor(void)
{
.
.
.
}
//------------------------------------
int16 read_sensor(void)
{
.
.
.
}
//------------------------------------
int16 process_sensor_data(int16 data)
{
.
.
.
}
|
Now the compiler has something to work with. It can come up with a
strategy to place the routines into the PIC's ROM pages, so that they will
all fit in the available space. It might place a small routine and a large
routine into one ROM page, They might take up 90% of the ROM in that
page, but they fit. The math routine might take up most of a page all
by itself. But it fits. Having lots of small to medium size routines
allows the compiler to partition the program so it fits into the available
ROM pages. |
|
|
aerodactyl
Joined: 22 Feb 2008 Posts: 14 Location: Germany
|
|
Posted: Mon Oct 19, 2015 3:20 pm |
|
|
Thanks for our answers.
I already searched for this topics but I found just this old thread.
The next days I will look what I can put into an external function in order to save space.
As my EEPROM is read in the main{} but before the endless loop its sound logic to put these EE-read blocks in a separate function.
Best regards
Uwe |
|
|
|