Raspberry Pi docker 環境を構築する

これまでPiはマイクロSDということもありdocker導入は躊躇していたのですがマイクロSDからSSDへの換装を機にdockerを導入してみました。

まだ触り始めて2週間の超初心者ですがちょっと試しただけでもdockerの便利さがわかります。話題に上がるのも当然と思います。使いこなすのはやはり相当のスキルが必要そうですが簡単なところから突破していきたいと思います。

開発環境

Raspberry Pi 3 Host
gnome-terminal + geany
dockerには新コマンドと旧コマンドがあるようです。
docker container / image コマンド新旧比較
web上では旧コマンドで書かれているものが多いのですが少し長ったらしくなりますが当サイトのような初心者には新コマンドのほうが理解しやすいと思います。
当サイトではできるだけ新コマンド体系で記述しようと思います。

インストール
なにはともあれHostになるPi3にインストールしないことには使えません。
dockerインストールに方法についてはraspberrypi.orgにあります。
初回のインストールはソースリストと鍵を取得する必要があるのでwww.raspberrypi.orgの方法でインストールしなければいけませんね 訂正します。
$ apt show docker-ce -a してみるとかなり新鮮なものが入るようです。

$ curl -sSL https://get.docker.com | sh
$ sudo usermod -aG docker pi (username)
$ docker -v
Docker version 18.06.1-ce, build e68fc7a

インストール時は18.06.0~ceだったのでがすぐにupdateが入り18.06.1-ceに上がりました。
docker-composeはpipで入れたほうが良さそうです。(まだ使ってないのですが)

$ sudo apt install python-pip
$ sudo pip install docker-compose
$ docker-compose -v
docker-compose version 1.22.0, build f46880f

以上で最低限の開発環境が整いました。

ベースイメージの選択
巷ではalpine linuxが人気のようですが初めて触るdockerにはいくら軽いと言っても初心者には荷が重いですね。
という訳でやはりここは少々慣れているraspbianを探してみます。
見つかったのがここstretchベースのようです。それもかなり新鮮な感じがします。
schachr/raspbian-stretch
自前でbuildする方法も載っていますがpullでいいでしょう。

$ docker pull schachr/raspbian-stretch
$ docker image ls
schachr/raspbian-stretch   latest    edebd95dc401     6 days ago   128MB

テストラン

新しいコンテナを作成実行
$ docker run --name raspbian -it schachr/raspbian-stretch:latest /bin/bash
root@1f0c05e837aa:/# ls
bin  boot  dev	etc  home  lib	media  mnt  opt  proc  root  run  sbin	srv  sys  tmp  usr  var
root@1f0c05e837aa:/# exit
exit
コンテナ一覧の表示
pi@pi3:~ $ docker container ls
CONTAINER ID  IMAGE  COMMAND   CREATED  STATUS  PORTS  NAMES
停止中のコンテナを起動
pi@pi3:~ $ docker container start raspbian
raspbian
pi@pi3:~ $ docker container ls
1f0c05e837aa schachr/raspbian-stretch:latest "/bin/bash" 19 seconds ago  Up 16 seconds raspbian
実行中のコンテナにアタッチ
pi@pi3:~ $ docker container attach raspbian
root@1f0c05e837aa:/# exit
exit
コンテナの削除
pi@pi3:~ % docker container rm raspbian
raspbian

いろいろ試してみるとインストールできないパッケージがあります。ソースリストが不足しているようです。
またこのままではsystemdも使えませんね。
Hostとコンテナ間の共有ディレクトリがほしい。
portを使ってみる。

あなたがする必要があるのは、それを引っ張ってdocker pull schachr/raspbian-stretch:latestこのイメージに基づいてコンテナを作り直すことだけです。

仰せの通りコンテナを作り直す
1.ソースリストはHostのPi3からコピー、設定する
2.pullしたimageには/sbin/initがないので/lib/systemd/systemdを指定
pi@pi3:~ $ ll /sbin/init
lrwxrwxrwx 1 root root 20 6月 14 05:20 /sbin/init -> /lib/systemd/systemd
3.Hostに~/buildを作成、共有ディレクトリにする。コンテナ側は/mntにマウント
4.sshを設定、-p 22:22で接続する

以上から新たにコンテナを作成(–name stretch_lite)

$ docker container run --privileged -d -p 22:22 --name stretch_lite -v /home/pi/build:/mnt schachr/raspbian-stretch /lib/systemd/systemd
4c4d641d1b952855436ed40d0413f54098255a1caf11a4c695e35ec8512add28
$ docker container ls
4c4d641d1b95        schachr/raspbian-stretch   "/lib/systemd/systemd"   About a minute ago   Up About a minute   0.0.0.0:22->22/tcp   stretch_lite

実行中のコンテナの中に入る

$ docker container exec -it stretch_lite /bin/bash
root@4c4d641d1b95:/# df -h
Filesystem                        Size  Used Avail Use% Mounted on
overlay                            29G   14G   15G  48% /
tmpfs                              64M     0   64M   0% /dev
tmpfs                             464M     0  464M   0% /sys/fs/cgroup
/home/pi/build                     30G    7G   23G  22% /mnt
/dev/root                          29G   14G   15G  48% /etc/hosts
shm                                64M     0   64M   0% /dev/shm
tmpfs                             464M  6.1M  458M   2% /run
tmpfs                             5.0M     0  5.0M   0% /run/lock

ソースリストの変更
Host(pi3)の/etc/apt/sources.list

deb http://raspbian.raspberrypi.org/raspbian/ stretch main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ stretch main contrib non-free rpi

Host(pi3)の/etc/apt/sources.list.d/raspi.list

deb http://archive.raspberrypi.org/debian/ stretch main ui
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ stretch main ui

imageではviやnanoも使えないのでコピーしたほうが早いです。共有ディレクトリ経由またはdocker cpでコピーします。
sources.listをコピー後1回目のupdateでkeyがないよと言ってくるのでdirmngrをインストール、gpgでkeyを取得します。keyを登録OK後再度update
手順の違いでkeyの取得に失敗した場合は/root/.gnupgを削除再度実行します。
upgradeではlocale関連で文句を言ってきますが取り敢えず問題ないと思います。

4c4d641d1b95:/ # cp /mnt/sources.list /etc/apt
# cp /mnt/raspi.list /etc/apt/sources.list.d
# apt update
# apt -y install dirmngr
# gpg --keyserver pgpkeys.mit.edu --recv-key 82B129927FA3303E
gpg: directory '/root/.gnupg' created
gpg: keybox '/root/.gnupg/pubring.kbx' created
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 82B129927FA3303E: public key "Raspberry Pi Archive Signing Key" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1
# gpg -a --export 82B129927FA3303E | apt-key add -
OK
# apt update && apt -y upgrade

アプリケーション(ツール)のインストール
使いやすいツールなどがあればここでインストールしておきます。

# apt -y install vim lv less dnsutils whois host curl wget sudo

ロケール
localesをインストール後/etc/locale.gen該当箇所のコメントを外してlocale-genを実行

# apt -y install locales
/etc/locale.gen
en_GB.UTF-8 UTF-8
ja_JP.UTF-8 UTF-8
# locale-gen
Generating locales (this might take a while)...
  en_GB.UTF-8... done
  ja_JP.UTF-8... done
Generation complete.

ローカルタイム

# rm /etc/localtime
# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# date
2018年  8月 31日 金曜日 11:01:29 JST

ssh server
sshを設定するにあたりuserを作成します。コンテナ内でもuserのファイルを操作することもあるだろうという想定で試してみます。

# adduser pi
ユーザ `pi' を追加しています...
新しいグループ `pi' (1000) を追加しています...
新しいユーザ `pi' (1000) をグループ `pi' として追加しています...
ホームディレクトリ `/home/pi' を作成しています...
`/etc/skel' からファイルをコピーしています...
新しい UNIX パスワードを入力してください:
新しい UNIX パスワードを再入力してください:
passwd: パスワードは正しく更新されました
pi のユーザ情報を変更中
新しい値を入力してください。標準設定値を使うならリターンを押してください
	フルネーム []: 
	部屋番号 []: 
	職場電話番号 []: 
	自宅電話番号 []: 
	その他 []: 
以上で正しいですか? [Y/n] 
# apt -y install openssh-server
# systemctl start ssh
# systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2018-08-31 19:15:37 JST; 4s ago
  Process: 5225 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
 Main PID: 5226 (sshd)
   CGroup: /docker/4c4d641d1b952855436ed40d0413f54098255a1caf11a4c695e35ec8512add28/system.slice/ssh.service
           └─5226 /usr/sbin/sshd -D


ssh接続での読み書きも特に問題なさそうです。

start exec stop

$ docker container start stretch_lite
stretch_lite
$ docker container exec -it stretch_lite /bin/bash
4c4d641d1b95:/ # exit
exit
$ docker container stop stretch_lite
stretch_lite

現在のコンテナからイメージ作成

$ docker container commit stretch_lite stretch_lite-img
sha256:6b75e8a5d6be8583ed48c2ffb47b066f62c3f08f10c9ec15046d73683e27e253
$ docker image ls | grep stretch_lite
stretch_lite-img  latest   6b75e8a5d6be    4 minutes ago   311MB

ファイルサイズは311MBになりました。
通常のraspbian-lite感覚で使うことができます。docker上の制約やないコマンドなどありますが必要なものはインストールすればいいだけでHostのPi3環境を汚すこと無くいろいろ試すことができそうです。

次回はこのイメージを活用してなんかやってみようと思います。

Raspberry Pi SSDにRaspbian Lite(デスクトップ)

Raspbianデスクトップを導入するには公式のRaspbianとRaspbian LiteからGUIを構築する方法があります。

参考 [GUIDE] Raspbian Lite with RPD/LXDE/XFCE/MATE/i3/Openbox/X11 GUI

今回は前回購入したSSDにRaspbian LiteからRaspbianデスクトップを構築してみました。

従来通りRaspbianの機能を活かすためにはメモリの大幅な節減効果はあまり期待できませんが必要なアプリケーションだけを入れることが可能になりディスクの節約には効果があります。

インストール
SSDをSATA-USB変換アダプタで接続するとUSBメモリ同様/dev/sdx形式で認識されます。
購入したSSDは一切フォーマットされていないようです。一旦適当な形式(ext4)でフォーマットしてみました。無事フォーマット完了、/dev/sdaで認識できています。
インストール方法はいろいろありますが今回は新規インストールということで従来通りDDでインストールしてみます。

# dd if=2018-06-27-raspbian-stretch-lite.img of=/dev/sda bs=1M

ここで起動をするとパーテーションを拡張されてしまうのでgpartedでパーテーションを切り直します。(OS領域と個人データを分けたい)

画像はインストール直後では無く現時点のものですがOS領域/dev/sda2を30000MiB残りを/dev/sd3に割り当てました。

注意することはパーテーションを手動でいじった場合はPTUUIDも適切に書き換えてやる必要があります。

# blkid /dev/sda
/dev/sda: PTUUID="3705c585" PTTYPE="dos"

/boot/cmdline.txt(該当箇所)
拡張領域が無いので拡張されることはないのですがinit_resize.shの部分も削除しています。

root=PARTUUID=3705c585-02
init=/usr/lib/raspi-config/init_resize.sh 削除

/etc/fstab

PARTUUID=3705c585-01  /boot      vfat    defaults          0       2
PARTUUID=3705c585-02  /          ext4    defaults,noatime  0       1

作業マシンのPi3から必要な設定をコピーします。
SSDは/media/pi/rootfsにマウントされているとします。

# cp /etc/dhcpcd.conf /media/pi/rootfs/etc
# cp /etc/wpa_supplicant/wpa_supplicant.conf /media/pi/rootfs/etc/wpa_supplicant
# cp /etc/hosts /media/pi/rootfs/etc
# cp /etc/hostname /media/pi/rootfs/etc

取り敢えずこんなとこでしょうか
準備ができたらスロットからマイクロSDを外して起動してみます。
無事起動してネットワークも繋がったらOK
ネットワークはip aで確認

$ ip a(省略しています)
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.3/24 brd 192.168.0.255 scope global wlan0
       valid_lft forever preferred_lft forever

取り敢えずupdate

$ sudo apt update && sudo apt -y upgrade

再起動

# reboot

Guiのインストール
Raspbian Lite Guide – Guiに沿ってインストールを進めますがコンソール画面だけでコマンドを打つのはしんどいです。
というわけで予め次のテキストファイルを用意しておきます。SSDで起動する前に/media/pi/rootfs/home/piに放り込んでおきます。
ファイル名は適当に(setup.sh)

#!/bin/sh
sudo apt install -y --no-install-recommends xserver-xorg
sudo apt install -y --no-install-recommends xinit
sudo apt install -y raspberrypi-ui-mods
sudo apt install -y lxde-core lxappearance
sudo apt install -y lightdm
sudo apt install -y fonts-ipafont fonts-ricty-diminished fcitx-mozc

ログインしたら実行〜(コーヒーブレイク)

$ sh ./setup.sh

再起動する前にraspi-config

$ sudo raspi-config


3 Boot Options
 B1 Desktop / CLI
  B4 Desktop Autologin
4 Localisation Options
 I1 Change Locale
  [*] ja_JP.UTF-8 UTF-8
    ja_JP.UTF-8
I2 Change Timezone
 Asia  Tokyo

I3 Change Keyboard Layout
 Generic 105-key(Intl)
  Other
   Japanese
    Japanese – Japanese(OADG 109A)
    Enter Enter

再起動
再起動すると日本語と日本語入力も有効で起動してくるはずです。

いつもの見慣れた画面ですがアプリケーションの類はほとんど入っていません。
基本はターミナル(termit)とファイルマネージャー(pcmanfm)ですがなぜかgnome-screenshotとxscreensaverが入っていたりします。
公式raspbianに含まれるアプリケーションはパッケージやPIホームページに情報があると思うので追加することは可能でしょう。

フォント設定
65-fonts-ipa-mincho.conf
65-fonts-ipa-pgothic.conf
65-fonts-monospace.conf
font_set.sh

#!/bin/sh
sudo cp *conf /etc/fonts/conf.avail
cd /etc/fonts/conf.d
sudo ln -s ../conf.avail/65-fonts-ipa-mincho.conf
sudo ln -s ../conf.avail/65-fonts-ipa-pgothic.conf
sudo ln -s ../conf.avail/65-fonts-monospace.conf

上記の65xxx.confとfont_set.shを適当なディレクトリ(~/font_set)を作成、保存して実行

$ sh ~/font_set/font_set.sh

/dev/sda3のマウント
パーテーション分けしたsda3はホームディレクトリやデータ保存に使います。
ホームディレクトリは使い回しの効くリンクを張って変更することにしました。
マウントは/home/dataとします。

# mkdir /home/data
# chown pi:pi /home/data
/etc/fstab
PARTUUID=3705c585-03  /home/data    ext4  defaults,noatime  0   1
# mount -a

ホームディレクトリをコピー
SSD起動後スロットにSDをセットすると認識します。

$ cp -Rp /media/pi/rootfs/home/pi /home/data

ここで一旦ログアウトしてCtrl+Alt+F2でコンソールからログイン、piディレクトリをリネームしてコピーしたに/home/data/piリンクを張ってやります。

$ cd /home
$ sudo mv pi pi.bak
$ sudo ln -s /home/data/pi

Ctrl+Alt+F7で再度Xからログイン、アプリケーションは歯抜けになっていますが今までの画面設定が戻りました。

アプリケーションインストール
初期にインストールしたアプリケーションは大体こんなもん。
これでディスク使用量は約4GBになりました。
–archiver xarchiver zip
–browser chromium-browser-l10n firefox-esr-l10n-ja
–desktop lxpolkit lxsession-edit alacarte xdotool devilspie gdevilspie
–editor  vim leafpad geany
–font   fonts-ipafont fonts-ipaexfont fonts-ricty-diminished
–graphics gimp imagemagick xsane gpicview geeqie mupdf epdfview evince
–japanese fcitx-mozc convmv
–mail   sylpheed
–multimedia pavucontrol gstreamer0.10-pulseaudio audacious mpv
   mplayer swftools libxml2-utils rtmpdump ffmpeg easytag
–net  samba dnsutils whois
–office libreoffice libreoffice-l10n-ja
–print cups system-config-printer
–programing kicad pigpio wiringpi gcc-avr avr-libc avrdude
–terminal lxterminal gnome-terminal terminator guake
–tool  gparted tmux lv kpartx numlockx galculator gnome-calculator

起動について
前回設定したUSB Boot Modeはboot開始まで約10秒強とSSDの魅力が半減してしまいます。やはりここは従来の方法でマイクロSDのbootを利用して起動することにしました。
当サイトのPiはシャットダウンにzenityを利用しているのでこのダイアログに追加することにします。
#編集を謝ると起動できなくなります。(参考までに願います)

メニューはSSDからの通常起動、STM32F103を利用する際のSSD(UART)起動、MicroSDからの起動となっています。boot領域の編集はMicroSD側になるのでPi3のUSB Boot Modeが有効であればMicroSDをスロットから外すことによりSSDは通常起動します。
起動選択はわかりやすくするため安易にファイルを上書きしています。

またMicroSDの/bootを書き込するため実行時のみマウントしています。
マウント位置はほとんど使っていない/srvにしました。
MicroSD起動も同じメニューを使う際は同様の設定をします。
SSDで運用しているとMicroSD起動はエマージェンシー的な役割になるのでSD側は専用の簡単なメニューでいいかもしれません。
/srv/mmcblk0をマウントする際はnoautoを指定すること。SDを外すと起動できなくなります。
fstabに記載することによって不要なオートマウントを抑制することができます。(下記はSSD側の設定)

# mkdir /srv/mmcblk0p1
# mkdir /srv/mmcblk0p2
/etc/fstab
PARTUUID=8fcce167-01    /srv/mmcblk0p1  vfat    defaults,noauto 0  2
PARTUUID=8fcce167-02    /srv/mmcblk0p2  ext4    defaults,noauto,noatime  0  1

MicroSDの/bootに各起動に応じたcmdline.txtを別名で用意します。初回起動用のconfig.txtとcmdline.txtも置いておきます。
違いはPARTUUIDの値とuartはconsole=serial0,115200を削除
cmdline.txt.ssd
cmdline.txt.uart
cmdline.txt.msd
SSD(UART)起動はconfig.txtも変更になります。
config.txt.def(デフォルト)
config.txt.uart
下記のスクリプトを実行権限を付けて適当なディレクトリ(~/bin)に保存、メニューに登録しておきます。

$ chmod 755 poweroff-helper
#!/bin/sh
LIGHTDM="Exit to command line"
if [ -e /etc/init.d/lightdm ]; then
  if ! service lightdm status | grep -q inactive; then
    LIGHTDM="Logout"
  fi
fi
RET=0
ACTION=$(zenity --list --radiolist \
  --width=300 --height=220 \
  --hide-header \
  --title="End session" \
  --text="What would you like to do?" \
  --column "Select" --column="Action" \
  TRUE  "Power OFF" \
  FALSE "Reboot(Now DeskTop)" \
  FALSE "LXDE(SSD)" \
  FALSE "LXDE(Uart)" \
  FALSE "Micro SD" \
  FALSE "$LIGHTDM")
RET=$?
echo $SOUND
if [ "$ACTION" = "Power OFF" ]; then
  sleep 1
  sudo shutdown -h now
elif [ "$ACTION" = "Reboot(Now DeskTop)" ]; then
  sleep 1
  sudo reboot
elif [ "$ACTION" = "LXDE(SSD)" ]; then
  sudo mount /srv/mmcblk0p1
  sudo cp /srv/mmcblk0p1/cmdline.txt.ssd /srv/mmcblk0p1/cmdline.txt
  sudo cp /srv/mmcblk0p1/config.txt.def /srv/mmcblk0p1/config.txt
  sleep 1
  sudo reboot
elif [ "$ACTION" = "LXDE(Uart)" ]; then
  sudo mount /srv/mmcblk0p1
  sudo cp /srv/mmcblk0p1/cmdline.txt.uart /srv/mmcblk0p1/cmdline.txt
  sudo cp /srv/mmcblk0p1/config.txt.uart /srv/mmcblk0p1/config.txt
  sleep 1
  sudo reboot
elif [ "$ACTION" = "Micro SD" ]; then
  sudo mount /srv/mmcblk0p1
  sudo cp /srv/mmcblk0p1/cmdline.txt.msd /srv/mmcblk0p1/cmdline.txt
  sudo cp /srv/mmcblk0p1/config.txt.def /srv/mmcblk0p1/config.txt
  sleep 1
  sudo reboot
elif [ "$ACTION" = "$LIGHTDM" ]; then
  pkill lxsession
else
   echo "cancel"
fi

劇的に早くなった訳ではないのですがやはりSSDは快適ですね〜 docker始めました。

Raspberry Pi SSD(KingSpec 64GB)を試してみる

Raspbian Strechのリリースから約1年になりますが安定度や起動の速度など以前と比べるとずいぶん改善されているように思います。

現行Pi3の足かせはマイクロSD、USB2.0そしてメモリ容量でしょうか。(マイクロSDは同時にメリットでもあるのですが)

今回は次期PiのUSB3.0を期待してマイクロSDの代わりにSSDを使ってみることにしました。

中華SSDはかなり怪しいものも流通しているようですが今回購入したKingSpecというメーカーは以前よりPCショップなどでも取り扱っており一定の評価があるようです。

マイクロSD(64GB)の価格帯としては現在1800〜2500円位が多く見られます。
SSD KingSpec(64GB)の価格は$18.61 + $3.51(SATA – USB3.0)とマイクロSDと同価格帯で導入できます。128GBは$10位アップしますが今回はその信頼性(性能)を検証する意味で最低の容量で試してみます。(信頼性、寿命は時間が証明するしか無いのですが)


こんなパッケージで送られてきます。(SATA to USB3.0変換は別メーカー、別ストア、別送付です)
AliExpressのKingSpec Global Storeというところで購入したのですが日本到着時及び地元郵便局到着時にも追跡メールを送信してくれて中華ストアには珍しく対応の良いところでした。到着までには約2週間要しています。


SSDは初めて使うのですが本体は非常に軽くてPiのベースにも良さそうです。


テスト中はディスプレイに貼り付けています。
SATA接続部分は少し熱を持ちます。

BOOT FROM A USB MASS STORAGE DEVICE
USBデバイスから起動させるためにUSBブートモードを有効にします。
HOW TO BOOT FROM A USB MASS STORAGE DEVICE ON A RASPBERRY PI 3

$ sudo apt update && sudo apt upgrade
$ echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
$ sudo reboot

確認してみます。こんな数値が帰ってくればOK

$ vcgencmd otp_dump | grep 17:
17:3020000a

これは元に戻すことはできません。戻す必要もありません。
カードスロットにSDカードがあればカードスロットから起動、なければ起動可能なUSBデバイスから起動します。大容量デバイスに限らず通常のSDカードもUSBアダプタ経由で起動します。

