Import Mbed OS hard-float snapshot

This commit is contained in:
Beslan
2026-06-01 20:15:04 +03:00
commit d3738e2f89
16278 changed files with 10628036 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
## Crash Log Parser Tool
This post-processing tool can be used to parse crash log generated by Mbed-OS when an exception happens.
## Capturing crash log
When an exception happens Mbed-OS will print out the crash information to STDOUT.
The crash information contains register context at the time exception and current threads in the system.
The information printed out to STDOUT will be similar to below. Registers captured depends on specific
Cortex-M core you are using. For example, if your target is using Cortex-M0, some registers like
MMFSR, BFSR, UFSR may not be available and will not appear in the crash log.
++ MbedOS Fault Handler ++
FaultType: HardFault
Context:
R0 : 0000AAA3
R1 : 20002070
R2 : 00009558
R3 : 00412A02
R4 : E000ED14
R5 : 00000000
R6 : 00000000
R7 : 00000000
R8 : 00000000
R9 : 00000000
R10 : 00000000
R11 : 00000000
R12 : 0000BCE5
SP : 20002070
LR : 00009E75
PC : 00009512
xPSR : 01000000
PSP : 20002008
MSP : 2002FFD8
CPUID: 410FC241
HFSR : 40000000
MMFSR: 00000000
BFSR : 00000000
UFSR : 00000100
DFSR : 00000008
AFSR : 00000000
SHCSR: 00000000
Thread Info:
Current:
State: 00000002 EntryFn: 0000ADF5 Stack Size: 00001000 Mem: 20001070 SP: 20002030
Next:
State: 00000002 EntryFn: 0000ADF5 Stack Size: 00001000 Mem: 20001070 SP: 20002030
Wait Threads:
State: 00000083 EntryFn: 0000AA1D Stack Size: 00000300 Mem: 20000548 SP: 200007D8
Delay Threads:
Idle Thread:
State: 00000001 EntryFn: 00009F59 Stack Size: 00000200 Mem: 20000348 SP: 20000508
-- MbedOS Fault Handler --
To generate more information copy and save this crash information to a text file and run the crash_log_parser.py tool as below.
NOTE: Make sure you copy the section with text "MbedOS Fault Handler" as the this tool looks for that header.
## Running the Crash Log Parser
crash_log_parser.py <Path to Crash log> <Path to Elf/Axf file of the build> <Path to Map file of the build>
For example:
crashlogparse.py crash.log C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.elf C:\MyProject\BUILD\k64f\arm\mbed-os-hf-handler.map
An example output from running crash_log_parser is shown below.
Parsed Crash Info:
Crash location = zero_div_test() [0000693E]
Caller location = $Super$$main [00009E99]
Stack Pointer at the time of crash = [20001CC0]
Target/Fault Info:
Processor Arch: ARM-V7M or above
Processor Variant: C24
Forced exception, a fault with configurable priority has been escalated to HardFault
Divide by zero error has occurred
Done parsing...

View File

