Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions artifacts/anti-pinch-example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Anti-Pinch Window Controller -- Example Application Artifacts
#
# System: Synth -- WebAssembly-to-ARM Cortex-M AOT compiler
# Scope: Safety-critical automotive anti-pinch protection example
#
# This example demonstrates Synth's value for ASIL-rated embedded systems.
# Inspired by https://osxcar.de/insights/demonstration/
#
# STPA context:
# L-1: Bodily injury to vehicle occupant
# L-2: Vehicle fails safety certification
# H-1: Window continues closing when obstruction present
# H-3: Jam detection has false negative
#
# Format: rivet generic-yaml

artifacts:
# =========================================================================
# System Requirements
# =========================================================================

- id: AP-001
type: system-req
title: Anti-pinch controller WASM module
description: >
The anti-pinch window controller shall be implemented as a WebAssembly
module (anti_pinch.wat) compiled to ARM Cortex-M via Synth. The module
shall use integer-only arithmetic (fixed-point with 0.1% resolution,
range 0-1000) and store all state in WASM linear memory. The module
shall export functions for initialization, target setting, current
sensor input, control tick (100Hz), state queries, and jam reset.
The tick function shall implement the complete control loop: direction
determination, jam detection, PWM ramping, and position estimation.
status: implemented
tags: [anti-pinch, wasm, safety-critical, automotive]
links:
- type: derives-from
target: BR-001
- type: derives-from
target: BR-003
- type: traces-to
target: H-1
- type: traces-to
target: L-1
fields:
req-type: functional
priority: must
asil: B
verification-criteria: >
WAT module compiles successfully with synth-cli (--cortex-m --all-exports);
all 11 exported functions produce valid ARM Thumb-2 code; total code
size under 2KB.

- id: AP-002
type: system-req
title: Jam detection via motor current threshold
description: >
The controller shall detect window jam/pinch conditions by comparing
the motor current sensor reading against a configurable threshold
(default: 800mA). Detection shall only be active while the window is
closing (direction == 1). To prevent false positives from transient
current spikes, the controller shall require a configurable number of
consecutive over-threshold readings (default: 3 ticks at 100Hz = 30ms)
before confirming a jam. On confirmed jam, the controller shall
immediately set PWM to 0 (motor stop), set the jam flag, and return 0
from the tick function.
status: implemented
tags: [anti-pinch, jam-detection, safety-critical, current-monitoring]
links:
- type: derives-from
target: BR-001
- type: traces-to
target: H-1
- type: traces-to
target: H-3
- type: traces-to
target: L-1
- type: traces-to
target: L-2
fields:
req-type: safety
priority: must
asil: B
verification-criteria: >
When motor current exceeds threshold for 3 consecutive ticks while
closing, the tick function returns 0 and is_jam_detected returns 1.
Motor stops within 30ms (3 ticks at 100Hz) of obstruction.

- id: AP-003
type: system-req
title: Soft start/stop PWM ramping
description: >
The controller shall implement soft start and soft stop via PWM duty
cycle ramping. The PWM output shall ramp toward the target duty cycle
at a configurable rate (default: 20 units/tick = 2.0% per 10ms tick).
The PWM value shall be clamped to the range [0, 1000] (0.0%-100.0%).
This prevents mechanical shock to the window regulator, reduces EMI
from the motor driver, and provides smoother occupant experience.
status: implemented
tags: [anti-pinch, pwm, motor-control, soft-start]
links:
- type: derives-from
target: BR-001
- type: derives-from
target: BR-002
fields:
req-type: functional
priority: must
verification-criteria: >
PWM output increases by at most ramp_rate per tick; PWM value
never exceeds 1000 or drops below 0; motor reaches target speed
within 500ms (50 ticks at 2%/tick from 0 to 100%).

# =========================================================================
# Verification
# =========================================================================

