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

User code relocation

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



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

User code relocation
PostPosted: Sat Sep 14, 2019 9:15 am     Reply with quote

Hello,

I am trying to use microchip's internet (tftp) bootloader with 18F97J60 but have trouble with relocation my user code.
This is microchip design memory map : https://ibb.co/3h4PYvR

Can anyone help?

Best Regards!
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Sep 14, 2019 1:13 pm     Reply with quote

Try the Microchip forum assuming you haven't converted over to CCS C. If you have converted, post your code.
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Sun Sep 15, 2019 9:27 am     Reply with quote

Hello mr. temtronic,

I don't have an account in this forum yet, but this is Microchip help info:

Quote:

*: GOTO instruction is automatically generated by bootloader when writing. Application instruction at address 000000h is moved to Bootloader Jump Table.

**: Some configuration options are not supported and will automatically be changed by the bootloader before flashing. The bootloader requires HS or HS+PLL oscillator mode and does not support 1:1 and 1:2 Watchdog Timer Postscale modes. Switching between Extended and non-Extended mode is not supported either. (The bootloader must be recompiled to change modes.)

The bootloader uses a block of 8256 bytes of program memory. To prevent the application from inadvertently using this block, you should modify the linker script in your application prior to compiling. For example, for the MPLABĀ® C18 C compiler, the linker script will contain a CODEPAGE line describing the available Flash memory in the device. For the PIC18F97J60 product with 128kB of program memory, the linker script (18f97j60i.lkr) will contain a line such as:

CODEPAGE NAME=page START=0x2A END=0x1FFF7

This line indicates that the linker can place application constants and code anywhere between 00002Ah and 01FFF7h. This line must be split into two CODEPAGE lines to describe the gap in available program memory occupied by the bootloader. Ex:

CODEPAGE NAME=page START=0x2A END=0x1DBBF

CODEPAGE NAME=page2 START=0x1FC00 END=0x1FFF7


I don't understand where to place CCS #build (reset ?, isr ?) vectors?


Best Wishes!
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Sep 16, 2019 1:29 am     Reply with quote

What is not made clear, is how the bootloader, knows where your code starts?.

If you look at the layout, except for the need for a goto 0x1Dc00 at the start
of memory, no code relocation is involved. This is a high memory bootloader
with the bootloader sitting near to the top of memory (with a small amount of
space afterwards, which seems silly). It relies on the bootloader then jumping
back to the code. But no information is given as to what address the
bootloader will jump back to.

It simply expects there to be a jump at address 0, to the bootloader.
Then the code can sit as normal with the interrupt handler at the bottom
of memory, followed by the code.
However there is an issue here, that CCS will by default always place
the interrupt handler code at the start of memory (OK), but then run
it upwards and put the code afterwards. Issue is that this bootloader seems
to require the code itself to have an entry point of 0x2A. So it becomes
necessary to put an interrupt relocation jump and place the actual
handlers somewhere else. On the basis that there is a small lump of
the ROM that otherwise would not be easy to use above the bootloader
I've elected to put the interrupt handlers here.
Finally CCS does not allow #ORG statements that cross pages (so go
beyond 64K), so if your code goes beyond this size you will have to
add a second #org for the routines beyond this point.

Checking in the MicroChip forum, the code entry point seems to be 0x2A.
So building to use this.

Code:

//Basic demo of setting up code to fit with the Microchip tftp bootloader
//(I hope!...).

//Interrupt entry point - using the space above the bootloader
#define INT_ENTRY 0x1FC00

#org 0x8, 0x1F default
//Build the interrupt relocation jumps
void isr(void) {
   jump_to_isr(INT_ENTRY);
}

//Now the code needs to be built to locate at 0x2A, but entry point is
//the bootloader at 0x1DC00. Needs also interrupt handler code.
//
#build (RESET=0x1DC00, INTERRUPT=INT_ENTRY)

#org 0x2a, 0xFFFF default
//Main code sits at 0x2A which is what is required
void main()
{
   setup_adc_ports(NO_ANALOGS, VSS_VDD);

   while(TRUE)
   {

   }
}
//Now issue here the compiler only allows you to specify a single 'page'
//for code locations. So if code grows past 64K, will need to add another
//#ORG
//for the routines that go past this point - so:
//#ORG 0x10000, 0x1DBBe, default
//then follow with the extended routines.

//Now the physical interrupt handlers all need to be located above
//the CCS 'global' routine which is at 0x1FC00 (INT_ENTRY)
#org INT_ENTRY+0x100, 0x1FFF6 default
#INT_EXT
void test(void)
{
   output_toggle(PIN_A0);
}
//and the rest of your interrupt routines


Hopefully the bootloader contains protection to prevent code being loaded
from overwriting the bootloader. Reason this is needed is that as built here
the code will add a goto 0x2A at the defined code start point (in the
bootloader). This is not wanted, but provided the bootloader does
protect itself, should not matter,
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Mon Sep 16, 2019 3:01 pm     Reply with quote

