APPENDIX E Cortex-M3 Troubleshooting Guide

Overview

One of the challenges of using the Cortex-M3 is to locate problems when the program goes wrong. The Cortex-M3 processor provides a number of fault status registers to assist in troubleshooting (see Table E.1).

Table E.1 Fault Status Registers on Cortex-M3

image

The MMSR, BFSR, and UFSR registers can be accessed in one go using a word transfer instruction. In this situation the combined fault status register is called the Configurable Fault Status Register (CFSR).

Another important piece of information is the stacked Program Counter (PC). This is located in memory address [SP + 0x24]. Since there are two stack pointers in the Cortex-M3, the fault handler might need to determine which stack pointer was used before obtaining the stacked PC.

In addition, for bus faults and memory management faults, you might also able to determine the address that caused the fault. This is done by accessing the MemManage (Memory Management) Fault Address Register (MMAR) and the Bus Fault Address Register (BFAR). The contents of these two registers are only valid when the MMAVALID bit (in MMSR) or BFARVALID bit (in BFSR) is set. The MMAR and BFAR are physically the same register, so only one of them can be valid at a time (see Table E.2).

image

Figure E.1 Accessing Fault Status Registers

Table E.2 Fault Address Registers on Cortex-M3

image

Finally, the Link Register (LR) value when entering the fault handler might also provide hints about the cause of the fault. In the case of faults caused by invalid EXC_RETURN value, the value of LR when the fault handler is entered shows the previous LR value when the fault occured. Fault handler can report the faulty LR value, and software programmers can then use this information to check why the LR ends up with an illegal return value.

Developing Fault Handlers

In most cases, fault handlers for development and for real running systems differ from one another. For software development, the fault handler should focus on reporting the type of error, whereas the fault handler for running systems will likely focus on system recovery actions. Here we cover only the fault reporting because system recovery actions highly depend on design type and requirements.

In complex software, instead of outputting the results inside the fault handler, the contents of these registers can be copied to a memory block and then you can use PendSV to report the fault details later. This avoids potential faults in display or outputting routines causing lockup. For simple applications this might not matter, and the fault details can be output directly within the fault handler routine.

Report Fault Status Registers

The most basic step of a fault handler is to report the fault status register values. These include:

  • UFSR
  • BFSR
  • MMSR
  • HFSR
  • DFSR
  • AFSR (optional)

Report Stacked PC

The step for getting the stacked PC is similar to the SVC example in this book.

image

Figure E.2 Getting the Value of a Stacked PC from Stack Memory

This process can be carried out in assembly language as:

image

To help with debugging, we should also create a disassembled code list file so that we can locate the problem easily.

Read Fault Address Register

The fault address register can be erased after the MMARVALID or BFARVALID is cleared. To correctly access the fault address register, the following procedure should be used:

  1. Read BFAR/MMAR.
  2. Read BFARVALID/MMARVALID. If it is zero, the BFAR/MMAR read should be discarded.
  3. Clear BFARVALID/MMARVALID.

The reason for this procedure instead of reading valid bits first is to prevent a fault handler being preempted by another higher-priority fault handler after the valid bit is read, which could lead to the following erroneous fault-reporting sequence:

  1. Read BFARVALID/MMARVALID.
  2. Valid bit is set, going to read BFAR/MMAR.
  3. Higher-priority exception preempts existing fault handler, which generates another fault, causing another fault handler to be executed.
  4. The higher-priority fault handler clears the BFARVALID/MMARVALID bit, causing the BFAR/MMAR to be erased.
  5. After returning to the original fault handler, the BFAR/MMAR is read, but now the content is invalid and leads to incorrect reporting of the fault address.

Therefore it is important to read the BFARVALID/MMARVALID after reading the Fault Address register to ensure that the address register content is valid.

Clear Fault Status Bits

After the fault reporting is done, the fault status bit in the FSR should be cleared so that next time the fault handler is executed, the previous faults will not confuse the fault handler. In addition, if the fault address valid bit is not clear, the fault address register will not get an update for the next fault.

Others

It is often necessary to save the contents of LR in the beginning of a fault handler. However, if the fault is caused by a stack error, pushing the LR to stack might just make things worst. As we know, R0–R3 and R12 should already been saved, so we could copy LR to one of these registers before doing any function calls.

Understanding the Cause of the Fault

After obtaining the information we need, we can establish the cause of the problem. Tables E.3E.7 list some of the common reasons that faults occur.

Table E.3 MemManage Fault Status Register

image

Table E.4 Bus Fault Status Register

image image

Table E.5 Usage Fault Status Register

image image

Table E.6 Hard Fault Status Register

image

Table E.7 Debug Fault Status Register

image image

Other Possible Problems

A number of other common problems are in Table E.8.

Table E.8 Other Possible Problems

image
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.80.187