Skip to content

Commit 7232e33

Browse files
committed
docs: replace ASCII images with Mermaid
1 parent 8bf7208 commit 7232e33

1 file changed

Lines changed: 62 additions & 78 deletions

File tree

README.md

Lines changed: 62 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,25 @@ FPBInject enables runtime function hooking and code injection on Cortex-M microc
2323

2424
## How It Works
2525

26-
```
27-
┌─────────────────────────────────────────────────────────────────────────┐
28-
│ FPBInject Injection Flow │
29-
├─────────────────────────────────────────────────────────────────────────┤
30-
│ │
31-
│ 1. Original Call 2. FPB Intercept 3. Trampoline │
32-
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
33-
│ │ caller() │ │ FPB Unit │ │ trampoline_0 │ │
34-
│ │ calls │────────> │ addr match │───────> │ in Flash │ │
35-
│ │ digitalWrite │ │ 0x08008308 │ │ loads target │ │
36-
│ └──────────────┘ └──────────────┘ └──────────────┘ │
37-
│ │ │
38-
│ 4. RAM Code Execution ▼ │
39-
│ ┌──────────────────────────────────────────────────────────────────┐ │
40-
│ │ inject_digitalWrite() @ 0x20000278 (RAM) │ │
41-
│ │ - Custom hook logic executes │ │
42-
│ │ - Can call original function or replace entirely │ │
43-
│ └──────────────────────────────────────────────────────────────────┘ │
44-
│ │
45-
└─────────────────────────────────────────────────────────────────────────┘
26+
```mermaid
27+
flowchart LR
28+
subgraph step1 ["1. Original Call"]
29+
A["caller()<br/>calls<br/>digitalWrite"]
30+
end
31+
32+
subgraph step2 ["2. FPB Intercept"]
33+
B["FPB Unit<br/>addr match<br/>0x08008308"]
34+
end
35+
36+
subgraph step3 ["3. Trampoline"]
37+
C["trampoline_0<br/>in Flash<br/>loads target"]
38+
end
39+
40+
subgraph step4 ["4. RAM Code Execution"]
41+
D["inject_digitalWrite() @ 0x20000278 (RAM)<br/>• Custom hook logic executes<br/>• Can call original function or replace entirely"]
42+
end
43+
44+
A --> B --> C --> D
4645
```
4746

4847
### Architecture
@@ -286,34 +285,29 @@ DebugMonitor mode provides a software-based alternative that works on both legac
286285

287286
### How DebugMonitor Mode Works
288287

289-
```
290-
┌─────────────────────────────────────────────────────────────────────────┐
291-
│ DebugMonitor Redirection Flow │
292-
├─────────────────────────────────────────────────────────────────────────┤
293-
│ │
294-
│ 1. Function Call 2. FPB Breakpoint 3. DebugMonitor │
295-
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
296-
│ │ caller() │ │ FPB Unit │ │DebugMon_ │ │
297-
│ │ calls │────────> │ BKPT trigger │───────> │Handler() │ │
298-
│ │ digitalWrite │ │ @ 0x08008308 │ │ (exception) │ │
299-
│ └──────────────┘ └──────────────┘ └──────────────┘ │
300-
│ │ │
301-
│ 4. Stack Frame Modification ▼ │
302-
│ ┌──────────────────────────────────────────────────────────────────┐ │
303-
│ │ Exception Stack Frame: │ │
304-
│ │ [SP+0] R0 - preserved │ │
305-
│ │ [SP+4] R1 - preserved │ │
306-
│ │ [SP+8] R2 - preserved │ │
307-
│ │ [SP+12] R3 - preserved │ │
308-
│ │ [SP+16] R12 - preserved │ │
309-
│ │ [SP+20] LR - preserved │ │
310-
│ │ [SP+24] PC ◄── MODIFIED to inject_digitalWrite (0x20000278) │ │
311-
│ │ [SP+28] xPSR - preserved │ │
312-
│ └──────────────────────────────────────────────────────────────────┘ │
313-
│ │
314-
│ 5. Exception Return → Execution continues at inject_digitalWrite() │
315-
│ │
316-
└─────────────────────────────────────────────────────────────────────────┘
288+
```mermaid
289+
flowchart TB
290+
subgraph step1 ["1. Function Call"]
291+
A["caller()<br/>calls<br/>digitalWrite"]
292+
end
293+
294+
subgraph step2 ["2. FPB Breakpoint"]
295+
B["FPB Unit<br/>BKPT trigger<br/>@ 0x08008308"]
296+
end
297+
298+
subgraph step3 ["3. DebugMonitor"]
299+
C["DebugMon_Handler()<br/>(exception)"]
300+
end
301+
302+
subgraph step4 ["4. Stack Frame Modification"]
303+
D["Exception Stack Frame:<br/>[SP+0] R0 - preserved<br/>[SP+4] R1 - preserved<br/>[SP+8] R2 - preserved<br/>[SP+12] R3 - preserved<br/>[SP+16] R12 - preserved<br/>[SP+20] LR - preserved<br/>[SP+24] PC ◄── MODIFIED to inject_digitalWrite<br/>[SP+28] xPSR - preserved"]
304+
end
305+
306+
subgraph step5 ["5. Exception Return"]
307+
E["Execution continues at<br/>inject_digitalWrite()"]
308+
end
309+
310+
A --> B --> C --> D --> E
317311
```
318312

