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 CCS Technical Support

Out of ROM error, but plenty of space left in the page?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
[email protected]



Joined: 05 Nov 2003
Posts: 23

View user's profile Send private message

Out of ROM error, but plenty of space left in the page?
PostPosted: Thu Apr 09, 2009 12:24 am     Reply with quote

I have a program I'm writing where I have my ISR defined as an #int_global so that I can make it leaner than CCS typically does. I've found that I get the "Out of ROM" error as soon as this grows past 0x0048 or so. When the ISR compiles, it uses addresses 0004-0048, when I add another case and a simple assign I get:
Out of ROM...
seg 00004-00045, 0042 left, need 004E

Huh? since when is a page only 0x87 bytes? (a page in this part is 0xFF bytes.) I've tried putting in #SEPARATE in front of this ISR and functions that follow and it doesn't help. I know that the compiler needs to put INLINE functions completely within a page boundary, but I don't enforce INLINE anywhere. My ISR isn't all that big either, but any other function with this simple switch in it would compile fine - The ISR is the one that the compiler appears to be complaining about.

Has anyone else seen this peculiarity before?

If this can't be fixed I'm going to have to poll my SPI clock instead of using the ISR, which would be a pity and be more troublesome in "book keeping".

I'm using PCM 3.242.

thanks,
DLC
_________________
--
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------
Ttelmah
Guest







PostPosted: Thu Apr 09, 2009 4:08 am     Reply with quote

What chip?.

Best Wishes
Guest








PostPosted: Thu Apr 09, 2009 8:27 am     Reply with quote

Ttelmah wrote:
What chip?.

Best Wishes


16F630 - I wouldn't think that it mattered, but you're correct, it could.

DLC
Ttelmah
Guest







PostPosted: Thu Apr 09, 2009 9:55 am     Reply with quote

OK.
Have you got the line *=16 in your device setup?.
Otherwise the chip will only use the bottom bank of the ROM.
Second comment, how small can you make the 'main'?.
Problem exists, that the compiler will normally want to fit the main into the bottom page. I'd suspect that what is actually happening, is that the 'main' is actually '0xBA' in size, and because it is written in one piece, can't be split up, not leaving enough space for the interrupt handler.

Best Wishes
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Apr 09, 2009 10:08 am     Reply with quote

In addition to Ttelmah's comment about the size of main, please note that the PCM compiler tends to put functions that are called only once into the calling function to save on call stack's limited space (only 8 deep). This will make the main function bigger than you expect.
To make the functions separate from main(), place a #separate directive above the function declaration.

Best regards
Noam
_________________
Every solution has a problem.
Guest








PostPosted: Thu Apr 09, 2009 10:57 pm     Reply with quote

Ttelmah wrote:
OK.
Have you got the line *=16 in your device setup?.
Otherwise the chip will only use the bottom bank of the ROM.
Second comment, how small can you make the 'main'?.
Problem exists, that the compiler will normally want to fit the main into the bottom page. I'd suspect that what is actually happening, is that the 'main' is actually '0xBA' in size, and because it is written in one piece, can't be split up, not leaving enough space for the interrupt handler.

Best Wishes


??? *=16? Hmm, I'm not sure just what good that will do, but hey, I'm puzzled so I'm go. Main is pretty darn small right now since it is little more than a while loop with a couple of function calls. Since the 16F630 only has 1K of ROM, I doubt that making the addresses 16 bit vs. 14 bit will have any effect, but hey, I'll try it.

I have two small functions (init and a SONAR ping) along with the main and the ISR. The whole bloody thing fits into 512 bytes, so I'm pretty baffled with this error.

... I tried the *=16, no effect on the issue, not even the numbers changed. Bummer.

Thanks for the help though, that suggestion could be useful in other parts.

DLC
[email protected]



Joined: 05 Nov 2003
Posts: 23

View user's profile Send private message

PostPosted: Thu Apr 09, 2009 11:03 pm     Reply with quote

