Please can someone help as at present, I'm totally baffled.
I have a C++ application which I'm developing in IAR for the MK60FN1M0VLQ12 device. In debug mode, this works a charm and I can single step or breakpoint the code wherever I choose. The code runs without issue every time. When I switch to runtime mode, i.e. remove the debugger, then the application fails to start at all. I've even reduced the project down to bare minimum - disable the wdog, toggle an LED - but this still won't run.
This same code compiled using a different compiler works every time without fail during runtime.
My finger started to point towards IAR.
I've since opened up a project which came with the Kinetis 120MHz samples (the Hello World example) and successfully programmed this into my board and I'm happy to say that this project runs at runtime. Having compared the two projects - my original and the Hello World one - it seems that the differences are relating to the startup assembly files.
The one contained in my project (which doesn't run at runtime) contains a full list of interrupt vector functions. Something like...
; etc, etc
; more PUBWEAKs for all interrupts
; etc, etc
; more handlers for interrupts
; etc, etc
Whereas the other startup file in the Hello World project contains the following...
Now, obviously there is a lot of difference. Firstly, I have no idea what most of the statements in the first assembler file do and why they are there, but I'm thinking that they may be related to my issue. Also, I've noticed that the linker configuration files differ significantly - my project uses MK60xN1M_12.icf whereas the Hello World project uses 1MB_Pflash.icf.
If I change my project to use the second linker file, I get errors when trying to download the binary to the device saying that "your application would set the system security of the device". I then have to use Seggers J-Link Commander to unlock the device before I can re-program it.
Finally, another point of confusion. In the Hello World example, I hooked up the SysTick_Handler interrupt without any problem. However, I have no idea where this function is defined. Likewise I'm trying to implement an interrupt handler for ports B and D and having set up the NVIC correctly, the interrupts never fire - presumably because the system doesn't know what interrupt function to point to.
There is a vectors.c file which defines a __vector_table array and populates it with default function pointers, but the Hello World example never seems to use this - its also not defined in the startup assembler file (but it is in the one in my project). How can I possibly use this to get working interrupts?
Please can someone improve my very chaotic and ultimately confusing Saturday.
Thanks in advance to any kind soul.
Clearly a long soak in the bath is good for clearing the mind.
I hadn't included the vectors.c file in the build. Having done that, I can then declare __VECTOR_RAM and update the relevant positions in the array with the required interrupt function pointers.
This doesn't fix the initial issue I was seeing in my original project where the code wouldn't start at runtime, but now that I have a platform that does start at runtime, I'm just going to copy the code across piece by piece to see where (and if) it breaks.
Ok, so I've since done some more investigation into why the device isn't starting up during runtime.
I have narrowed it down to the USB interrupt. I'm currently working on the USB MSD Device Bootloader example from Freescale and having got the code working in IAR at debug time, as soon as I try to run it without the debugger, the device won't start.
If I comment out the USB initialization code, but leave in the interrupt function, it still won't start. If I remove the USB interrupt function, things start to work again. Likewise, if I start to initialize the USB module but leave out the interrupt, it still works (but obviously, no USB functionality).
I've just checked the errata for the Kinetis K60, specifically my mask set (1N96B) but there is nothing that hints of this type of problem.