Hello,

Thanks Mr."Ttelmah" for the good explanation, but target still answer with "Attempting to overwrite bootloader memory!"

This is microchip bootloader linker file which may be the key..? ('Rolling Eyes')
Code:

// File: 18f97j60i_e.lkr
// Internet Bootloader linker script for the PIC18F97J60 processor

LIBPATH .

//FILES c018i_e.o
FILES clib_e.lib
FILES p18f97j60_e.lib

//CODEPAGE   NAME=vectors    START=0x0            END=0x29           PROTECTED
//CODEPAGE   NAME=page       START=0x2A           END=0x1FFF7
CODEPAGE   NAME=config     START=0x1FFF8        END=0x1FFFD        PROTECTED
CODEPAGE   NAME=bootjmprom START=0x1DBC0      END=0x1DBFF        PROTECTED
CODEPAGE   NAME=bootldrrom START=0x1DC00        END=0x1FBFF
CODEPAGE   NAME=devid      START=0x3FFFFE       END=0x3FFFFF       PROTECTED
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Sep 17, 2019 12:02 pm     Reply with quote

It will.

As I said what I posted is dependant on the bootloader protecting
itself. The compiler will _always_ place a jump to it's physical code at the
address specified as the reset location. Since this wants to be the
bootloader entry it'll put this at the location inside the bootloader.
I was 'hoping' the bootloader would silently protect itself (which would
then work), rather than complaining.
As it complains, you are going to have to cheat. Use what is posted,
but specify the reset location as an address in the code memory, and
at this point add your own routine to goto the bootloader address.
So:
Code:

//Basic demo of setting up code to fit with the Microchip tftp bootloader
//(I hope!...).

//Interrupt entry point - using the space above the bootloader
#define INT_ENTRY 0x1FC00

#org 0x8, 0x1F default
//Build the interrupt relocation jumps
void isr(void) {
   jump_to_isr(INT_ENTRY);
}

//Now the code needs to be built to locate at 0x2A, but entry point is
//the bootloader at 0x1DC00. Needs also interrupt handler code.
//Reset to 'rejump' routine to avoid compiler placing code in the
//bootloader area
#build (RESET=0x1DB00, INTERRUPT=INT_ENTRY)

#org 0x2a, 0xFFFF default
//Main code sits at 0x2A which is what is required
void main()
{
   setup_adc_ports(NO_ANALOGS, VSS_VDD);

   while(TRUE)
   {

   }
}
//Now issue here the compiler only allows you to specify a single 'page'
//for code locations. So if code grows past 64K, will need to add another
//#ORG
//for the routines that go past this point - so:
//#ORG 0x10000, 0x1DAFF default
//then follow with the extended routines.

#ORG 0x1DB00, 1DB0F default
void rejump(void)
{ //physical jump to bootloader
#asm
    goto 1DC00
#endasm
}


//Now the physical interrupt handlers all need to be located above
//the CCS 'global' routine which is at 0x1FC00 (INT_ENTRY)
#org INT_ENTRY+0x100, 0x1FFF6 default
#INT_EXT
void test(void)
{
   output_toggle(PIN_A0);
}
//and the rest of your interrupt routines


This cheats and adds a dummy routine to avoid this.
asmallri



Joined: 12 Aug 2004
Posts: 1630
Location: Perth, Australia

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

PostPosted: Mon Sep 23, 2019 12:14 pm     Reply with quote

I'm late coming to this thread..

The reason the bootloader leaves space between itself and the top of memory is due to the PIC Page Erase size (1K for this processor). If the user code wanted to change a config fuse it requires erasing the top 1K of memory therefore you can't put bootloader code anywhere in this 1K space. Having user code modify the config fuses is daft idea as you can brick your PIC but some people want to do it.

I have not looked at the Microchip bootloader code but the way I implement this class of bootloader is to put a parameter block in program memory below the start of the bootloader. When the bootloader "bootloads" a user program it relocates the first 8 bytes (the application's reset vector) to the parameter block. When a bootloader wants to pass control to the application it would check the parameter block to see if a valid vector is present and if so, pass control to the application. If there is no valid vector present, the bootloader would remain in bootloader mode. This means the application can be placed anywhere in program memory with the exception of the memory used by the bootloader.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Sep 23, 2019 12:55 pm     Reply with quote

Except, that you should never change a config fuse with a bootloader
present, since this can prevent the bootloader from working. So I'd
consider it better to have the bootloader in this area and make sure the
bootloader won't allow the fuses to be changed....
asmallri



Joined: 12 Aug 2004
Posts: 1630
Location: Perth, Australia

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

PostPosted: Mon Sep 23, 2019 1:14 pm     Reply with quote

Ttelmah wrote:
Except, that you should never change a config fuse with a bootloader
present, since this can prevent the bootloader from working. So I'd
consider it better to have the bootloader in this area and make sure the
bootloader won't allow the fuses to be changed....


I completely agree
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
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