起動してみる
OSには通常通りRaspbian Strechをインストールしました。(具体的なインストールについてはまた次回にしたいと思います)
カードスロットから元ディスクを抜いて電源を投入します。
約10秒過ぎくらいにブートが始まります。
ブートは成功ですね。

テストしてみる
環境を整えてディスクのリード、ライトの簡単なテストをしてみます。
テスト方法は下記のサイトを参考にしました。
Linux Tips – HDDベンチマーク手順+性能測定結果一覧(hdparm,dd,bonnie++)
方法としてはSSDで起動してhdparmからリード、ddでライトをSSDとマイクロSDのタイムを計測します。

SSD read (hdparm -t /dev/sda2を3回実行)

# for i in [1] [2] [3];do sleep 10;echo $'\n\n' $i;hdparm -t /dev/sda2;done


約39MB/sec

マイクロSD read

# for i in [1] [2] [3];do sleep 10;echo $'\n\n' $i;hdparm -t /dev/mmcblk0p2;done


約22MB/sec

SSD write (time dd if=/dev/zero of=./test/write.tmp ibs=1M obs=1M count=1024を3回実行)

# for i in [1] [2] [3];do sleep 10;echo $'\n\n' $i;time dd if=/dev/zero of=./test/write$i.tmp ibs=1M obs=1M count=1024;done
# rm -r test


約28MB/sec

マイクロSD write (SSD起動後マイクロSDをスロットに装着してマウント)

# for i in [1] [2] [3];do sleep 10;echo $'\n\n' $i;time dd if=/dev/zero of=./test/write$i.tmp ibs=1M obs=1M count=1024;done
# rm -r test


約10Mb/sec

マイクロSDから起動、同様に計測してもほとんど同じような結果を得ています。
マイクロSDはT社32GB(少し古い)
SSDは30GB、マイクロSDは15GBでパーテーションを切っています。
最新のマイクロSDがどれくらい早くなっているかはわかりませんがclass10と考えるとこんなもんかなと思っています。
この差は特にインストール作業時に違いを感じることができます。

次回はインストールについて少し書いてみようと思います。

Raspberry Pi STM32F103開発環境(Arduino IDE PlatformIO)

前回はRaspberry Piからのシリアル接続でBluepill,Blackpillへブートローダーの導入ができました。
Arduino IDE(PlatformIO)の環境を構築してブートローダー書き込み後スケッチのアップロードも可能のようです。
さらに環境を整備していろいろ試すと予期せぬアップロードエラーが頻発してしまいます。
これらについてはSTM32に対しての知識が乏しいのが最大の要因ですがOSやToolなどの問題もあるようです。
この点については後述しますが取り敢えずアップロードも正常にできるようになりました。(一手間必要ですが!)

環境構築
STM32ボードを使うためにはコンパイラやツールを導入する必要があるのですがArduino_STM32のツールはRaspberry Pi(ARM)に対応していません。そのため先にPlatformIOから環境構築をします。

PlatformIO
boardを選択

$ pio boards | grep -i stm32f103


型番STM32F103C8では(20k RAM. 64k Flash)になっているためSTM32F103CB (20k RAM. 128k Flash)を選択します。
おそらく現在流通しているSTM32F103C8搭載ボードは128k Flashになっていると思います。

boardはSTM32F103CBに決定しました。
ディレクトリ、設定ファイルを作成します。

$ mkdir -p ~/platformio/project/stm32/bluepill/Blink
$ cd ~/platformio/project/stm32/bluepill/Blink
$ pio init -b genericSTM32F103CB

platformio.iniが作成されているはずなので編集

[env:genericSTM32F103CB]
platform = ststm32
board = genericSTM32F103CB
framework = arduino
upload_port = /dev/ttyACM0
upload_protocol = dfu

ディレクトリsrc/にBlink.inoを作成(~/platformio/project/stm32/bluepill/Blink/src)
boardはBluepill

void setup() {
  pinMode(PC13, OUTPUT);
}

void loop() {
  digitalWrite(PC13, LOW);
  delay(1000);
  digitalWrite(PC13, HIGH);
  delay(1000);
}

準備ができたので実行(ディレクトリは~/platformio/project/stm32/bluepill/Blink)

$ pio run

コンパイラやツールのダウンロードとコンパイルのみ実行します。
終了すると~/.platformio/packages以下にSTM32関連のファイルがインストールされています。

Arduino IDE
ここからArduino IDE側の環境を構築していきます。
ボードマネージャからArduino SAM Boards (32-bits ARM Cortex-M3)インストール

Arduino_STM32をダウンロード

https://github.com/rogerclarkmelbourne/Arduino_STM32
Download ZIPでダウンロードしたファイルを展開コピー
tools/linuxをPlatformIOにリンク

