View previous topic :: View next topic |
Author |
Message |
simon Guest
|
Why does the compiler not use the whole ROM? |
Posted: Mon Jul 30, 2007 6:56 am |
|
|
Hi
I'have a problem with the memory space and I read allready all the formu articles about the compiler error 71: Out of ROM, A segment or the program is to larg.
I'm working with a PIC 10F202 it is one of the baseline contoller with just 512 words ROM. To write the program I use the PCW compiler (PCB+PCM+IDE) version 4.030.
Out of the list file I got the memory map below:
000
00A Function Pointer
00B
016 Function 1
017
01F Function 2
020
031 Function 3
032
039 Function 4
03A
051 Function 5
052
05D Function 6
05E
067 Function 7
068
071 Function 8
072
086 Function 9
087
1EB main Function
1EC SLEEP
1ED
1EF not used
1FF oszllator calibration value
This map corresponds also with the hex preview of the PICkit 2 Programmer.
Form adresse 1ED to 1EF are 17 words free.
The head of the list file looks as followed:
Quote: | ROM used: 482 words (94%)
Largest free fragment is 30
RAM used: 22 (92%) at main() level
23 (96%) worst case
Stack: 2 locations |
But if I add now one extra insruction i.e. a delay_cycles(1) what means a NOP, the compiler can't compile it and stops with a Out of ROM error.
It doesn't matter whether I write the "NOP" into any of function 1 ot 9 or into the main routine. I can even write a new function like
Code: | void Test(void)
{
delay_cycles(1);
} |
and the compiler has still a Out of ROM error. It no difference if I use the #SEPARATE instruction or not.
Has any body some experience with that kind of error and can tell me what I have to do to use also the last 17 words of the ROM. |
|
![](templates/subSilver/images/spacer.gif) |
Darren Rook
Joined: 06 Sep 2003 Posts: 287 Location: Milwaukee, WI
|
|
Posted: Mon Jul 30, 2007 2:16 pm |
|
|
Notice your stack is full, that means some functions will be made inline. If a function is inlined 10 times then 1 NOP inside that function will take 10 bytes. _________________ I came, I saw, I compiled. |
|
![](templates/subSilver/images/spacer.gif) |
simon Guest
|
|
Posted: Thu Aug 02, 2007 9:53 am |
|
|
I tried, tried and found a bit more out.
Is it maybe a PCB bug?
First the problem is surley not because of the rom code pages (segments) problem witch is discussed in some other forum aticles. That problem occours with stonger PICs than the 10Fxxx family. And solution is most to devide the biggest function into two functions and/or use #SEPARATE to avoid inlinde functions.
The 10Fxxx family has just 256 or 512 words ROM and therefore just one code page. But consider the call instruction can only operate over the fist 256 location of the ROM because of a reduction of the PC to 7bit. See Datasheet section "Program Counter".
Why do I think it is a PCB bug:
I have still the same program and memory structure as described above.
My main function starts now at adresse 0x087 and I can expand it (with NOP instructions) till adresse 0x1ED before I get a Out of ROM error. The main() is the last function in the memory map. After main() it follows just a SLEEP instruction on 0x1EE and the last word (0x1FF) is reserved for the oszillator calibrations value. The words between 0x1EE and 0x1FF are not used, that can be seen in the .lst file as well as in the HEX memory overview of the PICkit2 Programmer. That means there are still 16 words extra witch a can't use.
Quote: |
CCS PCB C Compiler, Version 4.030, 38158 02-Aug-07 15:54
Filename: X:\Projekte Aktuell\Telemetriesender\Software\PICC\SenderD1_V2\SenderD1_V2.lst
ROM used: 485 words (95%)
Largest free fragment is 27
RAM used: 22 (92%) at main() level
23 (96%) worst case
Stack: 2 locations
.
.
.
.................... ///////////////////////////////////////////////////////////////////////////////
....................
.................... void main(void)
.................... {
*
0087: MOVLW DF
0088: OPTION
0089: CLRF 04
....................
.................... int32 TempVar;
....................
.................... //Port Initialization
.................... OSCCAL &= 0xFE; //Set Pin4 as IO Port instead of System Clock out
008A: BCF 05.0
.................... set_tris_b(0xFE); //Set Port0 as output the others as input
008B: MOVLW FE
008C: TRIS 6
.................... //GPIO = 0; //Set outputs low
....................
.................... delay_cycles(1);
008D: NOP
.................... delay_cycles(1);
008E: NOP
.................... while(1){ //Main program loop
.
.
.
....................
.................... /*Default reset cause*/
.................... default:
.................... GoSendPulse(); //Send a Pulse
01EB: CALL 033
.................... break;
01EC: GOTO 1ED
.................... }
.................... }
01ED: GOTO 08F
.................... }
.................... /**************************end MAIN********************************************/
....................
....................
....................
....................
....................
.................... /***************************** FUNCTIONS **************************************/
....................
....................
.................... ///////////////////////////////////////////////////////////////////////////////
.................... // Init //
.................... ///////////////////////////////////////////////////////////////////////////////
.................... /*----------------------------------------------------------------------------*/
.................... /**
.................... Function : \c Init() Initialise the MCU and transmitter control program.
....................
.................... \type Local
....................
.................... \param[in] : void
.................... \param[out] : void
....................
.................... \return None
....................
....................
....................
.................... \author Simon von Ballmoos
.................... \date 04.07 Created SvB
....................
.................... \todo -
.................... \bug No bugs known
.................... \test -
.................... */
.................... ///////////////////////////////////////////////////////////////////////////////
.................... static void Init(void){
.................... //Init global variables
01EE: SLEEP
.................... rh_counter = ((int32)c_RUN_TIME_h<<16)+c_RUN_TIME_l;
*
0072: CLRF 16
0073: CLRF 15
0074: MOVLW 0E
0075: MOVWF 14
|
If I generate now a Out of Rom error (add one NOP more) the compiler shows the following message:
Quote: | ***Error 71 "SenderD1_V2.c" Line 626(0,1): Out of ROM, A segment or the program is too large main
Seg 00000-001FF, 017D left, need 017E |
Strange is the main() from 0x087 - 0x1ED need just 0x166 words (358) but the compiler sais he needs 0x17E words (382). That are 24 words extra witch don't exist neither in the .lst nor .hex file. Further if I reduce my code by one NOP the compiler error vanished although the 24 word extra would still exceed the memory size.
Can some body explain this?
To Darren Rooks post:
That's true I noticed this behavior also. But my current program has just two function levels (main() -> other function) and the the stack is also two words deep. And my program has no inline functions.
Thanks for every help. best wishes Simon |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 02, 2007 11:51 am |
|
|
To see all the CCS library function code in the .LST file, you need to
comment out the #nolist statement in the PIC's .H file. Example:
Quote: |
/////// Standard Header file for the PIC10F202 device ////////
#device PIC10F202
// #nolist |
Do that, then re-compile and check the .LST file again.
You might be correct. There may be a bug, but you should do this test
anyway. |
|
![](templates/subSilver/images/spacer.gif) |
Simon
Joined: 03 Aug 2007 Posts: 1
|
|
Posted: Fri Aug 03, 2007 3:10 am |
|
|
I commented the #nolist out and compiled the projecet again. But it didn't change anything. In the pic10f202.h file are just some defines witch don't need memory space.
I discovered also a similar porblem with the error 74 "Not enough RAM for all variables". But see therefore my other forum post "PIC10F202 Out of RAM". |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 03, 2007 3:28 pm |
|
|
I was able to duplicate the problem with the test program shown below.
I only have vs. 3.249 of the PCB compiler. If I uncomment the
delay_cycles(1) line at the end of this program, it says "out of ROM".
In MPLAB, if I go to the View/Program Memory menu, and scroll down
to the end of the code, it doesn't use addresses 0x1F1 to 0x1FF.
The 10F202 data sheet days that 0x1FF holds the Osccal value.
That still leaves 14 ROM words that aren't used for some reason.
I don't have PCW, so I can't look at the device data file for the 10F202
(by using the Device Editor). It's possible that a mistake was made in
entering the end ROM address for this PIC. It might have been set
to 0x1F1 instead of 0x1FE.
But at the present time, I don't have a solution.
Code: |
#include <10F202.h>
#fuses NOWDT, NOMCLR
#use delay(clock=4000000)
char const array1[] = {"ABCEDFGHIJKLMNOPQRSTUVWXYZ"};
char const array2[] = {"abcedfghijklmnop[qrstuvwxyz"};
char const array3[] = {"01234567890!@#$^&*()[]<>?/-"};
char const array4[] = {"asdfghjklqwertyuiozxcvbnmqw"};
char const array5[] = {"Hello 12"};
//==========================
void main()
{
int8 i, n;
int16 w, x, y, z;
w = 0x0123;
x = 0x4567;
y = 0x89AB;
z = 0xCDEF;
w++;
x++;
y++;
z++;
w--;
x--;
y--;
z--;
w = x + y + z;
w = x - y - z;
w = x * y * z;
w = (x / y) / z;
w = (x % y) % z;
w = x & y & z;
w = x | y | z;
w = x ^ y ^ z;
w = x && y && z;
w = x || y || z;
w = x >> y;
w = y >> z;
w = x << y;
w = y << z;
n = array1[i];
n = array2[i];
n = array3[i];
n = array4[i];
n = array5[i];
// delay_cycles(1);
while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
|