| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| dlc@frii.com 
 
 
 Joined: 05 Nov 2003
 Posts: 23
 
 
 
			    
 
 | 
			
				| Out of ROM error, but plenty of space left in the page? |  
				|  Posted: Thu Apr 09, 2009 12:24 am |   |  
				| 
 |  
				| 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  dlc@frii.com
 http://www.techtoystoday.com
 ------------------------------------
 |  |  
		|  |  
		| Ttelmah Guest
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Thu Apr 09, 2009 4:08 am |   |  
				| 
 |  
				| What chip?. 
 Best Wishes
 |  |  
		|  |  
		| Guest 
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Thu Apr 09, 2009 8:27 am |   |  
				| 
 |  
				|  	  | Ttelmah wrote: |  	  | What chip?. 
 Best Wishes
 | 
 
 16F630 - I wouldn't think that it mattered, but you're correct, it could.
 
 DLC
 |  |  
		|  |  
		| Ttelmah Guest
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Thu Apr 09, 2009 9:55 am |   |  
				| 
 |  
				| 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
 
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Thu Apr 09, 2009 10:08 am |   |  
				| 
 |  
				| 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 
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Thu Apr 09, 2009 10:57 pm |   |  
				| 
 |  
				|  	  | 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
 |  |  
		|  |  
		| dlc@frii.com 
 
 
 Joined: 05 Nov 2003
 Posts: 23
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Apr 09, 2009 11:03 pm |   |  
				| 
 |  
				|  	  | 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  dlc@frii.com
 http://www.techtoystoday.com
 ------------------------------------
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Apr 09, 2009 11:20 pm |   |  
				| 
 |  
				| 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.
 |  |  
		|  |  
		| dlc@frii.com 
 
 
 Joined: 05 Nov 2003
 Posts: 23
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Apr 10, 2009 12:06 am |   |  
				| 
 |  
				|  	  | 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  dlc@frii.com
 http://www.techtoystoday.com
 ------------------------------------
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Apr 10, 2009 1:16 am |   |  
				| 
 |  
				| 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
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Fri Apr 10, 2009 7:30 am |   |  
				| 
 |  
				| 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. |  |  
		|  |  
		| dlc@frii.com 
 
 
 Joined: 05 Nov 2003
 Posts: 23
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Apr 10, 2009 8:40 am |   |  
				| 
 |  
				|  	  | 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  dlc@frii.com
 http://www.techtoystoday.com
 ------------------------------------
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Apr 10, 2009 1:33 pm |   |  
				| 
 |  
				| 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
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Apr 10, 2009 1:46 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Apr 10, 2009 1:49 pm |   |  
				| 
 |  
				| Probably the latter (a bug). |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |