cortex-crash 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Trust & Thread
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: cortex-crash
3
+ Version: 1.0.0
4
+ Summary: All-in-one ARM Cortex-M HardFault triage suite (CFSR decoder, stack unwinder, C handlers)
5
+ Author-email: Trust & Thread <contact@trustandthread.com>
6
+ Project-URL: Homepage, https://www.trustandthread.com
7
+ Project-URL: Bug Tracker, https://github.com/GaneshMba4066/cortex-crash/issues
8
+ Project-URL: Documentation, https://www.trustandthread.com/firmware-checklist/
9
+ Keywords: arm,cortex-m,stm32,hardfault,firmware,debugging,unwind,cfsr
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Topic :: Software Development :: Embedded Systems
14
+ Requires-Python: >=3.6
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Dynamic: license-file
18
+
19
+ # cortex-crash
20
+
21
+ All-in-one ARM Cortex-M HardFault triage suite: decode CFSR status registers, unwind hardware-stacked frames with `addr2line`, and generate drop-in C/ASM fault capture stubs.
22
+
23
+ ## Installation
24
+
25
+ pip install cortex-crash
26
+
27
+ ## Usage
28
+
29
+ # Print drop-in naked C/ASM HardFault handler
30
+ cortex-crash init-c
31
+
32
+ # Decode fault registers
33
+ cortex-crash cfsr 0x00010200 0x20001FF7
34
+
35
+ # Unwind 8-word stack frame and resolve line from ELF
36
+ cortex-crash unwind 0x0 0x1 0x20000000 0x40021000 0x0 0x08001255 0x08001290 0x21000000 app.elf
37
+
38
+ # Unified triage
39
+ cortex-crash parse --cfsr 0x00010200 --bfar 0x20001FF7 --frame 0x0 0x1 0x20000000 0x40021000 0x0 0x08001255 0x08001290 0x21000000
40
+
41
+ ## License
42
+
43
+ MIT — Trust & Thread
@@ -0,0 +1,25 @@
1
+ # cortex-crash
2
+
3
+ All-in-one ARM Cortex-M HardFault triage suite: decode CFSR status registers, unwind hardware-stacked frames with `addr2line`, and generate drop-in C/ASM fault capture stubs.
4
+
5
+ ## Installation
6
+
7
+ pip install cortex-crash
8
+
9
+ ## Usage
10
+
11
+ # Print drop-in naked C/ASM HardFault handler
12
+ cortex-crash init-c
13
+
14
+ # Decode fault registers
15
+ cortex-crash cfsr 0x00010200 0x20001FF7
16
+
17
+ # Unwind 8-word stack frame and resolve line from ELF
18
+ cortex-crash unwind 0x0 0x1 0x20000000 0x40021000 0x0 0x08001255 0x08001290 0x21000000 app.elf
19
+
20
+ # Unified triage
21
+ cortex-crash parse --cfsr 0x00010200 --bfar 0x20001FF7 --frame 0x0 0x1 0x20000000 0x40021000 0x0 0x08001255 0x08001290 0x21000000
22
+
23
+ ## License
24
+
25
+ MIT — Trust & Thread
@@ -0,0 +1,2 @@
1
+ """cortex-crash: Unified ARM Cortex-M HardFault triage suite."""
2
+ __version__ = "1.0.0"
@@ -0,0 +1,59 @@
1
+ """CFSR and fault status register decoder logic."""
2
+
3
+ FAULT_STATUS_BITS = {
4
+ "DIVBYZERO": (1 << 25, "UsageFault", "Divide by zero executed (CCR.DIV_0_TRP enabled)."),
5
+ "UNALIGNED": (1 << 24, "UsageFault", "Unaligned memory access performed (CCR.UNALIGN_TRP enabled)."),
6
+ "NOCP": (1 << 19, "UsageFault", "Attempted coprocessor access without enable (e.g. FPU CPACR)."),
7
+ "INVPC": (1 << 18, "UsageFault", "Invalid PC load on EXC_RETURN or illegal integrity check."),
8
+ "INVSTATE": (1 << 17, "UsageFault", "Attempted execution in invalid EPSR state (e.g. Thumb bit cleared)."),
9
+ "UNDEFINSTR": (1 << 16, "UsageFault", "Undefined instruction encountered."),
10
+ "BFARVALID": (1 << 15, "BusFault", "BFAR address holds the valid faulting location."),
11
+ "LSPERR": (1 << 13, "BusFault", "Bus fault occurred during lazy FP state preservation."),
12
+ "STKERR": (1 << 12, "BusFault", "Bus fault on exception entry stacking."),
13
+ "UNSTKERR": (1 << 11, "BusFault", "Bus fault on exception exit unstacking."),
14
+ "IMPRECISERR": (1 << 10, "BusFault", "Imprecise data bus error (asynchronous)."),
15
+ "PRECISERR": (1 << 9, "BusFault", "Precise data bus error on valid address."),
16
+ "IBUSERR": (1 << 8, "BusFault", "Instruction bus error during prefetch."),
17
+ "MMARVALID": (1 << 7, "MemManage", "MMFAR holds valid address of memory management fault."),
18
+ "MLSPERR": (1 << 5, "MemManage", "MemManage fault during lazy FP preservation."),
19
+ "MSTKERR": (1 << 4, "MemManage", "MemManage fault during exception entry stacking."),
20
+ "MUNSTKERR": (1 << 3, "MemManage", "MemManage fault during exception exit unstacking."),
21
+ "DACCVIOL": (1 << 1, "MemManage", "Data access violation (MPU protection or NULL pointer dereference)."),
22
+ "IACCVIOL": (1 << 0, "MemManage", "Instruction access violation (MPU XN region or unmapped memory)."),
23
+ }
24
+
25
+
26
+ def classify_address(addr):
27
+ if 0x00000000 <= addr < 0x20000000:
28
+ return "Flash / Code Memory"
29
+ if 0x20000000 <= addr < 0x40000000:
30
+ return "SRAM"
31
+ if 0x40000000 <= addr < 0x60000000:
32
+ return "Peripheral Bus"
33
+ if 0x60000000 <= addr < 0xA0000000:
34
+ return "External RAM / Memory"
35
+ if 0xE0000000 <= addr <= 0xFFFFFFFF:
36
+ return "Private Peripheral Bus (PPB / System Control)"
37
+ return "Reserved / Undefined Region"
38
+
39
+
40
+ def decode_cfsr(cfsr, bfar=None, mmfar=None):
41
+ lines = [f"CFSR: 0x{cfsr:08X}"]
42
+ active = []
43
+ for bit_name, (mask, fault_type, desc) in FAULT_STATUS_BITS.items():
44
+ if cfsr & mask:
45
+ active.append((fault_type, bit_name, desc))
46
+
47
+ if not active:
48
+ lines.append(" No standard CFSR fault flags set.")
49
+ else:
50
+ for fault_type, bit_name, desc in active:
51
+ lines.append(f" [{fault_type}] {bit_name:<11} : {desc}")
52
+
53
+ if bfar is not None and (cfsr & (1 << 15)):
54
+ lines.append(f"\n BFAR: 0x{bfar:08X} ({classify_address(bfar)})")
55
+
56
+ if mmfar is not None and (cfsr & (1 << 7)):
57
+ lines.append(f"\n MMFAR: 0x{mmfar:08X} ({classify_address(mmfar)})")
58
+
59
+ return lines
@@ -0,0 +1,88 @@
1
+ """Main entry point for unified CLI."""
2
+
3
+ import argparse
4
+ import sys
5
+ from .cfsr import decode_cfsr
6
+ from .unwind import decode_frame
7
+ from .snippet import print_snippet
8
+
9
+ VERSION = "1.0.0"
10
+
11
+
12
+ def parse_hex(val):
13
+ return int(val.strip().lower().replace("0x", "").replace(",", ""), 16)
14
+
15
+
16
+ def main():
17
+ parser = argparse.ArgumentParser(
18
+ prog="cortex-crash",
19
+ description="Unified ARM Cortex-M Crash Diagnostics Suite by Trust & Thread"
20
+ )
21
+ parser.add_argument("-v", "--version", action="version", version=f"cortex-crash v{VERSION}")
22
+
23
+ subparsers = parser.add_subparsers(dest="command")
24
+
25
+ # Command: parse
26
+ p_parse = subparsers.add_parser("parse", help="Decode registers and unwound stack frame")
27
+ p_parse.add_argument("--cfsr", type=str, help="CFSR hex value (e.g. 0x00010200)")
28
+ p_parse.add_argument("--bfar", type=str, help="BFAR hex value")
29
+ p_parse.add_argument("--mmfar", type=str, help="MMFAR hex value")
30
+ p_parse.add_argument("--frame", nargs=8, help="8 stacked registers: r0 r1 r2 r3 r12 lr pc xpsr")
31
+ p_parse.add_argument("elf", nargs="?", help="Optional .elf file to resolve symbols")
32
+
33
+ # Command: cfsr
34
+ p_cfsr = subparsers.add_parser("cfsr", help="Quickly decode CFSR hex")
35
+ p_cfsr.add_argument("cfsr", type=str, help="CFSR register hex value")
36
+ p_cfsr.add_argument("bfar", nargs="?", type=str, help="Optional BFAR address")
37
+
38
+ # Command: unwind
39
+ p_unwind = subparsers.add_parser("unwind", help="Quickly unwind stack frame")
40
+ p_unwind.add_argument("regs", nargs=8, help="8 stacked registers: r0 r1 r2 r3 r12 lr pc xpsr")
41
+ p_unwind.add_argument("elf", nargs="?", help="Optional .elf file")
42
+
43
+ # Command: init-c
44
+ subparsers.add_parser("init-c", help="Print drop-in C/ASM HardFault handler source")
45
+
46
+ args = parser.parse_args()
47
+
48
+ if not args.command:
49
+ parser.print_help()
50
+ return 0
51
+
52
+ print("=" * 66)
53
+ print(f" TRUST & THREAD :: CORTEX-M CRASH ANALYZER v{VERSION}")
54
+ print("=" * 66)
55
+
56
+ if args.command == "init-c":
57
+ print_snippet()
58
+ return 0
59
+
60
+ if args.command == "cfsr":
61
+ cfsr_val = parse_hex(args.cfsr)
62
+ bfar_val = parse_hex(args.bfar) if args.bfar else None
63
+ print("\n".join(decode_cfsr(cfsr_val, bfar_val)))
64
+
65
+ elif args.command == "unwind":
66
+ frame_vals = [parse_hex(x) for x in args.regs]
67
+ print("\n".join(decode_frame(frame_vals, args.elf)))
68
+
69
+ elif args.command == "parse":
70
+ if args.cfsr:
71
+ cfsr_val = parse_hex(args.cfsr)
72
+ bfar_val = parse_hex(args.bfar) if args.bfar else None
73
+ mmfar_val = parse_hex(args.mmfar) if args.mmfar else None
74
+ print("\n[Fault Registers]")
75
+ print("\n".join(decode_cfsr(cfsr_val, bfar_val, mmfar_val)))
76
+ if args.frame:
77
+ frame_vals = [parse_hex(x) for x in args.frame]
78
+ print("\n[Stack Frame]")
79
+ print("\n".join(decode_frame(frame_vals, args.elf)))
80
+
81
+ print("\n" + "=" * 66)
82
+ print(" Free Firmware Checklist: https://www.trustandthread.com/firmware-checklist/")
83
+ print("=" * 66)
84
+ return 0
85
+
86
+
87
+ if __name__ == "__main__":
88
+ sys.exit(main())
@@ -0,0 +1,44 @@
1
+ """Embedded C/assembly snippet generator."""
2
+
3
+ C_STUB = r"""/* Drop-in HardFault Handler for ARM Cortex-M (Trust & Thread) */
4
+ #include <stdint.h>
5
+ #include <stdio.h>
6
+
7
+ #define SCB_CFSR (*(volatile uint32_t *)0xE000ED28)
8
+ #define SCB_BFAR (*(volatile uint32_t *)0xE000ED38)
9
+
10
+ typedef struct __attribute__((packed)) {
11
+ uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
12
+ } StackFrame_t;
13
+
14
+ void HardFault_Handler_C(StackFrame_t *frame, uint32_t lr_val) {
15
+ uint32_t cfsr = SCB_CFSR;
16
+ uint32_t bfar = SCB_BFAR;
17
+ printf("\r\n--- CORTEX-M CRASH DUMP ---\r\n");
18
+ printf("CFSR: 0x%08lX | BFAR: 0x%08lX\r\n", cfsr, bfar);
19
+ printf("STACK: 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX\r\n",
20
+ frame->r0, frame->r1, frame->r2, frame->r3,
21
+ frame->r12, frame->lr, frame->pc, frame->xpsr);
22
+ printf("RUN COMMAND:\r\n");
23
+ printf("cortex-crash parse --cfsr 0x%08lX --bfar 0x%08lX --frame 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX app.elf\r\n",
24
+ cfsr, bfar, frame->r0, frame->r1, frame->r2, frame->r3,
25
+ frame->r12, frame->lr, frame->pc, frame->xpsr);
26
+ __asm volatile("bkpt #1");
27
+ while (1);
28
+ }
29
+
30
+ __attribute__((naked)) void HardFault_Handler(void) {
31
+ __asm volatile(
32
+ "tst lr, #4 \n"
33
+ "ite eq \n"
34
+ "mrseq r0, msp \n"
35
+ "mrsne r0, psp \n"
36
+ "mov r1, lr \n"
37
+ "b HardFault_Handler_C\n"
38
+ );
39
+ }
40
+ """
41
+
42
+
43
+ def print_snippet():
44
+ print(C_STUB)
@@ -0,0 +1,111 @@
1
+ """Stack unwinder and symbol resolution logic."""
2
+
3
+ import shutil
4
+ import subprocess
5
+
6
+ FRAME_REGS = ["r0", "r1", "r2", "r3", "r12", "lr", "pc", "xpsr"]
7
+
8
+ EXC_RETURN_KIND = {
9
+ 0x01: ("Handler mode, MSP, no FP", False),
10
+ 0x09: ("Thread mode, MSP, no FP", False),
11
+ 0x0D: ("Thread mode, PSP, no FP", False),
12
+ 0x11: ("Handler mode, MSP, FP extended frame", True),
13
+ 0x19: ("Thread mode, MSP, FP extended frame", True),
14
+ 0x1D: ("Thread mode, PSP, FP extended frame", True),
15
+ }
16
+
17
+
18
+ def pick_addr2line():
19
+ for t in ("arm-none-eabi-addr2line", "addr2line"):
20
+ if shutil.which(t):
21
+ return t
22
+ return None
23
+
24
+
25
+ def addr2line(tool, elf, addr):
26
+ if not tool or not elf:
27
+ return None
28
+ try:
29
+ r = subprocess.run([tool, "-f", "-C", "-e", elf, f"0x{addr:08X}"],
30
+ capture_output=True, text=True, timeout=10)
31
+ lines = [l.strip() for l in r.stdout.strip().splitlines() if l.strip()]
32
+ if len(lines) >= 2 and "??" not in lines[0]:
33
+ return lines[0], lines[1]
34
+ except Exception:
35
+ pass
36
+ return None
37
+
38
+
39
+ def decode_xpsr(xpsr):
40
+ lines = []
41
+ ipsr = xpsr & 0x1FF
42
+ lines.append(f"IPSR = {ipsr}")
43
+ if ipsr == 0:
44
+ lines.append(" Active execution mode: Thread Mode")
45
+ elif ipsr == 2:
46
+ lines.append(" Active exception: NMI")
47
+ elif ipsr == 3:
48
+ lines.append(" Active exception: HardFault")
49
+ elif ipsr == 4:
50
+ lines.append(" Active exception: MemManage")
51
+ elif ipsr == 5:
52
+ lines.append(" Active exception: BusFault")
53
+ elif ipsr == 6:
54
+ lines.append(" Active exception: UsageFault")
55
+ elif 16 <= ipsr < 256:
56
+ lines.append(f" Active interrupt: IRQ{ipsr - 16}")
57
+
58
+ if xpsr & (1 << 24):
59
+ lines.append(" Thumb bit set (EPSR.T=1) — valid execution state")
60
+ else:
61
+ lines.append(" [!] Thumb bit CLEAR (EPSR.T=0) — invalid state / corrupt branch target")
62
+ return lines
63
+
64
+
65
+ def decode_frame(frame, elf=None):
66
+ tool = pick_addr2line()
67
+ lines = []
68
+ lines.append(f" {'Reg':<6} {'Value':<12} Notes")
69
+ lines.append("-" * 40)
70
+ lr_val = frame[5]
71
+ exc_return = (lr_val & 0xFFFFFFF0) == 0xFFFFFFF0
72
+ for name, val in zip(FRAME_REGS, frame):
73
+ if name == "lr" and exc_return:
74
+ note = "(EXC_RETURN)"
75
+ elif name in ("pc", "lr") and (val & 1):
76
+ note = "(Thumb bit set)"
77
+ else:
78
+ note = ""
79
+ lines.append(f" {name:<6} 0x{val:08X} {note}")
80
+ lines.append("-" * 40)
81
+
82
+ lines.append("\n[Execution State]")
83
+ for l in decode_xpsr(frame[7]):
84
+ lines.append(" " + l)
85
+
86
+ if exc_return:
87
+ n = lr_val & 0x1F
88
+ desc, fp = EXC_RETURN_KIND.get(n, (f"Variant 0x{lr_val & 0xFF:X}", not bool(lr_val & (1 << 4))))
89
+ lines.append(f"\n[EXC_RETURN] 0x{lr_val:08X} ({desc})")
90
+ if fp:
91
+ lines.append(" Extended frame: 26 words stacked (includes FP registers).")
92
+ else:
93
+ lines.append(" Basic frame: 8 words stacked.")
94
+
95
+ pc = frame[6] & ~1
96
+ lines.append("\n[Crash Site]")
97
+ lines.append(f" PC: 0x{pc:08X}")
98
+ res_pc = addr2line(tool, elf, pc)
99
+ if res_pc:
100
+ lines.append(f" -> {res_pc[0]} at {res_pc[1]}")
101
+
102
+ if not exc_return:
103
+ lr = lr_val & ~1
104
+ lines.append(f" LR: 0x{lr:08X}")
105
+ res_lr = addr2line(tool, elf, lr)
106
+ if res_lr:
107
+ lines.append(f" -> {res_lr[0]} at {res_lr[1]}")
108
+
109
+ if elf and not tool:
110
+ lines.append("\n [!] arm-none-eabi-addr2line not found in PATH.")
111
+ return lines
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: cortex-crash
3
+ Version: 1.0.0
4
+ Summary: All-in-one ARM Cortex-M HardFault triage suite (CFSR decoder, stack unwinder, C handlers)
5
+ Author-email: Trust & Thread <contact@trustandthread.com>
6
+ Project-URL: Homepage, https://www.trustandthread.com
7
+ Project-URL: Bug Tracker, https://github.com/GaneshMba4066/cortex-crash/issues
8
+ Project-URL: Documentation, https://www.trustandthread.com/firmware-checklist/
9
+ Keywords: arm,cortex-m,stm32,hardfault,firmware,debugging,unwind,cfsr
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Topic :: Software Development :: Embedded Systems
14
+ Requires-Python: >=3.6
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Dynamic: license-file
18
+
19
+ # cortex-crash
20
+
21
+ All-in-one ARM Cortex-M HardFault triage suite: decode CFSR status registers, unwind hardware-stacked frames with `addr2line`, and generate drop-in C/ASM fault capture stubs.
22
+
23
+ ## Installation
24
+
25
+ pip install cortex-crash
26
+
27
+ ## Usage
28
+
29
+ # Print drop-in naked C/ASM HardFault handler
30
+ cortex-crash init-c
31
+
32
+ # Decode fault registers
33
+ cortex-crash cfsr 0x00010200 0x20001FF7
34
+
35
+ # Unwind 8-word stack frame and resolve line from ELF
36
+ cortex-crash unwind 0x0 0x1 0x20000000 0x40021000 0x0 0x08001255 0x08001290 0x21000000 app.elf
37
+
38
+ # Unified triage
39
+ cortex-crash parse --cfsr 0x00010200 --bfar 0x20001FF7 --frame 0x0 0x1 0x20000000 0x40021000 0x0 0x08001255 0x08001290 0x21000000
40
+
41
+ ## License
42
+
43
+ MIT — Trust & Thread
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ cortex_crash/__init__.py
5
+ cortex_crash/cfsr.py
6
+ cortex_crash/cli.py
7
+ cortex_crash/snippet.py
8
+ cortex_crash/unwind.py
9
+ cortex_crash.egg-info/PKG-INFO
10
+ cortex_crash.egg-info/SOURCES.txt
11
+ cortex_crash.egg-info/dependency_links.txt
12
+ cortex_crash.egg-info/entry_points.txt
13
+ cortex_crash.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cortex-crash = cortex_crash.cli:main
@@ -0,0 +1 @@
1
+ cortex_crash
@@ -0,0 +1,31 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cortex-crash"
7
+ version = "1.0.0"
8
+ authors = [
9
+ { name="Trust & Thread", email="contact@trustandthread.com" },
10
+ ]
11
+ description = "All-in-one ARM Cortex-M HardFault triage suite (CFSR decoder, stack unwinder, C handlers)"
12
+ readme = "README.md"
13
+ requires-python = ">=3.6"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Topic :: Software Development :: Embedded Systems",
19
+ ]
20
+ keywords = ["arm", "cortex-m", "stm32", "hardfault", "firmware", "debugging", "unwind", "cfsr"]
21
+
22
+ [tool.setuptools]
23
+ packages = ["cortex_crash"]
24
+
25
+ [project.urls]
26
+ "Homepage" = "https://www.trustandthread.com"
27
+ "Bug Tracker" = "https://github.com/GaneshMba4066/cortex-crash/issues"
28
+ "Documentation" = "https://www.trustandthread.com/firmware-checklist/"
29
+
30
+ [project.scripts]
31
+ cortex-crash = "cortex_crash.cli:main"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+