Boot loader problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Boot loader problem

Jump to solution
2,816 Views
vines
Contributor III

Hi,

 

I am trying to do a Bootloader. On my bootloader program the LCF is the following:

 

  vectorrom  (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
  code        (RX) : ORIGIN = 0x00000410, LENGTH = 0x00001BF0
  data        (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00020000
  cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010

 

I din't use any MQX or interrupt for this code.

 

As for the application code here are the details:


   vectorrom   (RX): ORIGIN = 0x00002000, LENGTH = 0x00000400
   rom         (RX): ORIGIN = 0x00002400, LENGTH = 0x0003FDF0  # Code + Const data   
   ram         (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000  # SRAM - RW data

 

The application does have an MQX. Also, I already define MQX_ROM_VECTORS as 0 in BSP.

 

On my BL program I have this function:

 

static void JumpToUserApplication(LWord userStartup)
{
        unsigned long* ptr_jump = (LWord*)userStartup;
        test = userStartup;
        /* set up stack pointer */  
        asm("LDR      r13, [r1] ");
        ptr_jump++;
        /* jump to application reset vector */  
        asm("BX           *ptr_jump");

}

 

the userStartup variable being pass is 0x2000. However if I debug my BL program and tried to jump to that location it goes to another location unknown to me. After line asm("BX           *ptr_jump"), it lands to address 0x11a20.

 

Anybody can point to me what am I missing here?

 

FYI:

I am using Kinetis K60512

Also contents of flash where application program should start (0x2000 onwards) was verified by reading the memory of Kinetis itself. It is exactly the same as generated S19 file from application code. Thus it is not like I am jumping to an empty or FF byte.

 

Thanks in advance.

0 Kudos
1 Solution
1,512 Views
kaskasi
Contributor III

David and Carlos,

I have had similar problem with custom K53 board. Just got flash image with MQX working.

Double check your MAP file to see if in your case there is enough space for the RAM vector table.

I did start with the similar linker file that Carlos has below, but it resulted a image where vectors_ram section was not allocated, so I did add ramvectors section manually to the linker file and add code to manually copy the ROM vector to that section (RAM location 0x1fff0000 - 0x1fff0400).

I need to go back to study my BSP and PSP builds some more, for some reason it looks like #define MQX_ROM_VECTORS 0 was not "flushed" all the way. Since I also needed to change code in _bsp_enable_card to directly use __VECTOR_TABLE_RAM_START instead of BSP_INTERRUPT_VECTOR_TABLE.

Later,

Kari

View solution in original post

0 Kudos
13 Replies
1,512 Views
DavidS
NXP Employee
NXP Employee

Hi vines,

When the vector table is placed in RAM it will start at 0x1fff0000 and end 0x1fff400.

Please check your linker file setting to ensure you have correct variable to allow the vector table of the application to be copied to RAM and the vector table pointer updated to point to it.

I think the MQX app is dying because it doesn't have correct vector table.....but that is just a guess.

Regards,

David

1,512 Views
vines
Contributor III

Hi David,

 

Please see attached files. I have attached bsp’s vector , user_config and twr library.  The application program with MQX that I am trying to jump into is built on top of pe_demo project that comes along with the installation of MQX. Hence, the bsp for this project is bsp_twr60n512_pe. I just tailor made the project such a way that it supports my current board not the tower. My board  requires only Ethernet, spi(2), uart, rtc, gpio’s, flash. Do you see any problems with how I setup the bsp (with respect to user_config.h)? Also, as mentioned earlier my application program is perfectly running when flash directly to the board using the above bsp_pe.

 

I can only attached 3 files. So here is a copy my LCF.

 

MEMORY
{
   vectorrom   (RX): ORIGIN = 0x00002000, LENGTH = 0x00000400
   #cfmprotrom  (R): ORIGIN = 0x00002400, LENGTH = 0x00000020
   rom         (RX): ORIGIN = 0x00002420, LENGTH = 0x0007FFFF-0x00002420 # Code + Const data   
   ram         (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000  # SRAM - RW data
   
   # kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap)
   end_of_kd   (RW): ORIGIN = 0x2000FFF0, LENGTH = 0x00000000
   
   # Boot stack reused by MQX Kernel data
   bstack      (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200  # Boot stack
   end_bstack  (RW): ORIGIN = 0x2000FBFF, LENGTH = 0x00000000
}

KEEP_SECTION { .vectors_rom, .vectors_ram, .cfmconfig }

SECTIONS
{
   __INTERNAL_SRAM_BASE  = 0x1FFF0000;
   __INTERNAL_SRAM_SIZE  = 0x00020000;

   __INTERNAL_FLASH_BASE = 0x00000000;
   __INTERNAL_FLASH_SIZE = 0x00080000;

   __INTERNAL_FLEXNVM_BASE = 0;
   __INTERNAL_FLEXNVM_SIZE = 0;
   
   __EXTERNAL_MRAM_BASE  = 0x70000000;
   __EXTERNAL_MRAM_SIZE  = 0x00080000;
   __EXTERNAL_MRAM_ROM_BASE = 0x70000000;
   __EXTERNAL_MRAM_ROM_SIZE = 0x00000000;
   __EXTERNAL_MRAM_RAM_BASE = 0x70000000;
   __EXTERNAL_MRAM_RAM_SIZE = 0x00080000;

   __EXTERNAL_LCD_BASE = 0x60000000;
   __EXTERNAL_LCD_SIZE = 0x1FFFF;
   __EXTERNAL_LCD_DC_BASE = 0x60010000;

   # MQX link time configurations
   __DEFAULT_PROCESSOR_NUMBER = 1;
   __DEFAULT_INTERRUPT_STACK_SIZE = 1024;
   __KERNEL_DATA_VERIFY_ENABLE = 0;    # Test SDRAM read/write

   # Flashx configurations
   __FLASHX_SECT_SIZE = 0x800;

    .vectors :
    {
        __VECTOR_TABLE_ROM_START = .;        # Runtime vector table in sram
        *(.vectors_rom)
        . = ALIGN (0x4);
    } > vectorrom

    #.cfmprotect :
    #{
    #    *(.cfmconfig)
    #    . = ALIGN (0x4);
    #} > cfmprotrom

    .main_application :
    {
        *(KERNEL)
        *(S_BOOT)
        *(IPSUM)
        *(.text)
        *(.init)
        *(.fini)
        *(.eini)
        *(.ctors)
        *(.dtors)
        . = ALIGN(0x4);
        *(.rodata)
        . = ALIGN(0x4);
        *(.rdata)
        . = ALIGN(0x4);
        *(.exception)
        . = ALIGN(0x4);
        __exception_table_start__ = .;
        EXCEPTION
        __exception_table_end__ = .;
        __sinit__ = .;
        STATICINIT

        . = ALIGN(0x4);
        __COPY_OF_DATA = .;
    } > rom

    .main_application_data : AT(__COPY_OF_DATA)
    {
        . = ALIGN(128);
        __VECTOR_TABLE_RAM_START = .;        # Runtime vector table in sram
        *(.vectors_ram)

        . = ALIGN(512);
        __BDT_BASE = .;
        *(.usb_bdt)
        __BDT_END = .;

        __START_DATA = .;
        *(.data)
        __END_DATA = .;

        . = ALIGN(0x4);
        __START_SDATA = .;
        *(.sdata)
        __END_SDATA = .;

        . = ALIGN(0x4);
        __SDA_BASE  = .;
        __SDA_BASE_ = __SDA_BASE;
        . = ALIGN(16);
    } > ram

    .main_application_bss :
    {
        . = ALIGN(0x10);
        __START_SBSS = .;
        *(.sbss)
        *(SCOMMON)
        __END_SBSS = .;

        __START_BSS = .;
        *(.bss)
        *(COMMON)
        __END_BSS = .;
        . = ALIGN(16);
    } >> ram

    .kernel_data : #AT(ADDR(.main_application_bss) + SIZEOF(.main_application_bss))
    {
        __KERNEL_DATA_START = ALIGN(0x10);
    }
    .end_of_kernel_data :
    {
        __KERNEL_DATA_END = .;
    } > end_of_kd

    .boot_stack :
    {
        _stack_end = .;
    } > bstack
   
    .end_of_boot_stack :
    {
        _stack_addr  = .;
        __SP_INIT    = .;
        __BOOT_STACK_ADDRESS = .;
    } > end_bstack

    # Locate the ROM copy table into ROM after the initialized data
    _romp_at = __COPY_OF_DATA + SIZEOF(.main_application_data);

    .romp : AT (_romp_at)
    {
        __S_romp = _romp_at;
        WRITEW(__COPY_OF_DATA);                    #ROM start address
        WRITEW(ADDR(.main_application_data));      #RAM start address
        WRITEW(SIZEOF(.main_application_data));    #size
        WRITEW(0);
        WRITEW(0);
        WRITEW(0);
    }

    _flashx_start = __COPY_OF_DATA + SIZEOF(.main_application_data) + SIZEOF(.romp);

    # flashx working area spans across the whole rest of Flash memory
    __FLASHX_START_ADDR = ((_flashx_start + __FLASHX_SECT_SIZE - 1) / __FLASHX_SECT_SIZE) * __FLASHX_SECT_SIZE;
    __FLASHX_END_ADDR = __INTERNAL_FLASH_BASE + __INTERNAL_FLASH_SIZE;

}

/* EOF */

 

Do you see any problems on how I set it up? As far as I understand from program tracing, ram will still be allocated from 0x1fff0000. However, the first part will be for __VECTOR_TABLE_RAM_START which is for vector ram. Vectors are being initialized to ram in the psp project (psp_int_install). Then program vector table used ram or rom depending upon the definition of MQX_ROM_VECTORS (_int_set_vector_table(BSP_INTERRUPT_VECTOR_TABLE). As for the size of ram vector, will it not be dynamically allocated by bsp? Is this correct assumption?

 

Please let me know if you find anything wrong with the linker file or bsp setup.  

 

I appreciate all the help. Thanks.

0 Kudos
1,512 Views
norbertoj
Contributor III

MQX application don't run succesfully after 'go' of FNET bootloader‌ I have a similar problem. However, I change all my .ld linker and I still don't make my mqx application works.

This is my .ld

ENTRY(__boot)


/* 
_cfm - to keep vectors.c variables
__init_hardware - must be used from bsp.a, not from librt.a
*/
/*EXTERN(_cfm __init_hardware)*/
EXTERN(__vector_table  ram_vector rom_vector)

MEMORY
{
   /*fnet_bootloader (RX) : ORIGIN = 0x00000000, LENGTH = 0x0000C000*/
   vectorrom   (RX): ORIGIN = 0x0000C000, LENGTH = 0x00000420
   /*cfmprotrom  (R): ORIGIN = 0x00000400, LENGTH = 0x00000010*/
   rom         (RX): ORIGIN = 0x0000C420, LENGTH = 0x0007FBE0 - 0x0000C420 /*Code + Const data */  
   /*  rom         (RX): ORIGIN = 0x0000C420, LENGTH = 0x0007FBE0*/  /*Code + Const data */  
   ram         (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000  /* SRAM - RW data*/
  /* ram         (RW): ORIGIN = 0x1FFF8000, LENGTH = 0x00020000 */ /* SRAM - RW data*/
  
    
    /* kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap) */
    end_of_kd   (RW): ORIGIN = 0x2000FFF0, LENGTH = 0x00000000
    
    /* Boot stack reused by MQX Kernel data */
    bstack      (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200  /* Boot stack */
    end_bstack  (RW): ORIGIN = 0x2000FC00, LENGTH = 0x00000000  /* Boot stack end address requires 4B alignment */
     
     
   /* fnet_params (RW) : ORIGIN = 0x0007F800,LENGTH = 0x00001000*/

}


SECTIONS
{
    __INTERNAL_SRAM_BASE  = 0x1FFF0000;
    __INTERNAL_SRAM_SIZE  = 0x00020000;
    
   /* __INTERNAL_FLASH_BASE = 0x00000000 + 0x0000C000;*/
   /* __INTERNAL_FLASH_SIZE = 0x00080000 - 0x0000C000;*/
    
    __INTERNAL_FLASH_BASE = 0x00000000;
    __INTERNAL_FLASH_SIZE = 0x00080000;
    
    __INTERNAL_FLEXNVM_BASE = 0;
    __INTERNAL_FLEXNVM_SIZE = 0;
    
    __EXTERNAL_MRAM_BASE  = 0x70000000;
    __EXTERNAL_MRAM_SIZE  = 0x00080000;
    __EXTERNAL_MRAM_ROM_BASE = 0x70000000;
    __EXTERNAL_MRAM_ROM_SIZE = 0x00000000;
    __EXTERNAL_MRAM_RAM_BASE = 0x70000000;
    __EXTERNAL_MRAM_RAM_SIZE = 0x00080000;

    __EXTERNAL_LCD_BASE = 0x60000000;
    __EXTERNAL_LCD_SIZE = 0x1FFFF;
    __EXTERNAL_LCD_DC_BASE = 0x60010000;

    /* MQX link time configurations */
    __DEFAULT_PROCESSOR_NUMBER = 1;
    __DEFAULT_INTERRUPT_STACK_SIZE = 1024;
    __KERNEL_DATA_VERIFY_ENABLE = 0;    /* Test SDRAM read/write */

    /* Flashx configurations */
    __FLASHX_SECT_SIZE = 0x800;

    .vectors :
    {
        __vector_table = .;
        __VECTOR_TABLE_ROM_START = __vector_table;
        KEEP(*(.vectors_rom))
        . = ALIGN (0x4); 
    } > vectorrom

    /* Flash protection bits */
    /*.cfmprotect :*/
    /*{*/
    /*  KEEP(*(.cfmconfig))*/
    /*  . = ALIGN (0x4);*/
    /*} > cfmprotrom*/

    .text :
    {
        *(KERNEL)
        *(.text*)
        *(.rodata*)

        /* unwind exception frame */
        KEEP(*(.eh_frame))
        KEEP(*(.eh_frame_hdr))

        /* constructors */
        . = ALIGN(0x8);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        /* destructors */
        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        /* preinit_array */
        __preinit_array_start = .;
        KEEP (*(.preinit_array*))
        __preinit_array_end = .;

        /* init_array */
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array*))
        __init_array_end = .;

        /* fini_array */
        __fini_array_start = .;
        KEEP (*(SORT(.fini_array.*)))
        KEEP (*(.fini_array*))
        __fini_array_end = .;

        /* gnu arm zero table */
        . = ALIGN(4);
        __zero_table_start__ = .;
        LONG (_bss_start)
        LONG (_bss_end - _bss_start)
        __zero_table_end__ = .;

        /* gnu arm copy table */
        . = ALIGN(4);
        __copy_table_start__ = .;
        LONG (LOADADDR(.data))
        LONG (_data_start)
        LONG (_data_end - _data_start)
        __copy_table_end__ = .;
    } > rom

    /* unwind exception frame */
    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > rom
    .ARM :
    {
        __exidx_start = .;
        *(.ARM.exidx*)
        __exidx_end = .;
    } > rom

    /* create _etext symbol which keep 
    relocation(execution) address of "code" end */
    _etext :
    {
        . = ALIGN(0x4);
        _etext = .;
    } > rom
    
    .data :
    {
        . = ALIGN(128);
        _data_start = .;
        __VECTOR_TABLE_RAM_START = .;
        KEEP(*(.vectors_ram))

        . = ALIGN(512);
        __BDT_BASE = .;
        *(.usb_bdt)
        __BDT_END = .;

        *(.data*)
        . = ALIGN(4);
        _data_end = .;
        _edata = .;  
    } > ram AT> rom 

    .rom_end_data :
    {
        _rom_data_end = .;
    } > rom

    .bss :
    {
        . = ALIGN(4);
        _bss_start = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(4);
        _bss_end = .;
    } > ram

   .kernel_data : 
    {
        . = ALIGN(0x10);
        __KERNEL_DATA_START = .;
    } > ram

    .end_of_kernel_data :
    {
        __KERNEL_DATA_END = .;
        __KERNEL_AREA_END = .;
    } > end_of_kd

    .boot_stack :
    {
        _stack_end = .;
    } > bstack

    .end_of_boot_stack :
    {
         stack_addr  = .;
        __SP_INIT    = .;
        __BOOT_STACK_ADDRESS = .;
    } > end_bstack
    
    
    /* fill "__S_romp" table with memory region(s) to perform "rom to ram copy" */
    _romp_at = _etext + SIZEOF(.data);
    .romp : AT(_romp_at)
    {
        __S_romp = _romp_at;
        LONG(_etext); /* source (rom) address */
        LONG(_data_start); /* target (ram) address */
        LONG(_edata - _data_start); /* size */
        /*Cambios para Álamo*/
        /*LONG(__copy_table_end__); *//* source (rom) address */
        /*LONG(ADDR(.data));*/ /* target (ram) address */
        /*LONG(SIZEOF(.data));*/ /* size */
        /* null terminated */
        LONG(0);
        LONG(0);
        LONG(0);
    }

    /* user flash area starts here */
    _flashx_start = _etext + SIZEOF(.data) + SIZEOF(.romp); /*Cambios para Álamo*/
    
    /*_flashx_start = __INTERNAL_FLASH_BASE + __FLASHX_SECT_SIZE;*/

    /* flashx working area spans across the whole rest of Flash memory */
    /*_flashx_start = _rom_data_end;*/
    __FLASHX_START_ADDR = ((_flashx_start + __FLASHX_SECT_SIZE - 1) / __FLASHX_SECT_SIZE) * __FLASHX_SECT_SIZE;
    __FLASHX_END_ADDR = __INTERNAL_FLASH_BASE + __INTERNAL_FLASH_SIZE;
    
    _end = .;
}

My comp.c is this

/*HEADER**********************************************************************
*
* Copyright 2013 Freescale Semiconductor, Inc.
*
* This software is owned or controlled by Freescale Semiconductor.
* Use of this software is governed by the Freescale MQX RTOS License
* distributed with this Material.
* See the MQX_RTOS_LICENSE file distributed for more details.
*
* Brief License Summary:
* This software is provided in source form for you to use free of charge,
* but it is not open source software. You are allowed to use this software
* but you cannot redistribute it or derivative works of it in source form.
* The software may be used only in connection with a product containing
* a Freescale microprocessor, microcontroller, or digital signal processor.
* See license agreement file for full license terms including other restrictions.
*****************************************************************************
*
* Comments:
*
*   This file contains runtime support for the ARM GCC.
*
*
*END************************************************************************/

#include <stdio.h>
#include "mqx.h"

void *malloc(_mem_size);
void *calloc(_mem_size, _mem_size);  
void *realloc(void*,_mem_size);
void free(void *);
void exit(int);
void _exit(int);
void init_hardware(void);
void __libc_init_array(void);
void __libc_fini_array(void);
void atexit(void *);
int  main(void);

void *__dso_handle = NULL;



/*!
 * \brief Dummy function which avoid GCC to register destructors of global objects. 
 *  By default GCC use '__cxa_atexit' function which register destructors to 
 *  LIFO. When LIFO is full, it performs malloc, but at this point there is 
 *  no heap, so malloc fails. 
 *
 * \return int
 */
int __cxa_atexit (void (*fn) (void *), void *arg, void *d)
{
    return 0;
}

/*!
 * \brief Perform custom action before main
 */
void _init(void)
{
    ;
}

/*!
 * \brief Perform custom action before exit
 */
void _fini(void)
{
    ;
}

/*!
 * \brief Override C/C++ runtime heap allocation function
 *
 * \param bytes
 *
 * \return pointer
 */
void *malloc(_mem_size bytes)
{
    return _mem_alloc_system(bytes);
}

/*!
 * \brief Override C/C++ reentrant runtime heap allocation function
 *
 * \param reent
 * \param nbytes
 *
 * \return pointer
 */
void *_malloc_r(void *reent, size_t nbytes)
{
    return _mem_alloc_system(nbytes);
}

/*!
 * \brief Override C/C++ runtime heap deallocation
 *
 * \param n
 * \param z
 *
 * \return pointer
 */
void *calloc(_mem_size n, _mem_size z)
{
    return _mem_alloc_system_zero(n*z);
}

/*!
 * \brief Override C/C++ runtime heap reallocation function in IAR's DLIB
 *
 * \param ptr
 * \param bytes
 *
 * \return pointer
 */
void *realloc(void* ptr,_mem_size bytes)
{
    return _mem_realloc(ptr,bytes);
}

/*!
 * \brief Override C/C++ runtime heap deallocation function
 * 
 * \param p 
 */
void free(void *p)
{
    _mem_free(p);
}

typedef struct {
    uint32_t *  TARGET;
    uint32_t    BYTESIZE;
} STARTUP_ZEROTABLE_STRUCT, * STARTUP_ZEROTABLE_STRUCT_PTR;


typedef struct {
    uint32_t *  SOURCE;
    uint32_t *  TARGET;
    uint32_t    BYTESIZE;
} STARTUP_COPYTABLE_STRUCT, * STARTUP_COPYTABLE_STRUCT_PTR;


extern STARTUP_ZEROTABLE_STRUCT __zero_table_start__[];
extern STARTUP_ZEROTABLE_STRUCT __zero_table_end__[];
extern STARTUP_COPYTABLE_STRUCT __copy_table_start__[];
extern STARTUP_COPYTABLE_STRUCT __copy_table_end__[];


/*!
 * \brief setup zero sections, copy sections
 */
void data_startup(void)
{
    register uint32_t offset, i;

// TODO: address alignment assertion
    /* zero sections */
    for (i = 0; &__zero_table_start__[i] < __zero_table_end__; i++)
    {
        for (
            offset = 0;
            offset < __zero_table_start__[i].BYTESIZE;
            offset += sizeof(uint32_t)
        )
            (*(uint32_t*)((void*)__zero_table_start__[i].TARGET + offset)) = 0;
    }

// TODO: address alignment & overlapping assertion
    /* copy sections */
    for (i = 0; &__copy_table_start__[i] < __copy_table_end__; i++)
    {
        for (
            offset = 0;
            offset < __copy_table_start__[i].BYTESIZE;
            offset += sizeof(uint32_t)
        )
            (*(uint32_t*)((void*)__copy_table_start__[i].TARGET + offset))
                = (*(uint32_t*)((void*)__copy_table_start__[i].SOURCE + offset));
    }
    
}

/*!
 * \brief Perform necessary toolchain startup routines before main()
 */
void toolchain_startup(void)
{
     /****Cambios para Álamo****/
//       asm("LDR r4,=0x00");
//       asm("LDR sp, [r4]");
//       asm("LDR r5, [r4]");
//       asm("MSR MSP, r5");
//       asm("LDR r4,=0x04");
//       asm("LDR r5, [r4]");
//       asm("BLX r5");
//       _mqx_exit(0);
          
// initialize necessary hardware (clocks, ddr, ...)
    init_hardware();
// initialize data - copy and zero sections
// static variables can be used on return
    
    data_startup(); /*Cambios para Álamo*/
    
    /*Cambios para Álamo*/
    /***Copiar de ROM a RAM*/
   // zero_fill_bss();
  //  __copy_rom_sections_to_ram();
// register destructor calls of static objects
    atexit(__libc_fini_array);
// run constructor calls of static objects
    __libc_init_array();
// run main, if return go to exit
   //SCB_VTOR = (uint32_t)0x1FFF0000; /*Cambios para Álamo , Inicio del Vector RAM*/
    exit(main());
}

/*!
 * \brief Required implementation
 * 
 * \param status 
 */
void _exit(int status)
{
// disable all interrupts, run infinite loop
    __asm("cpsid i");
    while(1);
}

/*!
 * \brief Required implementation, we don't use this legacy feature for more information 
 *  see http//www.unix.com/man-page/FreeBSD/2/sbrk/
 *
 * \param increment
 */
void *_sbrk(intptr_t increment)
{
    _exit(-1);
}
0 Kudos
1,512 Views
vines
Contributor III

Just an update. I managed to make it work but the program counter (the address where bootloader will jump into to get to application program) stated by s19 file is different from the address I used to jump into. I was able to get the program counter by loading it(application program) first without the offset address (minus 0x2000 bootloader space). I step into the debug disassembly and found the address where main function starts. Then I just get this address and add my offset for bootloader and used it as a jumping address in my bootloader. It did work. However, this only confirms to me that the written flash contents are correct and routine in jumping to the location. My problem is the program counter. How come I get a different program counter from S19 file to the actual one? I suspect I might miss something on the LCF for application.

 

I attached here a copy of Linker file for Application program.

 

On the actual S19 for Application program I am getting this on address 0x2000

 

S35100002000FFFB0020B11A0100990B0100990B0100990B0100990B0100990B01000000000000000000000000000000000051240000990B010000000000FB240000990B0100990B0100990B0100990B0100A2

 

So if you based here, the program counter should be colored red. However, as mentioned above this is different from what I get from disassembly. The address I am jumping into is 0x10BAC (working). 

 

How can I correct this and automatically get the program counter from S19 file? Any inputs will be appreciated. Thank You.

0 Kudos
1,512 Views
DavidS
NXP Employee
NXP Employee

Hi vines,

Your solution looks correct and I was able to use your code snippet and test that it works.

Instead of passing 0x2000 I passed 0x0 so that my application would start all over.  I can step using debugger to validate it and hit my breakpoints.

Have you done the CW10.2 online update process?  Help->Install New Software... ->Select Work with: "FSL MCU Eclipse Update Site -http://freescale.com/lgfiles/updates/Eclipse/MCU10_2/com.freescale.mcu.updatesite "

If not then maybe the code is not generated correctly for you???

Regards,

David

0 Kudos
1,512 Views
vines
Contributor III

Hi David,

 

Yes my CW is updated. I have traced the problem. It is actually giving the correct program counter on the S19. I assume that the entry point for MQX programs was main(). I have checked the vectors under bsp and it is actually __boot. Thus the address on the S19 file was correct all along.

However when I jump to my application program it stops somewhere. I checked where it stop. I found out it stops at function

asm void __thumb_startup(void).

specifically at line bl     __init_hardware.

 

Any idea why it does not continue with the application program?

 

I do not have any interrupt nor mqx on bootloader program. On my application i have MQX. 

 

Sorry for the confusion of program counter. It was a mistake on my part. It did start on correct address.

 

Thanks.

 

 

0 Kudos
1,512 Views
DavidS
NXP Employee
NXP Employee

Hi Carlos,

I recently was playing with a bootloader on the TWR-K60n612 and trying to jump to MQX3.8.1 application built with CW10.2.

It was not working correctly either.

I tracked down the issue to the __init_hardware() routine which was disabling the watchdog timer.  But for some reason the CW10.2 compiler was doing instruction re-ordering and causing the watchdog not to be disabled.

I changed that code as follows and now it is working.

      //DES must use volatile below or compile does out of order writes!!! Therefore watchdog not disabled!!!

      *((volatile unsigned short *)KINETIS_WDOG_UNLOCK_ADDR)      = KINETIS_WDOG_UNLOCK_SEQ_1;               

      *((volatile unsigned short *)KINETIS_WDOG_UNLOCK_ADDR)      = KINETIS_WDOG_UNLOCK_SEQ_2;

      *((volatile unsigned short *)KINETIS_WDOG_STCTRLH_ADDR)     = KINETIS_WDOG_DISABLED_CTRL;    

Hope this helps.

Regards,

David

0 Kudos
1,513 Views
kaskasi
Contributor III

David and Carlos,

I have had similar problem with custom K53 board. Just got flash image with MQX working.

Double check your MAP file to see if in your case there is enough space for the RAM vector table.

I did start with the similar linker file that Carlos has below, but it resulted a image where vectors_ram section was not allocated, so I did add ramvectors section manually to the linker file and add code to manually copy the ROM vector to that section (RAM location 0x1fff0000 - 0x1fff0400).

I need to go back to study my BSP and PSP builds some more, for some reason it looks like #define MQX_ROM_VECTORS 0 was not "flushed" all the way. Since I also needed to change code in _bsp_enable_card to directly use __VECTOR_TABLE_RAM_START instead of BSP_INTERRUPT_VECTOR_TABLE.

Later,

Kari

0 Kudos
1,512 Views
vines
Contributor III

Hi Kari,

This topic was posted a long time ago. But I didn't have the time back then. Anyway, if you don't mind, can you post or send me the link files for both your bootloader and application? Also if you can show how you copied the vectors from rom to ram. I suspect this is my problem. Sorry I am not much into linker files and assembly. Thus, it is challenging for me to get what I need based on the twrXXn512_boot project.

Thank You.

0 Kudos
1,512 Views
vines
Contributor III

Solve. Something to do with application pointer to junp into.

Thanks everyone!

0 Kudos
1,512 Views
vines
Contributor III

Hi David and Kari,

First thanks for the comments. I was out for quite some time now because of I had an operation (sucks). I am just returning to the groove here in the office. Anyway, I will try your suggestions probably next month as I have a lot in my plate right now. I will let you know if this thing has been resolve.

Cheers.

0 Kudos
1,512 Views
DavidS
NXP Employee
NXP Employee

Hi vines,

If you are not using the Tower K60 platform but using your own hardware, then you need to review the BSP to ensure it is not turning on functions/capabilities that your hardware does not support.

Example in the init_hardware() function in init_hw.c is the flexbus and specifically MRAM.  If you have different functionality on those pins then issues can arise.

Also are you using the same clocking as the Tower?  If different did you update that code?

I've seen customers not disable the NMI (not issue with K60) software or watchdog.  So you must be sure to review the BSP that is ported to your hardware carefully.

Regards,

David

0 Kudos
1,512 Views
vines
Contributor III

If you are not using the Tower K60 platform but using your own hardware, then you need to review the BSP to ensure it is not turning on functions/capabilities that your hardware does not support.

Yes I am using my own HW.

Example in the init_hardware() function in init_hw.c is the flexbus and specifically MRAM.  If you have different functionality on those pins then issues can arise.

I didn't turn on anything regarding flexbus and MRAM for both BL and Application codes.

Also are you using the same clocking as the Tower?  If different did you update that code? I've seen customers not disable the NMI (not issue with K60) software or watchdog.  So you must be sure to review the BSP that is ported to your hardware carefully.

No I am using an external clock of 50MHz. And yes I did update the BSP. Also I turned off almost everything including (watchdog and NMI) for the sake of testing.To add to these, my application code is perfectly running on my board if it is directly flash to the chip and not thru  BL program.  So this eliminates the idea of my application not ported or what with my target board.

Well just an added info, I did try to boot an application program with no MQX and less peripherals (ie Serial, SPI, ADC, etc). The jump was successful and the application runs after jumping from the BL program. I was able to verify it because the Application code is just a simple toggle of LED.  Thus there is really nothing wrong with my BL program.

I will check my BSP again for any mistake. But other than these things you mention is there any other things I should look at?

#define MQX_ROM_VECTORS 0 is inserted for both bsp and psp.

0 Kudos