AliOS Things 3.0 アプリケーション開発ガイド

この記事は [alibabacloud Advent Calendar 2019](https://qiita.com/advent-calendar/2019/alibabacloud) 11日目の記事になります。

Alibaba には AliOS Things というデバイス向けのOSがあります。
本記事は、AliOS Things 3.0についていろいろと調べてみた記事になります。誤り等があればご指摘ください。

# AliOS Things 3.0 

AliOS Things 3.0 は、2019年9月27日 に Apsara Conference 2019 （云栖大会2019）にて正式にリリースされました。AliOS Thingsは、2017年10月に最初のバージョンがリリースされていて継続的にアップデートされてきました。

ちなみに、Alibabaには、[AliOS](http://www.alios.cn/)というスマートフォンのような高機能なデバイス向けのOSと、 [AliOS Things](https://aliosthings.io/#/)という IoT デバイス向けの軽量なOSがあります。

Alibabaは、これからIoTから、AIとIoTが融合したAIoTに進化すると唱えていて、そのAIoT時代のためのスマートデイバイスOSだとしています。以下のような新機能を備えています。当然、Alibaba Cloudと連携するインタフェースも標準で備えています。

## AliOS Things アーキテクチャの概要

[aliosthings.io](https://aliosthings.io/) に書いてある特徴が書いてあります。

いろいろと書いてありますが、IoTデバイスのアプリケーション開発において必要なライブラリをいろいろと集めたり、抽象化してるからクイックに開発できるよって事かなと思います。

機械翻訳してみるとこんな感じです。アーキテクチャとしては、AliOS Thingsはレイヤードアーキテクチャとコンポーネントアーキテクチャを採用しています。AliOS Thingsには以下が含まれます。

- BSP：SoCベンダーが主に開発および保守するボードサポートパッケージ
- HAL：WiFi、UARTなどのハードウェアアブストラクションレイヤー
- カーネル：Rhino RTOS Kernel、Yloop、VFS、KV Storageが含まれています
- プロトコルスタック：LwIP TCPIPスタック、uMeshメッシュネットワークスタックが含まれる
- セキュリティ：TLS、TFS（Trusted Framework Service）、TEE（Trusted Exexcution Environment）
- AOS API：AliOS Thingsが公開したアプリケーションとミドルウェアのAPI
- ミドルウェア：Alibabaの付加価値があり一般的に見られるIoTコンポーネントが含まれています
- 例：実践的なサンプルコード、およびAlinkappなどの十分にテストされたアプリケーション
- すべてのモジュールはコンポーネントとして構成されており、各コンポーネントには他のコンポーネントとの依存関係を記述する独自の.mkファイルがあります。これにより、アプリケーションは必要なコンポーネントを簡単に選択できます。

AliOS Things 3.0で新しくなった内容は、[AliOS Things v3.0.0リリースノート](https://github.com/alibaba/AliOS-Things/releases/tag/v3.0.0) を参照してください。中国語ですが Google 翻訳などを活用してみてください。

# この記事では開発環境を作るところまでやります

ちょっと使ってみたいと思った人が触ってみることができるように、日本語で開発環境の手順を書いてみようと思います。中国語では以下のページにありますので適宜参照してください。読んでつまづいたところなどは適宜フォローしてあります。つまりこの記事の方が分かりやすいはず！

[AliOS Things 3.0アプリケーション開発ガイド](https://yq.aliyun.com/articles/720516)

さらに詳しい環境構築については、[AliOS Things Environment Setup](https://github.com/alibaba/AliOS-Things/wiki/AliOS-Things-Environment-Setup) を参照してください。

## アプリケーション開発フレームワーク

開発者が開発に専念できるようにアプリケーション開発フレームワーク(应用开发框架 Yìngyòng kāifā kuàngjià)が提供されています。

## 開発環境

- 構築環境：Mac OS X(筆者の環境は10.14.6)
- デバイス：ESP32 Devkitc
- OS: AliOS Things 3.0

### 前提

- Visual Studio Code 1.40(インストール済み)
- AliOS Things >= 3.0 
- aos-cube >= 0.3.7 

# クイックスタート

AliOS Things のようなマイコン向けのOSは、OSは、デバイスにOSをインストールしてから、アプリケーションをインストールするような形では無く、OSとアプリケーションはセットで書き込む感じです。（たぶん）
なので、一旦はMac上に開発環境となる VS CodeとAliOS-Studioを構築し、AliOS THingsのソースコードを展開します。

このような6ステップで進めていきます。

- ステップ1： AliOS Studio をインストールする
- ステップ2： AliOS Things 3.0 ソースコードをダウンロードする
- ステップ3： AOS_SDK_PATH環境変数を追加する
- ステップ4： aos-cube をインストール
- ステップ5： AliOS Studioでアプリケーションプロジェクトを作成する
- ステップ6: コンパイル、フラッシュ、デバッグ

## ステップ1： AliOS Studio をインストールする

Visual Studio Codeはあらかじめインストールされて居ているとして、左側のエクステンション部分から AliOS Studio をインストールします。このスクリーンキャプチャは既にインストール済みなので歯車マークになっていますが、インストール前の場合は、こちらにインストールボタンが表示されます。インストールは容量が大きいため少し時間がかかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/2f8d07a5-9e6b-8115-3969-a723c7b860e9.png)


## ステップ2： AliOS Things 3.0 ソースコードをダウンロードする

まず、githubの以下のアドレスにアクセスして、AliOS Thingsの完全なソースコードをダウンロードします。

https://github.com/alibaba/AliOS-Things

```
$ git clone https://github.com/alibaba/AliOS-Things.git
```

これにはすべてが含まれますが、容量を軽くするためにソースコードをカスタマイズすることも可能です。以下のアドレスにアクセスしてください。

https://aliosthings.iot.aliyun.com

中国語ですがこの4点さえ分かれば迷うことは無いと思います。（ただ、ダウンロードには中国のAlibaba Cloudへのログインが必要なようです。アカウントは別途ご用意ください。実名認証は不要でした）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/d1384dc3-6f48-46e6-83eb-008544cad2a7.png)

## ステップ3： AOS_SDK_PATH環境変数を追加する

ソースコードを用意したら環境変数 AOS_SDK_PATH に、 AliOS Things 3.0 ソースコードパスを指定します。`/path/to/alios`は、各自の環境に書き直してください。

```
echo "export AOS_SDK_PATH=/path/to/alios" >> ~/.bash_profile
source ~/.bash_profile
```

aos-cube は、環境変化 AOS_SDK_PATH から AliOS Things のソースコードを見つけます。

ターミナルを再起動して以下のコマンドで設定が帰ってきたら設定が成功しています。

```
echo $AOS_SDK_PATH
```

## ステップ4： aos-cube をインストール

インストールには、 `Python2.7` と `pip` がインストールされている必要があります。なんどかディレクトリが作成出来ないエラーなどが出ましたが、２，３回繰り返したらインストールできました。

```
sudo pip install aos-cube
```
aos-cube 更新をする場合は以下のコマンド

```
sudo pip install -U aos-cube
```

以下のようになれば成功です


```
Successfully installed aos-cube-0.3.10 certifi-2019.11.28 chardet-3.0.4 configparser-4.0.2 idna-2.8 paho-mqtt-1.5.0 progressbar2-3.47.0 python-utils-2.3.0 requests-2.22.0 urllib3-1.25.7
```


## ステップ5： AliOS Studioでアプリケーションプロジェクトを作成する

VSCodeでAliOS Studioはどこにあるかというと、左下のステータスバーのところに [+] というアイコンがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/eeb6ce84-0bae-3354-888f-6c0179c8a2f7.png)

新規プロジェクトを作成するには、この [+] ボタンをクリックします。

そうすると、ウインドウの上部に入力フォームが現れて、「アプリケーションプロジェクト名」、「保存するパス」、「デバイス」を選択します。

「アプリケーションプロジェクト名」を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/4f975d9d-041f-bca2-7fe7-160fe9f2f1b4.png)

「保存するパス」を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/48316f3d-c019-95c6-f5be-9f2fb5970e0b.png)

デバイスは、ESP32 Devkitc を利用するので `esp32devkitc` を選択します。

## ステップ6: コンパイル、フラッシュ、デバッグ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/43f0283b-cb76-c890-9aad-b502e2726cfc.png)

初期状態では、 `aos/kernel.h` が見つからないようでしたので、PATHに SDK 内の include ディレクトリを追加しておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/daa0ba3d-8cf0-ea8b-8cc0-488bb0c3cbef.png)

