Hi all,
here I'm with my first PBP bootloader that unfortunately doesn't work properly....
The main program jumps to bootloader, flash the new code, come back to main, do something expected at beginning
then starts to behave "funny", resets chips, etc.
I describe everything as if it were a tutorial so some expert maybe can see where is the weak area.


The bootloader is intended for a PIC18F67k22 that has a blocksize of 128 bytes and Int_Vector at 08h and 18h.
I leave free the first block 0-127 to remap Reset_Vector and Int_Vectors.
The bootloader code starts at 80h after the first block and has available all memory to 2FFFh, it's about 12k.
The main program starts at 3000h and have avaliable the remaining about 120k.


The bootloader has a complex UART communication with a GSM module and I need interrupt to manage properly
a 1k serial buffer. It works fine in other applications of mine, no problem at all that side.
Please note, I have found in this forum some other interesting solutions, like keeping the bootloader in the
high memory, retrieve code from I2C EEprom etc. But for several reasons they doesn't fit my needings.
I just would like to discover why my code fails and let it works properly, hope to find help :-)


This is the bootloader code:


Code:
    DEFINE RESET_ORG 80h
    BlockSize    CON 128
    UpperLimit    CON $1FFFF-BlockSize
    @ nop
    STKPTR=0
    CLEAR
    ' initialize your stuff, declare VAR, etc
    Goto BootLoaderStart
    
        INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
        INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
ASM              
INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler     RX1_INT,  _Rx1INT,             PBP,  yes
    endm
    INT_CREATE               ; Creates the interrupt processor
ENDASM
    INCLUDE "interrupt.inc"                ; here I manage the serial buffer, it works perfect


BootLoaderStart:
    ' remap Reset_Vector and INT_Vectors for bootloader
    EraseCode 0                ' erase first block
    WriteCode $00,$EF40        ' --> put a GoTo $80 at address $00    
    WriteCode $02,$F000        
    WriteCode $08,$EF44        ' --> put a GoTo $88 at address $08
    WriteCode $0A,$F000
    WriteCode $18,$EF4C        ' --> put a GoTo $98 at address $18
    WriteCode $1A,$F000    
    WriteCode $7F,$FF        ' write the last byte of the block to allow WriteCode
    Pause 500


    ' erase memory from $3000 to end
       FOR Adr=$3000 to UpperLimit STEP BlockSize                 
           ERASECODE Adr
       NEXT Adr


    ' enable UART
    RCSTA1.4=0                        ' Reset Overrun flag
    RCSTA1.4=1
    @    INT_ENABLE  RX1_INT         ; enable RS232 interrupts
    INTCON.7=1                        ; enable global int
    INTCON.6=1                        


    ' here i scan the new HEX file that has been already downloaded via FTP and stored in the GSM module memory
ScanLoop:
    ' read a line, example :1000A0000BE0060604C0E9FF05C0EAFFEE50E9CF09
    ' decode address, check crc, etc
    '  be careful to skip addresses from 0 to 2FFFh, not to overwrite the bootloader we are executing
    ' WRITECODE Adr, FlashByte
    ' when fnished, exit loop
    goto ScanLoop
    
ExitBootLoader:
    ' remap Reset_Vector and INT_Vectors before jumping back to main program
    @    INT_DISABLE  RX1_INT         ; disable RS232 interrupts
    INTCON=0                        ; disable INT        
    EraseCode 0                        ; erase first block 0-127
    WriteCode $00,$EF00                ; --> put a GoTo $3000 at address 0h
    WriteCode $02,$F018        
    WriteCode $08,$EF04                ; --> put a GoTo $3008 at address 8h
    WriteCode $0A,$F018
    WriteCode $18,$EF0C                ; --> put a GoTo $3018 aat address 18h
    WriteCode $1A,$F018        
    WriteCode $7F,$FF                ; write the last byte of the block to allow WriteCode
    Pause 500
    @ RESET


@ ORG 0h
    @ GOTO 80h        ' Reset Vector
@ ORG 8h
    @ GOTO 88h        ' High priority Int_Vector
@ ORG 18h
    @ GOTO 98h        ' Low priority Int_Vector PIC18F67K22


@ ORG 3000h
BootLoaderEnd:

Now build the program. I'm using PBP Long option here to be able to WriteCode at address > 64k
I'm in MPLAB IDE 8.92, open "Program memory" view, then in the "Opcode HEX" tab right click "Export Table"
Put 0x80 as start Address and 0x2FFF as End Address, check "Single column output" and save.
Now you need to write a tool (I have used B4J) to read this file and obtain this format


Code:
ASM
    dw 0x0EFA1, 0x0F002, 0x0FFFF, 0x0FFFF, 0x0EF4D, 0x0F004, 0x0FFFF
    dw 0x0E00B, 0x00606, 0x0C004, 0x0FFE9, 0x0C005, 0x0FFEA, 0x050EE
    .....
    .....
ENDASM

Let's jump now to our main program. This (and all updates) needs to work starting at 3000h so it will have
the structure as below. When you want to trigger an update you can simpy call @ GOTO 80h


Code:
    DEFINE RESET_ORG 3000h
    @ nop
    STKPTR=0
    CLEAR
    ' initialize your stuff, declare VAR, etc
    goto Start
     
        INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
        INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
ASM              
INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler   TMR1_INT,  _Timer1_250mS_INT,   PBP,  yes
        INT_Handler     RX1_INT,  _Rx1INT,             PBP,  yes
        INT_Handler     RX2_INT,  _Rx2INT,             PBP,  yes
        INT_Handler   TMR0_INT,  _Timer0_8000mS_INT,  PBP,  yes
    endm
    INT_CREATE               ; Creates the interrupt processor
ENDASM
    INCLUDE "interrupt.inc"                ; here I manage all the interrupt, it works perfect (before an update)




Start:
    ; do your main program stuff
    ; When you want to trigger an update you can simpy call @ GOTO 80h


    if Update_Needed = true then
        ; download the new HEX file via FTP and store in the GSM module memory
        ; so that it will be available for the BootLoader code, then
        @ INT_DISABLE TMR1_INT
        @ INT_DISABLE TMR0_INT
        @ INT_DISABLE RX1_INT
        @ INT_DISABLE RX2_INT
        INTCON.7=0
        @ goto 80h
    endif
    goto start


@ ORG 0h
    @ GOTO 3000h
@ ORG 8h
    @ GOTO 3008h
@ ORG 18h
    @ GOTO 3018h




' here you have to copy the file generated before
@ ORG 80h
BootLoader:
ASM
    dw 0x0EFA1, 0x0F002, 0x0FFFF, 0x0FFFF, 0x0EF4D, 0x0F004, 0x0FFFF
    dw 0x0E00B, 0x00606, 0x0C004, 0x0FFE9, 0x0C005, 0x0FFEA, 0x050EE
    .....
    .....
ENDASM

The main program above works normally as expected. When I want to publish an update, I send the new HEX file
to the FTP server then send a message to the main program to inform that a new update is available.


As I told at beginning, everything works, but when the BootLoader jump back to the new main program, it starts
to do something correctly then behave funny and reset the chip.
Can you see some concept errors ? Besides disabling interrupt before enetering bootloader and remapping the vectors
is there any other register to take care ?
Thanks in advance. Hope that (once fixed) this stuff can be useful to other in the forum.
Cheers