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

Aligning a Function in Memory

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kthomas



Joined: 06 Jul 2010
Posts: 5

View user's profile Send private message

Aligning a Function in Memory
PostPosted: Thu Jul 08, 2010 11:09 am     Reply with quote

I am trying to use a #org statement to place a function in the last row of program memory. Specifically, I want to make a sleep statement the very last instruction in program memory.

However, the compiler wants to put a RETURN statement at the end of the function (thus making it the last instruction in memory). Is there a way to tell the compiler not to do this? Here is the code I have written and how it is compiled:

Code:
#ORG (getenv("PROGRAM_MEMORY")-63), (getenv("PROGRAM_MEMORY")-1)
void goToSleep()
{
   #asm
   //NOP I want to uncomment this, but the compiler chokes because it injects a RETURN. See below
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   PWRSAV #0
   #endasm
}


Here is the .lst of how it is compiled:
Code:
void goToSleep() 
.................... {
....................    #asm
....................    //NOP I want to uncomment this, but the compiler chokes because it injects a RETURN. See below
....................    NOP
*
AFC0:  NOP     
....................    NOP
AFC2:  NOP     
....................    NOP
AFC4:  NOP     
....................    NOP
AFC6:  NOP     
....................    NOP
AFC8:  NOP     
....................    NOP
AFCA:  NOP     
....................    NOP
AFCC:  NOP     
....................    NOP
AFCE:  NOP     
....................    NOP
AFD0:  NOP     
....................    NOP
AFD2:  NOP     
....................    NOP
AFD4:  NOP     
....................    NOP
AFD6:  NOP     
....................    NOP
AFD8:  NOP     
....................    NOP
AFDA:  NOP     
....................    NOP
AFDC:  NOP     
....................    NOP
AFDE:  NOP     
....................    NOP
AFE0:  NOP     
....................    NOP
AFE2:  NOP     
....................    NOP
AFE4:  NOP     
....................    NOP
AFE6:  NOP     
....................    NOP
AFE8:  NOP     
....................    NOP
AFEA:  NOP     
....................    NOP
AFEC:  NOP     
....................    NOP
AFEE:  NOP     
....................    NOP
AFF0:  NOP     
....................    NOP
AFF2:  NOP     
....................    NOP
AFF4:  NOP     
....................    NOP
AFF6:  NOP     
....................    NOP
AFF8:  NOP     
....................    NOP
AFFA:  NOP     
....................    PWRSAV #0
AFFC:  PWRSAV  #0
....................    #endasm
.................... }
AFFE:  RETURN // I want the PWRSAV instruction here! 


I am using v4.099 on a dsPIC30F5011.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 1:29 pm     Reply with quote

I don't have your compiler, so I tested this for an 18F452.
I put a Branch statement at the end of the routine, so it will jump
over the RETLW instruction and jump to a SLEEP instruction that
I've inserted at the end of program memory with an #org statement.

I don't guarantee this is the best way to do it. It's one way that I
quickly thought of.
Code:

#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)

#ORG (getenv("PROGRAM_MEMORY")-63), (getenv("PROGRAM_MEMORY")-1)
#inline
void goToSleep()
{
   #asm
   //NOP
   //NOP
   //NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP   // 10

   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP  // 20

   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP  // 29

   bra 0x7FFE
   #endasm
}

#rom 0x7FFE = {0x0003}  // Sleep Opcode for 18F452

//======================================
void main(void)
{


while(1);
}
kthomas



Joined: 06 Jul 2010
Posts: 5

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 1:36 pm     Reply with quote

Thanks. That got me thinking of another solution. Just use a #rom to fill the entire area with NOPs and stick the sleep opcode at the end. Basically what you're doing without the need of writing a function --

Code:
#rom 0x17FC0 = {0,0,0...until last instruction...,0xFE4000}


Where 0xFE4000 is the PWRSAV #0 instruction
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 1:51 pm     Reply with quote

Quote:

Just use a #rom to fill the entire area with NOPs and stick the sleep opcode at the end.

That would work too. I wasn't sure exactly what you were trying to do,
so that's why I tried to maintain as much of your function as possible.
kthomas



Joined: 06 Jul 2010
Posts: 5

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 1:57 pm     Reply with quote

You got me going down the right path, thanks.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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