I've seen two cases now with dsPIC 30F4013 where the controller was resetting due to an undefined trap. Why these traps were getting raised in the first place is still a mystery, but that's not my immediate question. I'm starting to think it would be a good programming practice to always define all traps, even if traps should never occur, so I get at least a clear error message instead of a random reset. Is this a standard practice that I'm unaware of? Are there disadvantages to this practice I should consider?
-
4\$\begingroup\$ Not an answer to your question, but I suffered with those kinds of symptoms on dsPIC & PIC24 systems a little while ago. In my case the traps resulted from bits of code where I was de-referencing pointers to 16-bit values and these pointers themselves had odd (not-even) values, since they were pointing into a circular comms buffer - and I had no prior way of knowing whether the 16-bit value would start on an odd or even boundary. The XC16 compiler doesn't protect you from the hardware's hangups here. I ended up writing a wrapper macro for these functions which forced 2 8-bit pointer de-refs. \$\endgroup\$– brhansFeb 22, 2016 at 15:23
2 Answers
My informal rule is:
- If an interrupt is enabled, then you should have code that handles it.
- If you don't write code for an interrupt, disable it.
- If you can't disable it, write code for it.
Even without that rule, though, the data sheet explicitly answers your question:
If the user does not intend to take corrective action in the event of a trap error condition, these vectors must be loaded with the address of a default handler that simply contains the RESET instruction. If, on the other hand, one of the vectors containing an invalid address is called, an address error trap is generated.
(Source, section 8.3, first note)
Given that you cannot mask traps, then you must handle them. If you do not desire to deal with the trap in a particular fashion, the appropriate method is to execute a RESET
instruction.
-
\$\begingroup\$ Yup. I have a standard module with targets for all traps. \$\endgroup\$ Feb 22, 2016 at 22:09
Yes, it's a good idea - the only downside is a bit of extra code size, and you have to decide what to do with the trap (emit a message on the serial port? turn on a "FAILED" light? Silently reboot? etc)
-
4\$\begingroup\$ I usually just have the processor run in a infinite NOP/GOTO loop. That way the stack hasn't been corrupted from the trap, and when debugging I have a chance to unravel it and figure out what happened. I don't get traps often, but 80% of the time its a odd address trap, usually because garbage got loaded as a pointer. Sometimes the stack pointer gets corrupted and produces odd address traps. Those are harder to debug since the stack is no longer there. Fortunately, that's really rare. \$\endgroup\$ Feb 22, 2016 at 22:08