• AVR Freaks

Hot!BootLoader Linker Script for the PIC32MZ - (what I did on my project)

Author
RB1
Starting Member
  • Total Posts : 1
  • Reward points : 0
  • Joined: 2016/12/16 07:55:46
  • Location: 0
  • Status: offline
2017/05/19 05:44:36 (permalink)
5 (3)

BootLoader Linker Script for the PIC32MZ - (what I did on my project)

I have struggled for the last few weeks getting a bootloader to work in a PIC32MZ2048. I figured it out, so now I will explain what I did to get it working.
 
I am using a PIC32MZ2048EFH144 (I did not see many bootloader examples of a "MZ")
I am using Harmony v2.01b
C compiler v1.42
--------------------------------
You should read AN1388, especially Appendix C
 
Print out the Memory Map for your PIC32MZ device, the addresses vary with FLASH memory size.
You will set up two project in Harmony. One for the "User App" (UA) and one for the bootloader (BL)
I set up everything for the UA and BL using the Harmony Configurator. The "pin settings" and "clock setting" must be the same for both projects.
 
For the UA project, just make it like a normal Harmony project. The only difference is you have to modify the linker script. (I will discuss this later)
 
For the BL project, use Harmony, select these "Bootloader Library" options

1) "Bootloader Type" = USART (or what ever you need).
2) "Bootloader or Application" select "Build a Bootloader".
3) Leave other click boxes "unchecked"
4) "Legacy Bootloader Options" Trigger Type = None
5) Select any other harmony features your BL project may need (USART/SPI/etc.)
 
VERY IMPORTANT: Try to write your BL so that no interrupts are used. If you use interrupts, once you jump to the UA, the IVT may have problems.
 
In your BL project, make the UA a loadables "project" of the BL project. Right click on "Loadables", select "Add Loadable Project" option.
 
NOTE: compare the system_config.h files for the BL and UA. If there are any differences, figure out why. I found an issue with Harmony pin configuration. It the pin was set to an output (with pull down active), then I set the RP to U3RX, the pin was still pulling the "RX" line low. The BL system_config.h will over rule the UAs system_config.h. If you have any "strange" pin behaviour, check these two files. This may be your problem.
 
