DE10-Nanoボードで遊べるAzure IoTの世界：FPGAでアジュチカ!!?

どうもこんにちわ．
[インテル® FPGA ユーザーコミュニティ ](https://qiita.com/organizations/intel-fpga-user-community)というのに加入させていただいたのは嬉しいですが，どうにも多趣味a.k.a.器用貧乏につき，タグとか記事一覧のジャンルを荒らしてしまっていて申し訳ない気持ちがあります．
でも[ Elixir ](https://qiita.com/tags/elixir)とか[ Nerves ](https://qiita.com/tags/nerves)はいいぞぉ^^;

そして今回は[「インテル® FPGA Advent Calendar 2020」](https://qiita.com/advent-calendar/2020/intelfpga)にお誘いいただきまして，22日目担当の大役をご指名いただきました．
とはいえFPGA界隈で最弱な著者ですので，ツヨツヨな皆さまを満足させられるような内容をお届けすることはできません,,,

ということで，HDLやHLSのコードは一切交えずに，ちょっと違った世界を皆さんにご紹介したいと思います（このAdvent Calendarにこんなんでいいのか？？しらんけど．

やることは至極単純です．
クラウドサービスであるMicrosoft Azure(アジュール)越しにFPGAの回路イメージを投げ込んで，DE10-Nanoボードで<font color="orange"><b>『アジュチカ』</b></font>します．Azure越しでLチカするから『アジュチカ』です．異論は認めます．（なお[某NervesJP界隈](https://qiita.com/advent-calendar/2020/nervesjp)では，[『ウェブチカ』](https://qiita.com/kentaro/items/e8df79aa93b9fe9a567e)とか[『フェニチカ』](https://qiita.com/nishiuchikazuma/items/6c537342f8815728f69d)とか[『エムネチカ』](https://qiita.com/32hero/items/b7fb8409f3f6d0a60f66)とか，ヒトそれぞれのLチカを楽しんでおります^^;

今回紹介する方法を応用すれば，本番環境に展開したどこにでもあるFPGAボードの回路を，開発現場から自在に(？)リモートアップデートすることができます．
いわゆるOTA（Over the Air）ってやつですね．でも今回の例題は，単にLチカするだけ,,, これぞテクノロジの無駄遣いｗｗ

**[PR] いいことあるじゃん♪ [広告]**
[![ALGYAN](https://algyan.github.io/img/algyan.jpg)](https://algyan.github.io/)


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ピンクのブースで青い行商をしております．よろしければー <a href="https://t.co/mYtjvrtGOU">pic.twitter.com/mYtjvrtGOU</a></p>&mdash; Hideki Takase (@takasehideki) <a href="https://twitter.com/takasehideki/status/1312230449511424001?ref_src=twsrc%5Etfw">October 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

_＠ Maker Faire Tokyo 2020 [「IoT ALGYAN(あるじゃん)」](https://algyan.connpass.com/) ブースにて_

# Azure IoTとは？

IoTは情報科学の総合格闘技です！ by ジョージ:sunglasses:

もちろんエンドデバイスを開発せにゃなりませんし，データをクラウドにアップせにゃなりませんし，せっかく収集したデータを綺麗に解析せにゃなりません．ぜんぶやってられません．

そんなときにツヨい味方となるのが，みんな大好きMicrosoft Azureです．
https://azure.microsoft.com

エンドデバイスの開発や保守・デプロイをお手軽に展開できますし，SaaSで収集したデータをすぐに可視化することができます．機械学習エンジンでの統計処理もお手の物です．

代表的なサービスとして『Azure IoT Hub』があります．
私の言葉で回りくどく説明するよりも，公式の資料を~~パクって~~引用しましょう．

- [Azure IoT Hub の概要 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/iot-hub/about-iot-hub)

> IoT Hub は、クラウド内でホストされているマネージド サービスであり、IoT アプリケーションとそれが管理するデバイスの間の双方向通信に対する中央メッセージ ハブとして機能します。 Azure IoT Hub を使って IoT ソリューションを構築し、何百万もの IoT デバイスとクラウドでホストされたソリューション バックエンドの間に、信頼性が高く、セキュリティで保護された通信を提供できます。 IoT Hub には、ほぼすべてのデバイスを接続できます。
> 
> IoT Hub は、デバイスからクラウドへと、クラウドからデバイスへの、両方の通信をサポートします。 IoT Hub は、デバイスとクラウドの間のテレメトリ、デバイスからのファイルのアップロード、クラウドからデバイスを制御するための要求/応答メソッドなど、複数のメッセージング パターンをサポートします。 IoT Hub の監視は、デバイスの作成、デバイスの障害、デバイスの接続などのイベントを追跡することにより、ソリューションの正常性を維持するのに役立ちます。
> 
> IoT Hub の機能を使うと、製造で使われる産業機器の管理、医療での価値の高い資産の追跡、オフィス ビルの使用状況の監視など、スケーラブルで機能を完備した IoT ソリューションを構築できます。

# DE10-Nanoボードで遊ぶ

Microsoft Azureでは，Azure Certified Device プログラムというのが提供されています．要するに，このデバイスやボードはAzureサービス用にうってつけだよ！っとMicrosoftが認定しているということを示します．

Terasic社の[ DE10-Nano Kit ](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=205&amp;No=1046&amp;PartNo=2)が，このお墨付きな認定ボードのひとつになっています．

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/e253cb02-b48a-4453-dacf-0e2256a23d3b.png)](https://devicecatalog.azure.com/devices/95565670-7265-a9bc-23ee-395b435ecbe7)

_[Azure Certified Device catalog (preview) ](https://devicecatalog.azure.com/devices/95565670-7265-a9bc-23ee-395b435ecbe7)よりキャプチャ引用_

つまり要するに，DE10-Nanoを使えばAzure IoTな世界がお手軽に楽しめるわけです．

ただしひとつだけ注意点があります．
[Terasicから公開されているmicroSDカードのイメージ](http://download.terasic.com/downloads/cd-rom/de10-nano/)は，カーネルのrootfsがUbuntu 16.04 LTSのものとなっています．最新のAzure IoT Edge RuntimeはOpen SSL 1.1に依存しているため，このままでは素直にインストールすることができません（古いバージョンでしたらインストール可能です）
ということで，rootfsをUbuntu 18.04 LTSにupgradeしてやったり，なんやかんやの作業が必要になります．

そんなんダルいな,,, という方は，こちらにいろいろ対応したイメージを公開しています．よろしければご利用ください．

- http://lab3.kuis.kyoto-u.ac.jp/~takase/algyan/DE10-Nano-Cloud-Native_ALGYAN.zip

具体的にどんな作業をやってるかは，[このテキスト](https://docs.google.com/document/d/1GEjcUaTV_shHZK85E4NPApeCh5uE9fn6IFqwMFVmadQ/edit?usp=sharing)をご参照くださいませ．

# FPGAをクラウド越しに書き換える！？？

さて本題です．Azure越しにFPGAの回路を書き換えてみます．

カラクリはこんな感じです．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/94e1a5fb-b2c0-4542-24c1-b1c94878fe48.png)

1. まずは普通にシステムを設計します．FPGAロジックにはみんな大好き[ Quartus Prime (18.1 Lite Edition) ](https://www.intel.co.jp/content/www/jp/ja/software/programmable/quartus-prime/overview.html)を使います．ソフトウェアもちゃんと開発する場合は[ SoC EDS ](https://www.intel.co.jp/content/www/jp/ja/software/programmable/soc-eds/overview.html)を使いましょう．また，FPGA部の回路構成やHPS部とのインタフェース構成に応じて，ハードウェア情報を含むDevice Tree Blobファイルやpreloaderなどを作成します．
2. IoT Edgeモジュールは，すごくざっくり言うと，Dockerコンテナとして稼働します．Azure readyなIoTボードに対してコンテナイメージをデプロイしてやって，そしてそこでコンテナを動作させます．ここではFPGA部の回路書換えの操作を含むDockerfileを作成し，コンテナイメージとしてビルドします．
3. [Azure Container Registry ](https://azure.microsoft.com/ja-jp/services/container-registry/)というサービスに，自身のレジストリを作成します．これはいわばAzure専用のDocker Hubに相当するサービスです．これに対して，ビルドしたコンテナイメージをプッシュします．
4. IoT Hubの操作設定を行い，対象のDE10-NanoボードをIoT Edegeデバイスとして登録します．そして，Azure Container Registryに登録したコンテナイメージを，IoT Edgeデバイスにデプロイします．
5. これでなんとできあがり！DE10-Nanoボード上では，IoT Edgeモジュールとしてコンテナイメージが実行されます．そして，FPGA部の回路を書換えてソフトウェアを実行します．

アジュチカの例を交えて，もうちょいだけ説明します．

## ①FPGAを含むシステムの設計

DE10-NanoのSystemCDに入っている `DE10_NANO_SoC_FB` をプロジェクト雛形（GSRD: Golden System Reference Design）として，ちょろっとだけ回路設計を書き換えました．

- https://github.com/algyan/IntelFPGA_AzureOTA/commit/4dd2e5cc2a774b9ad6c7bdad0cfcaf162a0328b4#diff-61a2893444a3944efaf12088bcc32dc4624976c225fe7ef9bf4175565456e30b

Verilog HDLコードの変更総数はたったの12行，変えたウチに入ってませんね^^;

ソフトウェアはまったく実装していません．だってLチカするだけだもんっ

## ②Dockerfileの作成とイメージのビルド

Dockerfileを[こんな感じ](https://github.com/algyan/IntelFPGA_AzureOTA/blob/main/vscode_project/L-Chika/EdgeSolution/modules/AwesomeLchika/Dockerfile.arm32v7)に拵えました．

```Dockerfile
# ベースとするカーネルの選択
FROM arm32v7/ubuntu:xenial AS base
# 本来はAzure IoT device SDKをインストールする
#RUN apt-get update && \
#    apt-get install -y --no-install-recommends software-properties-common && \
#    add-apt-repository -y ppa:aziotsdklinux/ppa-azureiot && \
#    apt-get update && \
#    apt-get install -y azure-iot-sdk-c-dev && \
#    rm -rf /var/lib/apt/lists/

# 本来はIoT Edgeモジュールで実行されるアプリケーションをビルドする
#FROM base AS build-env
#RUN apt-get update && \
#    apt-get install -y --no-install-recommends cmake gcc g++ make && \
#    rm -rf /var/lib/apt/lists/* 
#WORKDIR /app
#COPY . ./
#RUN cmake . 
#RUN make

# Device Tree Overlayを実行する
FROM base
WORKDIR /overlay
# 必要なファイルをコンテナイメージ内にコピーする
COPY ./soc_system_lchika.rbf ./
COPY ./overlay_lchika.dtbo ./
COPY ./overlay_lchika.sh ./
# Device Tree Overlayのスクリプトを実行する
RUN chmod +x /overlay/overlay_lchika.sh
CMD ["/overlay/overlay_lchika.sh"]

# 本来はIoT Edgeアプリケーションを実行する
#FROM base
#WORKDIR /app
#COPY --from=build-env /app ./
#RUN useradd -ms /bin/bash moduleuser
#USER moduleuser
#CMD ["./main"]
```

もともとのAzureのサンプルコードを雛形として引っ張ってきましたが，ほとんどコメントアウトですね,,, だってやりたいのはLチカだけやしソフトウェアは（ry
本来だと，Azure IoT device SDKというIoT Edgeモジュールのビルドのためのツールをインストールして，IoT Edgeモジュールのアプリをビルドします．そしてコンテナイメージ内でそのアプリを実行してやります．

今回は，FPGAの回路書換えのために必要なファイル群として，この３つのファイルをコンテナイメージ内に取り込んでいます．

- `soc_system_lchika.rbf` ：回路情報
- `overlay_lchika.dtbo` ：デバイスツリーファイル
- `overlay_lchika.sh` ：回路書換えのスクリプト

回路書換えのスクリプトの中身を見てみましょう．

```overlay_lchika.sh
#!/bin/bash

# ファイル名とディレクトリ名を定義する
DTBO="overlay_lchika.dtbo"
RBF="soc_system_lchika.rbf"
DTO_DIR="/sys/kernel/config/device-tree/overlays/socfpga"

echo 'Message : Starting Device Overlay at '$(date)

echo "Message : Checking Current Device Tree"
if [ -d ${DTO_DIR} ];then
    echo 'Message : Current Device Tree Overlay Name is '$(cat ${DTO_DIR}/path)
    
    echo "Message : Deleting ${DTO_DIR}"
    rmdir ${DTO_DIR}

    echo "Message : Successfully ${DTO_DIR} deleted"
else
    echo "Warning : ${DTO_DIR} does not exist"
fi

echo "Message : Copy dtbo & rbf file"
cp /overlay/${DTBO} /lib/firmware
cp /overlay/${RBF} /lib/firmware

echo "Message : Creating New Overlay Directory"
mkdir ${DTO_DIR}

echo "Message : Updating Overlay"
echo ${DTBO} > ${DTO_DIR}/path

echo 'Message : Checking Current Device Overlay Name is '$(cat ${DTO_DIR}/path)
echo "Message : Successfully Device Tree Overlay Done"

echo 'Message : Overlay Done at '$(date)

# IoT Edgeモジュールは実行すべき処理が無くなると自動的に
# 再起動されるため，コンテナを起動し続けるようしている
tail -f /dev/null
exit 0
```

詳しい方は，このテクノロジの無駄遣いのタネがだんだん分かってきたのではないかと思います．つまり，LinuxのDevice Tree Overlay機能をDockerコンテナ越しに利用してやっているだけです．

DE10-NanoのLinuxカーネルでは， `/sys/kernel/config/device-tree/overlays/socfpga` にDevice Tree Overlay操作のためのモジュールや各種ファイルがあります．回路情報とデバイスツリーファイルを `/lib/firmware` に置いてやって，そしてこのディレクトを作成することで，よしなに回路情報とHPS-FPGA間のデバイスツリー情報が更新されます．

Device Tree Overlayに関する詳しい説明は，@eofz さんのコチラの記事を見ていただくのが早いです．

- [DeviceTree Overlay でのFPGAコンフィグ(DE10nano) - Qiita](https://qiita.com/eofz/items/884b37e401c07a264d38)

## ③コンテナイメージのプッシュ

ここまで来たらもうお手の物です．

やはりMicrosoftよろしく，Azureは[Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)との親和性がトテモ良いです．Azure IoT対応の拡張機能である[Azure IoT Tools](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-device-management-iot-toolkit)を使うことで，IoT EdgeモジュールのビルドやIoT Hubの操作などをVS Code上で行うことができます．

Azure IoT ToolsでIoT Edgeモジュールをビルドしてやります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/21b69d88-5b0e-d1b0-7d8c-f62d3a4bd1f7.png)

そしたらあっという間にAzure Container RegistryにIoT Edgeモジュール（コンテナイメージ）が登録されます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/30bd655c-99bf-f41d-c24f-660c5bb9fe63.png)

## ④IoT Hubを介したIoT Edgeモジュールのデプロイ

もうあとはWebブラウザ上でIoT Hubの設定画面を操作するだけです．
こんな感じで，IoT Edgeデバイスとして登録したDE10-Nanoに，アジュチカのためのIoT Edgeモジュールである `AwesomeLchika` をデプロイ指定していきます（ざつ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/3caae335-eab8-643d-0768-63b591a3daea.png)

## ⑤IoT Edgeデバイスでのモジュールの実行

あとは素敵なLチカをお楽しみください〜

https://youtu.be/C_swG0KLgDg?t=9759

~~なんて地味な見映えなんだっ orz~~

# 注意事項

おぉっすげいっ！！っと，嘘でいいんで，とりあえず思っておいてください:D

じゃあどんな回路情報でもリモートで書き換えられるかというと，そうでもありません．あくまでDevice Tree Overlayで対応できる範囲です．ざっくり言うとpreloaderの書き換えはできませんし，HPS-FPGAのインタフェースは最初から固定化しておく必要があります．
また，デバイスツリーの書き換えを行いますので，プロセッサからFPGAに常時アクセスするようなアプリの場合は，その動作を一旦停止する必要があります．動作中に書き換えを行ったら，カーネルが軽くハングします．
そして，デバイスツリーの操作を行いますので，Dockerコンテナが特権で実行される必要があります．そこは気持ち悪いところですし，なんかしら他に方法はあると思います．


# おわりに

ということでこの記事では，FPGAな皆さまにAzure IoTな世界をご紹介しました．
実はこの記事の内容は，2020年9月20日(日)に実施したALGYANハンズオンのダイジェスト版だったりします．

- [実機貸出有！【オンライン】FPGA回路をリモートで書換→壮大なLチカ！インテルFPGAハンズオン#1 - connpass](https://algyan.connpass.com/event/185328/)

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/97281ab3-b243-f856-9b45-788396d4f55f.png)](https://algyan.connpass.com/event/185328/)

そして，ハンズオンのテキストと設計データは，全て下記のGitHubにて公開しています．
https://github.com/algyan/IntelFPGA_AzureOTA

<a href="https://github.com/algyan/IntelFPGA_AzureOTA"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/algyan/IntelFPGA_AzureOTA.png" width="460px"></a>

なんなら[ハンズオン当日のアーカイブ動画](https://youtu.be/C_swG0KLgDg?t=560)も公開しています．太っ腹！！？

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/c68d0a2d-2c06-7058-5346-2de5ffd9ed75.png)](https://youtu.be/C_swG0KLgDg?t=560)

ぜひぜひテキストや動画を追って，実際に<font color="orange"><b>『アジュチカ』</b></font>をやってみてください．
（ただしテキストは総計111ページあるらしいです．我ながらクルッテル:innocent:

# 次回予告？？

Azure IoTでは，今回紹介したIoT Hubの他にも，Saas (Software as a Service) 的にIoTサービスを開発・管理できる[「IoT Central」](https://docs.microsoft.com/ja-jp/azure/iot-central/core/overview-iot-central)だったり，Digital Twin的な連携ができる[Plug and Play](https://docs.microsoft.com/ja-jp/azure/iot-pnp/overview-iot-plug-and-play)なんかのサービスも展開されています．

冒頭のTwitterで示したデモでは，9軸や温湿度のセンサが載っている[ RFS Daugher Card ](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=225&No=1025&PartNo=2)をDE10-Nanoに挿して，それらの値をIoT Centralにぶん投げて可視化してやっています．

ALGYANでは，DE10-Nanoボードでこれらのサービスも使って遊ぶぜ！というような続編ハンズオンの企画をやるとかやらないとかラジバンダリです（というかFPGAツヨツヨな皆さま，たかせを手伝ってくださいm(_ _)m

ぜひALGYANのコミュニティに参加いただき，最新情報をチェックしてみてください．
2020年のうちに，メンバ数5,500名突破なるか？？
https://algyan.connpass.com/

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/3d4cd954-168d-2653-66eb-a33118c6472f.png)](https://algyan.connpass.com/)