Bootloader using MPLabX and XC8.

(instructions, reset, WDT, specifications...) PIC17Cxx, PIC18Fxxx

Bootloader using MPLabX and XC8.

Postby Tight Yorky » Sat Dec 03, 2016 1:23 pm

Below is some advice that others may find useful getting a boot loader and non-boot loader version of a PIC18 program to work.
Outline of the task I had.. Adapt an existing (production/field) loader for PIC24/33 FJ&EP to work with a PIC18 project (existing being upgraded).
The PC end program is existing and not being modified.
I found this thread very useful so thanks to the contributors for this..

Using MPLab 8.92, MPLabX V3.26, XC8 V1.37 (free). Win 7 64bit.
Much time was spent trying to get the XC8 compiler to work with MPLab 8.92 to implement the facilities needed for boot loading. Although got it compiling and running. Using the linker script memory region allocations - OK. The compiler would not implement the facilities to intercept the vectors (without resorting to assembly). Not acceptable.
After much time wasted the existing PIC18 project was imported to MPlab X, as if by magic all the promised compiler facilities appeared (MChip PDF document). But there still appears to be some issues. The compiler (free ver) removes unused code/routines but does not appear to have a facility to disable this (would be interested in anybody's success with this).
(as described in thread above) Declare an OFFSET in MPLabX based upon on your designed memory map. Example
This does not have to be a command line addition. There is a field in a dialog box that can be adjusted. It is found in the Project Properties, under XC8 Linker, Additional Otions (drop down box) 'Codeoffset'. Now be aware that adding this and compiling, your application is now broken and will not work properly!!! :(
Nor will the debugger (PICkit 3 in my case) work properly under certain cases.
To permit your application to be developed, with debugger and all, patches need to be added to the original code to 'link' the vectors as the boot loader would.
These are...

void VectorReset() @ 0x0000
asm( "GOTO 0x4000");

void VectorHigh() @ 0x0008
asm( "GOTO 0x4008");
void VectorLow() @ 0x0018
asm( "GOTO 0x4018");

...The compiler will then kill all your good intentions by removing these because they are 'never' used. :roll:
They MUST not be declared as interrupts. The only way I found for these to be included is to call all three routines in an 'unreachable' section of code and put up with the compiler warning.

//Need to place 'users' to prevent exclusion by compiler

I chose the location after the 'forever' while loop in main().
Now when compiled, loaded and debugging, the program operates exactly the same as if the boot loader was used, making it transparent. Simple but essential. :)
Sorry can not post details of the boot loader as it encrypts and is commercially protected. But if you are familiar with memory maps and such you will be aware of the need to protect certain memory areas, page 0 being one of them.
Hope this assists.
T Yorky.
Tight Yorky
Posts: 22
Joined: Thu Jun 19, 2014 10:32 pm
PIC experience: Professional 2-5 years with MCHP products

Re: Bootloader using MPLabX and XC8.

Postby Ian.M » Sun Dec 04, 2016 10:32 am

To force the optimiser not to discard a function funcname(), add:
Code: Select all
        GLOBAL _funcname
Verified identity
Posts: 94
Joined: Wed May 28, 2014 12:47 am
PIC experience: Professional 1+ years with MCHP products

Re: Bootloader using MPLabX and XC8.

Postby Tight Yorky » Mon Dec 05, 2016 12:12 am

Thanks Ian,
I had seen this in the XC8 pdf and tried it. And dismissed it as another item that didn't work. But my error :oops:
I had missed the underscore. Don't know why, the C30 compiler needs it as well.
I have tried it and it generates the functions.
I did use a slightly different format...
asm( "GLOBAL _VectorReset");
asm( "GLOBAL _VectorLow");
asm( "GLOBAL _VectorHigh");

..but because of where I originally placed the statements (end of main) I needed to move these.
I chose to move to start of main as these declarations have no effect on the operation.
This gets rid of the unreachable code warning. :)
T Yorky
Tight Yorky
Posts: 22
Joined: Thu Jun 19, 2014 10:32 pm
PIC experience: Professional 2-5 years with MCHP products

