Previous Post | Top | Next Post |
TOC
どうもカスタムキーボードのフリーのファームウエアとしてはQMKが一番充実しているのですが、久しぶりにのぞくと2017年2月のころとかなり様子が変わっているようにも見えます。特に気になるのはconfig.json
の存在です。
とにかくカバーするキーボードハードウエアー数が大きくなってきたので、リファクターして共通部分の重複回避を試みている様です。
QMKのドキュメントもかなり更新されています。
復習を兼ねてコード・ドキュメントを追います。
qmk
コマンド導入とファームウエアーのビルド
最近、QMK Toolboxをpip
経由で導入する、非プログラマーにも使いやすいマルチプラットフォーム対応のUIを目指したpythonで書かれたthin wrapperのqmkというCLIコマンドが提供されています。
qmk
コマンドは、作業環境設定や、firmwareのビルド、はたまた種々の関連処理プログラムの提供や起動に用いるようです。でもビルドされるCコードのコアの部分はあまり変わっていないようです。
まず、Install Using pipに従い環境をDebian 11 (Bullseye/testing)に導入しました。
qmk setup
の自動設定でチェックアウトされるレポは、git submodule
を使っていて、レボがうまくまとめられています。レポ内にグラフィクスなどを保存しなくなり、キーマッピングもキーボード間で共用可能なものをまとめたり、マッピングだけのユーザーカスタム化情報がメインのkeyboads/
以下のソースツリー外に置けるようです。ただソースを理解するのが少々手間となりました。
qmk
は、初期導入時に~/.bashrc
を変更し、shellの環境変数QMK_HOME
にチェックアウトしたレポの場所を保存したようです。(手動でしたのかどうか忘れました)
qmk
のコマンドの説明はQMK CLI Commandsにあります。
どうもビルドは公式にはqmk
コマンドを使うようになっているそうですが、その背後で何がどうなっているのかが気になります。
レポを見ると、791b9cc652
(“remove all makefiles from keyboard directories”, 2017-09-27)で昔ビルドに使っていた各キーボード毎の独立のMakefile
が無くなっています。だから、ビルドの実体はrootにあるMakefile
がしているはずです。いかんせんrootのMakefile
は複雑なので閉口でした。
今残っているrootにあるMakefile
にからむのかがwebにあるエンドユーザー向けの説明ではよく分からないので、試しにrootにあるMakefile
を無効なターゲットで動かすと以下のメッセージが出ます。
$ make help
QMK Firmware 0.15.12
make: *** No rule to make target 'help'. Stop.
|
| QMK's make format is:
| make keyboard_folder:keymap_folder[:target]
|
| Where `keyboard_folder` is the path to the keyboard relative to
| `qmk_firmware/keyboards/`, and `keymap_folder` is the name of the
| keymap folder under that board's `keymaps/` directory.
|
| Examples:
| keyboards/dz60, keyboards/dz60/keymaps/default
| -> make dz60:default
| -> qmk compile -kb dz60 -km default
| keyboards/planck/rev6, keyboards/planck/keymaps/default
| -> make planck/rev6:default:flash
| -> qmk flash -kb planck/rev6 -km default
|
WARNING: Some git submodules are out of date or modified.
Please consider running make git-submodule.
これで、マニュアルどおりにqmk
コマンドによりビルドする際に、バックエンドのMakefile
がどう起動されているかが分かりました。
Makefile
はかなり複雑ですが、%
ターゲット中で呼ばれるPARSE_RULE
がキーです。処理の実体はPARSE_RULE
が呼ぶPARSE_KEYBOARD
です。KEYMAPS := $$(sort $$(KEYMAPS) $$(LAYOUT_KEYMAPS))
となっているので、キーマップは旧来のスタイルのkeyboards/
以下の.../keymaps/*/
に定義された専用の定義のみならず、layouts/
以下に定義された汎用の定義も使えるようです。
qmk
コマンドは、一見便利なんですが、背後で何をしているのかが最初分からずちょっと悩みました。まだ開発中なので変わるかもしれませんが、気になった関連作業を以下にメモしておきます
qmkレポの移動方法
qmkレポの移動は、レポのディレクトリーを移動、それに併せて環境変数$QMK_HOME
の設定を~/.bashrc
中で対応して代え新規にシェルを立ち上げるとできます。
新規のクリーンなqmkレポを新規の場所に作成する方法
既存レポに手を加えず、新規にqmkレポを作成するには、何もない作成場所を確保し移動し以下を実行します。
$ qmk clone
すると、現行ディレクトリ下にqmk/qmk_firmware
が作成されます。
それに併せて環境変数$QMK_HOME
の設定を~/.bashrc
中で対応して代え新規にシェルを立ち上げます。
この状態では既存だったレポにはqmk
からはアクセスできませんが、GITからのデーターアクセスはできます。環境変数$QMK_HOME
の設定を戻せばqmk
からのアクセスが回復できます。
qmkレポのREMOTE名変更
上記のように普通にsetup やcloneをすると、デフォルトでorigin
にもupstream
にも、アップストリームのhttps://github.com/qmk/qmk_firmware
が指定されてます。
また、master
branchはorigin
をトラックしています。
How to Use GitHub with QMKにあるように、自分のレポにフォークしてgithubにバックアップをとりながら作業したいので、GITを使うフォークの管理の時と同様にqmkレポのREMOTE名をorigin
からupstream
に変更します。
$ git remote set-url origin git@github.com:osamuaoki/qmk_firmware.git
$ git branch -u upstream/master master
$ git remote set-url --push upstream BOGUS
$ git checkout master
$ git pull upstream master
$ git push origin master
QMKで使われているMakefile
のターゲットの整理
%
– ファームウエアーのビルド(keyboard_folder:keymap_folder[:target]
で指定) –qmk compile
やqmk flash
clean
– ソースのクリーン(生成したファームウエアーは残す) –qmk clean
distclean
– 全ソースのクリーン(生成したファームウエアーも含めて) –qmk clean -a
generate-keyboards-file
– ソース内のキーボードのリスト(改行で区切る) –qmk list-keyboards
list-keyboards
– ソース内のキーボードのリスト(空白で区切り1行化)git-submodule
– 全サブモジュールの再帰的 sync&updatelib/%
– 該当サブモジュールの再帰的 sync&update
QMK導入先システムのPython のアップグレード
Python 3.9下でQMK Toolboxを導入すると、~/.local/lib/python3.9
に導入されます。このままシステムのPython 3.10にアップグレードしたらQMK Toolboxが動かなくなりました。Symlink ~/.local/lib/python3.10 -> ~/.local/lib/python3.9
を作ったら、とりあえず動いています。
QMK関連の参考文書
現状のビルド環境のカスタマイズのために自力でコードを見たあと、見通しのよいカスタマイズ方法の入門参考文書を見つけました。
これで、ほぼ大枠がわかった気がしたので自力の努力はストップしました。
公式のドキュメントはエンドユーザー各論(Windows環境対応等…)が多すぎて迷いますが、少なくとも以下には目を通しましょう。
- QMK Keyboard Guidelines
- Coding Conventions (C)
- How to Contribute
- Data Driven Configuration –
info.json
,keymap.c
, 他のファイルの説明(INCLUDE順位の説明も)。
ウェッブアプも含めた開発環境
ウェッブアプも含めた開発環境としてQMK Web Stackを導入するのが良いみたい。
Debianだとdocker.io
パッケージ以外に、docker-compose
パッケージも必要みたい。
$ cd path/to/LAYOUTマクロ定義
$ git clone -r https://github.com/qmk/qmk_web_stack.git
$ cd qmk_web_stack
$ ./fix-submodules.sh
$ sudo apt update
$ sudo apt install docker.io docker-compose
$ sudo docker-compose build
$ sudo docker-compose up
この時に以下のような色々の警告が出ましたが、問題なく動いている様です。
...
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.2.4; however, version 21.3.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
...
これらは気にせずさらに指示どおり進めます。
$ cd path/to/qmk_web_stack
$ sudo ./populate_api.sh
ローカルのQMK Configuratorが立ち上がってます: http://127.0.0.1:5000/
docker-compose.yml
を変更すると、qmk_firmware
のレポやブランチ指定が変更できるようなので、種々のレポへの変更をPUSHする前にローカルで試すのにはよさそうです。
キーボードレイアウト外部ツール
新規キーボードレイアウトのデザインには外部ツールの WEB ベースのキーボードレイアウトエディター (a.k.a KLE) を利用すると便利です。
このKLEが生成するJSONファイル(layouts/
以下にはlayout.json
に保存されている)からQMKが利用するJSONファイル(info.json
)に変換するのには、Convert KLE raw to QMK info.jsonを用います。
以前は手動でコーディングしていたQMKのkeymap.c
は、info.json
からqmk c2json ...
として生成できます。一度これを作るとQMK自身のコンフィギュレーターでデーターを編集できます。このinfo.json
を用いるData Driven ConfigurationがQMKの今後の方向の様です。
QMKが利用するJSONファイルinfo.json
を直接編集するWEB上のQMKのコンフィギュレーターは、公式のqmk_firmwareに収録されている場合にのみつかえます。非公開の変更ソースに関してQMKのコンフィギュレーターを使うには、上記の様にローカルのqmk_firmware
のGITレポを用いる開発環境をローカルで作り利用します。
ちなみに、既存キーボードレイアウトがkeymap.c
で存在する場合、 これからQMKが利用するJSONファイルinfo.json
を逆生成するにはqmk c2json ...
を利用します。
QMKコードの全体感のメモ
- ビルド環境をBackward compatibilityを残しつつコードをリファクターしている様で、コードスタイルは参考にするには新旧玉石混交状態なので要注意。
- 2020年以降変更されていないコードは参考にしない。
- MCUによるGPIOやUSB等のアクセス関連は、AVRだとLUFA、ARMだとchibiosが使われています。
- キーボード固有のGPIOの接続状態とそのスキャン方法等は、
keyboards/.../
name/config.h
やkeyboards/.../
name/
name.c
やkeyboards/.../
name/
name.h
で定義されます。keyboards/.../
name/
name.h
には、以前どおりのLAYOUTマクロ定義があることもある。- LAYOUTマクロ定義はキーボード上の視覚位置をそのまま書くと、変換表のマトリクスの座標のマトリクスに変換します。
- 「Clueboad」等では
*name*
.hの中身が一見ないようで、一方
info.jsonに関連情報がある。LAYOUTマクロ定義は
layouts/にある定義を
info.json`に基づき自動INCLUDEされる模様?(未確認) users/
以下のファイルは、いくつかのキーボード間で利用されるコードをユーザーが置くところの様です。tmk_core/
下のファイルは、QMKのベースとなったTMKのコードで、QMKのコードの核心部分であるquontum/
から利用されている。
- キー入力状態を処理し、「データー変換ルール」に従い出力データーを生成する共有コードには
quontum/
以下のコードが用いられます。- 優先順位の低いダミー関数が
__attribute__((weak))
でhookとして多く提供されていて、ユーザーが同名前のコードを書くことで機能を挿入追加できる。
- 優先順位の低いダミー関数が
- 個別の「データー変換ルール」の表定義は、
keyboards/.../keymaps/
*/keymap.c
にC言語のLAYOUTマクロ定義を用いて定義されています。- 「データー変換ルール」の内容は、基本はGPIOがつながったピン入出力が生成するスイッチの押され具合へのレスポンスを記述したcolumn * rowの表です。Keymap Overview参照。
- 「データー変換ルール」の表を書き換えるとキーマップが変更できます。
- 「データー変換ルール」の表は、各キーへのキーコード定義を、LAYOUTマクロを用い記述することであたかもキーボード上の視覚位置の見やすい形で表現します。
- 「データー変換ルール」の表は、キー入力からの変換の自由度をあげるために、ノートパソコンの「Fn」キーのような多重化機能をサポートしています。
- 例えば「Fn」キーを用いると「データー変換ルール」が2層化でき、「Raise」・「Lower」キーを用いると「データー変換ルール」が4層化できます。
- 「データー変換ルール」表の内容は16ビットのデーターです。
- 上位8ビットが0の場合は、基本USBが送る「キーコード」その物です。
- 上位8ビットが非0の場合は、QMK独自拡張で
quantum_keycodes.h
に定義されています。単純なシフト状態付きの特殊キーコードから、別のキーコードシーケンス定義のマクロ参照指示の特殊キーコード等複雑です。
- どうも今後の機能拡張の追加機能でキーのマッピングやLEDの設定をファームウエアーを変更せず、設定データーだけファームウエアーが受け取り書き換える機能が、VIAのようです。書き換えはどうも別のUSB endpointにデーターを送りつけ行うようです。だから、TERMINALは使え無いそうです。当面不要ですが、コンパチブルなコードは悪くないかもしれません。
- それにしても、巨大なレポです。使う部分だけの心配をすることにし、あとは実際に使ってみるのでしょう。
QMKコードの注意点
keymap.c
の記述に、A
等とするのは古いスタイル。今はKC_A
等とフルネームで書く。KEYMAP
マクロ名は非推奨となり、LAYOUT
が代わりに用いられている。
QMK再導入の注意点
ホームディレクトリー中に開発環境を導入しているので、新規のシステムにホームディレクトリー関係を移動させる際にはいささか注意がいる。
- Debian package: python3-pip, libusb-dev
- sudoの導入を開発ユーザーのsudoグループへの追加は必要
~/bin/
と~/.local/bin
は事前に作成(無いとき)pip install qmk
- (自動導入されなかった際には、メッセージに従いpython moduleのpipによる導入。)
qmk setup
でqmk専用のbootloadHIDのコンパイルと/usr/local/bin/
への導入や、少々お節介なudevルール導入もされる。- エラーメッセージがでるので
qmk_firmware/util/udev/50-qmk.rules
を/etc/usdev/rules.d/
にコピーします。` - 現在
hid_bootloader_cli
がうまく動かないので要注意。(https://github.com/qmk/qmk_firmware/issues/18134)- Makefileからは
bootloadHID
でなくhid_bootloader_cli
が呼ばれていて使えないし、強引にsymlinkで呼んでもerror opening -mmcu=at90usb1286: No such file or directory
となって動きません。 - 仕方がないので
qmk_firmware/lib/lufa/Bootloaders/HID/HostLoaderApp
の中をcompileしてhid_bootloader_cli
を導入しました。
- Makefileからは
フレッシュなインストールのお試しにはKVMが便利。GNOME boxesが少々不安定だったので、Virtual Machine Manager (virt-manage
パッケージ)を利用した。
久しぶりにqmk_firmware
のレポを見ると、私の出した「Caps<->Esc交換マジックキー」関連のPRがマージされていました。これで楽になります。
Previous Post | Top | Next Post |