The following information is in addition to Igor's excellent answer.
From a C programming perspective, the interrupt handlers are defined in the cr_startup_xxx.c file (eg cr_startup_lpc13.c file for LPC1343). All possible interrupt handlers are defined there as a WEAK alias. If you do not define your own XXX_Handler() for an interrupt source, then the default interrupt handler function defined in this file will be used. The linker will sort out which function to include in the final binary along with the interrupt vector table from cr_startup_xxx.c
Example of GPIO interrupts from ports are shown in the demo files in gpio.c. There is one interrupt input to the NVIC per GPIO port. Each individual bit in the port can be enabled/disabled to generate an interrupt on that port. If you require interrupts on ports PIO1_4, and PIO1_5 for example, then you would enable the individual PIO1_4 and PIO1_5 interrupt bits in GPIO0IE. When your PIOINT0_Handler() interrupt handler function fires, it's up to you to determine which of PIO1_4 or PIO1_5 (or both) interrupts are pending by reading the GPIO0RIS register and handling the interrupt appropriately.
Illegal instruction means that it read an opcode, but that opcode does not match to any valid machine instruction.
Access violation means that you tried to use a type of memory access that is not supported by the device. For a flash, that usually means you tried to write to it without using the proper procedure for writing or erasing a page.
Access violation can also mean that you tried to execute a privileged instruction while in a user mode, though I'm not sure MSP430 supports this.
Another example of access violation is trying to fetch opcodes from a region of memory marked not-executable, though I doubt that the MSP430 has this kind of memory protection support.
Can I write an ISR for the NMI source, and make it act like a soft reset by reinitializing the stack pointer and "recursively" calling main or something like that, so that the register and RAM (global variable) state isn't altered?
I'd look for an app note or something in the datasheet saying how to do that. Generally, jumping to main()
does not work. You usually want to disable all interrupts, initialize the stack pointer, and jump to the reset vector. You may need to reset processor mode registers or control registers as well. This way, the code that sets things up before calling main()
gets run.
Assuming I can't intercept the one that results in a Reset vector (which I presume also comes along with a reinitialization of all the registers?), can I at least detect at startup that it happened by checking some status bit to decide what to do about it, and if so which status register/bit would that be?
I know the Atmel AVR has a register you can read that tells you why you were reset. Not sure about the MSP430.
Best Answer
Well as the name suggests. Non Maskable Interrupt (can't switch off or disable). It is for interrupts that are very important and should not be ignored. So it all depends on what you are using the chip for and what you would consider very important and can't be ignored.
So simple example is perhaps main power about to go down or going down so ignore what ever you are doing and save buffers to flash ram then perform a clean shutdown. Some micro systems have a super cap to hold main power for a short while extra after battery or regulator power dies.
Another might be in a heart beat monitor for surgical theater use. If the signal from the lead appears to vanish because the lead as disconnected or the patient is in trouble your micro runtime may need to indicate via an alarm of this situation. You don't want this ignored because the firmware is drawing fancy time expensive graphics on the monitor graphing moving average results etc.
I am sure that you can think of one or twp others. When designing your system not only do you have to decide the priority of interrupts as who can interrupt whom but which critical events can be wired in to interrupt anyone.