$ unzip Arduino_STM32-master.zip
$ cp -r Arduino_STM32-master ~/Applications/arduino-1.8.5/hardware
$ cd ~/Applications/arduino-1.8.5/hardware/Arduino_STM32/tools
$ rm -r linux
$ ln -s ~/.platformio/packages/tool-stm32duino linux

udev設定
PlatformIOからダウンロードした~/.platformio/packages/tool-stm32duinoディレクトリの45-maple.rulesを編集(コピーを取って編集)
Raspberry piではModemManagerと競合するようです。

$ cd ~/.platformio/packages/tool-stm32duino

45-maple.rules 3行目、4行目ENV{ID_MM_DEVICE_IGNORE}="1"追記
ATTRS{idProduct}=="1001", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev"
ATTRS{idProduct}=="1002", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev"
ATTRS{idProduct}=="0003", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idProduct}=="0004", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple", ENV{ID_MM_DEVICE_IGNORE}="1"

install.shを実行
$ sudo ./install.sh

/etc/udev/rules.dにrulesファイルが作成されます。

-rw-r--r-- 1 root root  411  7月 29 10:12 45-maple.rules
-rw-r--r-- 1 root root  471  7月 28 22:08 49-stlinkv1.rules
-rw-r--r-- 1 root root  532  7月 28 22:08 49-stlinkv2-1.rules
-rw-r--r-- 1 root root  530  7月 28 22:08 49-stlinkv2.rules
-rw-r--r-- 1 root root 1028  7月 28 22:10 99-com.rules

ここで設定を有効にするためRaspberry Piを再起動します。

書き込みを実行してみる
ここで前回のブートローダーを再度書き込みます。
BOOT0 1 reset
$ stm32flash -w generic_boot20_pc13.bin /dev/serial0
BOOT0 0 reset
/dev/ttyACM0 確認

先に作成したBlink.inoを書き込み ~/platformio/project/stm32/bluepill/Blink

$ pio run -t upload


upload OKですね

45-maple.rulesの追加修正が無いと下記のリセット操作が必要になります。

再度書き込み実行 $ pio run -t upload
dfu-util: No DFU capable USB device available

検索するとこのエラー報告は多く見つかりますが解決策はなかなか見つかりません。
いろいろ試すと適当なタイミングでリセットすると成功することがわかりました。根本的な解決策では無いのですがこんな解説が見つかります。
Uploading a sketch
多分ここに書いてあることと同じと思いますがdfu modeにできなかったので手動でリセットしなさいということです。

ブートローダー書き込み直後はflashに何も無いためdfu modeで起動、待ち受けるため初回のみ成功すると思います。
さてリセットのタイミングですがPlatformIOから実行した場合は(コンパイル済)
Compiling .pioenvs/genericSTM32F103CB/src/Blink.ino.cpp.o
または
Uploading .pioenvs/genericSTM32F103CB/firmware.bin
ここで少し待っているのでいいタイミングでリセットを1回押します。
慣れてくるとかなりの確率で成功すると思います。


Arduino IDEからも同様で書き込み動作(赤文字)に入る前のタイミングでリセットします。

dfu-utilは汎用書き込みツールでRasbpianにもパッケージ(同バージョン)があります。
おそらくwindowsではこのような問題は無いと思うので簡単に解決することは難しいと感じています。

取り敢えずリセット書き込みになりましたがなんとか正常に書き込めるようなのでこの状態で少し遊んでみようと思います。

アダプタの作成 bluepill.pdf

PiのGPIOを利用するためアダプタを作成しました。ESPの下駄を利用しています。(電源3V3はベース基板から)
空いてるランドにピンソケットを立て引き出しています。
またUSBコネクタも繋ぎ変えたくないのでベース基板のコネクタを利用します。
使用の際はcp2102モジュールを外してアダプタをセット。D-D+はピンヘッダを介してモジュールのPA11,12と接続しておりD+のプルアップはモジュール側を利用することになります。ブートローダーは適切にセットしてあれば確実に書き込んでくれます。スケッチ書き込みもOKです。

end

Raspberry Pi STM32F103開発環境(Bluepill Blackpill)

Raspberry Piによるマイコン開発環境はAVR,ESP-WROOM-02(32)と来たので今回はSTM32F103を試してみたいと思います。
STM32に関してはいろいろ開発環境がありますがRaspberry Piからの使用となるとかなり限られて来るのでここはアマチュアライクなArduino IDE(Platformio)に絞って調べてみます。
web上を検索するとなんとかRaspberry Piでも動きそうな感触が得られたのでBluepillとBlackpillを手配してみました。
このSTM32F103C8T6搭載基板は性能、価格面ではコスパの高いボードと思います。
ESPの開発基板を流用するのは貧乏性のせいか抵抗がありますがBluepillやBlackpillはmcuの形状、ピン数から見てもピッチ変換基板と思えば気兼ねなく使えそうです。

