Contributing
ANY contributions are welcome! There is a simple step by step guide for developers:
-
Before you start, you may want to read the [under the hood] section to understand how RMK works. Github Issue is also a good place for questions.
-
Checkout the active PRs, make sure that what you want to add isn't implemented by others.
-
Write your code!
-
Open a PR merging your code to main repo, make sure all CIs pass.
Under the hood
If you're not familiar with RMK, the following is a simple introduction of source code of RMK.
Project architecture
There're three crates in RMK project, rmk
, rmk-config
and rmk-macro
.
rmk-config
crate is the dependency of both rmk
and rmk-macro
, it includes both toml configs used in keyboard.toml
and normal config used in RMK core. rmk-macro
is a proc-macro helper of RMK, it reads keyboard.toml
config file and converts toml config to RMK config, generates the boilerplate code. The core of RMK stays in rmk
crate.
So, if you want to contribute new features of RMK, just look into rmk
core crate. If you want to add new chip support, rmk
and rmk-macro
should be updated, so that users could use keyboard.toml
to config keyboard with your new chip. And, if you want to add new configurations, look into rmk-config
.
RMK core
rmk
crate is the main crate, it provides several entry API to start the keyboard firmware. All the entry APIs are similar, it:
- Initialize the storage, keymap and matrix first
- Create services: main keyboard service, matrix service, usb service, ble service, vial service, light service, etc.
- Run all tasks in an infinite loop, if there's a task failed, wait some time and rerun
Generally, there are 4-5 running tasks in the meanwhile, according to the user's config. Communication between tasks is done by channels.There are several built-in channels:
FLASH_CHANNEL
: a multi-sender, single-receiver channel. There are many tasks send theFlashOperationMessage
, such as BLE task(which saves bond info), vial task(which saves key), etc.key_event_channel
: a multi-sender, single-receiver channel. The sender can be a matrix task which scans the key matrix or a split peripheral monitor which receives key event from split peripheral. The receiver, i.e. keyboard task, receives the key event and processes the keykeyboard_report_channel
: a single-sender, single-receiver channel, keyboard task sends keyboard report to channel after the key event is processed, and USB/BLE task receives the keyboard report and sends the key to the host.
Matrix scanning & key processing
An important part of a keyboard firmware is how it performs matrix scanning and how it processes the scanning result to generate keys.
In RMK, this work is done in Matrix
and Keyboard
respectively. The Matrix
scans the key matrix and send KeyEvent
if there's a key change in matrix. Then the Keyboard
receives the KeyEvent
and processes it into actual keyboard report. Finally, the keyboard report is sent to USB/BLE tasks and forwarded to the host via USB/BLE.