BulePillでスクリーンセーバーキラーを作る

昔BluePillで作った、スクリーンセーバーキラーが行方不明になってしまったので、環境構築から改めて作ってみます。

BluePillで作った理由は、ArduinoでUSBHIDのサンプルプログラムがあること、デバイス自身のUSBインタフェースなどを使わずにSTLINK V2を使ってArduino環境から書き込むことができるのでVID/PIDを書き換えても問題がないこと、手元にあったこと、などです。

今回の開発環境は新たにUbuntu 22.04をインストールして、その上でArduino環境でやってみます。NVME上の普段のLinuxMintのデスクトップ環境は維持したいので、以前調べた方法でリムーバブルにしてあるSSDドライブ上にインストールしています。

何度も

initcall_blacklist=nvme_init

と打つのはめんどくさいですが、なんとか頑張ってNVMEは認識させない状態でSATAのSSD上にインストールしました。

で、Arduinoをインストールしようと思ったら、AppImageで行けそうなことがわかったので、今回はAppImageでやってみます。

・・・が、ファイルに実行属性をつけても何も起きません。そこで、コマンドライン上で試してみたら、

$ ./arduino-ide_nightly-20240219_Linux_64bit.AppImage 
dlopen(): error loading libfuse.so.2

AppImages require FUSE to run.
You might still be able to extract the contents of this AppImage
if you run it with the --appimage-extract option.
See https://github.com/AppImage/AppImageKit/wiki/FUSE
for more information

ということで、FUSEが必要なようです。ぐぐってみると、Ubuntu 22.04の場合は、

$ sudo apt install libfuse2

でインストールしてやればOKなようで、その後はAppImageのArduinoが起動できました。

起動したら、File→PreferencesでLanguageを日本語に設定した後、追加のボードマネージャに

http://dan.drown.org/stm32duino/package_STM32duino_index.json

を設定します。

その後、ツール→ボード→ボードマネージャで、STM32を入れて検索して、STM32F1xx/GD32F1xx boardsのインストールをクリックします。

インストールしたら、ツール→ボード→STM32F1xx/GD32F1xx boards→Generic STM32F103C seriesを選択します。

CPU速度は48MHz、VariantはSTM32F103C8(20k RAM,64k Flash)、Upload methodはSTLinkに設定します。

PCとST-LINK V2、BluePillボードは以下のように接続します。

ST-LINK V2を認識させるために、/etc/udev/rules.d/49-stlinkv2.rules として以下の内容を作成します。

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", \
MODE:="0666", \
SYMLINK+="stlinkv2_%n"

作成したら、

$ sudo udevadm control --reload-rules

として適用します。これでblinkなどの適当なサンプルプログラムを書き込んでみて動かしてみます。

問題なければ、ソースコードを作成します。ソースコードはスケッチ例の中のUSB Composite for STM32F1の下のjigglemouseをベースに作成しました。

#include <USBComposite.h>

#define LED LED_BUILTIN

USBHID HID;
HIDMouse Mouse(HID);

void setup(){
  pinMode(LED,OUTPUT);
  digitalWrite(LED,1);
  HID.begin(HID_MOUSE);
  delay(1000);
}

void loop(){
  static int v = 1;
  int r = random(60000,90000);
  #ifdef DBG
  Serial3.println(r);
  #endif
  digitalWrite(LED,LOW);
  delay(100);
  digitalWrite(LED,HIGH);
  Mouse.move(v,0);
  delay(r);
  v = -v;
}

BluePillをUSBマウスとして動作させますが、マウスを横方向に1単位移動させたらランダムに60〜90秒待って、次は反対方向に1単位移動させるという動作を繰り返すだけです。

ただ、これだとOS上はMapleとして認識されてしまいますので、 ~/.arduino15/packages/stm32duino/hardware/STM32F1/2022.9.26/libraries/USBComposite にある、usb_generic.c の冒頭の部分のベンダIDとプロダクトIDを書き換えます。

#define LEAFLABS_ID_VENDOR                0x1EAF
#define MAPLE_ID_PRODUCT 0x0024 // was 0x0024

これを、例えば

#define LEAFLABS_ID_VENDOR                0x04d9
#define MAPLE_ID_PRODUCT 0x1503 // was 0x0024

として、手元の謎の古いジャンクキーボードのものに偽装しました。また、同じファイルの先頭部分の

const char DEFAULT_PRODUCT[] = "Maple";
const char DEFAULT_MANUFACTURER[] = "LeafLabs";

const char DEFAULT_PRODUCT[] = "Mouse";
const char DEFAULT_MANUFACTURER[] = "Generic";

として、プロダクト名等を書き換えました。

こうすることで、例えばLinuxのdmesgでは接続時のログが

usb 5-2.4: new full-speed USB device number 8 using xhci_hcd
usb 5-2.4: New USB device found, idVendor=1eaf, idProduct=0024, bcdDevice= 2.00
usb 5-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 5-2.4: Product: Maple
usb 5-2.4: Manufacturer: LeafLabs
input: LeafLabs Maple as /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb5/5-2/5-2.4/5-2.4:1.0/0003:1EAF:0024.0005/input/input29
hid-generic 0003:1EAF:0024.0005: input,hidraw4: USB HID v1.10 Mouse [LeafLabs Maple] on usb-0000:05:00.4-2.4/input0
usb 5-2.4: reset full-speed USB device number 8 using xhci_hcd

から、

usb 5-2.4: new full-speed USB device number 16 using xhci_hcd
usb 5-2.4: New USB device found, idVendor=04d9, idProduct=1503, bcdDevice= 2.00
usb 5-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 5-2.4: Product: Mouse
usb 5-2.4: Manufacturer: Generic
input: Generic Mouse as /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb5/5-2/5-2.4/5-2.4:1.0/0003:04D9:1503.0009/input/input33
hid-generic 0003:04D9:1503.0009: input,hidraw4: USB HID v1.10 Mouse [Generic Mouse] on usb-0000:05:00.4-2.4/input0

という感じになりました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)