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?
Solved! Go to Solution.
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.
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.
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?
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?
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.
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