以上で、開発環境の準備は終わりです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70132/3830c6d4-f799-1adb-ae29-a818fcb5adfb.png)

下のステータスバーの部分に、あるチェックマークがBuuildですのでクリックしてみましょう。コンソールが開いてコンパイルが始まります。
初回なので `esp32devkitc` 用のライブラリ？がgitから自動的にダウンロードされたり、しています。まだ何もコードを書いていないのでwifiの設定が無かったり警告は出ていますがとりあえず無視しましょう。

```

> Executing task: aos make <

aos-cube version: 0.3.10
Check if required tools for esp32devkitc exist
Toolchain gcc-xtensa-esp32 missing, start download ...
https://github.com/aliosthings/gcc-xtensa-esp32-osx.git -> /Users/eterao/Dropbox/git/AliOS-Things/build/compiler/gcc-xtensa-esp32/OSX
Cloning into 'gcc-xtensa-esp32'...
remote: Enumerating objects: 1377, done.
remote: Counting objects: 100% (1377/1377), done.
remote: Compressing objects: 100% (827/827), done.
remote: Total 1377 (delta 522), reused 1377 (delta 522), pack-reused 0
Receiving objects: 100% (1377/1377), 26.76 MiB | 1.56 MiB/s, done.
Resolving deltas: 100% (522/522), done.
Checking out files: 100% (1545/1545), done.
Download toolchain gcc-xtensa-esp32 succeed
Parsing all components ...

Build Configuration:
====================
App: myapp
Board: esp32devkitc
====================

Creating /Users/eterao/aosApp/myapp/out/config/autoconf.h ...
Making config file for first time
app_version:app-1.0.0-20191210.203900
processing components: myapp esp32devkitc
*** All Components: myapp esp32devkitc mcu_esp32 kernel_init lwip netmgr mbedtls rhino arch_xtensa_lx6 ulog kv osal_aos yloop debug vfs 
Build AOS Now
TOOLCHAIN_PATH=
Compiling myapp
Compiling board_esp32devkitc
Compiling mcu_esp32
Compiling kernel_init
Compiling lwip
/Users/eterao/Dropbox/git/AliOS-Things/platform/mcu/esp32/hal/wifi_port.c:591:28: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
     .get_wireless_info   = get_wireless_info,
                            ^
/Users/eterao/Dropbox/git/AliOS-Things/platform/mcu/esp32/hal/wifi_port.c:591:28: note: (near initialization for 'sim_aos_wifi_eps32.get_wireless_inf')
Compiling netmgr
Compiling mbedtls
Compiling rhino
Compiling arch_xtensa_lx6
Compiling ulog
Compiling kv
Compiling osal_aos
Compiling yloop
Compiling debug
Compiling vfs
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/ld/esp32.ld
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/ld/esp32.common.ld
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/ld/esp32.rom.ld
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/ld/esp32.peripherals.ld
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/ld/esp32.rom.spiram_incompatible_fns.ld
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/myapp.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/board_esp32devkitc.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/mcu_esp32.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/kernel_init.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/lwip.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/netmgr.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/mbedtls.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/rhino.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/arch_xtensa_lx6.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/ulog.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/kv.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/osal_aos.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/yloop.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/debug.a
Making /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/libraries/vfs.a
Making myapp@esp32devkitc.elf

Making myapp@esp32devkitc.bin
Making myapp@esp32devkitc.hex

                        AOS MEMORY MAP                            
|=================================================================|
| MODULE                                   | ROM       | RAM      |
|=================================================================|
| arch_xtensa_lx6                          | 3984      | 2088     |
| board_esp32devkitc                       | 306       | 0        |
| debug                                    | 3519      | 16       |
| kernel_init                              | 90        | 0        |
| kv                                       | 1940      | 24       |
| libapp_update                            | 1492      | 68       |
| libbootloader_support                    | 1698      | 0        |
| libc                                     | 59436     | 0        |
| libcoexist                               | 3716      | 1471     |
| libcontainer                             | 2224      | 0        |
| libcore                                  | 1197      | 5        |
| libdriver                                | 8798      | 121      |
| libesp32                                 | 31516     | 4420     |
| libgcc                                   | 5211      | 0        |
| libhal                                   | 547       | 0        |
| liblog                                   | 871       | 276      |
| libm                                     | 92        | 0        |
| libmesh                                  | 55        | 2        |
| libnet80211                              | 125046    | 9366     |
| libnewlib                                | 3137      | 424      |
| libnvs_flash                             | 11872     | 32       |
| libphy                                   | 34793     | 2194     |
| libpp                                    | 62888     | 6510     |
| librtc                                   | 879       | 4        |
| libsoc                                   | 7030      | 8        |
| libspi_flash                             | 6245      | 349      |
| libstdcc\+\+-cache-workaround            | 96        | 4        |
| libvfs                                   | 3602      | 335      |
| libwpa                                   | 23273     | 682      |
| libwpa2                                  | 0         | 1        |
| libwpa_supplicant                        | 15210     | 0        |
| libwps                                   | 0         | 1        |
| lwip                                     | 28422     | 1160     |
| mbedtls                                  | 3141      | 4        |
| mcu_esp32                                | 10637     | 600      |
| myapp                                    | 19        | 0        |
| netmgr                                   | 113       | 8        |
| osal_aos                                 | 927       | 0        |
| rhino                                    | 13987     | 9912     |
| ulog                                     | 444       | 7        |
| vfs                                      | 819       | 1105     |
| yloop                                    | 1305      | 32       |
| *fill*                                   | 3605      | 231      |
|=================================================================|
| TOTAL (bytes)                            | 484182    | 41460    |
|=================================================================|
esptool.py v2.5.1
Generate Raw OTA image: /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/binary/myapp@esp32devkitc_ota.bin ...
Generate Compressed OTA image: /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/binary/myapp@esp32devkitc_ota.bin.xz ...
492432
ab111719d9af2385817fc6fcc03bcf8a
288136
4ecefbaaacbe9d12ab27805be0b385a2
Build complete: myapp@esp32devkitc

Terminal will be reused by tasks, press any key to close it.

```

