QMKファームウェアの書き込み by Ubuntu - Claw44 ビルドログ03

2020-04-24 08:34:44

前回は、ProMicroのもげ対策をしたので、
そのまま次はProMicroにQMKファームウェアを書き込んだ。
今回はその記録。
エラーがでたりしたので、その対策も合わせて。

なお、今までのはビルドガイドに書いてなかったけど、今後はしっかりとビルドガイドを読むことをおすすめする。
Claw44 v2 ビルドガイド - yfuku blog

QMKファームウェアの書き込みについては下記
ファームウェア - yfuku blog

Claw44は最初からQMKファームウェアが書き込んであるから、デフォルトキーマップで十分という人は、
この手順は飛ばしても構わないと思う。

QMKファームウェア

QMKファームウェアとは、ProMicroに書き込みファームウェアの一種。
どのキーを押されたかというのを管理しているプログラムのことだ。
キーを押したときの電気信号を、PCに伝える前に実際の値に変換しているところと言ってもいいと思う。
その他、OLEDの描画なども担っている。

キーをPCに伝えるものなので、
自分の好きなようにキーマップをいじりたいと思った場合、
このQMKファームウェアを書き換えていくことになる。
まさにこういうことができるのが、自作キーボードの醍醐味だよね。
書き込みは一回だけやれば、そのキーボードを他PCに差し替えてもそのまま使えるので、OS側で何もしなくてよい。
(まあ、どうせキーマップをあれこれいじっていくだろうから、今後何度もやるだろうけど)

QMKファームウェアは基本的にC言語のソースだから、
まずはプログラムが必要だが、しっかりとGithubのリポジトリがある。
qmk/qmk_firmware: Open-source keyboard firmware for Atmel AVR and Arm USB families

しっかりとしたドキュメントまで。すばらしい。
QMK Firmware

QMK ConfiguratorとかQMK ToolboxみたいなGUIツールもあるみたいだけど、
僕はあまり色々GUIのソフトはいれたくないというのもあり、
自分でコマンドを叩くやり方でいく。
そうじゃない人は、これをみるとわかりやすい。
プログラマーではない人向けのQMK Firmware入門 - Qiita

意外にも自作キーボード界隈ではLinuxでやる人は少数派なのか、Macが多い印象。
次にWindowsかな。
僕はUbuntuなので、今後やる人のために書いておく。

参考になりそうなの
Linux/Macのターミナルだけで自作キーボードのファームウェアを書き込む一例 - Qiita
QMK_firmwareで自作キーボードのキーマップの変更 - Qiita

環境

  • Ubuntu 18.04LTS (そういや、昨日20.04がでたらしいな)
  • bash 4.4.20 (shellは特にこだわりがないので、bashでいい派)

では実践していこう

QMKファームウェアの準備

まずは先のGithubリポジトリを自身のアカウントにforkしておく。
別にこれはしなくてもいいんだけど、自分でキーマップを書き換えたいと思っているなら、
リポジトリを用意しておくことをおすすめする。

forkしたのがこれ
ryotakato/qmk_firmware

リポジトリから取得

$ git clone git@github.com:ryotakato/qmk_firmware.git

次にQMLのインストール(必要なライブラリなどが自動で入る)

$ ./qmk_firmware/util/qmk_install.sh

移動

$ cd qmk_firmware

あと、submoduleもしておく必要がある

$ make git-submodule

インストールが完了したら、ちゃんと動くかどうかの試しのビルド
makeコマンドに、キーボード:レイアウト という形で指定する。
指定できるものは決まっているのでkeyboardsディレクトリをみるとよい

$ make claw44:default

QMK Firmware 0.8.108
Making claw44/rev1 with keymap default

