How to handle interrupt vector remapping inside a custom bootloader?

Started by PicNoob, Dec 23, 2024, 07:31 PM

Previous topic - Next topic

PicNoob

Quote from: top204 on Jun 28, 2022, 07:00 PMThere is a declare in the compiler to move the start of the compiler's code up in flash memory, and any interrupt vectors are also positioned after the new flash address.

This means that within your bootloader, make sure it handles the interrupt vectors at address 0x08 and 0x18, so they jump to the new vectors. That's why I always create bootloaders at the top of flash memory. Not so secure, but very much more user friendly. :-)

Hi top204, could use a quick hand. I suddenly find myself needing to have interrupts work within a bootloader and realized I don't fully understand how this vector remap really works.

Normally what I do in the bootloader is On_Hardware_Interrupt GoTo vector_remap followed by org 0x804, vector_remap: at the bottom of the bootloader and all is well. In the main program I have the usual "On_Hardware_Interrupt GoTo HIGH_INTERRUPT_ROUTINE" which I define at the bottom of the program and it works fine.

The problem is this time I need to also operate interrupts in the bootloader to catch serial input at high speed from multiple possible sources.
My first thought was to just add bootloader interrupt handling code under the $0x804 org like this. But of course anything over 0x800 is wiped out by the main program so this doesn't work.

Then I started researching dynamic vector interrupt remapping and went down a rabbit hole. I don't believe this can be done on 18F devices anyway.

I need some way to have the vector pointed to one spot while in the boot loader and to another spot in the main program, or some way to have them pointed to the same spot but in such a way that the code all works in both programs. Just don't know how to accomplish that. As always any assistance appreciated!

Quote'On_Hardware_Interrupt GoTo vector_remap ; RE-MAP INT VECTORS 
On_Hardware_Interrupt GoTo HIGH_INTERRUPT_ROUTINE

'****************************************************************       
'* Interrupt Service Routine Inside Bootloader
'****************************************************************
Org 0x804
HIGH_INTERRUPT_ROUTINE:
Context Save

    While RCIF = 1 
        serial_in[serial_in_count] = RCREG
       
        'HRSOut serial_in[serial_in_count]
       
        Inc serial_in_count
        If serial_in_count > 74 Then
            serial_in_count = 0
        EndIf
        RCIF = 0
    Wend
   
Context Restore                                                                                                                           


'*****************************************************************************

'Org 0x804
'vector_remap:


 

trastikata

Hi,

where does your Bootloader reside, at the bottom or the top of the memory?

PicNoob

I use the first 0x800 bytes for the bootloader. So in my main program I have:

Declare Compiler_Start_Address = 0x800

trastikata

See if this helps:

Bootloader structure:

Device = 18F14K50
Declare Xtal = 4
                 
On_Interrupt     GoTo High_Int   
On_Low_Interrupt GoTo Low_Int
   
Dim bVectorFlag As Byte At 0x00 = 0 'Bootloader vector flag
Symbol MainCodeStart = 0x800        'Main code start address                 

Main:
    '.... do something
    End
   
'Bootloader Interrupt vectors
High_Int:
    Context Save
        If bVectorFlag = 1 Then
            GoTo High_Int_Main_Program
        EndIf
        'Rest of the high bootloader interrupt
    Context Restore
Low_Int:
    Context Save
        If bVectorFlag = 1 Then
            GoTo Low_Int_Main_Program
        EndIf
        'Rest of the low bootloader interrupt
    Context Restore
   
   
    Org MainCodeStart + $8      'Main program vector remapping
High_Int_Main_Program:
    Org MainCodeStart + $18     'Main program vector remapping
Low_Int_Main_Program:

Main program structure:

Device = 18F14K50
Declare Xtal = 4

Declare Compiler_Start_Address = 0x800
                 
On_Interrupt     GoTo High_Int   
On_Low_Interrupt GoTo Low_Int
   
Dim bVectorFlag As Byte At 0x00 = 1     'Main program vector flag                     

Main:
    '.... do something
    End
   
'Main program Interrupt vectors
High_Int:
    Context Save
   
    Context Restore
Low_Int:
    Context Save
   
    Context Restore

PicNoob

Quote from: trastikata on Dec 23, 2024, 10:00 PMSee if this helps:

Worked perfectly, it's a Christmas miracle! :) Thanks for the tip it would not have occurred to me to redirect within the interrupt handler itself.