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

Bootloader Example Understandings

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



Joined: 27 Jul 2021
Posts: 14

View user's profile Send private message

Bootloader Example Understandings
PostPosted: Wed Sep 15, 2021 11:32 am     Reply with quote

Hey all,

I have been trying to understand how bootloader is implemented using the CCS C Compiler (using PIC18F46Q10; compiler version 5.105). Here is what I have gathered so far, please correct any misunderstandings:

1. The recommended practice for fuses is to specify them in the bootloader project, and put #fuses NONE in the application project.

2. To modify the size of the bootloader, adjust the macro LOADER_END in bootloader.h. LOADER_END must be 1 minus a multiple of getenv("FLASH_ERASE_SIZE").

3. The function jump_to_isr internally adjusts the input parameter to align with the instruction word boundary.

4. A 2-instruction wide application stub after LOADER_END within the bootloader project tells the bootloader where to jump to application. By including bootloader.h in the application project (required), the reset element within the #build macro enables the compiler to replace the stub with the start of actual application.

Code:

#org LOADER_END+1,LOADER_END+3
void application(void) {
  while (TRUE);
}


5. Similar to item 4, within the bootloader project, the #int_global causes the jump_to_isr function to replace the compiler's interrupt dispatcher, which is located at the interrupt vector address. This effectively tells PC to jump to wherever jump_to_isr specifies when interrupts occur. By including bootloader.h in the application project, the interrupt element within the #build macro enables the compiler to place the actual interrupt handling function pointers at the location specified by jump_to_isr.

When interrupts occur, the PC first goes to the interrupt vector table, then gets redirected by jump_to_isr to reach the actual interrupt handling function.

Code:

#int_global
//-------------------------------------------------------------------------
void isr (void) {
//-------------------------------------------------------------------------
   jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}


Thank you for your time and help!

jychua
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Thu Sep 16, 2021 6:44 am     Reply with quote

1) Yes.
2) No. Try never to change things 'in' the supplied files. All you do is have
a define for LOADER_END, _before_ you load bootloader.h.
The key is that if the file finds this already defined, it uses the existing
definition.
So:
Code:

#define LOADER_END 0x7FF
#include "bootloader.h"

Also you have your calculation the wrong way round. It wants to be a
multiple of FLASH_ERASE_SIZE - 1, not 1 - a multiple.
3) The processor only supports jumps to an instruction boundary.
If you look at the instruction set in the data sheet, the call, and goto
instructions put the target address into PC<20:1>. Note 20.1, not 20.0.
The executing instruction is always on an instruction boundary, so the new
address is also always on an instruction boundary.
4) The built program always starts with a jump to the actual code. This
has to happen to allow the code to jump 'round' the interrupt jumps that
are just above this. The 'stub' is just a dummy to maintain this same layout.
The loaded program also has this same layout.
5) Key here is that the jump_to_isr code replaces both vectors if needed.
So 'functions', not just 'function'.
jychua



Joined: 27 Jul 2021
Posts: 14

View user's profile Send private message

PostPosted: Thu Sep 16, 2021 7:48 am     Reply with quote

Thank you for the clarifications! Sounds good to me.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Thu Sep 16, 2021 7:56 am     Reply with quote

Nice to have somebody actually trying to 'get their head round' how the
stuff works. Very Happy
jeremiah



Joined: 20 Jul 2010
Posts: 1346

View user's profile Send private message

Re: Bootloader Example Understandings
PostPosted: Thu Sep 16, 2021 7:04 pm     Reply with quote

jychua wrote:


1. The recommended practice for fuses is to specify them in the bootloader project, and put #fuses NONE in the application project.


I would also recommend that when you specify #use delay() that for the application you only use

Code:
#use delay(clock=XXXX)


to avoid generating #fuses, but in the bootloader feel free to use the other parameters like internal/crystal/etc as those can generate #fuses
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Fri Sep 17, 2021 12:09 am     Reply with quote

Absolutely.
A very good point.

#use delay with just a 'clock', simply sets the clock. With almost any other
parameter (crystal, internal etc.), it generates fuses and/or PLL settings.
jychua



Joined: 27 Jul 2021
Posts: 14

View user's profile Send private message

PostPosted: Fri Sep 17, 2021 2:32 pm     Reply with quote

Will do. Thanks for the input!
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