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 support@ccsinfo.com

How to change start address in program memory
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

How to change start address in program memory
PostPosted: Fri Jan 27, 2012 8:45 am     Reply with quote

Hi,
I need to change the start address of the program memory from a PIC24FJ128GA Pic. The bootloader is not allowed to programm adress below 0x400 when CodeProtect is active. But the compiler generates code from adress 0x200.

How can this be shifted? Normally this is done in the Linker, but how to make this with CCS C?
Twisted Evil
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Fri Jan 27, 2012 9:11 am     Reply with quote

#build

Best Wishes
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

PostPosted: Fri Mar 09, 2012 6:15 am     Reply with quote

Hello Ttelmah,

Can you describe more exactly? The Help file give no answer to my question as it define the memory from start to and end address. But I only want to define the start address. End address may change with program changes.

At what place of the program must I write the #build ?


thanks
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

PostPosted: Fri Mar 09, 2012 6:23 am     Reply with quote

I tried this, but it doesn´t work:
Code:

#include <24FJ128GA108.h>
#device adc=10

#build(memory=0x06CD4:0x157F6)
dyeatman



Joined: 06 Sep 2003
Posts: 1912
Location: Norman, OK

View user's profile Send private message

PostPosted: Fri Mar 09, 2012 9:29 am     Reply with quote

Try looking on page 97 of the CCS C manual
_________________
Google and Forum Search are some of your best tools!!!!
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

PostPosted: Fri Mar 09, 2012 9:41 am     Reply with quote

Hello,

so it´s not possible to say CCS: here is the start address? This is Page 98:

Syntax: #build(segment = address)
#build(segment = address, segment = address)
#build(segment = start:end)
#build(segment = start: end, segment = start: end)
#build(nosleep)
#build(segment = size) : For STACK use only
#build(ALT_INTERRUPT)

Elements: segment is one of the following memory segments which may be assigned a
location: RESET, INTERRUPT, or STACK


For PIC24 it seems it´s not possible... I need that because after every compiling of the main program, the CCS makes another startadress. I have always to change the start adress in my combined HEXFILE (MAIN+BOOT)
jeremiah



Joined: 20 Jul 2010
Posts: 1319

View user's profile Send private message

PostPosted: Sat Mar 10, 2012 3:59 pm     Reply with quote

Did you try the #BUILD statement to see what it does?

I inserted this into a random program of my code:
Code:

#DEFINE LOADER_END (getenv("FLASH_ERASE_SIZE")-1)
#BUILD (reset=LOADER_END+1,interrupt=LOADER_END+5)
#ORG 0x000,LOADER_END {}


Inserting that into your application code with a header file would probably get what you are wanting, unless I am misunderstanding you.

Mind you, you have to handle the ISR mapping in your bootloader program. When using the #build to remap the interrupt vector table, it appears to place interrupt vector addresses every +4 addresses instead of the normal +2, at least in compiler revision 4.130
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

PostPosted: Mon Mar 12, 2012 10:30 am     Reply with quote

Hello,

I don´t overwrite the page with the interoupt vektors with the bootloader, as this causes problem with older PIC24 with REV.01
The Interrupt vektors are defined by the main program. How can I ensure that they are always at the same adresses?
The thing with the start adress is now secondary... but if later changes to the program change the interrupt vectors, this would be critical...

The problem is the misssing linker in the CCS compiler.
jeremiah



Joined: 20 Jul 2010
Posts: 1319

View user's profile Send private message

PostPosted: Mon Mar 12, 2012 10:59 am     Reply with quote

richi-d wrote:
Hello,

I don´t overwrite the page with the interoupt vektors with the bootloader, as this causes problem with older PIC24 with REV.01
The Interrupt vektors are defined by the main program. How can I ensure that they are always at the same adresses?
The thing with the start adress is now secondary... but if later changes to the program change the interrupt vectors, this would be critical...

The problem is the misssing linker in the CCS compiler.


With PIC24, the only thing I could figure out to do which seems to work is in your bootloader, have the IVT point to specific addresses that would appear in your application program. Then you just have to make sure the application programs all put their interrupt GOTO.

So for example, lets take the timer1 interrupt. NORMALLY, the IVT entry for this is 0x001A, which holds the jump address. What I would do is in your "application" include those 3 lines I mentioned in my last post. What this will do is is put a line at 0x830 that says GOTO XXXX, where XXXX is the interrupt isr location. If your bootloader calls:

#ROM 0x001A = {0x0830}

Then when a timer 1 interrupt happens, it will go to the IVT at location 0x001A, which tells it the ISR is at 0x0830. It will then go to 0x0830 and see the GOTO XXXX instruction, which it will follow to the ISR

The nice thing about this method is that your compiler will use the correct location every time as long as you include those 3 lines in the top of your application
jeremiah



Joined: 20 Jul 2010
Posts: 1319

View user's profile Send private message

PostPosted: Mon Mar 12, 2012 11:32 am     Reply with quote

Here is an example of what I mean. It's a mix of the bootloader + application together, so I had to use some #ORG statements to make it all line up:

Code:

#case
#include <24FJ256GA106.h>

//16 bit pointers
#device *=16


