From v0.8 to v0.9
v0.9 introduces Rynk, RMK's optional native host protocol, while keeping Vial as
the default. v0.9 also updates the embassy and BLE dependency stacks, unifies the event/processor
Rust API, restructures keyboard.toml to separate the electrical matrix, physical layout, and
logical keymap, and includes a few smaller breaking changes.
Each change below is labeled with who it affects. Use the table to find what applies to you, then
follow the steps in that section. Changes are grouped as Everyone and Rust API developers
(examples/use_rust); keyboard.toml users (examples/use_config) are affected only by the
Everyone changes.
Everyone
Rynk is a new optional host protocol
Rynk is RMK's native host protocol and a new opt-in alternative to Vial. Vial
remains the default host protocol. The rmk crate's default features changed only to replace the
removed vial_lock alias with its underlying host_lock feature:
Rynk and Vial are mutually exclusive — enable exactly one. If you relied on the defaults, your firmware continues to use Vial with its physical-presence lock.
If you use keyboard.toml
The [host] section must match the rmk Cargo features — RMK checks this when it builds and stops
with an error if they disagree.
To keep Vial, no host-protocol changes are needed. The default [host] values continue to match the
rmk default features.
To opt into Rynk, update [host]:
Then turn off default features and explicitly enable rynk along with the other features you need:
See Host Configuration for the full set of options.
If you use the Rust API
Step 1 — pick the protocol in Cargo.toml. Rust projects that list vial explicitly do not need
to change it. To move to Rynk, disable default features and replace vial (and vial_lock) with
rynk in your explicit feature list.
Step 2 — update how you wire up the host service. It no longer takes a separate KeyboardContext,
and it now attaches to a transport instead of running as its own task.
Before (v0.8):
After (v0.9):
On wireless boards, attach it to the BLE transport the same way:
HostService is protocol-agnostic — it resolves to whichever of rynk or vial you enabled, so the
wiring above is the same for both.
keyboard.toml layout restructured
Who this affects: everyone using keyboard.toml.
The keyboard description is now split into three sections: [matrix] (electrical wiring, unchanged),
[layout] (physical arrangement), and the new [keymap] (layer count and key actions). The
layer-related fields move out of [layout] into [keymap]:
[layout].rows and [layout].cols stay in [layout].
Before (v0.8):
After (v0.9):
Experimental protocol features renamed
Who this affects: the rare early adopters who enabled the experimental protocol features by name.
If your Cargo.toml used the experimental feature rmk_protocol, rename it to rynk. The separate
bulk_transfer feature is gone — bulk transfers are now always on with rynk and sized by the
[rmk].rynk_buffer_size knob, so just drop bulk_transfer from your feature list.
The [rmk].protocol_max_bulk_size key was likewise removed; [rmk].rynk_buffer_size is now the
single knob for bulk-transfer throughput.
Dependency updates
Who this affects: everyone — these versions live in your own Cargo.toml.
v0.9 moves to newer embassy and BLE-stack releases. Update your dependency versions to match the example for your chip. The main bumps are:
embassy-time is unchanged (0.5). For nRF BLE boards, the nrf-sdc / nrf-mpsl git rev also
moves forward — copy the exact rev (and any other pins) from the matching example under examples/
for your chip, since some boards track specific git revisions.
Rust API developers
Event and processor API is unified
Who this affects: anyone who wrote custom controllers, input processors, or events.
v0.9 consolidates the previously separate controller and input_processor APIs into a single,
cohesive event/processor model. Rename the macros and functions as follows.
Macro changes
Function changes
Examples
Migrating a controller to a processor:
Migrating registration:
Migrating custom events:
Migrating multi-event enums:
Pointing device API renamed
Who this affects: anyone constructing a pointing device in Rust.
The generic PointingDevice / PointingProcessor replace the PMW3610-specific Pmw3610Device /
Pmw3610Processor. For the PMW3610, only the type name changes — the ::new() arguments are the
same:
keyboard.toml users don't need to do anything — the TOML config is unchanged.
PollingController interval is now a method
Who this affects: anyone who implemented PollingController for a custom input device.
The INTERVAL associated constant became an interval() method, so the interval can be chosen at
runtime:
MouseKeyConfig fields renamed
Who this affects: anyone building a MouseKeyConfig in Rust. (keyboard.toml users are unaffected —
the [rmk] mouse_key_interval / mouse_wheel_interval settings are unchanged.)
The renames reflect that these values now count acceleration ticks, not milliseconds.
Tap-hold macros take a profile index
Who this affects: Rust keymaps that set custom tap-hold timing profiles, or that construct
KeyAction::TapHold directly. (keyboard.toml users are unaffected — the macro interns profiles by
name automatically.)
KeyAction::TapHold now carries a u8 index into the morse-profile table instead of an inline
MorseProfile. The custom-profile macros thp! / mtp! / ltp! / ttp! take that index as their
last argument: populate behavior.morse.profiles and pass the 0-based index of the profile you want.
An index with no matching entry falls back to the default profile. The default-profile macros th! /
mt! / lt! / tt! are unchanged.
Automatic changes (usually no action)
- Event channel subscriber counts. Several events had their default
subscount increased to make room for Rynk's host sessions. This is applied automatically. You only need to act if you pinned custom[event.<name>]subsvalues — recheck them against the new defaults. When enabling Rynk, also make sure there are enough subscriber slots, or the keyboard will panic on connect. keyboard.tomlrejects unknown keys. A leftover or misspelled key that v0.8 silently ignored is now an error at build time. No action unless the build complains — then remove or fix the flagged key.
New in v0.9 (no migration needed)
These are new capabilities, listed so you know they exist:
rmk::bootis now public — callrmk::boot::jump_to_bootloader()from your own code.bootmagic— hold a designated key during boot to drop into the chip bootloader (works per-half on splits).- New input-device drivers — Azoteq IQS5xx trackpad and PMW3360 / PMW3389 mouse sensors.
See the changelog for the complete list.
Why these changes?
- Rynk gives RMK a native host protocol that understands every RMK feature, instead of being limited to what the Vial standard supports.
- The unified event/processor API collapses two parallel systems into one: a single
#[event]macro, a single#[processor]macro, and onepublish_event()family — simpler to learn and maintain, with no loss of functionality.