Bluepill Blackpill
市場で一番流通しているのはBluepillと思います。
Bluepillは200円以下で購入(送料無料)できます。Blackpillはそれより20円位高い。

ボードの作り(質)としてはBlackpillのほうが良さそうです。
BlackpillはBluepillより少し大きい(ピッチ幅も1ピッチ広め)のですが6ピン少ない。少ないピンは
VBAT バッテリーバックアップ端子(RTC)
5V端子(あれば便利、基板上から引き出すことは可能)
PC14,PC15 実質利用できない端子
3.3V GND 余分に出ている
この中でバッテリーバックアップが必要な場合はBlackpill以外のボードを選んだほうがいいですね。


BluepillにはUSB問題(誤抵抗)があります。
Blackpillと同条件にしたいため問答無用で対策をします。
10K -> 1.5Kにするのですが小さい1.5Kを探すのが大変、かといって敢えて購入するまでもないことから1.8Kをパラにしました。
手持ちの1/6W抵抗を裏側に取り付けています。

シリアル接続(ブートローダーの書き込み)

MicroUSBからスケッチを書き込むためにはブートローダーを導入する必要があります。
USBシリアル変換モジュールを用いるのですが当サイトのcp2102は認識しませんでした。linux系ではCH340もだめなようです。
Raspberry PiのGPIOを利用してブートローダーを書き込む手法を紹介しているサイトがあります。
Flashing the STM32F103 using a Raspberry Pi 3
BluetoothはUARTの一部を利用しているですね。それをブートローダー書き込みのシリアル接続に用いるというものです。したがってこの設定をするとBluetoothは利用不可になります。
(常時使用する訳ではないので簡単に切り替え方法は後日検討してみたいと思います)

/boot/config.txtの編集 (末尾に追記)

dtoverlay=pi3-miniuart-bt

/boot/cmdline.txtの編集 (一部削除)

console=serial0,115200

stm32flash utilityはパッケージにあります。

# apt install stm32flash

接続
Raspberry Pi TX (pin 8) to STM32 RX (pin A10)
Raspberry Pi RX (pin 10) to STM32 TX (pin A9)
Blackpill(Bluepill)ジャンパー設定
BOOT0 jumper to 1
セットが完了したら再起動します。
再起動するとBluetoothマネージャーはグレーになって動作を停止しているはずです。

STM32duino-bootloaderのダウンロード
https://github.com/rogerclarkmelbourne/STM32duino-bootloader
ダウンロードしたSTM32duino-bootloader-master.zipは適当なディレクトリ(~/Applications)に展開します。

ブートローダーの書き込み
書き込む前に確認してみます。Flashメモリ128KiBが確認できます。

$ stm32flash /dev/serial0
stm32flash 0.5
http://stm32flash.sourceforge.net/
Interface serial_posix: 57600 8E1
Version      : 0x22
Option 1     : 0x00
Option 2     : 0x00
Device ID    : 0x0410 (STM32F10xxx Medium-density)
- RAM        : Up to 20KiB  (512b reserved by bootloader)
- Flash      : Up to 128KiB (size first sector: 4x1024)
- Option RAM : 16b
- System RAM : 2KiB

書き込んでみましょう。(Blackpill)

$ cd ~/Applications/STM32duino-bootloader-master/binaries
$ stm32flash -w generic_boot20_pb12.bin /dev/serial0
stm32flash 0.5
http://stm32flash.sourceforge.net/
Using Parser : Raw BINARY
Interface serial_posix: 57600 8E1
Version      : 0x22
Option 1     : 0x00
Option 2     : 0x00
Device ID    : 0x0410 (STM32F10xxx Medium-density)
- RAM        : Up to 20KiB  (512b reserved by bootloader)
- Flash      : Up to 128KiB (size first sector: 4x1024)
- Option RAM : 16b
- System RAM : 2KiB
Write to memory
Erasing memory
Wrote and verified address 0x08005294 (100.00%) Done.

Bluepillはgeneric_boot20_pc13.bin

BOOT0のジャンパー設定を0にしてリセットするとLEDが点滅してブートローダーが起動する様子がわかります。
新たに/dev/ttyACM0が生えてきます。

$ ls -la /dev/ttyA*
crw-rw-r-- 1 root dialout 166,  0  7月 29 22:35 /dev/ttyACM0
crw-rw---- 1 root dialout 204, 64  7月 29 21:54 /dev/ttyAMA0


あとはArduino IDE(Platformio)の環境を構築してスケッチを書き込んであげればいいだけなのですが・・・(実際書き込みはできる) なかなか微妙なところがあります。

この辺はまた次回にしたいと思います。

では!

Top