//Fuses for this project
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES WINDIS                   //Watch Dog Timer in non-Window mode
#FUSES WDT128                   //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES NOIESO                   //Internal External Switch Over mode enabled
#FUSES PR                       //Pimary oscillaotr enabled
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO                  //OSC2 is clock output
#FUSES HS   


//Only adding this to align application code settings
#DEFINE LOADER_END (getenv("FLASH_ERASE_SIZE")-1)
#BUILD (interrupt=LOADER_END+5)


//Remap IVT table, #ORG empty spaces
#ORG 0x0004,0x0019 {}
#ROM 0x001A = {0x0830}  //Timer1 Interrupt will always be at 0x0830
#ORG 0x001C,0x01FF {}


void app_main();  //just for forward declaration purposes



#ORG 0x0200,LOADER_END
void main()
{
   app_main();  //normally a GOTO LOADER_END+1 here in the bootloader
}


//Application code.  Normally, you would do a
//  #include "bootloader.h"   here which contains:
// 
//   #DEFINE LOADER_END (getenv("FLASH_ERASE_SIZE")-1)
//   #BUILD (reset=LOADER_END+1,interrupt=LOADER_END+5)
//   #ORG 0x0000,LOADER_END

#pin_select U1TX = PIN_B6
#pin_Select U1RX = PIN_B7

#use delay(clock=22118400)
#use rs232(UART1,baud=9600,ERRORS,bits=8,parity=N,stop=1)

unsigned int8 count = 0;
#INT_TIMER1
void timer1_isr(){
   if(count){count--;}
}

#define COUNTER_VAL 500;
void app_main(){
   setup_timer1(TMR_INTERNAL | TMR_DIV_BY_1,11060);
   set_timer1(0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INTR_GLOBAL);
   
   printf("STARTING:\r\n\r\n");
   
   count = COUNTER_VAL;
   while(TRUE){
      if(!count){
         printf("Timer Finished...Restarting\r\n");
         count = COUNTER_VAL;
      }
   }
}


The #build(interrupts=LOADER_END+5) guarantees the ISR's will be at the same location every time as long as your application code includes the bootloader.h I recommend. No linker would be needed, because as long as the #build statements are there, all the ISRs will be put into the right place no matter how your code changes.
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

PostPosted: Tue Mar 13, 2012 2:28 am     Reply with quote

Hello,
thank you for the detailed answer. The Bootloader is not writen with CCS Compiler (Microchip compiler). We are merging the *.hex Files together.
But if I have the IVT always identical in my CCS Main File, it works.
jeremiah



Joined: 20 Jul 2010
Posts: 1319

View user's profile Send private message

PostPosted: Tue Mar 13, 2012 2:26 pm     Reply with quote

Yeah, that can be sucky if the bootloader is not CCS, but it can still work.

Are you able to recompile the "application" code (not the bootloader code)?
Where does the bootloader expect the application reset vector to be?
Where does the bootloader expect the application IVT to be and how is it aligned?
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 2:37 am     Reply with quote

Hello,

Yes it works perfect, but after every change in the application I have to look where the code start address is, and have to write this start address in the Hex File of the combined App+Boot. This is why I asked how I can make the start address of the application fix. So I don´t have to change always this address in the combined .hex.
The Bootloader doesn't need interrupts. It's polling the Uart and this works perfect.
jeremiah



Joined: 20 Jul 2010
Posts: 1319

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 9:00 am     Reply with quote

Well, just the bootloader by itself should expect the code start address to be a particular value. It has to for a bootloader to even work. If you can find out that value from the maker of the bootloader, then all you have to do is:

#build (reset=address)

Where address is that address the bootloader itself expects the code to start.

Once that is done, then the compiler will make changes to the start address for you and always put it where the bootloader expects. The compiler will put a GOTO statement at that address and it will automatically update it with the location of your main when you compile your code. No need to maintain it.

The only reason I mentioned the interrupts is if your application wanted to use them. You said you couldn't write to less than 0x400, so you wouldn't be able to do interrupts unless you went through the steps I mentioned. If you don't need them in the application, then forget about that part.
richi-d



Joined: 28 Aug 2007
Posts: 106

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 2:16 pm     Reply with quote

Thank you!

Thats what I was looking for: #build (reset=address)

Now I can say adress is always at 0x10000 and I don´t have to change the adress in the Main+Boot.hex.

But now I really have problems with the Interrupts of my main application. You are right- the compiller doesn´t make the IVT´s at the same adresses when something changes in the aplication. Because of the Bug in the REV01 Pic24FJ the bootloader is not allowed to write the IVT new. Else different IVT would be a problem. But now I must ensure that the IVTs are always on the same adress. For example I have found this two different pointers, because I changes only some little in the code:

This is from the Program memory of the Version 1 of my app:
18 00022 00791E TIMER2_isr

This is from the Program memory of the Version 2 of my app:
18 00022 00790E TIMER2_isr

I tried your code, but get a lot of error messages:
//Remap IVT table, #ORG empty spaces
#ORG 0x0004,0x0019 {}
#ROM 0x001A = {0x0830} //Timer1 Interrupt will always be at 0x0830
#ORG 0x001C,0x01FE {}


How can I easilymake it that this example above is always on 00791
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, 3  Next
Page 1 of 3

 
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