- id: AP-VER-001
type: sys-verification
title: Anti-pinch controller Renode simulation test
description: >
End-to-end verification of the anti-pinch controller on a simulated
ARM Cortex-M4 target via Renode. The test shall verify: (1) controller
initialization sets correct default state, (2) window closes normally
with PWM ramping, (3) jam detection triggers within 30ms of current
threshold exceedance, (4) motor stops immediately on jam confirmation,
(5) jam flag can be cleared and window can be reopened, (6) all integer
arithmetic produces correct results (no overflow, no truncation).
The Zephyr application (main.c) simulates motor current and injects
a jam event at ~70% position.
status: planned
tags: [anti-pinch, renode, simulation, verification]
links:
- type: verifies
target: AP-001
- type: verifies
target: AP-002
- type: verifies
target: AP-003
- type: traces-to
target: H-1
- type: traces-to
target: H-3
- type: traces-to
target: L-1
- type: traces-to
target: L-2
fields:
method: simulation
target: cortex-m4
preconditions:
- Synth compiler builds successfully
- anti_pinch.wat compiles to ELF via synth-cli
- Zephyr SDK and Renode installed
steps:
compile: "cargo run -p synth-cli -- compile examples/anti-pinch-controller/anti_pinch.wat -o /tmp/antipinch.elf --cortex-m --all-exports"
build: "west build -b stm32f4_disco examples/anti-pinch-controller"
test: "bazel test //tests:anti_pinch_renode"
expected-results:
- "Jam detected at ~70% position (700/1000)"
- "Motor stops within 30ms of jam detection"
- "Window reverses to fully open (0/1000)"
- "Total code size under 2KB"
19 changes: 19 additions & 0 deletions examples/anti-pinch-controller/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Anti-Pinch Window Controller -- Synth WASM Compiler Demo
#
# Safety-critical automotive use case: anti-pinch protection via
# motor current monitoring. All control logic compiled from WebAssembly
# using formally verified Synth compiler.

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(synth_anti_pinch)

# Main Zephyr application (simulates motor/window system)
target_sources(app PRIVATE src/main.c)

# Synth-compiled WASM control functions (anti_pinch.wat -> ARM Thumb-2)
# These are compiled using formally verified instruction selection.
# In production, generate this file with:
# synth compile anti_pinch.wat -o anti_pinch.s --cortex-m --all-exports
target_sources(app PRIVATE src/anti_pinch.s)
188 changes: 188 additions & 0 deletions examples/anti-pinch-controller/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Anti-Pinch Window Controller

