Relocating Interrupt Vector Table When Using MQX

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

Relocating Interrupt Vector Table When Using MQX

Jump to solution
2,588 Views
kackle123
Contributor IV

I can import an example Kinetis K64F Freedom board (FRDM-K64F) bareboard project, modify its linker file to something like the following (that is, relocate its interrupt vector table), and it still works fine:

MEMORY

{
    vectorrom   (RX): ORIGIN = 0x00001000, LENGTH = 0x00000400
    cfmprotrom  (R):  ORIGIN = 0x00001400, LENGTH = 0x00000020
    rom         (RX): ORIGIN = 0x00001420, LENGTH = 0x000FeBE0  
    ram         (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00040000 

}

But I cannot do the same with an example MQX project; it crashes near __thumb_startup().  Upon loading the code, I see with the debugger that the table has moved to 0x1000, which is correct.  But I suspect MQX or CodeWarrior (Kinetis Design Studio/KDS fails too) is not properly setting something else up.

Could someone please try loading the MQX 4 "hello world" project, confirm it executes, and then try using my linker file's MEMORY section above to see whether it still works? 

0 Kudos
1 Solution
2,272 Views
kackle123
Contributor IV

I figured out a workaround to the MQX register-setup bug.  It seems to have something to do with a cold boot versus a warm boot, as described here: Problem of initialization of MQX...

My fix was similar to what is described here: Bootloader mqx k64f.  But I used a variable from the linker script file to pass the stack pointer address(es) into my modified boot.S code.

Update: I later learned that the K64/ARM must have its vector table located at 0x0000 to know where to find the executable code.  The only reason that my table relocation works (without a bootloader's table located at 0x0000) is that the debugger initializes the MCU's program counter for me.  My code does not work without the debugger/programmer attached.

View solution in original post

0 Kudos
7 Replies
2,273 Views
kackle123
Contributor IV

I figured out a workaround to the MQX register-setup bug.  It seems to have something to do with a cold boot versus a warm boot, as described here: Problem of initialization of MQX...

My fix was similar to what is described here: Bootloader mqx k64f.  But I used a variable from the linker script file to pass the stack pointer address(es) into my modified boot.S code.

Update: I later learned that the K64/ARM must have its vector table located at 0x0000 to know where to find the executable code.  The only reason that my table relocation works (without a bootloader's table located at 0x0000) is that the debugger initializes the MCU's program counter for me.  My code does not work without the debugger/programmer attached.

0 Kudos
2,272 Views
kackle123
Contributor IV

Hi Daniel,

I don't want to locate my vector table in RAM.  I want to move it from 0x0 to another place in ROM.

I tried changing MQX_ROM_VECTORS to 0 anyway, but it didn't work.

After these lines (in boot.S), the stack should be initialized, but my stack is not:

        /* Prepare process stack pointer */
        mrs r0, MSP
        msr PSP, r0

        /* Switch to proccess stack (PSP) */
        mrs r0, CONTROL

Do you know where MSP (in boot.S) is initialized?

0 Kudos
2,272 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi

Please also see my attached link file.

Please note there is a macro MQX_ROM_VECTORS in user_config.h

pastedImage_4.png

You can set MQX_ROM_VECTORS macro = 0 in user_config.h and rebuild bsp and psp. This will relocate vectors in RAM

Regards

Daniel

0 Kudos
2,272 Views
kackle123
Contributor IV

Thank you Daniel for trying that project.  My linker file's MEMORY portion looks like yours; I only showed part of it above to save space. 

See the attached screen shot; it looks like the code is trying to push bytes onto the stack when the stack hasn't been set up yet.   The code comment on the left says that __boot() (in boot.S) is supposed to set up the registers (and stack pointer) but it doesn't.  Can you attach your C:\Freescale\Freescale_MQX_4_2\mqx\source\psp\cortex_m\core\M4\boot.S so I can compare them? 

0 Kudos
2,272 Views
danielchen
NXP TechSupport
NXP TechSupport

HI Kackle123:

The boot.S I used is from MQX  package.

Regards

Daniel

0 Kudos
2,272 Views
kackle123
Contributor IV

Thank you, Daniel.  Your boot.S and my boot.S are the same. 

When I tell the debugger to pause at the entry point (top of boot.S), my MSP/SP_MAIN/$SP_MAIN is set to 0xfffffffc.  I believe this is incorrect because it then gets used/copied here (within boot.S):

        mrs r0, MSP

If I use the debugger at the entry point to force SP_MAIN to be 0x20000000 (the start of RAM), then my code works fine.  Can you tell me where/how SP_MAIN is supposed to be set up?  I suspect the linker file is involved; if so, please attach your *.ld file so I can compare them.

0 Kudos
2,272 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi Kackle123:

I changed the linker file as your suggested in MQX hello world project

MEMORY
{
    vectorrom   (RX): ORIGIN = 0x00001000, LENGTH = 0x00000400
    cfmprotrom  (R): ORIGIN = 0x00001400, LENGTH = 0x00000020
    rom         (RX): ORIGIN = 0x00001420, LENGTH = 0x000FeBE0  /* Code + Const data */
    ram         (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00040000  /* SRAM - RW data */
    
    /* kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap) */
    end_of_kd   (RW): ORIGIN = 0x2002FFF0, LENGTH = 0x00000000
    
    /* Boot stack reused by MQX Kernel data */
    bstack      (RW): ORIGIN = 0x2002FA00, LENGTH = 0x00000200  /* Boot stack */
    end_bstack  (RW): ORIGIN = 0x2002FC00, LENGTH = 0x00000000  /* Boot stack end address requires 4B alignment */
}

It can work on my side.

Please note that should be a kernel space after RAM variables, which is MQX needed.

Regards

Daniel

0 Kudos