Sierra Wireless 社の WPシリーズは,「LTE モデム + Linux が動作するCPU環境」というモジュールで,スタンドアロンでLTE接続可能なIoTエッジ装置の開発にぴったりのアイテムです.
e-trees.Japanでは,このモジュールをコンパクトに組み込める開発ボードを用意しました.
このモジュールでは Linux 上に Sierra Wireless 社が提供する Legato と呼ばれるフレームワークが動作しています.今回は Legato 上で動かすアプリケーションを開発する環境を構築してみます.
開発環境の構築
最初にフレームワークの準備を行い,次にビルドを行うためのツールチェインを導入します.
導入にあたって Legato の Webサイトを参考にします.
OS は Legato が推奨している Ubuntu 18.04 を使用します.
(20.04で行うと GCC のバージョン関連の問題でビルドが行なえませんでした)
フレームワークの準備
https://docs.legato.io/latest/basicBuildLegato.html
必要なツールをインストールします.
openjdk やドキュメント生成用のツールも入れておくと良いと書いてあるので入れます.
$ sudo apt install -y build-essential python python-jinja2 python-pkg-resources python-git cmake git libsdl-dev diffstat texinfo gawk chrpath wget cpio bash ninja-build bc unzip libxml2-utils gcovr libcurl4-gnutls-dev zlib1g-dev libbz2-dev bsdiff libssl-dev autoconf automake iputils-ping libtool flex bison gperf libncursesw5-dev libncurses5-dev
$ sudo apt install -y openjdk-8-jdk
$ sudo apt install -y doxygen graphviz
ホームディレクトリ以下に workspace ディレクトリを作成し,使用していきます.
$ mkdir ~/workspace
$ cd ~/workspace
$ mkdir boardSupport
$ mkdir legatoAF
$ mkdir firmware
次に Legato のソースコードをダウンロードします.
ダウンロードの仕方に 2 種類あり, GitHub からと 直接サイトからダウンロードする方法です.
今回は直接サイトからダウンロードしてきます.
WP7605 のファームウェアに応じてバージョンを指定します.
確認方法は後述しますが,今回使用しているモジュールは「SWI9X07Y_02.28.03.05」なので以下のサイトを参考にして続けます.
https://source.sierrawireless.com/resources/airprime/software/wp76xx/wp76xx-firmware-release-13,-d-,1-components/#sthash.TbNgxygV.WZtZVr6h.dpbs
$ cd ~/workspace/legatoAF
$ wget https://downloads.sierrawireless.com/legato/1902/legato-19.02.0.tar.bz2
$ tar -xvf legato-19.02.0.tar.bz2
$ cd legato-19.02.0
$ make wp76xx
最終的な legat-19.02.0 ディレクトリ以下の構成です.
.
├── 3rdParty
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIB_COMPANY.md
├── CONTRIB_INDIVIDUAL.md
├── Documentation -> build/doc/user/html
├── KConfig
├── LICENSE.md
├── Makefile
├── Makefile.framework
├── Makefile.hostTools
├── Makefile.targetTools
├── README.md
├── apps
├── bin
├── build
├── cmake
├── components
├── conftest.py
├── default.sdef
├── default_readonly.sdef
├── drivers
├── framework
├── interfaces
├── legatoTargetConfig.sinc
├── localhost.sdef
├── modules
├── package.properties
├── platformAdaptor
├── platformBuildVars.sinc
├── pytest.ini
├── run-tests
├── sources.md5
├── targetFiles
├── targets
├── utils.mk
└── version
フレームワークの準備はこれで完了です.
ツールチェインの準備
クロスコンパイルを行うためにツールチェインの準備を行います.
https://docs.legato.io/latest/basicBuildToolchain.html
WP7605 なので WP76xx を導入していきます.
$ cd ~/workspace/firmware
$ mkdir wp76xx
$ cd wp76xx
$ wget https://downloads.sierrawireless.com/AirPrime/WP76xx/Release13.3/poky-swi-ext-glibc-x86_64-meta-toolchain-swi-armv7a-neon-toolchain-swi-SWI9X07Y_02.28.03.05.sh
$ chmod +x poky-swi-ext-glibc-x86_64-meta-toolchain-swi-armv7a-neon-toolchain-swi-SWI9X07Y_02.28.03.05.sh
インストールスクリプトの実行時にインストール場所を尋ねられますが特に変更せず 2 回 Enter を押せば良いと思います.以下ログ.
$ ./poky-swi-ext-glibc-x86_64-meta-toolchain-swi-armv7a-neon-toolchain-swi-SWI9X07Y_02.28.03.05.sh
Poky (Yocto Project Reference Distro) SDK installer version 2.5.2
=================================================================
Enter target directory for SDK (default: /opt/swi/SWI9X07Y_02.28.03.05):
You are about to install the SDK to "/opt/swi/SWI9X07Y_02.28.03.05". Proceed[Y/n]?
Extracting SDK.................................................................done
Setting it up...done
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/bin2c
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
SHIPPED scripts/dtc/dtc-lexer.lex.c
SHIPPED scripts/dtc/dtc-parser.tab.h
HOSTCC scripts/dtc/dtc-lexer.lex.o
SHIPPED scripts/dtc/dtc-parser.tab.c
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTLD scripts/dtc/dtc
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
CC scripts/mod/devicetable-offsets.s
GEN scripts/mod/devicetable-offsets.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/kallsyms
HOSTCC scripts/conmakehash
HOSTCC scripts/sortextable
HOSTCC scripts/asn1_compiler
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
$ . /opt/swi/SWI9X07Y_02.28.03.05/environment-setup-armv7a-neon-poky-linux-gnueabi
$
ログにも出ているようにこのツールチェインを使用する際には新しいシェルセッションのたびに. /opt/swi/SWI9X07Y_02.28.03.05/environment-setup-armv7a-neon-poky-linux-gnueabi
を入力する必要があります.
ここまでで環境構築は完了です.
Hello World
それでは実際にアプリケーションをビルドして実機上で動作させてみます.
アプリケーションのビルド
今回は簡単にフレームワークのサンプルをビルドして実行します.
環境の設定としてツールチェインとフレームワークの 2 つがありどちらも実行する必要があります.
サンプルはフレームワーク以下の apps/sample にいくつか存在します.
今回は単純な helloWorld を表示するだけのものを使用します.
apps/sample/helloWorld 以下はこのとおりです.
.
├── CMakeLists.txt
├── Makefile
├── helloComponent
└── helloWorld.adef
ビルドされるソースコードの内容は helloComponent/helloWorld.c です.
見るとわかりますが,なかなかクセが強いです.
#include "legato.h"
COMPONENT_INIT
{
LE_INFO("Hello, world.");
}
それでは実際にビルドします.
ターゲットは wp76xx を指定しておきます.
## execute if not running in this session
$ . /opt/swi/SWI9X07Y_02.28.03.05/environment-setup-armv7a-neon-poky-linux-gnueabi
$ cd ~/workspace/legatoAF/legato-19.02.0/
## Only the root directory of the Legato framework can execute config code
$ . bin/configlegatoenv
$ cd apps/sample/helloWorld
$ mkapp -t wp76xx helloWorld.adef
ビルドするとディレクトリとファイルが 1 つずつ増えています.
.
├── CMakeLists.txt
├── Makefile
├── _build_helloWorld
├── helloComponent
├── helloWorld.adef
└── helloWorld.wp76xx.update
実機について
実際に実機で動かすのですが,その前に一通り実機の操作について説明します.
PC と USB ケーブルで接続し電源ボタンを長押しします.
そうすると PC 側で認識され NIC として扱うことができます.
余談
今回接続し PC 側から確認したところモデムのみとして認識され WP7605 との通信用の NIC が有効にならない問題が発生しました.
以下の issue より Modem Manager を無効にすると通信ができるという記述がありました.
https://docs.legato.io/17_11/releaseNotes17110.html
Modem Manager を無効化し,再接続することで通信用 NIC が認識され,その NIC を有効化することで問題なく接続できるようになりました.sudo systemctl disable ModemManager.service
sudo systemctl stop ModemManager.service
Modem Manager がよしなに動いていてくれたのが裏目に出たのでしょうか…
PC から SSH で接続します.モジュールの IP アドレスは 192.168.2.2 ,ユーザ名は root です.
別のターミナルを開いて実行することをおすすめします.
$ ssh root@192.168.2.2
このモジュール特有のコマンドがいくつか存在します.
Target Tools
- cm info : モジュールについての詳細な情報を確認 (IMEI,ファームウェアのバージョン等)
- cm sim info : SIM の情報を確認
- cm data connect : モバイルネットワークに接続
- fwupdate query : ファームウェアや Linux のバージョンを確認
- etc…
接続が確認できたところでビルドしたアプリケーションを実機で動かしてみましょう.
実機で動かす
まず別のターミナルで接続しておいたシェルで logread -f | grep "helloWorld"
を実行します.
次にコンパイルしたターミナルからアプリケーションを転送し実行します.
$ app install helloWorld.wp76xx.update 192.168.2.2
$ app status 192.168.2.2
[running] atAir
...
[stopped] wifiWebAp
[stopped] helloWorld
$ app start helloWorld
モジュール側のログが以下の通りです.
様々な情報が出ていますが一番最後に “Hello, world.” と表示されたことがわかります.
# logread -f | grep "helloWorld"
Sep 22 11:41:51 swi-mdm9x28-wp user.info Legato: INFO | updateDaemon[837]/updateDaemon T=main | app.c app_InstallIndividual() 707 | App helloWorld <9523f4cd5eadfe3beb21672c946e86b3> was already installed
Sep 22 11:41:51 swi-mdm9x28-wp user.info Legato: INFO | updateDaemon[837]/updateDaemon T=main | updateDaemon.c ApplyAppUpdate() 963 | App 'helloWorld<9523f4cd5eadfe3beb21672c946e86b3>' already installed. Discarded app installation.
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c app_Start() 3420 | Starting app 'helloWorld'
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/dev/log' to '/legato/systems/current/appsWriteable/helloWorld/dev/log': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/dev/null' to '/legato/systems/current/appsWriteable/helloWorld/dev/null': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/dev/zero' to '/legato/systems/current/appsWriteable/helloWorld/dev/zero': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/legato/systems/current/lib/liblegato.so' to '/legato/systems/current/appsWriteable/helloWorld/lib/liblegato.so': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/lib/ld-linux.so.3' to '/legato/systems/current/appsWriteable/helloWorld/lib/ld-linux.so.3': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/lib/libc.so.6' to '/legato/systems/current/appsWriteable/helloWorld/lib/libc.so.6': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/lib/libpthread.so.0' to '/legato/systems/current/appsWriteable/helloWorld/lib/libpthread.so.0': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/lib/librt.so.1' to '/legato/systems/current/appsWriteable/helloWorld/lib/librt.so.1': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/lib/libdl.so.2' to '/legato/systems/current/appsWriteable/helloWorld/lib/libdl.so.2': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/lib/libgcc_s.so.1' to '/legato/systems/current/appsWriteable/helloWorld/lib/libgcc_s.so.1': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/lib/libm.so.6' to '/legato/systems/current/appsWriteable/helloWorld/lib/libm.so.6': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/usr/lib/libstdc++.so.6' to '/legato/systems/current/appsWriteable/helloWorld/lib/libstdc++.so.6': Already exists
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/legato/systems/current/apps/helloWorld/read-only/lib/libComponent_helloComponent.so' to '/legato/systems/current/appsWriteable/hello
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2034 | Skipping file link '/legato/systems/current/apps/helloWorld/read-only/bin/helloWorld' to '/legato/systems/current/appsWriteable/helloWorld/bin/helloWorld
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateTmpFs() 1738 | Mounted tmpfs at /legato/systems/current/appsWriteable/helloWorld/tmp.
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2104 | Created file link '/tmp/legato/serviceDirectoryServer' to '/legato/systems/current/appsWriteable/helloWorld/tmp/legato/serviceDirectoryServer'.
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | app.c CreateFileLink() 2104 | Created file link '/tmp/legato/serviceDirectoryClient' to '/legato/systems/current/appsWriteable/helloWorld/tmp/legato/serviceDirectoryClient'.
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[823]/supervisor T=main | proc.c proc_Start() 1390 | Starting process 'helloWorld' with pid 6245
Sep 22 11:43:59 swi-mdm9x28-wp user.info Legato: INFO | supervisor[6245]/supervisor T=main | proc.c proc_Start() 1355 | Execing 'helloWorld'
Sep 22 02:43:59 swi-mdm9x28-wp user.debug Legato: DBUG | helloWorld[6245]/framework T=main | LE_FILENAME InitPool() 295 | Memory pool name 'framework.msgs-LogControlProtocol' is truncated to 'framework.msgs-LogControlProtoc'
Sep 22 02:43:59 swi-mdm9x28-wp user.debug Legato: DBUG | helloWorld[6245]/framework T=main | LE_FILENAME le_mem_ForceAlloc() 833 | Memory pool 'framework.SigMonitor' overflowed. Expanded to 1 blocks.
Sep 22 02:43:59 swi-mdm9x28-wp user.debug Legato: DBUG | helloWorld[6245]/framework T=main | LE_FILENAME le_mem_ForceAlloc() 833 | Memory pool 'framework.SigHandler' overflowed. Expanded to 1 blocks.
Sep 22 02:43:59 swi-mdm9x28-wp user.debug Legato: DBUG | helloWorld[6245]/helloWorld_exe T=main | _main.c main() 60 | == Starting Event Processing Loop ==
Sep 22 02:43:59 swi-mdm9x28-wp user.info Legato: INFO | helloWorld[6245]/helloComponent T=main | helloWorld.c _helloComponent_COMPONENT_INIT() 5 | Hello, world.
このままでは実行中なので app stop helloWorld 192.168.2.2
と実行し停止することができます.
まとめ
Legato フレームワークを用いた WP7605 向けのアプリケーション開発環境を整える事ができました.
また実機で文字を出力するプログラムを実行することができました.
実行の際の注意は以下のコマンドを新しいシェルを開くたびに実行することです.
(bashrc などに書き込むのもあり?)
$ . /opt/swi/SWI9X07Y_02.28.03.05/environment-setup-armv7a-neon-poky-linux-gnueabi
$ cd ~/workspace/legatoAF/legato-19.02.0/
$ . bin/configlegatoenv
ただしこれだけでは LTE モジュールである意味がないのでその利点を生かしたアプリケーションが求められます.
コメント