Re: Bootloader using MPLabX and XC8.

Postby jtemples » Mon Dec 05, 2016 1:10 am

All you need to redirect the vectors is:

Code: Select all

psect intcode
   goto    4008h

psect intcodelo
   goto    4018h


You don't need a GLOBAL directive or any intermediate functions (which will waste code space if the compiler doesn't optimize away the RETURN instructions).
Verified identity
Posts: 173
Joined: Sun May 25, 2014 2:23 am
Location: The 805
PIC experience: Professional 5+ years with MCHP products

Re: Bootloader using MPLabX and XC8.

Postby AussieSusan » Mon Dec 05, 2016 3:40 am

Re: the need for a leading underscore: as far as I know this is fairly general practice with compilers on the basis that all variables with a single leading underscore are supposed to the 'private' to whatever code declared/defined them. Therefore the 'c' compiler puts in the leading underscore on the assumption that this will make *any* user defined variable/function/whatever name unique when converted to assembler.
Verified identity
Posts: 93
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

Re: Bootloader using MPLabX and XC8.

Postby Tight Yorky » Mon Dec 05, 2016 10:10 am

Thanks for all the replies. Much appreciated. I had to have this finished for today. I'm happy that I have a solution with the help of this forum and the MChip forum.
From the replies it appears that there is no way of implementing programs such as this without resorting to assembler in the XC8. Even though the intention originally was to avoid assembly code.
I have placed a big block of comments above the statements explaining the use and reason for it, so the customer will (hopefully) not reject it.
T Yorky.
Edit... Just a note.. The User Guide for XC8 does suggest using the asm() for the C interface.
Tight Yorky
Posts: 22
Joined: Thu Jun 19, 2014 10:32 pm
PIC experience: Professional 2-5 years with MCHP products

Re: Bootloader using MPLabX and XC8.

Postby feraamorim » Mon Dec 03, 2018 6:32 pm

Hi Tight Yorky,

Thank you for your excelent hints and tips. It's been a while since you've posted here, but now I'm porting a dsPic bootloader to a PIC18F8723. The XC8 compiler version now is v2.00 (C99), MPLAB X is v5.10. Please, can any of you check the source code below, to see where am I wrong?

The bootloader will be placed in address range 0x19000 - 0x1FFFF in program memory, and the application will be placed in range 0x40 - 0x18FFF

Code: Select all
void VectorReset(void) __attribute__((address(0x00000)))
    asm("GOTO 0x19000");

void VectorHigh(void) __attribute__((address(0x00008)))
    asm("GOTO 0x1A000");

void VectorLow(void) __attribute__((address(0x00018)))
    asm("GOTO 0x1A100");


void VectorHigh2(void) __attribute__((address(0x1A000)))
    //Int_High(); //asm("GOTO Int_High");
    if(PIE1bits.RC1IE)                      //uart 1
             u1_rx_int(); //asm("GOTO u1_rx_int");

    if(PIE3bits.TMR4IE)                     //display - 1.75ms
            t4_int(); //asm("GOTO t4_int");

    if(PIE1bits.SSP1IE)                     //spi
            spi1_int(); //asm("GOTO spi1_int");

void VectorLow2(void) __attribute__((address(0x1A100)))
    //Int_Low(); //asm("GOTO Int_Low");
    if(INTCONbits.TMR0IE)                   //timers - 1ms
            t0_int(); //asm("GOTO t0_int");

    if(PIE1bits.TMR1IE)                     //check_busy
            t1_int(); //asm("GOTO t1_int");   

In main() function:

Code: Select all
    asm("GLOBAL _VectorReset");
    asm("GLOBAL _VectorLow");
    asm("GLOBAL _VectorHigh");
Posts: 1
Joined: Mon Dec 03, 2018 6:05 pm

Return to 16-Bit Core

Who is online

Users browsing this forum: No registered users and 2 guests