目次

ラズベリーパイ

組立I/Fシステムをラズベリーパイ上で動かす。

Linuxの基礎

各ディレクトリの役割を知ろう(ルートディレクトリ編)

ラズベリーパイ環境(実機)

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メモリのアクセス

ラズパイ上では自動で認識してマウントしてくれる。

USBメモリが認識しないのでいろいろやってしまった。

LinuxでUSBメモリをフォーマットしたらWindows上で認識しなくなった場合の対応
WindowsでUSBメモリを認識しないときの対処方法

最終的にUSBメモリをWindows上でNTFSでフォーマットしラズパイ上でも読み書きが出来るようになった。
※FAT32だとラズパイ側で読めるが書き込みが出来なかった。

USBメモリ内のファイルを実行可能にする

実行時に「許可がありません」が表示される。
USBメモリー上のファイルに「chmod +x 」としても実行可能パーミッションがつかないし、実行できない。

原因

USBスティックのファイルシステムがFAT / VFATまたはNTFSの場合、デフォルトのマウントオプションはnoexecです。
これは、UnixセキュリティモデルをサポートしていないUSBファイルシステムからシステムに不正なプログラムが到着するのを防ぐためです。
簡単な対応としては、フォーマット形式をext2,3 or 4にする。
https://forums.raspberrypi.com/viewtopic.php?t=99124

対応方法1

debianでUSBメモリを実行権付きでマウントするメモ

usbmountの設定を書き換えます。場所は/etc/usbmount/usbmount.confです。

usbmount.conf
MOUNTOPTIONS="sync,nodev,noatime,nodiratime" ←noexecを削除
FS_MOUNTOPTIONS="-fstype=ntfs,uid=pi,gid=pi" ←「""」内を追加

対応方法2

USBメモリ内のファイルを実行可能にするには、一苦労する。
Raspberry PiでUSBメモリ内のファイルを実行可能にする方法

対応方法3

※該当USBメモリ上ファイルのぜんぶに実行権限がつくようになる

固定IP接続

ノート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エミュレーションをするためのソフトウェア

マシン名:versatilepb

Windows で Raspbian システムを起動(QEMU, qemu-rpi-kernel を使用)
※2020年5月に正式名称がRaspbianからRaspberry Pi OSへ変更され、PCとMac​向けのRaspbianについても、Raspberry Pi Desktopへと変更

上記サイトを参考に、最新版をインストールする。

qemu以外は C:\RaspberryPiフォルダに格納
RaspberryPiOS起動用バッチを作成する。

run.bat
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

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で接続・開発する

マシン名:raspi2

イメージファイルから「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起動用バッチを作成する。

run.bat
@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

マシン名:raspi3

イメージファイルは「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起動用バッチを作成する。

run.bat
@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

WSL環境での動作確認

ラズベリーパイ上で動かす前に、Linux上で動くかを検証

WSL環境作成

  1. Windowsの機能の有効化で「​Linux用Windowsサブシステム」を有効化する。
  2. Windows Storeからubuntu 18.04 ltsをインストールする。

VSCode+WSLのC++開発

Linux用のC++開発環境構築するのに、Visual Studio Code(VSCode)を使用する。
Windows側のVSCodeからWSL環境にアクセスし、Linux環境でのC/C++開発が可能となります。

【環境構築】VSCode+WSL+Remote WSLでWindows上にC/C++開発・デバッグ環境を構築する

WSL Ubuntu上で行う作業

  1. sudo apt update
  2. sudo apt install build-essential -y
  3. sudo apt install gdb -y

VSCode拡張機能のインストール

現在編集中のフォルダ以下に「.vscode」フォルダ内に launch.json と tasks.json を作成する。
「C++(GDB/LLDB)」と「g++ アクティブファイルのビルドとデバッグ(コンパイラ /usr/bin/g++)」を選択している。

launch.json
{
    // 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"
        }
    ]
}
tasks.json
{
    "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": "デバッガーによって生成されたタスク。"
        }
    ]
}

Linux向け.NET5アプリケーションの発行

Visual Studioにて.NET5アプリケーションをLinux用に発行する。

  1. ビルドの対象プラットフォームをx64にする。
  2. ターゲット ランタイムを「linux-x64」にする。

.NET5アプリケーションの動作確認

コマンドプロンプト上で、wslコマンドを実行する。
「cd /mnt/c/」で、Windows上のCドライブにアクセスできる。
実行ファイルがあるフォルダまでCDコマンドでディレクトリを移動させる。
実行ファイルは、“./(実行ファイル名)“と先頭に”./“を付けることで実行できるようになる。
先頭に”./“を付けないと、「command not found」エラーとなる。

Windowsで開発したアプリをLinuxで実行する【C# / .Net Core】

プログラムからの呼び出し

Windowsでは CreateProcessとWaitForSingleObjectを使用するが、Linuxにはないため forkとexeclとwaitpidを使用する。

main.cpp
#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;
}

Python

C#版のインターフェイスではメモリ2GByteのラズパイでは5秒かかるなど動作が遅いこともあり、Pythonで作成しPyInstallerで実行ファイルを作成する方法を試す。

ラズパイの実機は外部ネットワークに接続できないため、ラズパイ(raspi3)のエミュレーター環境で行う。

Python3に切り替え

ラズパイのPythonのバージョンがデフォルトが2系になっているで、3系をデフォルトにする。

cd /usr/bin
 
sudo unlink python
sudo ln -s python3 python

ラズパイ(Raspberry Pi)のpythonバージョン確認、python3への変更方法。

仮想環境作成

Python3ならデフォルトで仮想環境作成の「venv」が備わっている。

pyhton -m venv {環境名}
# 例
pyhton -m venv cnvnet

仮想環境の有効化

source {環境名}/bin/activate
# 例
source cnvnet/bin/activate

コマンドラインの先頭に(環境名)が追加された状態になります。

({環境名}) pi@raspberrypi:~/ $
# 例
(cnvnet) pi@raspberrypi:~/ $

Pyinstaller

Pyinstallerのインストール

仮想環境にPyinstallerをインストールする

(cnvnet) pi@raspberrypi:~/ $ pip install pyinstaller
 
(cnvnet) pi@raspberrypi:~/ $ pyinstaller -v
4.10

テスト

(cnvnet) pi@raspberrypi:~/ $ mkdir test
(cnvnet) pi@raspberrypi:~/ $ cd test
test.py
(cnvnet) pi@raspberrypi:~test/ $ nano test.py
print("Hello cnvnet")
(cnvnet) pi@raspberrypi:~test/ $ pyinstaller test.py

Pythonスクリプトを実行形式のファイルにまとめる(2)

テストフォルダ配下にdistフォルダが作成され実行ファイルの「test」ファイルができる。
実行すると”Hello cnvnet”が表示される。

(cnvnet) pi@raspberrypi:~/ $ ./dist/test/test
Hello cnvnet

Windows側にファイル転送

Windows側に「WinSCP」をインストールして、「WinSCP」を使用すればGUI上でファイル転送ができる。
https://forest.watch.impress.co.jp/library/software/winscp/

速度検証

dotNET版の半分程度の速度改善が見られた。

種類1回目2回目3回目4回目5回目
dotNET版4440ms3130ms3120ms3110ms3130ms
Python版3690ms1670ms1630ms1620ms1620ms