|
|
View previous topic :: View next topic |
Author |
Message |
mpopko
Joined: 13 Dec 2024 Posts: 2
|
Bootloader with two apps flashing pattern |
Posted: Fri Dec 13, 2024 4:59 am |
|
|
Hi,
I'm trying to prepare bootloader on PIC18F46K20 with two app slots. As target application will do OTA upgrade's, it'll save life when something go wrong during flashing so we can fallback to previous working slot.
I've expanded bootloader example from CCS to have two app slots:
device_bootloader.c
Code: | #include <stdio.h>
#include <stdint.h>
#include <string.h>
//#define BOOTLOADER_MODE2X
#define BOOTLOADER_AT_START
#include <bootloader.c>
#define APP_A_START 0x0800
#define APP_B_START 0x8000
#org APP_A_START+1,APP_A_START+2
void application_A(void) {
while(TRUE);
}
#org APP_B_START+1,APP_B_START+2
void application_B(void) {
while(TRUE);
}
static uint8_t APP_SEL = 0;
void main(void) {
set_tris_b(0b11111011); // Set port B I/O pins directions
delay_ms(100);
printf("\r\nBootloader Version 1.0\r\n");
if(!MODE_SW){
APP_SEL = 1;
printf("\r\nAPP A\r\n");
} else {
APP_SEL = 2;
printf("\r\nAPP B\r\n");
}
if(!RATE_SW)
{
printf("\r\nUpgrade...\r\n");
// Let the user know it is ready to accept a download
printf("\r\nWaiting for download...");
load_program();
}
printf("\r\nLaunching program...\r\n");
if(APP_SEL == 1){
application_A();
}
if(APP_SEL == 2){
application_B();
}
}
#int_global
void isr(void) {
if(APP_SEL == 1){
jump_to_isr(APP_A_START+8);
}
if(APP_SEL == 2){
jump_to_isr(APP_B_START+8);
}
} |
Flashing apps via SIOW.exe is working totally fine. When I've compiled version for slot A (with adresses setted here as LOADER_END) it's putting into slot A and loading correctly, when I've compiled version for slot B it's putting into slot B and also loading correctly.
device_app.c
Code: | #define LOADER_END 0x07FF
#define APP_A_END 0x7FFF
#build(reset=LOADER_END+1:LOADER_END+8, interrupt=LOADER_END+9:LOADER_END+16)
#org 0, LOADER_END {}
#org default
#org LOADER_END+17, 0x7FFF
void main(void)
{
delay_ms(100);
fprintf(STD_PORT,"APP started\r\n");
while(1){
fprintf(STD_PORT,"Hello\r\n");
delay_ms(1000);
}
} |
Header (same for app and bootloader):
Code: | #include <18F46K20.h>
#device pic18f46k20
#device CCS4
#device ADC=10
#case // symbols case sensitive
#device HIGH_INTS=TRUE
#device PASS_STRINGS=IN_RAM
#device ADC=10
#ifdef __DEBUG
#device ICD=TRUE
#FUSES HS,NOPROTECT,NOPUT,NOLVP,NOMCLR,NOWDT,DEBUG
#use delay(clock=64000000)
#else
#FUSES HS,NOPROTECT,NOPUT,NOLVP,NOMCLR,NOWDT,NODEBUG, INTRC_IO
#use delay(clock=64000000,restart_wdt)
#endif |
Idea I want to achieve is to compile app without slot awareness so no matter which slot will be flashed app will be loaded into its adress correctly. First thing in my mind tell me "hey just offset APP_A adresses by 0x7800 when flashing B!", it even looked fine in hex viewer, then I realised that it doesn't affect any asm goto statements.
Is there any way to achieve that solution?
Peace,
Marcin |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Fri Dec 13, 2024 5:55 am |
|
|
No,
Code works at the address it is complied for. It won't work at a different
address. Calls, and absolute jumps are to specific locations.
Many larger processors can be generated to support relative jumps across
the whole of memory, but the PIC does not support this.
So it needs to be compiled for where it is meant to go. |
|
|
mpopko
Joined: 13 Dec 2024 Posts: 2
|
|
Posted: Fri Dec 13, 2024 6:14 am |
|
|
Ttelmah wrote: | No,
Code works at the address it is complied for. It won't work at a different
address. Calls, and absolute jumps are to specific locations.
Many larger processors can be generated to support relative jumps across
the whole of memory, but the PIC does not support this.
So it needs to be compiled for where it is meant to go. |
So we have no other option than to build slot A and slot B hexes and push correct ones on demand.
Thanks for clarification! |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Fri Dec 13, 2024 10:30 am |
|
|
I developed something similar quite some time ago. The PCBA had a dedicated memory which stored what you refer to as 'slots'. An OTA update would interact with the current running application, and it would simply place the update in an unused/old slot. Once complete, it would then trigger a processor reset which would invoke the bootloader.
The bootloader's job was pretty easy - examine the external memory to see if a new image had been placed there. If so, download that new image into the application space.
If you want it to be 'bulletproof' you have to place a lot of thought into these images and tagging them as 'new/to be loaded', 'reliability unsure', 'proven/active', and 'unreliable'. This is necessary for the bootloader to be able to automatically detect if there was a problem with the previous update and to be able to automatically 'roll back' the application to a known good version in the event of something bad happening. The application itself has to have the ability to mark itself as 'proven/active' as long as certain conditions are met: watchdog doesn't activate for x cycles / all code paths exercised in situ. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 554 Location: Des Moines, Iowa, USA
|
|
Posted: Fri Dec 13, 2024 6:38 pm |
|
|
mpopko wrote: |
So we have no other option than to build slot A and slot B hexes and push correct ones on demand.
|
The first OS I learned on was Microware's OS-9/6809. It was fully position independent, and I thought the whole world was that way ;-) We had to do something similar on our system with an 'A' and 'B' build, with the firmware updated pushing whichever file was needed.
Our PIC24 system had one vector table at the start, so when loading 'B' it would load the app portion, then update the IVT with jumps to 'B'. The fall-back to 'A' stuff was never implemented, so I have been doing a similar bootloader the past week or so (based on work I researched in this forum three years ago).
Pity PIC doesn't have the kind of following Arduino has, or we'd have tons of wikis, YouTube videos, blogs, etc. that would already have figured all this out ;-)
Good luck! _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ? |
|
|
|
|
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
|