|
|
View previous topic :: View next topic |
Author |
Message |
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
Error 71 ... Out of ROM, A segment or the program is too lar |
Posted: Wed Jul 13, 2016 4:34 am |
|
|
Hi guys
I have to make some little changes in a program I wrote one year ago.
At this date I compiled with Ccsc.exe V 4.3.0.357 (30/11/2012) PCW V4.119 (PCH V4.140) and it worked
I still have a workstation with this configuration, and it still works on it ...
As world has turned since this date I now compile with Ccsc.exe V5.0.0.463 (28/06/2016) PCW 5.061 (PCH V5.061) on another workstation and ...
I get the error 71 :
Quote: | Executing: "C:\Program Files (x86)\PICC\Ccsc.exe" +FH "cms.c" +DF +LN +T +A +M +Z +Y=9 +EA
>>> Warning 216 "cms.c" Line 1121(1,2): Interrupts disabled during call to prevent re-entrancy: (LED)
>>> Warning 216 "cms.c" Line 1121(1,2): Interrupts disabled during call to prevent re-entrancy: (I2C_Transmit)
>>> Warning 202 "cms.c" Line 458(5,6): Variable never used: i
*** Error 71 "cms.c" Line 1121(1,2): Out of ROM, A segment or the program is too large LitRegistre
Seg 00188-00FFE, 006E left, need 0016A
Seg 00000-00002, 0000 left, need 0016A Reserved
Seg 00004-00006, 0004 left, need 0016A
Seg 00008-00186, 0000 left, need 0016A Reserved
1 Errors, 3 Warnings.
Build Failed.
Skipping link step. Not all sources built successfully.
BUILD FAILED: Wed Jul 13 11:46:11 2016 |
As you imagine, it is very irritating, especially when the planning is short
Does anybody had this issue and have an idea to solve as I do not believe I have a lack of memory. maybe a configuration somewhere is not correct
Thanks for your help |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jul 13, 2016 5:07 am |
|
|
The PIC you're using has 'banks' of program memory and requires that functions and main() be located wholely within a single bank. IE: a function can't cross or be in 2 banks. Say the banks are 10KB in size and you have 2 functions of 4KB each. 2 of them fit into a bank fine(2 X4=8) with some space left over but 3 will NOT fit(3 x 4=12), the 3rd function would have to overlap or cross or occupy 2 banks and that's NOT allowed.
One possible way to fix this is to rearrange the order of your functions and main() so that the compiler might get better use of the banks.
If that doesn't work, options include using a PIC with more memory or re-coding to maximize space. Since this is an existing project, hopefully you can re-code or rearrange existing code to get it to work.
Jay |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Wed Jul 13, 2016 7:38 am |
|
|
Thanks for your quick answer temtronic
I think I understand what you write, but ...
In this case, the same PIC18F2220 compiled on the old workstation works, and on the new one does not !!!
It is the same panel that I move from one to the other, I hope the banks have not changed during the transfer.
If I increase memory (I put a PIC18F2520 = 16384 bytes iso 4096 bytes) I obtain exactly the same : it works on the old compiler and not on the new one.
I find it curious, not you ? |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Wed Jul 13, 2016 7:57 am |
|
|
With the newer version there have been udpates and fixes causing the assembly code size to increase just enough to not fit within the banking limitiations. |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Wed Jul 13, 2016 8:39 am |
|
|
gaugeguy wrote: | With the newer version there have been udpates and fixes causing the assembly code size to increase just enough to not fit within the banking limitiations. |
Aïe Aïe Aïe
Do you mean the code can increase from 4K to 16K ? |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 13, 2016 10:42 am |
|
|
Are you using a bootloader with #org statements ? Did those #org
statements come from a CCS example file available for vs. 4.119 ?
They might not work with the larger code size in the modern compiler.
Post your #org statements. |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Mon Jul 18, 2016 1:44 am |
|
|
The function which seems too large for it is the following (it is the one the error 71 mentions)
In my mind, it is not very long, and not so easy to split off
Why the V5.061 makes code larger than V4.119 ? Have they communicate on that ?
Code: | /**************************************************************************
Renvoie la valeur d'un registre
**************************************************************************/
Int LitRegistre(Int Numero)
{
int I_Valeur=0x00;
switch(Numero) // numero du registre à lire
{
case 0x00: // Adresse Module
I_Valeur=I_Adresse_JX;
break;
case 0x01: // numéro de série L
I_Valeur=I_NumeroSerieL;
break;
case 0x02: // numéro de série H
I_Valeur=I_NumeroSerieH;
break;
case 0x03: // Version minor
I_Valeur=VERSION_MINOR;
break;
case 0x04: // Version Major
I_Valeur=VERSION_MAJOR;
break;
case 0x05: // Lamp alarm delay
I_Valeur=I_Delai_Lampe_Alarme_Max;
break;
case 0x06: // Global alarm delay
I_Valeur=I_Delai_Alarme_Max;
break;
case 0x07: // 14ms
I_Valeur=I_Duree_14_Mesuree; // Attention L_period a changé peut-être
break;
case 0x08: // durée trou de faulty lamp
if(SFLS.Alarm) I_Valeur=(int)(L_TrouMesure); else I_Valeur=0x00;
break;
case 0x09: // durée trou de faulty lamp
if(SFLS.Alarm) I_Valeur=(int)(L_TrouMesure>>8); else I_Valeur=0x00;
break;
case 0x0A: // off, LI MI ou HI
if (SFLS.MA)
{
if(SFLS.HI)
{
I_Valeur=0x03;
}
else if (SFLS.MI)
{
I_Valeur=0x02;
}
else
{
I_Valeur=0x01;
}
}
else I_Valeur=0x00;
if(B_NoSignal) I_Valeur+=0x04;
if(SFLS.Local) I_Valeur+=0x08;
if(SFLS.Alarm) I_Valeur+=0x10;
break;
case 0x0B:
if(I_No_15ms>=CYCLE_15) I_Valeur=0x01; else I_Valeur=0x00;
if(I_No_5ms>=CYCLE_40) I_Valeur+=0x02;
break;
default:
if (Numero<0x10) // Unsused
{
I_Valeur=UART_Trace_Adress[Numero-0x0C];
}
else if(Numero<0x31) // chaque lampe
{
int k=Numero-0x10;
if (k>=SFLS.length)
{
I_Valeur=0x00; // pas de lampe
}
else if (SFLS.defaut[k]>=I_Delai_Lampe_Alarme_Max)
{
I_Valeur=SFLS.defaut[k]; // Panne lampe
}
else I_Valeur=0x01; // OK
}
break;
}
return(I_Valeur);
} |
|
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Mon Jul 18, 2016 2:09 am |
|
|
And if I clearly empty this function (mark inside as /* ... */) another one appears :
Code: | *** Error 71 "cms.c" Line 1119(1,2): Out of ROM, A segment or the program is too large bputc
Seg 00188-00FFE, 005E left, need 00064
Seg 00000-00002, 0000 left, need 00064 Reserved
Seg 00004-00006, 0004 left, need 00064
Seg 00008-00186, 0000 left, need 00064 Reserved |
Does that mean it does not find place to put 64 bytes ?
Where do I find the length of segment for my PIC18F2220 or PIC18F2520 ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Jul 18, 2016 2:13 am |
|
|
You are fractionally missing the point here.
It's a 'blocks into hole' puzzle. The compiler tells you which one it can't fit, but the problem is almost certainly caused by one of the ones it has already put into the space. Imagine you have two boxes to fit on a shelf. Shelf is 1m long, and one box is 800mm long, and the other 250mm long. You put the 800mm box on the shelf, and then find the 250mm one won't fit. However the real problem is the 800mm one....
You can almost certainly get V5 to actually fit the code, if it did go in with V4, by compiling with the option (near the top of your source file):
#OPT compress
However this is fractionally dangerous. The reason V5 code is at times slightly larger, is that CCS have added more internal error checking to a lot of the functions. The compress option turns some of this off, and is less well tested code.
The real problem is that somewhere you have two of more large pieces of code, that are 'monolithic', and these are tending to block other items from fitting. It's down to programming 'style'. Keeping function sizes slightly smaller, allows much easier packing by the code. |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Mon Jul 18, 2016 2:43 am |
|
|
Ttelmah wrote: |
You can almost certainly get V5 to actually fit the code, if it did go in with V4, by compiling with the option (near the top of your source file):
#OPT compress
|
OK thanks Ttelmah
I put #OPT compress and I get another function !!!
Where can I find the block length ? as I can look at function size with V4 and react on code on the good ones on V5, no ? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Mon Jul 18, 2016 7:53 pm |
|
|
OK, going back to your original post, if v4.xyz worked WHY bother upgrading to v5.abc ? Obviously v4 was suitable for your PIC, perhaps you can explain why you upgraded?
I don't know how the 'optimize' feature may work but I do know that if YOU reorganize the functions, it might actually compile. I've seen it in the past where functions A,B,C would not compile but 'cut and paste' as A,C,B and it compiled just fine.
If you look at the disassembled listing ,you'll see the start and ending addresses for each function.Simply use a 'hex' calculator to subtract start from end and you'll know the size of the function. There's probably a magic bullet to choose this in MPLAB but I'm old school, like to dump listings and see what's going on...
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Tue Jul 19, 2016 12:31 am |
|
|
Lets make some further comments.
It is important to understand what is actually involved here. The PIC program memory, is not one large 'lump' of memory, it is instead for certain things treated like a book with pages. Your code is also in sections. A subroutine is a 'section' (effectively a paragraphs). Now a single part of a program (routine), can only work inside one page. (So in publishing terms, 'widow' lines must not exist).
So you have loads of 'paragraphs' and 'pages', and the compiler then tries to fit combinations of the latter in the former. The more the code is split up, the better the packing it can do. If you have no paragraph that is over half a page long, and most are much smaller, the compiler can look through all the different size pieces you have, and fit things in.
However we then come to V5, versus V4. There are two differences here. The first is that V5, in some places does try to generate 'safer' code, and this can cost a little on size. However the changes for this are small. The other though is that by default, V5, is optimised for speed, rather than for code size. As such, it will 'inline' more code by default.
What does 'inline' mean?.
A subroutine, can be generated in two ways. One is 'inline', and the other 'separate'. With the 'inline' version, the whole of a routine, is included 'inside' the calling code. With the 'separate' version, instead the routine is placed elsewhere, and called. The downside of the former, is that it prevents splitting up across pages, and can result in bulkier code. It's plus, is that it is faster, and involves less actual data movements. The _default_ action with V5, is to put routines which are small, and not called from many locations 'inline'.
So, when laying out code, think what routines do not matter if it takes a tiny bit longer to call, and mark these yourself, as #separate. Try to avoid large routines. If you have something doing a series of different sequences of operations, then consider whether each of these sequences could instead be moved to separate routines. A search here will find notes about how to do this, from literally hundreds of threads. It is a fundamental part of writing code for the PIC (particularly the older PIC's).
For comparison, the page size on most PIC16's, is 2K words. So a PIC with 16K of ROM (8K words), will have this split into four pieces. However on a PIC18, the memory is generally no longer paged (there are paging limitations that appear over 64K).
However I must also go back to PCM_programmer's question about whether you are using a bootloader?. The error being reported, appears to show the compiler behaving as if it is being excluded from some areas of the memory. Also there is a 'nasty', in trying to use I2C, both inside and outside an interrupt..... |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Tue Jul 19, 2016 2:41 am |
|
|
temtronic wrote: | OK, going back to your original post, if v4.xyz worked WHY bother upgrading to v5.abc ? Obviously v4 was suitable for your PIC, perhaps you can explain why you upgraded?
|
Really I am a bit lost
last July 13th I compiled without problem on PC nbr1 with V4, I still have the .hex and .lst files
After I needed to move to PC nbr 2, which was not used for programming since a long time, so i upgraded MPLAB and Ccs. To do that I took contact with [email protected] and they sent me the procedure.
V5 has been download and installed
At this moment, my Error 71 appeared. No chance cos of course planning is too short !
So I finally post here and discovered and understood the changes in V5 and this story of paging (in 18F2220.h I read //////// Program memory: 2048x16 Data RAM: 512 Stack: 31, does that mean the pages are 2048x2 long ? If yes, I can be sure my routine are smaller)
As Planning is too short as I wrote, I decide this morning to come back to the PC nbr 1 with V4
And !!!
Error 71
It worked the 13th and not the 19th ? |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Tue Jul 19, 2016 3:19 am |
|
|
Ttelmah wrote: |
However I must also go back to PCM_programmer's question about whether you are using a bootloader?. The error being reported, appears to show the compiler behaving as if it is being excluded from some areas of the memory. Also there is a 'nasty', in trying to use I2C, both inside and outside an interrupt..... |
No I have no bootloader.
As soon I can compile, I will see and put I2C outside interrupt. |
|
|
|
|
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
|