n-squared wrote:
In addition to Ttelmah's comment about the size of main, please note that the PCM compiler tends to put functions that are called only once into the calling function to save on call stack's limited space (only 8 deep). This will make the main function bigger than you expect.
To make the functions separate from main(), place a #separate directive above the function declaration.

Best regards
Noam


Thanks. I put #SEPARATE before _every_ function to try this out and nothing changed. There is some other pathological activity going on here that I don't grok. The list file (when it compiled) seemed very logical. I've been using CCS for 10 years and I've never had this issue before.

Still working on it - I'm going to try "org"ing the ISR elsewhere in memory to see if that helps.

thanks all,
DLC
_________________
--
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 09, 2009 11:20 pm     Reply with quote

Post the smallest possible program that shows the problem, but that
also compiles with no errors. Then show in comments the line that
if added, causes the error.
[email protected]



Joined: 05 Nov 2003
Posts: 23

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 12:06 am     Reply with quote

PCM programmer wrote:
Post the smallest possible program that shows the problem, but that
also compiles with no errors. Then show in comments the line that
if added, causes the error.


You got it. BTW, if I use #int_ext instead of #int_global, it will compile, but the ISR is WAY bigger than it needs to be in this case.

Here is my code, trimmed to useless, but showing the compile error:
Code:

#include <16F630.h>
#fuses HS,NOWDT,MCLR,NOPROTECT,NOBROWNOUT
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C1, rcv=PIN_C2, INVERT)   //software UART
#use FAST_IO(C)
#use FAST_IO(A)

#define myAddr 0x10         //This should be stored in EEPROM and be configurable
                      //But I ran out of time for a full implementation.
#define PWR PIN_C3
#define ECHO PIN_C4
#define SINIT PIN_C5
#define SDA PIN_C0
#define SCK PIN_A2

#define ATRIS 0x04         //data direction for TRIS A
#define CTRIS 0x14         //data direction for TRIS C C0 output
#define RSPI  0x15         //turn C0 to input

#define S_IDLE 0         // waiting for any clock
#define S_ADDRCMD 1         //Address and command input state
#define S_DOUT 2         //Sending data out
#define S_DIN 3            //Pulling in 16 bits of data
#define S_READY 4         //There is a command ready

int cmdIn = 0;            //Most recent command received
#locate cmdIn = 0x5c      //Keep it in common memory for ISR use
int bCount = 0;            //bit coming in or going out
#locate bCount = 0x5b      //Kept in register memory for fast access in ISR
long dataIn = 0;
#locate dataIn = 0x59      //Should I ever take 16 bits of data in...
int spiState = 0;         //state machine variable for communications
#locate spiState = 0x58
int addrIn = 0;            //incoming address target
#locate addrIn = 0x57
long dataOut = 0;         //16 bit data to send back

int save_w;
#locate save_w=0x5f
int save_status;
#locate save_status=0x5e
int save_FSR;
#locate save_FSR=0x5d

/*
 * Give me direct access to several SFR's that I want to deal with.
 */
#byte INTCON = 0x0B
#byte FSR = 0x04
#byte status = 0x03
#byte TRISC = 0x87

#int_global
void isr(void)
{
   #asm
      //store current state of processor
      MOVWF save_w
      SWAPF status,W
      MOVWF save_status
      SWAPF FSR,W
      MOVWF save_FSR
      BCF   status,5                              //Set to page 0 for SFR's
      BCF   status,6
   #endasm
   
   switch (spiState)
   {
// Uncomment these next two lines and it won't compile. (DLC)
//      case S_IDLE:                     //Kick start the state machine
//         spiState = S_ADDRCMD;            //and move right to the next state
      case S_ADDRCMD:
         if (bCount <8)                  //We are getting the target address
         {
            shift_left(&addrIn,1,SDA);      //Get the current data value
         }
         else if(bCount < 16)            //Now getting the command
         {
            shift_left(&cmdIn,1,SDA);
            if ((addrIn == myAddr) && ((cmdIn & 0x80) == 0))
            {
               set_tris_C(CTRIS);         //Make SDA an output now
               spiState = S_DOUT;         //next state is data going out
            }
            else
            {
               spiState = S_DIN;         //next state is 16 bits data in
            }
         }   
         break;
         
      case S_DOUT:                     //Next 16 bits go out
         output_bit(SDA,shift_right(&dataOut,2,0));
      
         break;
         
      case S_DIN:                        //Next 16 bits come in
         shift_left(&dataIn,1,SDA);
         
         break;
   }      
   bCount++;
                              //increment the bit count   
      #asm
      // clear INT flag and restore processor and return from interrupt
      BCF INTCON,1
      SWAPF save_FSR,W
      MOVWF FSR
      SWAPF save_status,W
      MOVWF status
      SWAPF save_w,F
      SWAPF save_w,W
      #endasm 
}                               

