The following steps explain how to enable Fault component using the µVision. Other tools might use different ways to accomplish this.
For User Code:
- Add Fault Storage (and Record) Component.
- Locate fault information in uninitialized memory to be preserved over system reset.
Add Fault Storage (and Record) Component
To use the Fault component in an application, you need to:
- Select the software components CMSIS-View:Fault:Storage, CMSIS-View:Fault:Record and CMSIS-View:Event Recorder using the RTE management dialog.
- Include the ARM_Fault.h header and EventRecorder.h header files in your source code
- Add fault handlers that jump to ARM_FaultSave function
- Check if a fault has occurred and output fault information to Event Recorder or STDIO and analyze it, or analyze fault information in a Component Viewer window in a debug session
Code example:
#include "EventRecorder.h"
#include "ARM_Fault.h"
__attribute__((naked)) void HardFault_Handler (void) {
__ASM volatile (
"b ARM_FaultSave\n"
);
}
int main() {
SystemCoreClockUpdate();
}
while (1) {
__NOP();
}
}
Locate fault information in uninitialized memory
For preservation of the saved fault information after system reset, RAM for the ARM_FaultInfo structure should be placed to a memory region that is not cleared (or initialized) by a system restart (reset).
Note
- Make sure that you use normal, non-cacheable, and non-shareable memory for fault information data.
For size of this memory section take a look at Resource requirements.
To setup this uninitialized RAM, use either Create memory region using linker script or Create memory region using µVision procedure.
Create memory region using linker script
If the linker script does not contain provisions for uninitialized memory section then, for respective toolchain, add the necessary section like described below:
Arm Compiler:
For the Arm Compiler toolchain add the following code snippet to the linker script (.sct file), in the part specifying RAM sections (usually before Heap section):
RW_NOINIT <start_address> UNINIT 0x800 {
*(.bss.noinit)
*(.bss.noinit.*)
}
Note
- <start_address> is the physical address in RAM where the section will start.
- 0x800 is the size of the section covering also default Event Recorder data, adjust that as necessary
GCC:
For the GCC toolchain add the following code snippet to the linker script (.ld file), in the part specifying RAM sections (usually before Heap section):
.noinit (NOLOAD) :
{
. = ALIGN(4);
__noinit_start = .;
*(.noinit)
*(.noinit.*)
. = ALIGN(4);
__noinit_end = .;
} > RAM
Note
- The code snippet above expects defined RAM memory region, if RAM region is not defined then adapt the script accordingly.
Create memory region using µVision
To setup this uninitialized RAM in the µVision, follow the steps below:
- In the Options for Target dialog, define a Read/Write Memory Area that is not initialized, by splitting available internal RAM into 2 areas.
For example, split IRAM1 into two regions. Reduce size of IRAM1 to 0x800 and create an IRAM2 area with remaining of the available RAM. Enable NoInit for the IRAM1 region.
- In the Options for Component Class 'CMSIS-View' dialog (opens with right-click on ARM_FaultStorage.c in the Project window), on the Memory tab, assign Zero Initialized Data to the IRAM1 region.
- Build the application to place the ARM_FaultInfo structure to uninitialized RAM.