📘

Raspberry Pi + YoctoでWLAN自動接続・状況監視の実装

に公開

作りたいものの全体像から参照しています
https://zenn.dev/takumique/articles/a451ffd2393b1f

作りたいもの

Raspberry Pi 4 (RasPi4)にYoctoを載せて、WLAN(WiFi)に自動接続させます。また接続状況と現在のIPを監視しUIに表示させます。
https://zenn.dev/takumique/articles/4b436162197148

動作する全ソースコードをGitHubで公開しています。

ハードウェア

RasPi4のWLANをそのまま使います。HDMIと同時に使う場合ハードウェアの問題でWLANが接続できない場合があります。私の場合、HDMIケーブルを変えることで回避できました。

デバイスドライバ

デバイスドライバはYocto 5.2のRasPi4ターゲット標準のデバイスドライバを使用します。

local.confに下記のおまじないが必要です。これはRasPi(Broadcom)のWiFiファームウェアのライセンスにSynaptics has the right, in its sole discretion, to terminate this agreement immediately by giving written notice of termination to you.という文言が含まれており、このリスクを了承するという意味合いです。

local.conf
# required for wifi
LICENSE_FLAGS_ACCEPTED = "synaptics-killswitch"

wpa supplicant

wpa supplicantもYocto 5.2のRasPi4ターゲット標準のwpa supplicantを使用します。

実装

それでは作っていきます。meta-sample-connectivityレポジトリを作成し、その下にrecipes-wlanディレクトリを作成してここにレシピを作っていきます。なお、initマネージャはsystemdを前提にしています。

WLAN enablers

実際のレシピはこちらです。

wpa_supplicant.conf

簡単のためWPA2などは設定していません。必要に応じて変更してください。

wpa_supplicant自動起動

systemd-serviceとしてwpa_supplicantを起動します。

systemd-networkd

systemd-networkdを設定し、DHCPクライアントを設定してもらいます。

WLAN接続状況監視

実際のレシピはこちらです。

shellスクリプトを作成し、cronのかわりにsystemd timerから定期的に実行することで実現します。

定期的ipコマンドでwlan0のインタフェース情報を取得+パースしてIPアドレスが表示されていたら接続状態として、そうでなければ未接続状態としてMQTTメッセージを送信しているだけです。

一点わかりにくいのがwhileの中はサブシェル(子プロセス)で実行されるため、普通にexitしても親プロセスは実行を継続する点(結果ループ継続→最後の"DISCONNECTED"送信)です。これを回避するため親プロセスでサブシェルの異常終了(ここではexit 1)をトラップして、親プロセスを正常終了させています。

wlan-monitor.sh
#!/bin/sh

# trap subshell error, code 1 is SUCCESS_PUBLISH
set -E
trap '[ "$?" -ne 1 ] || exit 0' ERR

DEVICE=wlan0

ip addr show dev ${DEVICE} |
while read row; do
	col1=`echo ${row} | cut -d ' ' -f 1`
	col2=`echo ${row} | cut -d ' ' -f 2`
	if [[ "${col1}" == "inet" ]]; then
		/usr/bin/mosquitto_pub -d -t ui/state -m "{\"wlan\":\"CONNECTED: ${col2}\"}"
		# return error to exit main shell safely
		exit 1
	fi
done

/usr/bin/mosquitto_pub -d -t ui/state -m "{\"wlan\":\"DISCONNECTED\"}"

Yoctoターゲットのビルド対象への追加

最後にこれまでのレシピをYoctoターゲットのビルド対象に追加します。

bblayers.conf
  ${TOPDIR}/../meta-sample-connectivity \
local.conf
CORE_IMAGE_EXTRA_INSTALL:append = " wlan-enablers"
CORE_IMAGE_EXTRA_INSTALL:append = " wlan-monitor"

Discussion