Peter
A lock-up occurs when either an NMI or hard fault takes place but then results in another error that can't be recovered from.
This probably means that you don't have a proper hard fault handler installed so I would add this first. It can be any routine but I prefer to just use:
void __interrupt fnHardFault(void) // __interrupt has no meaning apart from making it clear that it is an interrupt handler
{
}
You can then set a break point in the interrupt handler and wait for it to be called (it will usually be due to code accessing non-existent memory or trying to write to a NULL pointer, or general run-away code).
When the break point is hit switch the debugger to disassemble mode (instruction stepping) and simply step back out of the interrupt and you will see the operation that caused it to fire. Then you can usually see what went wrong.
In the worst case it will be random code, which means that the fault was a result of a pevious fault (then trace may be useful to be able to look back to the initial fault).
If you happen to see what looks like valid code it can be an indication that the you have the Flash clock set too high (max. 25MHz) because this can make program operation unreliable. (In fact I have also seen Flash running sightly less that the maximum Flash speed randomly causing faults to occur but I understand that this was due to poor power supply design in that particular case).
Finally you should look at the watchdog concept since it is usually the first part of a design and not an after-thought in a project.
Regards
Mark
Kinetis: µTasker Kinetis support
K20: µTasker Kinetis TWR-K20D72M support / µTasker Kinetis FRDM-K20D50M support / µTasker Kinetis TWR-K20D50M support / µTasker Teensy3.1 support
For the complete "out-of-the-box" Kinetis experience and faster time to market