雷のマークを押すと、デバイスへの Uploadが始まります。

このとき、シリアルポートに `/dev/cu.SLAB_USBtoUART` が存在することを確認しましょう。これがデバイスへの書き込みポートになります。それ以外のポートを指定しても書き込めないので注意してください。これが表示されていない場合は、差し込みが甘いか、10中89ケーブルが充電専用か品質が悪いことに起因すると思います。ケーブルを変えて見てください。

```
> Executing task: aos upload myapp@esp32devkitc <

aos-cube version: 0.3.10
[INFO]: Target: myapp@esp32devkitc

--- Available ports:
---  1: /dev/cu.Bluetooth-Incoming-Port 'n/a'
---  2: /dev/cu.SLAB_USBtoUART u'CP2102N USB to UART Bridge Controller'
--- Enter port index or full name: 2
```

`/dev/cu.SLAB_USBtoUART` が2番に表示されるので、 `2` を入力します。アップロードが無事開始されます。

```
[INFO]: Running cmd:
        'esptool.py --chip esp32 --port /dev/cu.SLAB_USBtoUART --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /Users/eterao/Dropbox/git/AliOS-Things/platform/mcu/esp32/bsp/bootloader.bin 0x8000 /Users/eterao/Dropbox/git/AliOS-Things/platform/mcu/esp32/bsp/custom_partitions.bin 0x10000 /Users/eterao/aosApp/myapp/out/myapp@esp32devkitc/binary/myapp@esp32devkitc.bin'
esptool.py v2.5.1
Serial port /dev/cu.SLAB_USBtoUART
Connecting........_____.
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse
MAC: 30:ae:a4:ee:91:a4
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 19504 bytes to 12342...
Wrote 19504 bytes (12342 compressed) at 0x00001000 in 0.1 seconds (effective 1062.2 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 159...
Wrote 3072 bytes (159 compressed) at 0x00008000 in 0.0 seconds (effective 3139.5 kbit/s)...
Hash of data verified.
Compressed 492432 bytes to 311527...
Wrote 492432 bytes (311527 compressed) at 0x00010000 in 4.4 seconds (effective 899.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
---host_os:OSX
[INFO]: Firmware upload succeed!
```

succeedと表示されれば完了です。

# まとめ

初めてのAliOS Things開発環境作りで、少し前までネイティブアプリとしての ATOM ベースの AliOS Studio もあったり、VS Code上での設定方法も少し前から変更になっていたりと、いろいろとつまずきは多かったですが、その分皆さんはスムーズに環境構築できるかなと思います。

説明を読むと多くのセンサーにも対応していて、多くのデバイスにも対応しているようです。いろいろと便利そうなのでもう少しいろいろ使ってみようと思います。

一緒に、良き AliOS Things Lifeを送りましょう！

では次にバトンタッチ。