avr-gcc (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling: keyboards/claw44/i2c.c                                                                   [OK]
Compiling: keyboards/claw44/serial.c                                                                [OK]
Compiling: keyboards/claw44/ssd1306.c                                                               [OK]
Compiling: keyboards/claw44/rev1/matrix.c                                                           [OK]
Compiling: keyboards/claw44/rev1/split_util.c                                                       [OK]
Compiling: keyboards/claw44/rev1/split_scomm.c                                                      [OK]
Compiling: keyboards/claw44/lib/glcdfont.c                                                          [OK]
Compiling: keyboards/claw44/lib/layer_state_reader.c                                                [OK]
Compiling: keyboards/claw44/lib/logo_reader.c                                                       [OK]
Compiling: keyboards/claw44/lib/keylogger.c                                                         [OK]
Compiling: keyboards/claw44/claw44.c                                                                [OK]
Compiling: keyboards/claw44/rev1/rev1.c                                                             [OK]
Compiling: keyboards/claw44/keymaps/default/keymap.c                                                [OK]
Compiling: quantum/quantum.c                                                                        [OK]
Compiling: quantum/keymap_common.c                                                                  [OK]
Compiling: quantum/keycode_config.c                                                                 [OK]
Compiling: quantum/debounce/sym_g.c                                                                 [OK]
Compiling: quantum/process_keycode/process_space_cadet.c                                            [OK]
Compiling: quantum/process_keycode/process_magic.c                                                  [OK]
Compiling: quantum/process_keycode/process_grave_esc.c                                              [OK]
Compiling: tmk_core/common/host.c                                                                   [OK]
Compiling: tmk_core/common/keyboard.c                                                               [OK]
Compiling: tmk_core/common/action.c                                                                 [OK]
Compiling: tmk_core/common/action_tapping.c                                                         [OK]
Compiling: tmk_core/common/action_macro.c                                                           [OK]
Compiling: tmk_core/common/action_layer.c                                                           [OK]
Compiling: tmk_core/common/action_util.c                                                            [OK]
Compiling: tmk_core/common/print.c                                                                  [OK]
Compiling: tmk_core/common/debug.c                                                                  [OK]
Compiling: tmk_core/common/util.c                                                                   [OK]
Compiling: tmk_core/common/eeconfig.c                                                               [OK]
Compiling: tmk_core/common/report.c                                                                 [OK]
Compiling: tmk_core/common/avr/suspend.c                                                            [OK]
Compiling: tmk_core/common/avr/timer.c                                                              [OK]
Compiling: tmk_core/common/avr/bootloader.c                                                         [OK]
Assembling: tmk_core/common/avr/xprintf.S                                                           [OK]
Compiling: tmk_core/common/magic.c                                                                  [OK]
Compiling: tmk_core/protocol/lufa/lufa.c                                                            [OK]
Compiling: tmk_core/protocol/usb_descriptor.c                                                       [OK]
Compiling: tmk_core/protocol/lufa/outputselect.c                                                    [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.c                                       [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c                                        [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c                                [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c                                      [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c                                          [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c                                    [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c                                          [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c                                 [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c                                  [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/ConfigDescriptors.c                                       [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/DeviceStandardReq.c                                       [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/Events.c                                                  [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/HostStandardReq.c                                         [OK]
Compiling: lib/lufa/LUFA/Drivers/USB/Core/USBTask.c                                                 [OK]
Linking: .build/claw44_rev1_default.elf                                                             [OK]
Creating load file for flashing: .build/claw44_rev1_default.hex                                     [OK]
Copying claw44_rev1_default.hex to qmk_firmware folder                                              [OK]
Checking file size of claw44_rev1_default.hex                                                       [OK]
 * The firmware size is fine - 20144/28672 (70%, 8528 bytes free)

これが終わると、カレントディレクトリに、ファイルができている
これができていれば、一通り正しく準備できたということ

$ ls claw44_rev1_default.hex 

claw44_rev1_default.hex

自身用の新規キーマップ作成

新規キーマップのディレクトリを作成するが、
専用のシェルが用意してあって、助かる。
なお、引数は、キーボードと、新規キーマップの名前。
だいたい個人用のキーマップを作るときはその人のハンドルネームをつけることが多いらしい。

$ ./util/new_keymap.sh claw44 ryotakato
ryotakato keymap directory created in: qmk_firmware/keyboards/claw44/keymaps/

Compile a firmware file with your new keymap by typing: 
   make claw44:ryotakato
from the qmk_firmware directory

では、これもビルド

$ make claw44:ryotakato

・・・省略

$ ls claw44_rev1_ryotakato.hex 

claw44_rev1_ryotakato.hex

次にキーマップの書き換えだが、
これの詳細は別途記事にする予定なので、今は割愛。
なんやかんや書き換えたと思ってください。

$ vim keyboards/claw44/keymaps/ryotakato/keymap.c

書き換えたら、再度ビルド

$ make claw44:ryotakato

・・・省略

$ ls claw44_rev1_ryotakato.hex 

claw44_rev1_ryotakato.hex

これで、自身のキーマップの書き込む用のファイルができた。

実際にProMicroに書き込み

正直ここまでは苦労せずにいったが、
ここからがひっかかった。

まずは書き込む前に、
ProMicroとPCをUSBでつなぐ。
ここで前回のもげ対策が活きてくる

つなぐと、Claw44のProMicroは緑のLEDが点灯した。
どうやらこれが接続OKということらしい。

では、書き込んでいく

$ make claw44:ryotakato:avrdude

ここで、途中で、Detecting USB port, reset your controller now
という文字がでたので、ProMicroのRSTとGNDをショートさせる
動作としては、ピンセットで触って、離して、ということだが、
RSTとGNDは穴になっているので、穴の間をつまんだってのが、やったことを正確に表しているかも。

これは、公式ビルドガイドの、図がわかりやすい。
ファームウェア - yfuku blog

なお、リセットスイッチを2回って書いてあるから、ピンセットでショートさせるときも2回なのかと思ったが、
そうならそうと書くはずだから、僕は1回だけ触ったが、それで問題なかったみたい。

また、ショートさせた際、LEDは緑の他に赤が2つほどひかったが、これで正常動作っぽい。(下記リンクの図)
ProMicroのモゲ防止ついでにQMK_Firmwareを書き込む - Qiita

コンソール画面が進んだのでいったかなと思ったが、
Waiting for /dev/ttyACM0 to become writable. の最後のドットが出続けて、終わらない。
なんかで無限ループしているみたい?
調べてみると、
自作キーボード初心者がfirmware書き込みで躓いたこと集 - Qiita
で書いてある通り、権限が足りないみたいなので、sudoつける
これはLinux特有だと思う

# 下記コマンドをうったら、さっきと同じタイミングでショートさせる
$ sudo make claw44:ryotakato:avrdude

・・・省略
sh: 1: avrdude: not found

今度はavrdudeが存在しないってエラー
avrdudeは書き込むときに使うライブラリだろうから、きっと最初にいれておかなきゃいけなかったんだな。
後日、下記をみつけたので、間違いない。
自作キーボードのファームウェア(qmk_firmware)の書き込み環境をRaspberryPi3上に構築する方法 – StupidDog’s blog

ということで、apt-getでいれておく

$ sudo apt-get install avrdude

入れたら、
再度(長いけど、エラーがでたので全量)

$ sudo make claw44:ryotakato:avrdude

QMK Firmware 0.8.108
Making claw44/rev1 with keymap ryotakato and target avrdude

avr-gcc (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Size before:
   text	   data	    bss	    dec	    hex	filename
      0	  20132	      0	  20132	   4ea4	.build/claw44_rev1_ryotakato.hex

Copying claw44_rev1_ryotakato.hex to qmk_firmware folder                                            [OK]
Checking file size of claw44_rev1_ryotakato.hex                                                     [OK]
 * The firmware size is fine - 20132/28672 (70%, 8540 bytes free)
Detecting USB port, reset your controller now.............
# ここでショートさせる
Device /dev/ttyACM0 has appeared; assuming it is the controller.
Waiting for /dev/ttyACM0 to become writable.

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file ".build/claw44_rev1_ryotakato.hex"
avrdude: input file .build/claw44_rev1_ryotakato.hex auto detected as Intel Hex
avrdude: writing flash (20132 bytes):

Writing | ###                                                | 5% 0.10savrdude: error: programmer did not respond to command: set addr
Writing | ######                                             | 11% 0.20savrdude: error: programmer did not respond to command: set addr
Writing | #############                                      | 26% 0.42savrdude: error: programmer did not respond to command: set addr
Writing | ################                                   | 32% 0.50savrdude: error: programmer did not respond to command: set addr
Writing | ####################                               | 39% 4.38savrdude: error: programmer did not respond to command: set addr
Writing | #######################                            | 45% 4.48savrdude: error: programmer did not respond to command: set addr
Writing | ##############################                     | 60% 4.69savrdude: error: programmer did not respond to command: set addr
Writing | #####################################              | 74% 8.38savrdude: error: programmer did not respond to command: set addr
Writing | ########################################           | 79% 8.46savrdude: error: programmer did not respond to command: set addr
Writing | ###############################################    | 94% 8.68savrdude: error: programmer did not respond to command: set addr
Writing | ################################################## | 100% 8.76s

avrdude: 20132 bytes of flash written
avrdude: verifying flash memory against .build/claw44_rev1_ryotakato.hex:
avrdude: load data flash data from input file .build/claw44_rev1_ryotakato.hex:
avrdude: input file .build/claw44_rev1_ryotakato.hex auto detected as Intel Hex
avrdude: input file .build/claw44_rev1_ryotakato.hex contains 20132 bytes
avrdude: reading on-chip flash data:

Reading |                                                    | 0% 0.00savrdude: butterfly_recv(): programmer is not responding
avrdude: error: programmer did not respond to command: set addr
avrdude: butterfly_recv(): programmer is not responding
Reading | ################################################## | 100% 10.65s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x0d != 0x0c
avrdude: verification error; content mismatch

avrdude: safemode: Fuses OK (E:FB, H:D8, L:FF)

avrdude done.  Thank you.

tmk_core/avr.mk:203: recipe for target 'avrdude' failed
make[1]: *** [avrdude] Error 1
Make finished with errors
Makefile:560: recipe for target 'claw44:ryotakato:avrdude' failed
make: *** [claw44:ryotakato:avrdude] Error 1

進みはしたし、doneは出力されたけど、Errorだな。。。
ここで結構詰まった。
このうち、 avrdude: butterfly_recv(): programmer is not responding でググると、
色々でてくるが、どうも明確な回答が見当たらない。

ただ、色々みてるうちに、ModemManagerが邪魔しているとエラーになるって話をみかけた。
LinuxのModemManagerが自作キーボードへのキーマップ書き込みを邪魔している時の対処法 - Qiita

確かに、statusをみてみると、なんか色々警告を出力している

$ sudo systemctl status ModemManager.service

● ModemManager.service - Modem Manager
・・・省略
ModemManager[1104]: <warn>  (ttyACM0) could not open serial device (2)
ModemManager[1104]: <warn>  [plugin manager] task 9,ttyACM0: error when checking support with plugin 'Iridium': '(tty/ttyACM0) failed to open port: Could not open serial d
ModemManager[1104]: <warn>  (ttyACM0) could not open serial device (2)
ModemManager[1104]: <warn>  [plugin manager] task 9,ttyACM0: error when checking support with plugin 'Cinterion': '(tty/ttyACM0) failed to open port: Could not open serial
ModemManager[1104]: <warn>  (ttyACM0) could not open serial device (2)
ModemManager[1104]: <warn>  [plugin manager] task 9,ttyACM0: error when checking support with plugin 'Generic': '(tty/ttyACM0) failed to open port: Could not open serial d
ModemManager[1104]: <info>  Couldn't check support for device '/sys/devices/pci0000:00/0000:00:13.1/usb6/6-3': not supported by any plugin
ModemManager[1104]: <info>  [device /sys/devices/pci0000:00/0000:00:13.1/usb6/6-3] creating modem with plugin 'Generic' and '1' ports
ModemManager[1104]: <warn>  Could not grab port (tty/ttyACM0): 'Cannot add port 'tty/ttyACM0', unhandled serial type'
ModemManager[1104]: <warn>  Couldn't create modem for device '/sys/devices/pci0000:00/0000:00:13.1/usb6/6-3': Failed to find primary AT port

どうやら、有名な問題らしい。影響があるかどうかわからないが、一旦ModemManagerをとめてみる

$ sudo systemctl stop ModemManager.service

再度

$ sudo make claw44:ryotakato:avrdude

QMK Firmware 0.8.108
Making claw44/rev1 with keymap ryotakato and target avrdude

avr-gcc (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Size before:
   text	   data	    bss	    dec	    hex	filename
      0	  20132	      0	  20132	   4ea4	.build/claw44_rev1_ryotakato.hex

Copying claw44_rev1_ryotakato.hex to qmk_firmware folder                                            [OK]
Checking file size of claw44_rev1_ryotakato.hex                                                     [OK]
 * The firmware size is fine - 20132/28672 (70%, 8540 bytes free)
Detecting USB port, reset your controller now............................
# ここでショートさせる
Device /dev/ttyACM0 has appeared; assuming it is the controller.
Waiting for /dev/ttyACM0 to become writable.

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file ".build/claw44_rev1_ryotakato.hex"
avrdude: input file .build/claw44_rev1_ryotakato.hex auto detected as Intel Hex
avrdude: writing flash (20132 bytes):

Writing | ################################################## | 100% 1.90s

avrdude: 20132 bytes of flash written
avrdude: verifying flash memory against .build/claw44_rev1_ryotakato.hex:
avrdude: load data flash data from input file .build/claw44_rev1_ryotakato.hex:
avrdude: input file .build/claw44_rev1_ryotakato.hex auto detected as Intel Hex
avrdude: input file .build/claw44_rev1_ryotakato.hex contains 20132 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.64s

avrdude: verifying ...
avrdude: 20132 bytes of flash verified

avrdude: safemode: Fuses OK (E:FB, H:D8, L:FF)

avrdude done.  Thank you.

おー、うまくいった!
もう片方もやろうということで、
ProMicroをケーブルから抜き、
もう一つのProMicroを挿す。

$ sudo make claw44:ryotakato:avrdude
・・・省略
avrdude done.  Thank you.

成功!
確か分割キーボードは、USBケーブルをつなぐほうをMasterと認識するはず、かつ左手が一般的だから左手から?なので、
正直、2つともやる必要があるのかは分からないが、念の為。
なお、とりあえず右手用にしようとしてたProMicroを先にやってしまったが、それだと先にやったほうがMasterと認識されるのではないかなと。
とりあえず作るときに気をつけて、左手用にする。

一応最後、ModemManagerを元に戻しておく

$ sudo systemctl start ModemManager.service

ちなみに、トラブルシュートまわりには下記も参考になる
QMK configuratorを使ってキーマップを作成する - 天高工房

まとめ

  • いつになく他サイトへのリンクが多くなった。先人たちに感謝。

次回はダイオードを折り曲げる工程