Safety-critical automotive example demonstrating Synth's value proposition for
ASIL-rated embedded systems. Inspired by the [OSxCAR anti-pinch
demonstration](https://osxcar.de/insights/demonstration/).

## Safety-Critical Use Case

Power window anti-pinch protection is an ISO 26262 ASIL-B function required in
all modern vehicles. The controller must:

1. **Detect obstructions** (fingers, limbs) by monitoring motor current
2. **Stop the motor within milliseconds** when a jam/pinch is detected
3. **Reverse the window** to release the trapped object
4. **Never produce a false negative** -- missing a real pinch causes injury

This maps directly to Synth's strengths:

| Concern | Synth Solution |
|---------|---------------|
| Compiler bugs cause incorrect jam detection | Formally verified compilation (Rocq proofs) |
| Floating-point non-determinism | Integer-only arithmetic (0.1% fixed-point) |
| Runtime overhead misses WCET deadlines | Zero-overhead native ARM Thumb-2 code |
| Memory corruption corrupts safety state | WASM linear memory model (bounds-checked) |
| Untraceable code transformations | Bidirectional WASM-to-ARM traceability |

## Architecture

```
+------------------+
Current Sensor | | PWM Output
(ADC, mA) ---->| anti_pinch.wat |----> Motor Driver
| (WASM module) | (H-bridge)
Position Sensor | |
(Hall/encoder)-->| compiled by | Jam Alert
| Synth to ARM |----> Dashboard
+------------------+
|
100Hz tick loop
```

### Control Flow (tick function)

```
1. Read motor current from memory
2. If jam already flagged -> return 0 (motor stopped)
3. Determine direction (closing/opening/stopped)
4. If closing AND current > threshold (debounced, 3 ticks):
-> Set jam flag
-> Set PWM = 0 (emergency stop)
-> Return 0
5. Ramp PWM toward target (soft start/stop, 2%/tick)
6. Update position estimate (PWM-proportional)
7. If position == target -> stop motor
8. Return new PWM duty cycle
```

### Memory Layout

All state is in WASM linear memory (integer, 4-byte aligned):

| Offset | Field | Range | Description |
|--------|-------|-------|-------------|
| 0 | `window_position` | 0-1000 | Current position (0.0%-100.0%) |
| 4 | `motor_current_ma` | mA | Last sensor reading |
| 8 | `pwm_duty` | 0-1000 | Current PWM output (0.0%-100.0%) |
| 12 | `direction` | 0/1/2 | 0=stopped, 1=closing, 2=opening |
| 16 | `jam_detected` | 0/1 | Jam flag |
| 20 | `current_threshold_ma` | mA | Jam detection threshold (default: 800) |
| 24 | `target_position` | 0-1000 | Commanded position |
| 28 | `pwm_ramp_rate` | units/tick | Soft start/stop rate (default: 20 = 2.0%) |
| 32 | `consecutive_over` | count | Debounce counter |
| 36 | `jam_debounce_limit` | count | Ticks to confirm jam (default: 3) |

## ASPICE / STPA Mapping

### STPA Losses

- **L-1**: Bodily injury to vehicle occupant (finger/limb trapped by window)
- **L-2**: Vehicle fails safety certification (non-compliant anti-pinch)

### STPA Hazards

- **H-1**: Window continues closing when obstruction present
- **H-3**: Jam detection has false negative (current reading below threshold
despite real obstruction)

### STPA Unsafe Control Actions

| Control Action | Not Providing | Providing Incorrectly | Too Late |
|---------------|---------------|----------------------|----------|
| Stop motor on jam | H-1: injury | N/A | H-1: injury if >100ms |
| Reverse window | L-1: prolonged pinch | H-3: false negative | L-1 |
| Current threshold check | H-1, H-3 | H-3: wrong threshold | H-1 |

### Synth Mitigations

- **Formal verification**: Compilation correctness proven in Rocq -- the
threshold comparison in the WAT produces the same result in ARM
- **Deterministic execution**: Integer arithmetic, no floating-point rounding,
bounded WCET for the tick function
- **Memory safety**: WASM linear memory prevents state corruption from adjacent
components

## Project Structure

```
anti-pinch-controller/
+-- anti_pinch.wat # WASM module (control logic source)
+-- CMakeLists.txt # Zephyr build configuration
+-- prj.conf # Zephyr project settings
+-- README.md # This file
+-- src/
+-- main.c # Zephyr app (simulation + control loop)
+-- anti_pinch.s # ARM Thumb-2 assembly (reference implementation)
```

## Building

### Compile WAT to ELF (standalone verification)

```bash
# From repository root
cargo run -p synth-cli -- compile \
examples/anti-pinch-controller/anti_pinch.wat \
-o /tmp/antipinch.elf \
--cortex-m --all-exports

# Disassemble to verify generated code
cargo run -p synth-cli -- disasm /tmp/antipinch.elf
```

### Build Zephyr firmware

```bash
export ZEPHYR_BASE=/path/to/zephyr

# Build for Cortex-M4 (e.g., STM32F4 Discovery)
west build -b stm32f4_disco examples/anti-pinch-controller

# Build for QEMU emulation
west build -b qemu_cortex_m3 examples/anti-pinch-controller
west build -t run
```

## Expected Output

```
===========================================================
Anti-Pinch Window Controller
Compiled by Synth (WebAssembly -> ARM Cortex-M)
===========================================================

Scenario: close window to 100%, jam at ~70%, then reopen

Time | Pos | Current | PWM | Dir | Jam | Event
-------|--------|---------|--------|-------|-----|------
0 | 0.0% | 0 mA | 2.0% | CLOSE | no |
100 | 10.5% | 256 mA | 64.0% | CLOSE | no |
200 | 25.2% | 320 mA | 80.0% | CLOSE | no |
...
700 | 70.0% | 1200 mA | 0.0% | STOP | YES | << JAM DETECTED

>> Anti-pinch activated! Window will reverse in 500ms.

>> Reversing window (opening to 0%).

1200 | 65.0% | 320 mA | 80.0% | OPEN | no |
...
1800 | 0.0% | 0 mA | 0.0% | STOP | no |

===========================================================
Demo complete -- anti-pinch safety function verified.
===========================================================
```

## Rivet Traceability

See `artifacts/anti-pinch-example.yaml` for full ASPICE traceability:

- **AP-001**: Anti-pinch controller WASM module (derives-from BR-001, BR-003)
- **AP-002**: Jam detection via current threshold (system-req)
- **AP-003**: Soft start/stop PWM ramping (system-req)
- **AP-VER-001**: Renode simulation test (sys-verification)

## License

Same as Synth project (see root LICENSE file).
Loading
Loading