@@ -0,0 +1,213 @@
#!/usr/bin/env python
"""
mbed SDK
Copyright (c) 2017-2019 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
LIBRARIES BUILD
"""
from __future__ import print_function
from os import path
import re
import bisect
from subprocess import check_output
import sys
#arm-none-eabi-nm -nl <elf file>
_NM_EXEC = "arm-none-eabi-nm"
_OPT = "-nlC"
_PTN = re.compile("([0-9a-f]*) ([Tt]) ([^\t\n]*)(?:\t(.*):([0-9]*))?")
class ElfHelper(object):
def __init__(self, elf_file, map_file):
op = check_output([_NM_EXEC, _OPT, elf_file.name]).decode('utf-8')
self.maplines = map_file.readlines()
self.matches = _PTN.findall(op)
self.addrs = [int(x[0], 16) for x in self.matches]
def function_addrs(self):
return self.addrs
def function_name_for_addr(self, addr):
i = bisect.bisect_right(self.addrs, addr)
funcname = self.matches[i-1][2]
return funcname
def print_HFSR_info(hfsr):
if int(hfsr, 16) & 0x80000000:
print("\t\tDebug Event Occurred")
if int(hfsr, 16) & 0x40000000:
print("\t\tForced exception, a fault with configurable priority has been escalated to HardFault")
if int(hfsr, 16) & 0x2:
print("\t\tVector table read fault has occurred")
def print_MMFSR_info(mmfsr, mmfar):
if int(mmfsr, 16) & 0x20:
print("\t\tA MemManage fault occurred during FP lazy state preservation")
if int(mmfsr, 16) & 0x10:
print("\t\tA derived MemManage fault occurred on exception entry")
if int(mmfsr, 16) & 0x8:
print("\t\tA derived MemManage fault occurred on exception return")
if int(mmfsr, 16) & 0x2:
if int(mmfsr, 16) & 0x80:
print("\t\tData access violation. Faulting address: %s"%(str(mmfar)))
else:
print("\t\tData access violation. WARNING: Fault address in MMFAR is NOT valid")
if int(mmfsr, 16) & 0x1:
print("\t\tMPU or Execute Never (XN) default memory map access violation on an instruction fetch has occurred")
def print_BFSR_info(bfsr, bfar):
if int(bfsr, 16) & 0x20:
print("\t\tA bus fault occurred during FP lazy state preservation")
if int(bfsr, 16) & 0x10:
print("\t\tA derived bus fault has occurred on exception entry")
if int(bfsr, 16) & 0x8:
print("\t\tA derived bus fault has occurred on exception return")
if int(bfsr, 16) & 0x4:
print("\t\tImprecise data access error has occurred")
if int(bfsr, 16) & 0x2:
if int(bfsr,16) & 0x80:
print("\t\tA precise data access error has occurred. Faulting address: %s"%(str(bfar)))
else:
print("\t\tA precise data access error has occurred. WARNING: Fault address in BFAR is NOT valid")
if int(bfsr, 16) & 0x1:
print("\t\tA bus fault on an instruction prefetch has occurred")
def print_UFSR_info(ufsr):
if int(ufsr, 16) & 0x200:
print("\t\tDivide by zero error has occurred")
if int(ufsr, 16) & 0x100:
print("\t\tUnaligned access error has occurred")
if int(ufsr, 16) & 0x8:
print("\t\tA coprocessor access error has occurred. This shows that the coprocessor is disabled or not present")
if int(ufsr, 16) & 0x4:
print("\t\tAn integrity check error has occurred on EXC_RETURN")
if int(ufsr, 16) & 0x2:
print("\t\tInstruction executed with invalid EPSR.T or EPSR.IT field( This may be caused by Thumb bit not being set in branching instruction )")
if int(ufsr, 16) & 0x1:
print("\t\tThe processor has attempted to execute an undefined instruction")
def print_CPUID_info(cpuid):
if (int(cpuid, 16) & 0xF0000) == 0xC0000:
print("\t\tProcessor Arch: ARM-V6M")
else:
print("\t\tProcessor Arch: ARM-V7M or above")
print("\t\tProcessor Variant: %X" % ((int(cpuid,16) & 0xFFF0 ) >> 4))
def parse_line_for_register(line):
_, register_val = line.split(":")
return register_val.strip()
def main(crash_log, elfhelper):
mmfar_val = 0
bfar_val = 0
lines = iter(crash_log.read().decode('utf-8').splitlines())
for eachline in lines:
if "++ MbedOS Fault Handler ++" in eachline:
break
else:
print("ERROR: Unable to find \"MbedOS Fault Handler\" header")
return
for eachline in lines:
if "-- MbedOS Fault Handler --" in eachline:
break
elif eachline.startswith("PC"):
pc_val = parse_line_for_register(eachline)
if elfhelper:
pc_name = elfhelper.function_name_for_addr(int(pc_val, 16))
else:
pc_name = "<unknown-symbol>"
elif eachline.startswith("LR"):
lr_val = parse_line_for_register(eachline)
if elfhelper:
lr_name = elfhelper.function_name_for_addr(int(lr_val, 16))
else:
lr_name = "<unknown-symbol>"
elif eachline.startswith("SP"):
sp_val = parse_line_for_register(eachline)
elif eachline.startswith("HFSR"):
hfsr_val = parse_line_for_register(eachline)
elif eachline.startswith("MMFSR"):
mmfsr_val = parse_line_for_register(eachline)
elif eachline.startswith("BFSR"):
bfsr_val = parse_line_for_register(eachline)
elif eachline.startswith("UFSR"):
ufsr_val = parse_line_for_register(eachline)
elif eachline.startswith("CPUID"):
cpuid_val = parse_line_for_register(eachline)
elif eachline.startswith("MMFAR"):
mmfar_val = parse_line_for_register(eachline)
elif eachline.startswith("BFAR"):
bfar_val = parse_line_for_register(eachline)
print("\nCrash Info:")
print("\tCrash location = %s [0x%s] (based on PC value)" % (pc_name.strip(), str(pc_val)))
print("\tCaller location = %s [0x%s] (based on LR value)" % (lr_name.strip(), str(lr_val)))
print("\tStack Pointer at the time of crash = [%s]" % (str(sp_val)))
print("\tTarget and Fault Info:")
print_CPUID_info(cpuid_val)
print_HFSR_info(hfsr_val)
print_MMFSR_info(mmfsr_val, mmfar_val)
print_BFSR_info(bfsr_val, bfar_val)
print_UFSR_info(ufsr_val)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Analyse mbed-os crash log. This tool requires arm-gcc binary utilities to be available in current path as it uses \'nm\' command')
# specify arguments
parser.add_argument(metavar='CRASH LOG', type=argparse.FileType('rb', 0),
dest='crashlog',help='path to crash log file')
parser.add_argument(metavar='ELF FILE', type=argparse.FileType('rb', 0),
nargs='?',const=None,dest='elffile',help='path to elf file')
parser.add_argument(metavar='MAP FILE', type=argparse.FileType('rb', 0),
nargs='?',const=None,dest='mapfile',help='path to map file')
# get and validate arguments
args = parser.parse_args()
# if both the ELF and MAP files are present, the addresses can be converted to symbol names
if args.elffile and args.mapfile:
elfhelper = ElfHelper(args.elffile, args.mapfile)
else:
print("ELF or MAP file missing, logging raw values.")
elfhelper = None
# parse input and write to output
main(args.crashlog, elfhelper)
#close all files
if args.elffile:
args.elffile.close()
if args.mapfile:
args.mapfile.close()
args.crashlog.close()