Offsetting compiler library start address for bootloader

Started by mikeselectricstuff, Jun 28, 2022, 05:04 PM

Previous topic - Next topic

mikeselectricstuff

Hi - I'm not a Proton user, but have been asked by a user to look at implementing my (existing) serial bootloader code ( written in XC8) to their existing Proton8 Basic PIC16F15355 project. 

My bootloader sits at the bottom 256 words of memory, so what's needed is to shift the whole Proton code ( compiler library, reset/interrupt vector entry points and aplication code) up by 0x100 words. (In Microchip XC8, this can be done using the -codeoffset option.)

I've had a quick play with the trial version and the "blink" example, and although I can move the application code up using the org directive, the compiler is still putting some startup/library code at 0x000.

Is there a way to tell the compiler to just move everything up by a specified offset, or place the startup/library code at a different address?

(I did look at the assembler view, and looks like it would be possible, though fiddly,  to tweak things here, but couldn't get it to assemble - I just got an info window that looked like it was failing to find mpasmwin.exe i did try copying Microchip mpasmwin.exe to PDS\bin but got errros due to it not finding the right includes)






top204

There 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.

For example, for an 18F device:

Declare Compiler_Start_Address = $0100

Once the above declare is used in the BASIC listing, the assembler listing will now be:
_compiler__start_
    org 0X0100
    goto _compiler_main_start_

Where it has moved the compiler's start to flash memory address $0100 (256)

If interrupt/s are required:

Declare Compiler_Start_Address = $0100
On_Hardware_Interrupt GoTo ISR_Handler_High
On_Low_Interrupt GoTo Isr_Handler_Low


It will produce the assembler code:
_compiler__start_
    org 0X0100
    goto _compiler_main_start_
    org 0X0108
    goto ISR_Handler_High
    org 0X0118
    goto Isr_Handler_Low

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. :-)

trastikata

Quote from: top204 on Jun 28, 2022, 07:00 PMThat's why I always create bootloaders at the top of flash memory. Not so secure, but very much more user friendly. :-)

Hello Les, how do you deal with Procedures when using Bootloader at the top of the memory?

top204

Procedures are created after the main body of the code, so they just grow and grow up in flash memory, as if a user created subroutines after the main program, and after any interrupt handlers.

So just like a normal flat program, just make sure the program does not get large enough to fill the flash memory too much, so it will not overflow the bootloader that is sitting at the top of it, invisible to the rest of the code and the compiler.

I still think Microchip dropped a bollock making the protected memory for bootloaders at the beginning of flash memory, because that is where the interrupt vectors are, so jumping over them to the re-written vectors actually adds time to an interrupt event. The protected memory should have been at the top of flash, so it is out of the way of everything.


mikeselectricstuff

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 only appears to work on PIC18F. Is there an equivalent for 16F ?

top204

The start address can only be used with 18F family devices because of the way the compiler stores its library routines for 14-bit core devices. They must reside in page 0 of the microcontroller because of the dreadful flash paging system in the 14-bit core devices and their 9-bit stack, so a bootloader sitting in there as well might move some of them up too much and require paging mnemonics for all the calls and goto within the library routines. This will make the code both bloated and slower.

Again, the reason for bootloader's sitting at the top of flash, where it is out of the way of everything and totally invisible to the program' code.


keytapper

Is it possible to implement a code protection, to avoid overwriting?
Ignorance comes with a cost

trastikata

Quote from: keytapper on Jun 29, 2022, 05:15 PMIs it possible to implement a code protection, to avoid overwriting?

That's what I do - block code protection to prevent bootloader overwrite, also I use configuration register protection in the bootloader - this combination protects the device in any situation and can't be bricked by the end-user.

dave_gte

As far as I'm aware, enabling the boot block (BBEN=1) only defines a safe boot block starting at 0x0000. I think the issue in any case is not whether the boot code can be made safe, but whether the method of getting to the boot code can be made safe. If the reset vector points to the boot block but then gets corrupted, you're stuffed.

Maybe one could arrange the application code to start at 0x0000, include ASM code to jump to the bootloader at the top and protect the boot block to stop the jump getting corrupted.

You still have to plonk your main app in the middle somewhere which leads back to the lack of ORG. GCBasic appears to manage 16F low memory boots with '#OPTION bootloader addr' though I haven't as yet tried it in anger but the .hex looks convincing.

top204

With the compiler's staring address moved up, the Microchip bootloaders can be placed in the device at the bottom of flash memory. However, I dislike them a lot, and they are bloated and the PC application for them is utterly dreadful.

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.

What I have now in the bootloader (it's 0x800 long)
On_Hardware_Interrupt GoTo vector_remap
...
at the bottom...
Org 0x804
vector_remap:

Then in the main program I have the usual "On_Hardware_Interrupt GoTo HIGH_INTERRUPT_ROUTINE" and all works fine in there.

But I have no idea how to setup a separate interrupt routine in my boot loader.