void init(void)
{
   set_tris_C(RSPI);            //SDA is an input
   set_tris_A(ATRIS);

   enable_interrupts(INT_EXT);               //enable external INT (SCK line)
   enable_interrupts(GLOBAL);               //turn on the interrupts
}

int16 ping(void)
{
   int16 temp;            //holder for 16 bit time

   return (temp/92);      //148us/1.6us = 92.5, return inches
}

void main(void)
{
   int16 x;
   init();
   delay_ms(2000);
      
   while(1)
   {
      output_high(PIN_C0);
      x = ping();               //Get SONAR reading
   }   
}


This compiles, pull out the noted commented lines in the ISR and it won't. When compiled this code uses 18% of the ROM space.

thanks,
DLC
_________________
--
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 1:16 am     Reply with quote

If you add a default case, it compiles:
Quote:
case S_DIN: //Next 16 bits come in
shift_left(&dataIn,1,SDA);

break;

default:

}
dbotkin



Joined: 08 Sep 2003
Posts: 197
Location: Omaha NE USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Apr 10, 2009 7:30 am     Reply with quote

I've seen that happen myself, just a couple of days ago (version 4.087, 18F4620). I had a switch statement that caused an "Out of ROM" error until I added a default case. Nothing else, just default: at the end, and it worked fine.
[email protected]



Joined: 05 Nov 2003
Posts: 23

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 8:40 am     Reply with quote

PCM programmer wrote:
If you add a default case, it compiles:
Quote:
case S_DIN: //Next 16 bits come in
shift_left(&dataIn,1,SDA);

break;

default:

}


Thanks - I don't think that I'd ever have found that one. I don't have unbounded switch blocks so I rarely use "default" in them, there would be no point to it in a state machine. I'll mark that one down in my toolbox. I do this all the time in other routines, I wonder what makes it so special in an ISR.

Thanks for the pointer!

DLC
_________________
--
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 1:33 pm     Reply with quote

The way I found it was this:

First I tried relocating main() to high memory (0x300 range) with an
#org statement. That didn't fix it.

Then I moved your sub-routines to below main() and put function
prototypes above main(), in attempt to re-arrange partitioning of ROM.
That didn't help.

Then I tried commenting out all your #locate statements, because I
thought maybe the compiler didn't like you taking away it's preferred
area for variables. That didn't work.

Then I just started chopping out sections of your code. I removed your
sub-routines init() and ping(). I removed all the code in main() except
a while(1) statement. That didn't help.

Then I started removing blocks of code from your isr. I deleted all the
ASM code. I still got the error. Then I removed most of the case code,
while still keeping the case statements in place. It still failed.

At that point, there wasn't much left. I recalled earlier threads by
Ttelmah, where he had remarked on how the compiler creates different
code based on the number of cases, and also whether or not there is
a default case present. So I said "Hmmm, what if I add a default case ?"

So the basic strategy is to cut the code down until I find the line that's
causing the problem, or until the code is so small that it's evident
what the problem is, and it can solved almost by inspection.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 1:46 pm     Reply with quote

Do you see anything reasonable in this behaviour? Or is it just a bug, continued since V3.xx of the compiler?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 1:49 pm     Reply with quote

Probably the latter (a bug).
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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