319313
### Technical Implementation
@@ -391,36 +385,26 @@ On NuttX RTOS, the DebugMonitor implementation uses NuttX's native `up_debugpoin
391385

392386
#### Architecture
393387

394-
```
395-
┌─────────────────────────────────────────────────────────────────────────┐
396-
│ NuttX DebugMonitor Implementation │
397-
├─────────────────────────────────────────────────────────────────────────┤
398-
│ │
399-
│ 1. Initialization │
400-
│ ┌──────────────────────────────────────────────────────────────────┐ │
401-
│ │ fpb_debugmon_init() │ │
402-
│ │ ├── irq_attach(NVIC_IRQ_DBGMONITOR, arm_dbgmonitor, NULL) │ │
403-
│ │ │ (Replace vendor's PANIC handler with NuttX's handler) │ │
404-
│ │ └── arm_enable_dbgmonitor() │ │
405-
│ │ (Initialize FPB/DWT hardware) │ │
406-
│ └──────────────────────────────────────────────────────────────────┘ │
407-
│ │
408-
│ 2. Set Redirect │
409-
│ ┌──────────────────────────────────────────────────────────────────┐ │
410-
│ │ fpb_debugmon_set_redirect(comp, orig_addr, redirect_addr) │ │
411-
│ │ └── up_debugpoint_add(DEBUGPOINT_BREAKPOINT, addr, size, │ │
412-
│ │ debugmon_callback, &redirect_info) │ │
413-
│ └──────────────────────────────────────────────────────────────────┘ │
414-
│ │
415-
│ 3. Breakpoint Trigger │
416-
│ ┌──────────────────────────────────────────────────────────────────┐ │
417-
│ │ CPU hits breakpoint → arm_dbgmonitor() → debugmon_callback() │ │
418-
│ │ └── regs = running_regs() ← Get saved register context │ │
419-
│ │ └── regs[REG_PC] = redirect_addr ← Modify stacked PC │ │
420-
│ │ └── Exception return → Execution at inject function │ │
421-
│ └──────────────────────────────────────────────────────────────────┘ │
422-
│ │
423-
└─────────────────────────────────────────────────────────────────────────┘
388+
```mermaid
389+
flowchart TB
390+
subgraph init ["1. Initialization"]
391+
A1["fpb_debugmon_init()"] --> A2["irq_attach(NVIC_IRQ_DBGMONITOR,<br/>arm_dbgmonitor, NULL)<br/><i>Replace vendor's PANIC handler</i>"]
392+
A2 --> A3["arm_enable_dbgmonitor()<br/><i>Initialize FPB/DWT hardware</i>"]
393+
end
394+
395+
subgraph redirect ["2. Set Redirect"]
396+
B1["fpb_debugmon_set_redirect<br/>(comp, orig_addr, redirect_addr)"] --> B2["up_debugpoint_add<br/>(DEBUGPOINT_BREAKPOINT,<br/>addr, size,<br/>debugmon_callback,<br/>&redirect_info)"]
397+
end
398+
399+
subgraph trigger ["3. Breakpoint Trigger"]
400+
C1["CPU hits breakpoint"] --> C2["arm_dbgmonitor()"]
401+
C2 --> C3["debugmon_callback()"]
402+
C3 --> C4["regs = running_regs()<br/><i>Get saved register context</i>"]
403+
C4 --> C5["regs[REG_PC] = redirect_addr<br/><i>Modify stacked PC</i>"]
404+
C5 --> C6["Exception return<br/>→ Execution at inject function"]
405+
end
406+
407+
init --> redirect --> trigger
424408
```
425409

426410
#### Key NuttX APIs Used

0 commit comments

Comments
 (0)