Linker Scripts:
This was my biggest problem to solve. For the BL, I used the default linker script and modified it slightly.
The "important parts" of my BL linker script
----------------------------------------------------------------
PROVIDE(_vector_spacing = 0x00000001);
PROVIDE(_ebase_address = 0x9FC01000);
_BEV_EXCPT_ADDR = 0xBFC00380;
_DBG_EXCPT_ADDR = 0xBFC00480;
_RESET_ADDR = 0xBFC00000;
_SIMPLE_TLB_REFILL_EXCPT_ADDR = _ebase_address + 0;
_CACHE_ERR_EXCPT_ADDR = _ebase_address + 0x100;
_GEN_EXCPT_ADDR = _ebase_address + 0x180;
MEMORY
{
/* Bootloader C program is in the Boot_Flash */
/* adjust length, as the boot program grows. (0x80000 for now) */
kseg0_program_mem (rx) : ORIGIN = 0x9fc02000, LENGTH = 0x80000

/* first half of boot flash */
kseg0_boot_mem : ORIGIN = 0x9FC004b0, LENGTH = 0x0
 
/* Interrupt vector table */
exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
 
/* other half of boot flash */
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x480
kseg1_boot_mem_4B0 : ORIGIN = 0xBFC004B0, LENGTH = (0x1000 - 0x4B0)
...
----------------------------------------------------------------
For the UA linker script, I copied & modified the default linker script that Harmony uses. If you modify the harmony file directly, then you will affect any project Harmony makes for that microcontroller.
The "important parts" of my UA "modified" linker script
----------------------------------------------------------------
PROVIDE(_vector_spacing = 0x0001);
PROVIDE(_ebase_address = 0x9D000000);
 
_RESET_ADDR = (_ebase_address + 0x1000);
_BEV_EXCPT_ADDR = ((_ebase_address + 0x1000) + 0x380);
_DBG_EXCPT_ADDR = ((_ebase_address + 0x1000) + 0x480);
_SIMPLE_TLB_REFILL_EXCPT_ADDR = _ebase_address + 0;
_CACHE_ERR_EXCPT_ADDR = _ebase_address + 0x100;
_GEN_EXCPT_ADDR = _ebase_address + 0x180;
 
MEMORY
{
/* All C Files will be located here */
/* PIC32MZ2018 flash size = 0x200000 */
kseg0_program_mem (rx) : ORIGIN = (0x9D000000 + 0x2000), LENGTH = (0x200000 - 0x2000)

/* This memory region is dummy */
kseg0_boot_mem : ORIGIN = 0x9D000000, LENGTH = 0x0

/* Interrupt vector table */
exception_mem : ORIGIN = 0x9D000000, LENGTH = 0x1000

/* C Startup code */
kseg1_boot_mem : ORIGIN = (0x9D000000 + 0x1000), LENGTH = 0x490
kseg1_boot_mem_4B0 : ORIGIN = (0x9D000000 + 0x1000 + 0x4B0), LENGTH = (0x1000 - 0x4B0)
----------------------------------------------------------------

For reference, below is the original "parts" of the UA linker script (default from Microchip)
----------------------------------------------------------------
PROVIDE(_vector_spacing = 0x0001);           // ORIGINAL LINKER SCRIPT
PROVIDE(_ebase_address = 0x9D000000);   // ORIGINAL LINKER SCRIPT
// ORIGINAL LINKER SCRIPT
_RESET_ADDR = 0xBFC00000;                   // ORIGINAL LINKER SCRIPT
_BEV_EXCPT_ADDR = 0xBFC00380;           // ORIGINAL LINKER SCRIPT
_DBG_EXCPT_ADDR = 0xBFC00480;           // ORIGINAL LINKER SCRIPT
_SIMPLE_TLB_REFILL_EXCPT_ADDR = _ebase_address + 0;  // ORIGINAL LINKER SCRIPT
_CACHE_ERR_EXCPT_ADDR = _ebase_address + 0x100;      // ORIGINAL LINKER SCRIPT
_GEN_EXCPT_ADDR = _ebase_address + 0x180;                 // ORIGINAL LINKER SCRIPT
                                                                                        // ORIGINAL LINKER SCRIPT
MEMORY                                                                           // ORIGINAL LINKER SCRIPT
{                                                                                      // ORIGINAL LINKER SCRIPT
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x200000  // ORIGINAL LINKER SCRIPT
kseg0_boot_mem : ORIGIN = 0x9FC004B0, LENGTH = 0x0                       // ORIGINAL LINKER SCRIPT
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x480                   // ORIGINAL LINKER SCRIPT
kseg1_boot_mem_4B0 : ORIGIN = 0xBFC004B0, LENGTH = 0xFA50         // ORIGINAL LINKER SCRIPT

----------------------------------------------------------------
The final step:
To make the BL code jump to the UA:
#define MAIN_APP_ADDRESS (0x9D000000 + 0x1000)
 
// Disable Global Interrupts
PLIB_INT_Disable(INT_ID_0);
 
// Exit the bootloader, run the new (or old) image.
fptr = (void (*)(void))MAIN_APP_ADDRESS;
fptr();
 
// Bootloader has jumped, past here is never reached...

----------------------------------------------------------------
I hope this saves someone some time when they have for figure out how to make a bootloader in a PIC32MZ.
#1

8 Replies Related Threads

    chavan
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2017/11/02 23:13:00
    • Location: 0
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2018/11/22 20:47:37 (permalink)
    0
    Hi.. . if u r still around..
    I'm trying to create unified hex file for my user application and bootloader application..when I try to build it, I'm getting a error stating.. '(944) data conflict at address 1FC0FFC0h'. Im using my user application as loadable to bootloader application. I tried to follow the related threads but none were useful.. What might be the reason for this error?
    For information I'm using pic32mz2048EFG144, mplab x idd v3. 65, harmony v2. 03b, xc32 v1. 42
    I followed the steps that u hv posted in last thread..
    #2
    PIC GUY 32
    New Member
    • Total Posts : 29
    • Reward points : 0
    • Joined: 2017/01/10 09:20:40
    • Location: 0
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2019/01/29 08:38:03 (permalink)
    0
    Hey chavan,
     
    If you still haven't solved the problem check your configuration bits.  They have to be identical for both the bootloader and application projects.  I had the exact same problem.
    #3
    realexander
    Super Member
    • Total Posts : 187
    • Reward points : 0
    • Joined: 2006/04/08 09:50:42
    • Location: 0
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2019/01/31 10:56:14 (permalink)
    0
    The PIC32MZ2048 supports Live Update, where you load your new code into the upper bank of flash memory. I implemented my bootloader using that feature and did not need to modify the linker file at all.
    #4
    Paul PortSol
    Super Member
    • Total Posts : 471
    • Reward points : 0
    • Joined: 2015/07/03 11:52:03
    • Location: Newfoundland, Canada
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2019/01/31 11:56:41 (permalink)
    0
    RB1,
    Thank you for Posting "How to make it work"
    I'll be doing this soon and your notes look good.
    Paul
    #5
    nich2011
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2018/03/05 18:24:51
    • Location: 0
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2019/03/28 19:39:30 (permalink)
    0
    @realexander. Can u describe in detailed how to parse the hex file?
    #6
    NKurzman
    A Guy on the Net
    • Total Posts : 17625
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2019/03/28 19:53:45 (permalink)
    0
    https://en.m.wikipedia.org/wiki/Intel_HEX

    All of the example bootloaders have Hex parscer code.
    #7
    nich2011
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2018/03/05 18:24:51
    • Location: 0
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2019/03/28 19:59:04 (permalink)
    0
    So, in order to do a live update, I have to parse the hex file 1st and then send it through I2C?
    #8
    Paul PortSol
    Super Member
    • Total Posts : 471
    • Reward points : 0
    • Joined: 2015/07/03 11:52:03
    • Location: Newfoundland, Canada
    • Status: offline
    Re: BootLoader Linker Script for the PIC32MZ - (what I did on my project) 2019/05/03 07:18:40 (permalink)
    0
    RB1,
    I'm not sure this line is valid, may only work for short bootloaders?
    - kseg0_program_mem (rx) : ORIGIN = 0x9fc02000, LENGTH = 0x80000
    That memory area seems to overlap Reserved Areas, DevCfg areas, and repeated copies of the BootFlash?
     
    Looking at the PIC32MZ-EF Datasheet (ww1.microchip.com/downloads/en/DeviceDoc/PIC32MZ-EF-%20Family-DS60001320F.pdf)
    Figure 4-4 is main memory map, but figure 4-5 shows more detail of the segmented boot map.
    0x1FC0FF00~0x1FC0FFFF Cfg
    0x1FC14000~0x1FC1FFFF Reserved
    0x1FC2FF00~0x1FC2FFFF Unused Cfg but tagged as not usable for executable code
    0x1FC34000~0x1FC3FFFF Reserved
    0x1FC40000~0x1FC73FFF original Boot Flash blocks that are accessed from the above sections
     
    I'm having some trouble as my "long" custom bootloader doesn't run if overlap some of those blocks, so I'm trying to reserve those areas in the linker file (not fully successful yet).
     
    Paul
    post edited by Paul PortSol - 2019/05/03 07:19:41
    #9
    Jump to:
    © 2019 APG vNext Commercial Version 4.5