組立I/Fシステムをラズベリーパイ上で動かす。
HDMIをマイクロUSBの変換アダプターを使用してモニターに繋げる。
モニターのINPUTボタンにて、HDMI接続をできるようにしておく。
型番 B03114
$ cat /proc/cpuinfo
Raspberry Pi 4 ARMv7 Processor rev 3 メモリ 2.0GB
32-bit OS と 64-bit OSの両方あるが、今回の実機はARMv7 (32bit)を使用している。
Raspberry Pi 32-bit OS と 64-bit OS の違いは?
ラズパイ上では自動で認識してマウントしてくれる。
USBメモリが認識しないのでいろいろやってしまった。
LinuxでUSBメモリをフォーマットしたらWindows上で認識しなくなった場合の対応
WindowsでUSBメモリを認識しないときの対処方法
最終的にUSBメモリをWindows上でNTFSでフォーマットしラズパイ上でも読み書きが出来るようになった。
※FAT32だとラズパイ側で読めるが書き込みが出来なかった。
実行時に「許可がありません」が表示される。
USBメモリー上のファイルに「chmod +x 」としても実行可能パーミッションがつかないし、実行できない。
USBスティックのファイルシステムがFAT / VFATまたはNTFSの場合、デフォルトのマウントオプションはnoexecです。
これは、UnixセキュリティモデルをサポートしていないUSBファイルシステムからシステムに不正なプログラムが到着するのを防ぐためです。
簡単な対応としては、フォーマット形式をext2,3 or 4にする。
https://forums.raspberrypi.com/viewtopic.php?t=99124
usbmountの設定を書き換えます。場所は/etc/usbmount/usbmount.confです。
MOUNTOPTIONS="sync,nodev,noatime,nodiratime" ←noexecを削除 FS_MOUNTOPTIONS="-fstype=ntfs,uid=pi,gid=pi" ←「""」内を追加
USBメモリ内のファイルを実行可能にするには、一苦労する。
Raspberry PiでUSBメモリ内のファイルを実行可能にする方法
※該当USBメモリ上ファイルのぜんぶに実行権限がつくようになる
ノートPCとラズパイは、LANケーブル(ストレートケーブルでよい)を直接つないでも繋がる。
※LANケーブルの爪が折れていたりすると接続不良で接続できないので、ランプが着くのを確認すること
固定IPで192.168.0.101で接続する。変更後に「↑↓」マークをクリックすると数秒点滅後に点滅が止まり点灯した状態になる。
Raspberry Pi OSのIPアドレスの固定方法 GUIマウス操作で簡単に設定
ノートPC側は固定IPで192.168.0.100とする。ファイアーウォールは一時的に無効とするか、pingの応答を返すように設定する。
Windows10 PCへのpingが通らない
pi@raspberrypi:~ $ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.101 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::e0a:ab87:e066:407f prefixlen 64 scopeid 0x20<link> ether dc:a6:32:f2:61:93 txqueuelen 1000 (イーサネット) RX packets 48 bytes 3904 (3.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 32 bytes 3766 (3.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (ローカルループバック) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 pi@raspberrypi:~ $ ping 192.168.0.100 PING 192.168.0.100 (192.168.0.100) 56(84) bytes of data. 64 bytes from 192.168.0.100: icmp_seq=1 ttl=128 time=1.08 ms 64 bytes from 192.168.0.100: icmp_seq=2 ttl=128 time=0.528 ms
Windows 10上でQEMUを使用することで、Raspberry Pi OSを動かすことが出来る。
※QEMUは、CPUエミュレーションをするためのソフトウェア
Windows で Raspbian システムを起動(QEMU, qemu-rpi-kernel を使用)
※2020年5月に正式名称がRaspbianからRaspberry Pi OSへ変更され、PCとMac向けのRaspbianについても、Raspberry Pi Desktopへと変更
上記サイトを参考に、最新版をインストールする。
qemu以外は C:\RaspberryPiフォルダに格納
RaspberryPiOS起動用バッチを作成する。
cd "C:\Program Files\QEMU" qemu-system-arm.exe -M versatilepb ^ -cpu arm1176 ^ -m 256 ^ -drive format=raw,file=C:\RaspberryPi\2021-05-07-raspios-buster-armhf-full.img ^ -net nic ^ -net user,hostfwd=tcp::2222-:22 ^ -dtb C:\RaspberryPi\versatile-pb-buster.dtb ^ -kernel C:\RaspberryPi\kernel-qemu-4.19.50-buster ^ -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" ^ -no-reboot
メモリを増やそうと -m 256 → 1Gだと下記エラーになる。
qemu-system-arm.exe: versatilepb: memory size must not exceed 256MB
※256MBしかメモリを割り当てられないQEMUの制限に対し、後述するスワップ領域を用意することで対処し、わりと多めのメモリを必要とする処理が可能になる。
起動時設定については、言語設定以外はスキップでよい。
再度、Raspberry Pi OSを起動、Raspberry Pi OS上のターミナルで実行する。
デフォルトの管理者 | |
---|---|
ユーザー名 | pi |
パスワード | raspberry |
sudo apt install -y gnome-disk-utility ; gnome-disks ;
ディスクユーティリティ(gnome-disks)が起動しますので、先程足した 2GB を拡張します。
空き容量が570MBくらいしかないので下記サイトを参考に空き容量を増やす
"Ubuntu で" Raspberry Pi を動かす QEMU
C:\Program Files\qemu>qemu-img resize C:\RaspberryPi\2021-05-07-raspios-buster-armhf-full.img +2G WARNING: Image format was not specified for 'C:\RaspberryPi\2021-05-07-raspios-buster-armhf-full.img' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. Image resized.
スワップ領域も少ないのでラズパイ上で下記コマンドで修正を行います。
sudo nano /etc/dphys-swapfile ; /etc/dphys-swapfile #CONF_SWAPSIZE=100 CONF_SWAPSIZE=1024
保存をして閉じたら下記コマンドでスワップファイルサイズの更新を行います。
sudo dphys-swapfile install ; sudo dphys-swapfile swapon ;
アップデートを行います。
sudo apt update
SSHとVNCを有効にする。
Raspberry Pi 4にSSHとVNCで接続してみた
Windows TerminalでSSHに接続する。
SSH pi@127.0.0.1 -p 2222 パスワード入力 raspberry
Visual Studio Codeをインストールするが、エラー「Illegal instruction」により動作せず。
$ sudo apt install code $ code Illegal instruction
動作しないのは「Unsupported architecture: armv6l」のため
CPUのアーキテクチャがarmv7lのRaspberry Piが今回サポートされるようになりました。つまり、Raspberry Pi 2系統とRaspberry Pi 3系統はすべて実行可能です。Raspberry Pi Zero系統はCPUのアーキテクチャがarmv6となっているので現在は実行不可能です。
Raspberry PiにVSCodeのRemote SSHで接続・開発する
イメージファイルから「kernel7.img」と「bcm2709-rpi-2-b.dtb」を抽出する。
Windowsではイメージファイルをマウントできないため、抽出するにはLinuxを使用する。
WSL2からはext4ファイルをマウント出来るが、WSL1では対応していない。
WSL2が無い場合、VirtualBox内にUbuntuをインストールして抽出する。ファイル共有しておけばWindows側に持ってこれる。
qemu以外は C:\RaspberryPi2フォルダに格納
先にイメージサイズの変更を行う。イメージサイズは2の冪乗を指定する。
"C:\Program Files\qemu\qemu-img.exe" resize 2021-05-07-raspios-buster-armhf.img 8G
RaspberryPiOS起動用バッチを作成する。
@echo off cd /d %~dp0 "C:\Program Files\qemu\qemu-system-arm.exe" ^ -m 1024 ^ -M raspi2 ^ -kernel kernel7.img ^ -dtb bcm2709-rpi-2-b.dtb ^ -drive format=raw,file=2021-05-07-raspios-buster-armhf.img ^ -append "console=ttyAMA0 root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4 dwc_otg.fiq_fsm_enable=0" ^ -serial stdio ^ -no-reboot ^ -device usb-kbd ^ -device usb-tablet ^ -device usb-net,netdev=net0 ^ -netdev user,id=net0,hostfwd=tcp::2222-:22
メモリは1G(1024)まで、それを超えた値を指定しても「Invalid RAM size, should be 1 GiB」エラーになる。
起動時設定については、言語設定以外はスキップでよい。
再度、Raspberry Pi OSを起動、Raspberry Pi OS上のターミナルで実行する。
デフォルトの管理者 | |
---|---|
ユーザー名 | pi |
パスワード | raspberry |
Raspberry Pi OSが起動したら、ターミナルで以下を実行し、ディスクの容量分だけ利用できるようにファイルシステムを拡張する。
$ sudo raspi-config --expand-rootfs
ここで一旦、再起動します。
スワップ領域も少ないのでラズパイ上で下記コマンドで修正を行います。
sudo nano /etc/dphys-swapfile ; /etc/dphys-swapfile #CONF_SWAPSIZE=100 CONF_SWAPSIZE=2048
保存をして閉じたら下記コマンドでスワップファイルサイズの更新を行います。
sudo dphys-swapfile install ; sudo dphys-swapfile swapon ;
アップデートを行います。
sudo apt update
イメージファイルは「2020-08-20-raspios-buster-arm64.img」を使用する。2021年以降では動作しなかった。
イメージファイルから「kernel8.img」と「bcm2710-rpi-3-b.dtb」を抽出する。
Windowsではイメージファイルをマウントできないため、抽出するにはLinuxを使用する。
WSL2からはext4ファイルをマウント出来るが、WSL1では対応していない。
WSL2が無い場合、VirtualBox内にUbuntuをインストールして抽出する。ファイル共有しておけばWindows側に持ってこれる。
qemu以外は C:\RaspberryPi3フォルダに格納
先にイメージサイズの変更を行う。イメージサイズは2の冪乗を指定する。
"C:\Program Files\qemu\qemu-img.exe" resize 2020-08-20-raspios-buster-arm64.img 8G
RaspberryPiOS起動用バッチを作成する。
@echo off cd /d %~dp0 "C:\Program Files\qemu\qemu-system-aarch64.exe" ^ -m 1024 ^ -M raspi3 ^ -kernel kernel8.img ^ -dtb bcm2710-rpi-3-b.dtb ^ -drive format=raw,file=2020-08-20-raspios-buster-arm64.img ^ -append "console=ttyAMA0 root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4 dwc_otg.fiq_fsm_enable=0" ^ -serial stdio ^ -no-reboot ^ -device usb-kbd ^ -device usb-tablet ^ -device usb-net,netdev=net0 ^ -netdev user,id=net0,hostfwd=tcp::2222-:22
メモリは1G(1024)まで、それを超えた値を指定しても「Invalid RAM size, should be 1 GiB」エラーになる。
起動時設定については、言語設定以外はスキップでよい。
再度、Raspberry Pi OSを起動、Raspberry Pi OS上のターミナルで実行する。
デフォルトの管理者 | |
---|---|
ユーザー名 | pi |
パスワード | raspberry |
Raspberry Pi OSが起動したら、ターミナルで以下を実行し、ディスクの容量分だけ利用できるようにファイルシステムを拡張する。
$ sudo raspi-config --expand-rootfs
ここで一旦、再起動します。
スワップ領域も少ないのでラズパイ上で下記コマンドで修正を行います。
sudo nano /etc/dphys-swapfile ; /etc/dphys-swapfile #CONF_SWAPSIZE=100 CONF_SWAPSIZE=2048
保存をして閉じたら下記コマンドでスワップファイルサイズの更新を行います。
sudo dphys-swapfile install ; sudo dphys-swapfile swapon ;
アップデートを行います。
sudo apt update
ラズベリーパイ上で動かす前に、Linux上で動くかを検証
Linux用のC++開発環境構築するのに、Visual Studio Code(VSCode)を使用する。
Windows側のVSCodeからWSL環境にアクセスし、Linux環境でのC/C++開発が可能となります。
【環境構築】VSCode+WSL+Remote WSLでWindows上にC/C++開発・デバッグ環境を構築する
WSL Ubuntu上で行う作業
VSCode拡張機能のインストール
現在編集中のフォルダ以下に「.vscode」フォルダ内に launch.json と tasks.json を作成する。
「C++(GDB/LLDB)」と「g++ アクティブファイルのビルドとデバッグ(コンパイラ /usr/bin/g++)」を選択している。
{ // IntelliSense を使用して利用可能な属性を学べます。 // 既存の属性の説明をホバーして表示します。 // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "g++ - アクティブ ファイルのビルドとデバッグ", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/${fileBasenameNoExtension}", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "gdb の再フォーマットを有効にする", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "C/C++: g++ アクティブなファイルのビルド", "miDebuggerPath": "/usr/bin/gdb" } ] }
{ "version": "2.0.0" "tasks": [ { "type": "cppbuild", "label": "C/C++: g++ アクティブなファイルのビルド", "command": "/usr/bin/g++", "args": [ "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}" ], "options": { "cwd": "${fileDirname}" }, "problemMatcher": [ "$gcc" ], "group": { "kind": "build", "isDefault": true }, "detail": "デバッガーによって生成されたタスク。" } ] }
Visual Studioにて.NET5アプリケーションをLinux用に発行する。
コマンドプロンプト上で、wslコマンドを実行する。
「cd /mnt/c/」で、Windows上のCドライブにアクセスできる。
実行ファイルがあるフォルダまでCDコマンドでディレクトリを移動させる。
実行ファイルは、“./(実行ファイル名)“と先頭に”./“を付けることで実行できるようになる。
先頭に”./“を付けないと、「command not found」エラーとなる。
Windowsでは CreateProcessとWaitForSingleObjectを使用するが、Linuxにはないため forkとexeclとwaitpidを使用する。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid < 0) { perror("fork"); exit(-1); } else if (pid == 0) { // 子プロセスで別プログラムを実行 execl("./Client/test", "./Client/test", "-u", "HOGE", NULL); exit(-1); } // 親プロセス int status; //子プロセスの終了待ち pid_t r = waitpid(pid, &status, 0); if (r < 0) { perror("waitpid"); exit(-1); } if (WIFEXITED(status)) { // 子プロセスが正常終了の場合 printf("child exit-code=%d\n", WEXITSTATUS(status)); } else { printf("child status=%04x\n", status); } return 0; }
C#版のインターフェイスではメモリ2GByteのラズパイでは5秒かかるなど動作が遅いこともあり、Pythonで作成しPyInstallerで実行ファイルを作成する方法を試す。
ラズパイの実機は外部ネットワークに接続できないため、ラズパイ(raspi3)のエミュレーター環境で行う。
ラズパイのPythonのバージョンがデフォルトが2系になっているで、3系をデフォルトにする。
cd /usr/bin sudo unlink python sudo ln -s python3 python
Python3ならデフォルトで仮想環境作成の「venv」が備わっている。
pyhton -m venv {環境名} # 例 pyhton -m venv cnvnet
source {環境名}/bin/activate # 例 source cnvnet/bin/activate
コマンドラインの先頭に(環境名)が追加された状態になります。
({環境名}) pi@raspberrypi:~/ $ # 例 (cnvnet) pi@raspberrypi:~/ $
仮想環境にPyinstallerをインストールする
(cnvnet) pi@raspberrypi:~/ $ pip install pyinstaller (cnvnet) pi@raspberrypi:~/ $ pyinstaller -v 4.10
(cnvnet) pi@raspberrypi:~/ $ mkdir test (cnvnet) pi@raspberrypi:~/ $ cd test
(cnvnet) pi@raspberrypi:~test/ $ nano test.py print("Hello cnvnet")
(cnvnet) pi@raspberrypi:~test/ $ pyinstaller test.py
テストフォルダ配下にdistフォルダが作成され実行ファイルの「test」ファイルができる。
実行すると”Hello cnvnet”が表示される。
(cnvnet) pi@raspberrypi:~/ $ ./dist/test/test Hello cnvnet
Windows側に「WinSCP」をインストールして、「WinSCP」を使用すればGUI上でファイル転送ができる。
https://forest.watch.impress.co.jp/library/software/winscp/
dotNET版の半分程度の速度改善が見られた。
種類 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 |
---|---|---|---|---|---|
dotNET版 | 4440ms | 3130ms | 3120ms | 3110ms | 3130ms |
Python版 | 3690ms | 1670ms | 1630ms | 1620ms | 1620ms |