No safe way to reach a GPIO or LED pin outside the audio context
- Vorherrschende Sprache
- Rust
- Sterne
- 1
- Forks
- 0
- Ø Merge
- 5 Std. 19 Min.
- Gemergte PRs (30 T.)
- 26
Beschreibung
`bela-sys/vendor/bela/include/GPIOcontrol.h` is vendored, and `Bela.h` includes it (line 189), so it is part of `wrapper.h`'s include closure and bindgen parses it. Nothing it declares is generated:
```
$ grep -c 'gpio_' bela-sys/src/bindings.rs
0
```
The allowlist in `xtask/src/generate.rs` is why:
```rust
.allowlist_function("Bela_.*")
.allowlist_function("rt_.*")
```
`gpio_*` and `led_set_trigger` match neither, so they are dropped. Unlike the `FILE*` and `va_list` printf variants blocklisted a few lines below — which carry their reason in a comment beside them — nothing records a decision here, and the header was vendored as if these were meant to be in.
All thirteen are exported from the library the crate already links:
```
$ nm -D --defined-only bela-sysroot/root/Bela/lib/libbela.so | grep -E 'gpio_|led_set_trigger'
0000000000079030 T gpio_setup
00000000000790e0 T gpio_export
0000000000079340 T gpio_unexport
00000000000791c0 T gpio_set_dir
00000000000793e0 T gpio_set_value
0000000000079490 T gpio_get_value
0000000000079550 T gpio_set_edge
00000000000792c0 T gpio_fd_open
00000000000795f0 T gpio_fd_close
0000000000079660 T gpio_write
0000000000079600 T gpio_read
00000000000796a0 T gpio_dismiss
0000000000079740 T led_set_trigger
```
## What is missing without them
`RenderContext::digital_read` and `digital_write` cover the digital channels of a block. That is the PRU path, and it exists only while a block is being rendered. `GPIOcontrol.h` is the other mechanism — sysfs, one pin at a time, callable from `setup`, from `cleanup`, from an `AuxiliaryTask` or from a thread of the program's own. Without it a Rust program on a Gem has no way to:
- read or drive a GPIO pin that is not one of the sixteen digital channels;
- touch a pin at all outside the render callbacks;
- set an LED trigger (`led_set_trigger`, `/sys/class/leds`).
## What has to be answered before this closes
- **Real-time safety.** These are `open`, `read` and `write` on sysfs. They must not be reachable from `render`, and a safe API has to make that hard rather than warn about it — the same problem MIDI output had, which `docs/midi.md` answered with an auxiliary task rather than a note.
- **Collision with the pins libbela claims.** libbela drives the LEDs and the stop button through this same sysfs interface. "The board LEDs" in `docs/board-facts.md` measured which pins it claims and when — `gpio584` and `gpio585` for the two LEDs, exported for the duration of a run, and `gpio586` for the stop button. A safe API has to say what an application asking for one of those gets, measured rather than assumed.
- **Whether an export outlives the run.** The same section measured that the stop button pin stays exported after a run, because libbela opens it with `unexport = false`, unlike the LEDs. A Rust wrapper has to make the same choice, and whichever RAII shape it takes will encode it.
- **Which pins a Gem exposes.** `docs/board-facts.md` maps no GPIO number to a header pin, so there is nothing yet to check a wrapper's arguments against.
Widening the allowlist and regenerating is a small change on its own. The measurements above are what a safe API in `bela` waits on, and they need the board.
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.