General Exception Code Example in C Using chipKIT™ Wi-FIRE

 Objective

This page contains a basic general exception code example for the PIC32MZ MCU.

The project implements a custom _general_exception_handler() function that is triggered by either a trap exception, or an illegal address exception, depending on which line of "bad" code is un-commented in main.c.

Simply uncomment one of the "bad" lines of code, then build/run in debug mode. The project contains a while(1); loop inside the general exception handler. When this is reached, the code can be halted, and the "Watches" window may be examined to view the Cause, Status and EPC registers to determine the cause of the exception. The disassembly listing output file should also be examined to verify the EPC value.

The hardware for this project uses the ArduinoTM compatible chipKIT Wi-FIRE board from Digilent Inc.

 Materials

Hardware Tools (Optional)

Tool About Purchase
chipkit-wifire-50px.png
chipKIT™ Wi-FIRE
Development Board
PICkit3-50px.png
PICkit™ 3
In-Circuit Debugger
TPROG001-50px.png
TPROG001
PICkit 3 Programming Cable Kit
AC002014-50px.png
AC002014
9V Wall Mount Power Supply

Software Tools

This project has been verified to work with the following versions of software tools:
MPLAB® X IDE v3.15, MPLAB® XC32 Compiler v1.40. The current versions of these tools will probably work as well, so try using them first.

Tool About Installers
Installation
Instructions
Windows Linux Mac OSX
MPLAB® X
Integrated Development Environment
MPLAB® XC32
C/C++ Compiler

Exercise Files

File Download
Installation
Instructions
Windows Linux Mac OSX
Project and Source Files

We recommend extracting the .zip to the following "root" folders:

Windows:

  • C:


Linux:

  • /home/<username>/MPLABXProjects


Mac OS:

  • Users/<username>/MPLABXProjects


You should see an appended sub-folder "/MTT/32bit-mz-ef/code-examples/general-exception-usage" containing the project "general-exception-usage.X"

 Procedure

Attach the debugger to the Wi-Fire board. Power up the board. Start MPLAB X.

1

Open the project

mplabx-open-project.png

2

Un-comment either line 168 or 169 in main.c (line 168 will trigger an "write to illegal address" exception, while line 169 will trigger a "divide-by-zero trap" exception)

pic32mz-general-exception-usage.png

3

Build/Debug the project

mplabx-build-debug.png

4

Run the project

mplabx-debug-run.png

5

Halt the project

mplabx-debug-halt.png

 Results

Error 1 (Illegal Address Exception - main.c - line 168 executed)

LED LD1 will light up, to indicate the occurrence of this exception:

code-examples-general-exception-usage-results-error1.png

In MPLAB® X, open the Watches Window window and add the Status, Cause and EPC CP0 registers to the view:

pic32mz-general-exception-usage-watches-window-error1.png

The Status register reads 0x05000002. Ignore the leading 0x05 for now and focus on the last nibble 0x2 (StatusEXL = 1). Per the PIC32 Datasheet, this indicates that we've encountered an error.

StatusEXL:

Exception Level: Set by the processor when any exception other than Reset, Soft Reset, NMI or Cache Error exception are taken

The Cause register reads 0x00800014. Ignore the leading 0x0080 for now. The LSB value of 0x14 is tricky since it isn't properly aligned within the LSB to directly represent the EXCCODE value. We need to convert this number to the true value of the structure within CauseEXCCODE.

Right shift 0x14 twice, and we get the value 0x05. Looking at the exception cause table in the PIC32MZ CPU Family Reference Manual, we see that this equates to ADDRESS ERROR EXCEPTION (STORE):

CauseEXCCODE<4:0>:

Exception Code Bits:

Indicates what kind of exception happened. Used by the _general_exception_handler() to determine the cause of the exception and branch to the appropriate handler code.

table50-27.png


Note: On PIC32MZ, Interrupt Exceptions all have their own dedicated entry point and therefore, their handlers do not need to need to consult CauseEXCCODE.

The EPC register reads 0x9D000630. This is the address of the instruction which the CPU will resume processing after returning from exception. We can confirm this by displaying the disassembly listing file (in MPLAB X, select Window»Output»Disassembly Listing File):

error-1-disassembly-listing-ef.png

This is an example of a precise exception, whereby the EPC value identifies the instruction that caused the exception.

Error 2 (Trap Exception - main.c - line 169 executed)

LED LD2 will light up, to indicate the occurrence of this exception:

code-examples-general-exception-usage-results-error2.png

In MPLAB® X, open the Watches Window window and add the Status, Cause and EPC CP0 registers to the view:

pic32mz-general-exception-usage-watches-window-error2.png

The Status register reads 0x05000002. Ignore the leading 0x05 for now and focus on the last nibble 0x2 (StatusEXL = 1). Per the PIC32 Datasheet, this indicates that we've encountered an error.

The Cause register reads 0x00800034. Right shift the LSB 0x34 twice, and we get the value 0x0D. Looking at the exception cause table in the PIC32MZ CPU Family Reference Manual, we see that this equates to a TRAP EXCEPTION.

The EPC register reads 0x9D000634. This is the address of the instruction which the CPU will resume processing after returning from exception. We can confirm this by displaying the disassembly listing file (in MPLAB X, select Window»Output»Disassembly Listing File):

error-2-disassembly-listing-ef.png

This is an example of an imprecise exception, whereby the EPC value does not identify the instruction that caused the exception.

In this example, the divide operation is carried out by the Multiply-Divide Unit which runs in parallel to the main CPU. The EPC value points to the CPU instruction that was interrupted by the MDU exception.

 Conclusions

This project has provided an example of how to implement a custom general exception handler on the PIC32MZ MCU. For more information on the steps required to setup and configure interrupts and exceptions on the PIC32MZ, please visit the PIC32MZ Interrupt and Exception Usage page.

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.