|
|
View previous topic :: View next topic |
Author |
Message |
edgarp
Joined: 18 Jun 2024 Posts: 6
|
interrupt in bootloader |
Posted: Fri Jun 28, 2024 5:42 pm |
|
|
device : 16F1939
compiler version: 5.116
from what I understood in this post,
https://www.ccsinfo.com/forum/viewtopic.php?t=60380
if you use the bootloader example the ISR would be placed at the application code area not bootloader's area, making the bootloader dependent on the application.
I would like to make it so that the interrupt is placed in the bootloader's area and make the application use the ISR placed on the bootloader.
to get it to work like this I Would like to know if the following configuration would be what you would expect to see.
Code: |
#define LOADER_END 0x1ffF
#build(reset=LOADER_END+1)
#org 0, 0x7FF {}
#org 0x800, 0xFFF{}
#org 0x1000, 0x17FF {}
#org 0x1800, 0x1ffF {}
#IMPORT (FILE=Botlloader_interrupt_test.hex,HEX,RANGE=0:LOADER_SIZE)
BYTE next_in = 0;
BYTE global_flag =0;
BYTE JUMP_flag =0;
#byte global_flag = 40
#byte next_in = 44
#byte JUMP_flag = 48
//#define TICKS_PER_SECOND 10000
void main(void)
{
unsigned int16 tick;
printf("Application 1.2 running\r\n");
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
tick = get_ticks();
for(;;)
{
if (global_flag)
{
if ((get_ticks() - tick) >= TICKS_PER_SECOND/5)
{
tick = get_ticks();
output_toggle(EXT_WATCHDOG_IO);
}
}
else
{
if ((get_ticks() - tick) >= TICKS_PER_SECOND/10)
{
tick = get_ticks();
output_toggle(EXT_WATCHDOG_IO);
}
if (JUMP_flag)
{
// application();
}
}
}
}
|
I would be using the flags set by the interrupt in the main loop.
the bootloader configuration would be like this :
Code: |
#define _bootloader 1
#define LOADER_END 0x1ffF//
#org LOADER_END+1,LOADER_END+3
void application(void) {
while(TRUE);
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
BYTE global_flag =0;
BYTE JUMP_flag =0;
#byte global_flag = 40
#byte next_in = 44
#byte JUMP_flag = 48
#int_rda
void serial_isr()
{
int t;
buffer[next_in]=getc();
t=next_in;
if ( buffer[next_in] == 0x03)
{
global_flag = ~global_flag;
}
if ( buffer[next_in] == 0x05)
{
JUMP_flag = ~JUMP_flag;
}
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==3)
next_in=0; // Buffer full !!
printf("B");
}
}
void main(void)
{
unsigned int16 tick;
printf("Bootloader 1.1 running\r\n");
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
tick = get_ticks();
for(;;)
{
if (global_flag)
{
if ((get_ticks() - tick) >= TICKS_PER_SECOND/2)
{
tick = get_ticks();
output_toggle(EXT_WATCHDOG_IO);
}
}
else
{
if ((get_ticks() - tick) >= TICKS_PER_SECOND/4)
{
tick = get_ticks();
output_toggle(EXT_WATCHDOG_IO);
}
if (JUMP_flag)
{
application();
}
}
}
}
|
I Kept things that are not relevant out of the code, but if it is easier to follow I could just post the whole file.
-would I need to make use of the #build(share_interrupts) directive at all?
-at the application code it the build directive is only setting the reset, would it be good to also set the interrupt like this ?
// #build(reset=LOADER_END+1, interrupt=4)
Thanks in advance for any help.
Edgar |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
Re: interrupt in bootloader |
Posted: Fri Jun 28, 2024 7:39 pm |
|
|
I know a thing or two about bootloaders. The question to ask yourself is why do you need a bootloader to support interrupts?
A bootloader really has a single task - to bootload an image.
Adding interrupt capability in the bootloader, when unnecessary, just adds complexity and latency to the application. It typically requires remapping of interrupt vectors, and double jump on interrupt. The first to the interrupt handler of the bootloader and the second to the application.
The method I use is to reserve the bootloader vectors and the remainder of the first page of program memory for the application. The application is compiled ti reserve the program memory space used by the bootloader. This way the application image can run unchanged whether or not the bootloader is present. This greatly simplifies application development and debugging. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Last edited by asmallri on Wed Jul 03, 2024 6:19 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Jun 29, 2024 5:32 am |
|
|
There can be an advantage to doing this, but it does bring potential
issues.
So (for example), imagine you have a very well written neat serial
handler, and are using no other interrupts. Provided you are 100%
certain that this will never need to change, using it in both the
bootloader and the main code could make a lot of sense. Now the
issues are that first this implies you are stuck with the handlers in
the bootloader. If any fault is found, you have to program the whole
chip, and that you are restricted to only using the interrupts for which
the bootloader has handlers.
However you then have to realise a very simple thing. Your code never
actually 'uses' an interrupt handler. It only uses the variables that connect
'to' it. So in the example of the serial ISR, you have the buffered gutc
routine, which reads from the buffer, and updates the counters, and the
interrupt handler itself, then handles putting the data into this buffer.
So you can use the routine in the bootloader, by simply declaring these
same variables in the main code, and #locating these to the locations
used in the bootloader, then enabling the interrupt. Have a duplicate
buffered getc routine, and the bootloader ISR will then handle this
interrupt. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Sat Jun 29, 2024 6:10 am |
|
|
You have not convinced me but maybe this is because I use common CPU boards across multiple projects. The bootloaders, once installed, stay on the board irrespective of the project / application. I would rarely ever changed the bootloader unless I am using encryption in which case I have to accommodate different encryption keys and mechanisms.
Having a dependency between the bootloaders and applications is, in my opinion just creating a problem down the track. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Jun 29, 2024 9:35 am |
|
|
For 99% of situations, I'd say you are right. The 1%, is the odd situation,,
where (for example), you are very restricted on space, and have just
enough room in the allocated page for the bootloader, to have this extra
handling, which then saves space for the main program.
I did this decades ago, when dealing with an early PIC, and was very
short of space, but needed to offer bootloader updates for the main code.
In recent years, where I will always if possible use a chip larger than I
actually need, I have never had to do it again.... |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Sun Jun 30, 2024 6:53 pm |
|
|
Ttelmah wrote: | For 99% of situations, I'd say you are right. The 1%, is the odd situation,,
where (for example), you are very restricted on space, and have just
enough room in the allocated page for the bootloader, to have this extra
handling, which then saves space for the main program.
I did this decades ago, when dealing with an early PIC, and was very
short of space, but needed to offer bootloader updates for the main code.
In recent years, where I will always if possible use a chip larger than I
actually need, I have never had to do it again.... |
I agree - this would be a valid use case but, for anyone designing a new product that needs to do this, it is an indication that they should have spent a few more cents to buy the next variant of the processor with the amount flash to support the what if ... _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
edgarp
Joined: 18 Jun 2024 Posts: 6
|
Re: interrupt in bootloader |
Posted: Tue Jul 02, 2024 10:26 am |
|
|
asmallri wrote: | I know a thing or two about bootloaders. The question to ask yourself is why do you need a bootloader to support interrupts?
A bootloader really has a single task - to bootload an image.
Adding bootloader capability in the bootloader, when unnecessary, just adds complexity and latency to the application. It typically requires remapping of interrupt vectors, and double jump on interrupt. The first to the interrupt handler of the bootloader and the second to the application.
The method I use is to reserve the bootloader vectors and the remainder of the first page of program memory for the application. The application is compiled ti reserve the program memory space used by the bootloader. This way the application image can run unchanged whether or not the bootloader is present. This greatly simplifies application development and debugging. |
this bootloader uses encrypted firmware over a proprietary protocol which the application also uses, it is transmitted over I2C to an slave device.
Latency or complexity is not a priority for this task but we would like to make the bootloader completely standalone from application. |
|
|
edgarp
Joined: 18 Jun 2024 Posts: 6
|
|
Posted: Tue Jul 02, 2024 10:41 am |
|
|
Ttelmah wrote: | There can be an advantage to doing this, but it does bring potential
issues.
So (for example), imagine you have a very well written neat serial
handler, and are using no other interrupts. Provided you are 100%
certain that this will never need to change, using it in both the
bootloader and the main code could make a lot of sense. Now the
issues are that first this implies you are stuck with the handlers in
the bootloader. If any fault is found, you have to program the whole
chip, and that you are restricted to only using the interrupts for which
the bootloader has handlers.
However you then have to realise a very simple thing. Your code never
actually 'uses' an interrupt handler. It only uses the variables that connect
'to' it. So in the example of the serial ISR, you have the buffered gutc
routine, which reads from the buffer, and updates the counters, and the
interrupt handler itself, then handles putting the data into this buffer.
So you can use the routine in the bootloader, by simply declaring these
same variables in the main code, and #locating these to the locations
used in the bootloader, then enabling the interrupt. Have a duplicate
buffered getc routine, and the bootloader ISR will then handle this
interrupt. |
yes, this is a risk we are willing to take, extensive testing will be done to try to avoid this to happen.
We would like to keep the bootloader completely standalone from the application incase the application memory area gets corrupted. That's why we would like to put the interrupt on the bootloader and make the application use the variables hooked to it. do you have any comments on the code itself ?specially the set up of the interrupt. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Jul 03, 2024 1:33 am |
|
|
I have to reiterate Andrews comment. There is honestly no reason to use
the interrupt in the bootloader. So just poll the serial here, and use interrupts
only in the main code. It is much neater and less likely to give issues.
If you do decide to embed an ISR, there is nothing special involved at all
just enable the interrupt in the main, and have a copy of the bgetc routine
here that references the variables #located at the locations use in the
bootloader. |
|
|
|
|
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
|