zmkfirmware / zmk

ZMK Firmware Repository
https://zmk.dev/
MIT License
2.82k stars 2.85k forks source link

Towards a modular ZMK #453

Open innovaker opened 3 years ago

innovaker commented 3 years ago

Fellow developers, thank you for your patience. The modular proof-of-concept (PoC) is ready for evaluation.

Purpose

This is a (fully functional) proof of concept. Its purpose is to:

What's "a modular ZMK"?

Motivations

I'm suggesting we consider a modular approach for ZMK because of several pressing issues, including:

First steps

Local development

i.e. developers with an existing ZMK development environment setup on Windows, macOS, Linux or WSL2.

west init --mr master-v2 -m https://github.com/innovaker/my-zmk-keyboard zmk-workspace
cd zmk-workspace/my-zmk-keyboard
west update
west build

You may need to install v0.11.4 of the Zephyr SDK.

GitHub Actions (cloud)

Docker

If you want to try developing in Docker containers ...

VS Code Remote Containers

Due to current shortcomings in VS Code, VS Code Remote Containers, Codespaces, Docker and the Zephyr build system, it's proving tricky to find an intuitive one-size-fits-all approach for containers. However, their potential benefits make them worthy of further exploration. Here's a guide to the known approaches at time of writing ...

Cloning straight from a repository into a container with VS Code

This approach is my personal preference. It's quick to setup, performant and I don't mind my files being inside volumes. It lets you clone a repository straight into a Docker container/volumes without touching the local system or needing any tools besides VS Code. I also use the WSL2 backend which makes it really fast.

Cloning to a local disk first, then opening it in VS Code, then reopening it in a container

Some people prefer this method as it makes more sense to them. But it's not as performant.

Note, I've configured it to mount zephyr and its dependencies into (shared) Docker volumes so that it doesn't take an eternity to run west update. These volumes are shared across containers and not junked when you delete a container. zmk is currently stored within the container itself (so it will be lost/re-cloned if you rebuild the container) but it too can be mounted as a volume by a savvy user (I've left it commented out).

Codespaces + nested branch

I've not personally tested Codespaces yet but my cursory understanding is that it's built around the mono-repository paradigm and doesn't support untracked flat structure workspaces??? In anticipation of that, I've' been exploring a nested version of zmk-app/my-zmk-keyboard. I'm not keen on it personally but I made it as an experiment.

The branch names are nested-v2 if you want to try it but it's largely untested.

Next steps

Going forward

innovaker commented 3 years ago

For those wishing to dig deeper:

innovaker commented 3 years ago

For those out the loop, the general ideas for discoverability of modules has so far been:

innovaker commented 3 years ago

I've released v2 of the modular PoC, which is (re-)based onto zmk's main as of today (f3502dbcb5f017e0b62b9cf09cb0e81c26ce4589 which includes Zephyr v2.4.0).

I've updated the previous posts accordingly. If you've already tried v1 with Docker, you may have to remove the old containers before trying v2.

I have no intentions of making another release in the foreseeable future as it's quite an intensive process.

Nicell commented 3 years ago

While testing this on Windows I found an issue with finding module root paths causing mixed styles of path separators, which seems to be fixed in https://github.com/zephyrproject-rtos/zephyr/pull/29243, but it isn't in a stable release of Zephyr yet.

For now I've manually added this fix to my local development workspace, but we should be aware of it when getting closer to a full implementation of this.

petejohanson commented 3 years ago

Some initial thoughts:

Upstream modules:

I think templates like this are really important, ideally they can be as minimalist as possible while still offering the full features. Something I don't love about the current templates for the user config repos is them being external to the core repo, so changes that need coordination are harder.

I would propose those templates actually be in the main repo, and creating new downstream copies can pull from the subdirectory of the core.

Discoverability

One idea that came up earlier today was some GH label conventions for repositories that we could then query on ussng their API to find/discover modules for users.

innovaker commented 3 years ago

For the benefit of casual observers, there were some further discussions on Discord:

innovaker commented 3 years ago

While making ZMK a "core library" is generally a great move, 95% of users are unlikely to ever want to have a custommain entrypoint, versus having their custom code just be in their module w/ init callbacks, etc. Thoughts on having our core library still add a main unless a Kconfig option is set to disable that? In that scenario it's disabled, we would still export an entrypoint that the user main could invoke.

This makes sense and I'm fine with it. I also tested the principle last night. It's serves the majority but facilitates the minority.

innovaker commented 3 years ago

Doing that possibly removes need for a CMakeLists.txt by default in the "user application".

I doubt the bootstrapping code can be removed from the application but I'm not a cmake expert and welcome alternatives.

innovaker commented 3 years ago

I would propose those templates actually be in the main repo, and creating new downstream copies can pull from the subdirectory of the core.

I wasn't aware that pulling from a subdirectory of a git repository was possible (unless you're talking about partial clone?)? That's partly why I went for an upstream module approach in the PoC.

schengnz commented 3 years ago

Is there any possibility of decoupling the key processing engine as a separate module, independent of LED, key-scanning, sensors, display, power management and BLE/USB HID support? That way a key processing engine can be swapped in and out.

Anutrix commented 1 year ago

Any updates?

Anutrix commented 1 year ago

It's been almost 3 years. Has there been no updates or was this just not updated?

caksoylar commented 1 year ago

@Anutrix This is partially implemented in how currently user config repos work (where zmk itself is used as a Zephyr module and they support custom boards, shields and custom code for them). Maybe you should note what exactly are you looking to accomplish and what issue are you running into with the current limitations.

Anutrix commented 1 year ago

I am looking for support on ESP32-S3 which is supported officially by Zephyr Project(https://docs.zephyrproject.org/latest/boards/xtensa/esp32s3_devkitm/doc/index.html; https://github.com/zephyrproject-rtos/zephyr/commits/main/boards/xtensa/esp32s3_devkitm has had most features added by now.) but not ZMK.

It seemed that Modular ZMK would make adding support for it easier before I can deep type into this repo.

caksoylar commented 1 year ago

You can directly use boards from Zephyr in ZMK but you'll typically need to enable certain options, see some examples like for Adafruit KB2040 (overlay and conf). You could even do these overrides in a config repo, under config/boards/*.overlay etc.