1. Examples 一覧
Spresense SDKでは、NuttShell の Built-in コマンドとして各種 Example を用意しています。
SDK v2.0 以降から NuttX オリジナルのアプリケーションも Examples に追加されています。
(SDK v1.x 以前のバージョンのチュートリアルは こちら を参照してください)
初めてビルドする方は、はじめにスタートガイドを参照してください。 コンフィグレーションの方法や、ビルドしたプログラムを実行する手順についての詳しい説明があります。 |
1.1. SDK examples
カテゴリ | Example名 | 説明 |
---|---|---|
Peripheral |
||
GPS (GNSS) |
||
GNSS 評価用のサンプルです。 |
||
GNSS PVTログを出力するサンプルです。 |
||
Audio |
||
オーディオのパススルー機能を用いて、マイク入力、スピーカ出力、I2S入出力を使用したサンプルです。 |
||
PCMデータをキャプチャするサンプルです。 |
||
オーディオビープ音を再生するサンプルです。 |
||
オーディオのデュアルデコード再生のサンプルです。 |
||
オブジェクトインターフェース層を用いたオーディオプレーヤーのサンプルです。 |
||
オブジェクトインターフェース層を用いたオーディオレコーダーのサンプルです。 |
||
オブジェクトインターフェース層を用いたPCMキャプチャのサンプルです。 |
||
低遅延で音声エフェクトを行うサンプルです。 |
||
ASMP |
ASMPフレームワークによるマルチコアを使用したサンプルです。 |
|
マルチコアを使用して素数計算を行うサンプルです。 |
||
マルチコアを使用してFFT演算を行うサンプルです。 |
||
Sensor |
加速度センサからセンサ情報を取得するサンプルです。 |
|
ジャイロセンサからセンサ情報を取得するサンプルです。 |
||
照度センサからセンサ情報を取得するサンプルです。 |
||
地磁気センサからセンサ情報を取得するサンプルです。 |
||
気圧センサからセンサ情報を取得するサンプルです。 |
||
近接センサからセンサ情報を取得するサンプルです。 |
||
カラーセンサからセンサ情報を取得するサンプルです。 |
||
加速度センサを使用して傾き検出を行うサンプルです。 |
||
SCUによるデシメータ機能を使って間引き処理を行うサンプルです。 |
||
加速度センサによる歩数計及び行動認識を行うサンプルです。 |
||
Camera |
||
JPEG |
JPEGデコードのサンプルです。 |
|
DNN |
DNN Runtime機能を使用して、数字認識を行うサンプルです。 |
|
LTE |
||
LTE通信機能を用いて、WebSocket通信を行うサンプルです。 |
||
Others |
setjmp()/longjmp() 関数を使用したサンプルです。 |
2. Peripheral Driver チュートリアル
2.1. RTC alarm サンプルアプリケーション
RTC alarm サンプルアプリケーションの動作について説明します。
2.1.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/alarm
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/alarm make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
2.1.2. 動作確認
シリアルターミナルを開いて、alarm
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
alarm
コマンドを実行します。alarm
コマンドの使い方を以下に示します。nsh> alarm ERROR: Invalid number of arguments: 0 USAGE: alarm <seconds> Where: <seconds> The number of seconds until the alarm expires.
<seconds> には相対時間(秒)を指定します。例えば、
alarm 5
と入力すると、5 秒後にアラームが発火します。nsh> alarm 5 alarm_daemon started alarm_daemon: Running Opening /dev/rtc0 Alarm 0 set in 5 seconds nsh> alarm_demon: alarm 0 received
2.1.3. 省電力機能と組み合わせて使用する
alarm
コマンドと省電力機能を組み合わせて使用する例について紹介します。
Spresense には、Deep Sleep や Cold Sleep モードといった省電力機能が提供されています。
poweroff
コマンドを用いてこれらの Sleep 状態に入ることができます。
そして、RTC アラーム機能により、この Sleep 状態から起床することができます
Deep Sleep や Cold Sleep について、詳しくは スリープモード を参照してください。
2.1.4. その他の RTC に関するコマンド
date
コマンドにより、RTC に時刻を設定したり、RTC に設定された現在時刻を表示することができます。
nsh> help date date usage: date [-s "MMM DD HH:MM:SS YYYY"]
例)RTC に 2019年12月1日23時34分56秒を設定する場合、
nsh> date -s "Dec 1 23:34:56 2019"
date コマンドにより現在時刻を表示します。
nsh> date Dec 01 23:35:14 2019
RTC は、Deep/Cold Sleep といったスリープ中や reboot
コマンドにより再起動した場合でも時刻を保持し続けます。ただし、電源供給がオフされたり、リセットボタンが押された場合は、RTC に設定された時刻はリセットされます。
以下に reboot
コマンドによる再起動後も時刻が保持されている例を示します。
nsh> date Dec 01 23:41:08 2019 nsh> reboot NuttShell (NSH) NuttX-8.2 nsh> date Dec 01 23:41:12 2019 nsh>
2.2. Watchdog サンプルアプリケーション
Watchdog サンプルアプリケーションの動作について説明します。
2.2.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/watchdog
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/watchdog make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
2.2.2. 動作確認
シリアルターミナルを開いて、wdog
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
wdog
コマンドを実行します。wdog
コマンドの使い方を以下に示します。nsh> wdog -h Usage: wdog [-h] [-d <pingdelay>] [-p <pingtime>] [-t <timeout>] Initialize the watchdog to the <timeout>. Start the watchdog timer. Ping for the watchdog for <pingtime> seconds, then let it expire. Options include: [-d <pingdelay>] = Time delay between pings in milliseconds. Default: 500 [-p <pingtime>] = Selects the <pingtime> time in milliseconds. Default: 5000 [-t timeout] = Time in milliseconds that the example will ping the watchdog before letting the watchdog expire. Default: 2000 [-h] = Shows this message and exits
- -d
-
指定された周期 [msec] で ioctl(fd, WDIOC_KEEPALIVE, 0) を呼び出すことで watchdog タイマーをクリアします。
- -p
-
指定された期間中 [msec] は watchdog をクリアし続けます。
- -t
-
指定された値 [msec] で ioctl(fd, WDIOC_SETTIMEOUT, (unsigned long)wdog.timeout) を呼び出しwatchdog タイマーの周期を設定します。
本サンプルアプリケーションは、watchdog タイマーの発火に伴いシステムがリブートすることを確認できます。
wdog
コマンドを実行した例を以下に示します。
引数無しで動作させたときは、デフォルト値の 2 秒で watchdog タイマー周期を設定します。
5 秒間は 500 msec 周期で watchdog タイマーをクリアし続けます。
その後、watchdog タイマーをクリアしないままタイマーが満了してシステムがリブートします。
nsh> wdog ping elapsed=0 ping elapsed=500 ping elapsed=1000 ping elapsed=1500 ping elapsed=2000 ping elapsed=2500 ping elapsed=3000 ping elapsed=3500 ping elapsed=4000 ping elapsed=4500 NO ping elapsed=5000 NO ping elapsed=5500 NO ping elapsed=6000 up_assert: Assertion failed at file:irq/irq_unexpectedisr.c line: 65 task: Idle Task up_dumpstate: sp: 0d0279d4 up_dumpstate: IRQ stack: up_dumpstate: base: 0d027a00 up_dumpstate: size: 00000800 up_dumpstate: used: 00000120 up_stackdump: 0d0279c0: 00000000 0d003e3d 0d0291a8 0d02975c 00000000 00000002 466cc9d4 0d002f69 up_stackdump: 0d0279e0: 0d002f55 0d00703d 00000000 0d02975c 0d028a20 00000003 00000000 0d006fd5 up_dumpstate: sp: 0d029830 up_dumpstate: User stack: up_dumpstate: base: 0d029840 up_dumpstate: size: 00000400 up_dumpstate: used: 00000000 up_stackdump: 0d029820: 9b7feebc 1f86add5 00000000 0d002e75 0d029844 001567bc 2df7cabf 00000000 up_registerdump: R0: 00000000 0d026bcc 0d02df68 00000014 0d026b54 0d028a20 00000003 00000000 up_registerdump: R8: 0d026ca0 f0bbaf7f dc9161d8 466cc9d4 00000003 0d029830 0d002e79 0d008792 up_registerdump: xPSR: 21000000 BASEPRI: 00000000 CONTROL: 00000000 up_registerdump: EXC_RETURN: ffffffe9 up_taskdump: Idle Task: PID=0 Stack Used=0 of 0 up_taskdump: hpwork: PID=1 Stack Used=344 of 2028 up_taskdump: lpwork: PID=2 Stack Used=352 of 2028 up_taskdump: lpwork: PID=3 Stack Used=352 of 2028 up_taskdump: lpwork: PID=4 Stack Used=352 of 2028 up_taskdump: init: PID=5 Stack Used=1032 of 8172 up_taskdump: cxd56_pm_task: PID=6 Stack Used=320 of 996 up_taskdump: wdog: PID=8 Stack Used=528 of 2028 NuttShell (NSH) NuttX-8.2 nsh>
2.3. ADC サンプルアプリケーション
この章では、ADC サンプルアプリケーションの動作手順を示します。
2.3.1. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/adc_monitor
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/adc_monitor make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
2.3.2. 動作確認
シリアルターミナルを開いて、adc_monitor コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
adc_monitor
コマンドを実行します。adc_monitor コマンドの Usage を以下に示します。
nsh> adc_monitor -h Usage: adc_monitor [OPTIONS] Arguments are "sticky". For example, once the ADC device is specified, that device will be re-used until it is changed. "sticky" OPTIONS include: [-p devpath] selects the ADC device. /dev/lpadc0, 1, 2, 3, /dev/hpadc0, 1 Current: /dev/lpadc0 [-n count] set the number of reads. Current: 10 [-h] shows this message and exits
- -p
-
全部で 6 つの ADC 専用端子があります。-p オプションにより、-p /dev/lpadc[0-3] もしくは /dev/hpadc[0-1] を指定します。 Spresense ボード上のピン番号とデバイスファイルの関係は下記の通りです。
ピン番号
A0
A1
A2
A3
A4
A5
/devファイル
/dev/lpadc0
/dev/lpadc1
/dev/lpadc2
/dev/lpadc3
/dev/hpadc0
/dev/hpadc1
- -n
-
測定回数を指定します。
例えば、HPADC0 (A4) に対して、10 回分の ADC データ取得を行います。 HPADC0 に対して、ADC データをバッファリングし、その平均値、最小値、最大値を表示します。 ADC データは 16bit の符号付きデータで、範囲は -32767 ~ 32767 です。
nsh> adc_monitor -p /dev/hpadc0 -n 10 ADC example - Name:/dev/hpadc0 bufsize:16 Ave:-32767 Min:-32767 Max:-32767 Cnt:8 Ave:-32767 Min:-32767 Max:-32767 Cnt:8 Ave:-32767 Min:-32767 Max:-32767 Cnt:8 Ave:14673 Min:14668 Max:14676 Cnt:8 Ave:14681 Min:14677 Max:14684 Cnt:8 Ave:14690 Min:14687 Max:14694 Cnt:8 Ave:14684 Min:14680 Max:14690 Cnt:8 Ave:14677 Min:14672 Max:14682 Cnt:8 Ave:14677 Min:14675 Max:14682 Cnt:8 Ave:14672 Min:14667 Max:14677 Cnt:8 ADC example end
2.3.3. ADC サンプリング周波数について
ADC のサンプリング周波数は SCU clock mode により選択されたクロックに依存します。

2.3.3.1. HPADC (High Performance ADC)
HPADC は高速サンプリングが可能な ADC です。
HPADC の クロック系統図を以下に示します。

クロックソースを固定分周して HPADC クロックが決まります。 その ADC クロックを 2 のべき乗で分周してサンプリング周波数が決定されます。
n の値は、次の SDK コンフィグレーションにより変更することができます。
System Type -> CXD56xx Package Configuration -> Peripheral Support -> ADC -> HPADC0 -> Coefficient of sampling frequency (CONFIG_CXD56_HPADC0_FREQ) ADC -> HPADC1 -> Coefficient of sampling frequency (CONFIG_CXD56_HPADC1_FREQ)

n の取りうる範囲は、SCU clock mode によって変わります。
-
SCU clock mode = RTC の場合
n 9 10 11 Fs(Hz)
64
32
16
Available
〇
〇
〇
-
SCU clock mode = RCOSC/XOSC の場合
n 0 1 2 3 4 5 6 7(*1) Fs(Hz)
2M
1M
512K
256K
128K
64K
32K
16K
Available
(*2)
×
△(*3)
△(*3)
△(*3)
〇
〇
〇
(*1): デフォルトは SCU clock mode = RCOSC, Coefficient = 7 が選択されており、Fs = 16KHz です。
(*2): Coefficient = 0 にしたとき、後段の平滑化CICフィルタが無効化され、10bit精度のADC生値を出力します。
(*3): CONFIG_CXD56_HPADC0_HIGHSPEED=y のとき、最大512KHzまでのFsをサポートします。CONFIG_CXD56_HPADC0_HIGHSPEED を有効にした場合、
HPADC1、LPADC、I2C/SPI の SCUシーケンサを使用することはできなくなります。高速サンプリングレート(512KHz)を使用する際の推奨コンフィグレーションを以下に示します。
Configuration Value Description CONFIG_CXD56_ADC
y
ADC を有効にします。
CONFIG_CXD56_HPADC0
y
HPADC0 を有効にします。
CONFIG_CXD56_HPADC1
n
HPADC1 を無効にします。
CONFIG_CXD56_LPADC
n
LPADC を無効にします。
CONFIG_CXD56_HPADC0_FREQ
2
Fsを512KHzに設定します。
CONFIG_CXD56_HPADC0_HIGHSPEED
y
高速オプションを有効にします。
CONFIG_CXD56_HPADC0_INPUT_GAIN_M6DB
y
入力ゲイン設定として-6dBを選択します。
CONFIG_CXD56_I2C0_SCUSEQ
n
I2C0 SCUシーケンサを無効にします。
CONFIG_CXD56_I2C1_SCUSEQ
n
I2C1 SCUシーケンサを無効にします。
CONFIG_CXD56_SPI3_SCUSEQ
n
SPI3 SCUシーケンサを無効にします。
CONFIG_CXD56_SCU_XOSC
y
SCUクロック源としてXOSCを選択します。
2.3.3.2. LPADC (Low Power ADC)
LPADC は HPADC に比べてサンプリングレートは低速ですが省電力で動作する ADC です。 LPADC のクロック系統図を以下に示します。

LPADC を RTC クロックをベースに動作します。そのクロックを 2 のべき乗で分周してサンプリング周波数が決定されます。
n の値は、次の SDK コンフィグレーションにより変更することができます。
System Type -> CXD56xx Package Configuration -> Peripheral Support -> ADC -> LPADC0 -> Coefficient of sampling frequency (CONFIG_CXD56_LPADC0_FREQ) ADC -> LPADC1 -> Coefficient of sampling frequency (CONFIG_CXD56_LPADC1_FREQ) ADC -> LPADC2 -> Coefficient of sampling frequency (CONFIG_CXD56_LPADC2_FREQ) ADC -> LPADC3 -> Coefficient of sampling frequency (CONFIG_CXD56_LPADC3_FREQ)

n の取りうる範囲は、SCU clock mode によって変わります。 また、LPADC は全部で 4 チャンネルありますが、1 ch のみ使用する場合、2ch で使用する場合、4ch で使用する場合 でもサンプリング周波数の上限値が変わります。それぞれのケースで、n の取りうる値を以下に示します。

-
SCU clock mode = RTC の場合
-
LPADC channel 0 ~ 3 のいずれか一つのチャンネルを選択した場合
n 11 12 13 14 15 Fs(Hz)
16
8
4
2
1
Available
〇
〇
〇
〇
〇
-
LPADC channel 0 and 1 の二つのチャンネルを選択した場合
n 12 13 14 15 Fs(Hz)
4
2
1
0.5
Available
〇
〇
〇
〇
-
LPADC channel 0 ~ 3 の四つのチャンネルを選択した場合
n 11 12 13 14 15 Fs(Hz)
4
2
1
0.5
0.25
Available
〇
〇
〇
〇
〇
-
-
SCU clock mode = RCOSC の場合
-
LPADC channel 0 ~ 3 のいずれか一つのチャンネルを選択した場合
n 3 4 5 6 7 8 9 10 11 12 13 14 15 Fs(Hz)
4K
2K
1K
512
256
128
64
32
16
8
4
2
1
Available
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
-
LPADC channel 0 and 1 の二つのチャンネルを選択した場合
n 6 7 8 9 10 11 12 13 14 15 Fs(Hz)
256
128
64
32
16
8
4
2
1
0.5
Available
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
-
LPADC channel 0 ~ 3 の四つのチャンネルを選択した場合
n 7(*) 8 9 10 11 12 13 14 15 Fs(Hz)
64
32
16
8
4
2
1
0.5
0.25
Available
〇
〇
〇
〇
〇
〇
〇
〇
〇
(*): デフォルトは LPADC 全チャンネル有効で SCU clock mode = RCOSC, Coefficient = 7 が選択されています。
-
-
SCU clock mode = XOSC の場合
-
LPADC channel 0 ~ 3 のいずれか一つのチャンネルを選択した場合
n 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Fs(Hz)
8K
4K
2K
1K
512
256
128
64
32
16
8
4
2
1
Available
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
-
LPADC channel 0 and 1 の二つのチャンネルを選択した場合
n 6 7 8 9 10 11 12 13 14 15 Fs(Hz)
256
128
64
32
16
8
4
2
1
0.5
Available
〇
〇
〇
〇
〇
〇
〇
〇
〇
〇
-
LPADC channel 0 ~ 3 の四つのチャンネルを選択した場合
n 7 8 9 10 11 12 13 14 15 Fs(Hz)
64
32
16
8
4
2
1
0.5
0.25
Available
〇
〇
〇
〇
〇
〇
〇
〇
〇
-
2.4. PWM サンプルアプリケーション
PWM サンプルアプリケーションの動作について説明します。
2.4.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/pwm
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/pwm make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
2.4.2. 動作確認
シリアルターミナルを開いて、pwm
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
pwm
コマンドを実行します。pwm
コマンドの使い方を以下に示します。nsh> pwm -h Usage: pwm [OPTIONS] Arguments are "sticky". For example, once the PWM frequency is specified, that frequency will be re-used until it is changed. "sticky" OPTIONS include: [-p devpath] selects the PWM device. Default: /dev/pwm0 Current: /dev/pwm0 [-f frequency] selects the pulse frequency. Default: 1000 Hz Current: 1000 Hz [-d duty] selects the pulse duty as a percentage. Default: 50 % Current: 50 % [-t duration] is the duration of the pulse train in seconds. Default: 5 Current: 5 [-h] shows this message and exits
例)PWM1 に対して、周期 2000 Hz、デューティー比 30 % の PWM 信号を 10 秒間出力します。
nsh> pwm -p /dev/pwm1 -f 2000 -d 30 -t 10
- -p
-
全部で 4 つの PWM 専用端子があります。-p オプションにより、-p /dev/pwm[0-3] を指定します。
- -f
-
PWM 周期 [Hz] を設定します。
- -d
-
デューティー比(周期に対する High 期間の割り合い) [%] は、1 ~ 99 までの数字を指定します。
- -t
-
指定された時間 [s] の PWM 信号を出力します。
2.4.3. PWM 周波数とデューティー比について
PWM は SCU clock mode により選択されたクロックで動作します。

SCU clock を以下に示します。
-
Same with SCU32K → RTC 32.768kHz
-
RCOSC → 約8.2MHz
-
XOSC → TCXO 26MHz を CONFIG_CXD56_SCU_XOSC_DIV(=2) で分周した 13MHz
PWM 信号の波形は、下図で表されるように SCU clock の PWM_CYCLE カウント数により周期が決まり、 PWM_THRESH カウント数により Low 出力の期間が決定されます。カウント数の上限は 0xffff です。

PWM で設定できる周波数の範囲は、
1 <= PWM frequency <= SCU clock / 2
となり、例えば、SCU clock が RCOSC を選択した場合は、1Hz ~ 約 4MHz までとなります。
デューティー比について、-d
で指定された数字から計算上の近似値で Low, High の区間を決定するため、
出力される波形は正確なデューティー比にならず丸め誤差を含むことがあります。
3. GPS チュートリアル
3.1. GNSS サンプルアプリケーション
GNSS サンプルアプリケーションの動作について説明します。
3.1.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/gnss
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/gnss make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
3.1.2. 動作確認
シリアルターミナルを開いて、gnss
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
gnss
コマンドを実行します。図 1. gnssコマンド起動時ログ
本アプリケーションを実行すると、はじめに /dev/gps
ドライバを open() します。
fd = open("/dev/gps", O_RDONLY);
openしたドライバに対して ioctl() を用いて、測定周期の設定や衛星システムの選択を行います。
ret = ioctl(fd, CXD56_GNSS_IOCTL_SET_OPE_MODE, (uint32_t)&set_opemode);
ret = ioctl(fd, CXD56_GNSS_IOCTL_SELECT_SATELLITE_SYSTEM, set_satellite);
ioctl() の CXD56_GNSS_IOCTL_START コマンドにより測位を開始します。
ret = ioctl(fd, CXD56_GNSS_IOCTL_START, CXD56_GNSS_STMOD_HOT);
測位結果は、read() を用いて読みだすことができます。
ret = read(fd, &posdat, sizeof(posdat));
本アプリケーションでは 1 秒周期で測位結果を表示します。
位置情報が取得できるまでの間は、"No Positioning Data"と表示されます。
Hour:0, minute:0, sec:3, usec:503 No Positioning Data
はじめに時刻情報を取得できたら、ターミナル上に UTC 時刻を表示します。
さらに位置情報を取得できたら次のように緯度、経度情報がターミナル上に表示されます。
Hour:9, minute:13, sec:20, usec:559 LAT 35.25.6303 LNG 139.22.1986
本アプリケーションは、位置情報を取得してから約200秒後に測位動作を終了します。
ioctl() の CXD56_GNSS_IOCTL_STOP コマンドにより測位を停止した後に、/dev/gps
ドライバを close() します。
ret = ioctl(fd, CXD56_GNSS_IOCTL_STOP, 0);
ret = close(fd);
上空がよく見える屋外など受信環境が良い場合は、約30秒~1分ぐらいで測位ができますが、 受信環境がよくない場合は測位するまでに数分かかる場合があります。
3.2. Geofence サンプルアプリケーション
Geofence サンプルアプリケーションの動作について説明します。
Geofence は、GNSS で取得される位置情報を使って、特定のリージョンに入る・抜ける・一定期間滞在している、 といったイベントを検出しアプリケーションに通知する機能を提供します。そのリージョンは、中心座標(緯度経度)とその半径によって 指定され、ユーザーが任意の位置を最大 20 地点まで登録することができます。
3.2.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/geofence
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/geofence make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
3.2.2. 動作確認
シリアルターミナルを開いて、geofence
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
geofence
コマンドを実行します。nsh> geofence
本アプリケーションでは、まず現在位置の情報を測位によって取得します。
その現在位置と、そこを起点として東西南北方向にそれぞれ 50 m ずつ離れた場所の計 5 つのリージョンを登録します。
現在位置の測位が完了しリージョンが設定された後に、デバイスを持ち歩いて移動することにより、 特定のリージョンに入った"ENTER"/抜けた"EXIT"/滞在している"DWELL"、といったステータスの情報がログ上に表示されます。
具体的な Geofence 機能の使い方については以下の通りです。
/dev/gps
ドライバを open() して測位を行う方法は、
前述した GNSS サンプルアプリケーション を参照してください。
Geofence 機能を使用するためには /dev/geofence
ドライバを open() します。
g_fdgeo = open("/dev/geofence", O_RDONLY);
openしたドライバに対して ioctl() を用いて、Dead zone [m] や滞在通知期間 [s] を設定します。
mode.deadzone = 5;
mode.dwell_detecttime = 10;
ret = ioctl(g_fdgeo, CXD56_GEOFENCE_IOCTL_SET_MODE, (unsigned long)&mode);
ioctl() の CXD56_GEOFENCE_IOCTL_ADD コマンドにより、リージョンを追加します。
region_xxx.id = 0;
region_xxx.latitude = own_latitude;
region_xxx.longitude = own_longitude;
region_xxx.radius = GEOFENE_REGION_RADIUS;
ret = ioctl(g_fdgeo, CXD56_GEOFENCE_IOCTL_ADD, (unsigned long)®ion_xxx);
ioctl() の CXD56_GEOFENCE_IOCTL_START コマンドにより、Geofence 動作を開始します。
ret = ioctl(g_fdgeo, CXD56_GEOFENCE_IOCTL_START, 0);
Geofence イベントを poll() によって待ち受け、read() により情報を取得します。
ret = read(g_fdgeo, &g_geofence_status, sizeof(struct cxd56_geofence_status_s));
本アプリケーションは、トータル 10 個のイベント通知がきたら Geofence 動作を終了します。
ioctl() の CXD56_GEOFENCE_IOCTL_STOP コマンドにより停止した後に、/dev/geofence
ドライバを close() します。
ret = ioctl(g_fdgeo, CXD56_GEOFENCE_IOCTL_STOP, 0);
ret = close(g_fdgeo);
3.3. GNSS ATCMD アプリケーション
gnss_atcmd
は Spresense SDK 上で動作する GNSS 機能評価用のサンプルアプリケーションです。
PC 等のホストからシリアルポートを介してコマンドを送信すると、そのシリアルポートに NMEA センテンスの結果が出力されます。具体的なコマンドの仕様とアプリケーションの使用例について示します。
3.3.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
本アプリケーションを実行するためには、以下の SDK Configuration を有効にしてください。
CONFIG_CXD56_GNSS=y CONFIG_GPSUTILS_CXD56NMEA_LIB=y CONFIG_EXAMPLES_GNSS_ATCMD=y
下記のコマンド実行することでこれらの Configuration を自動的に有効にすることができます。
./tools/config.py examples/gnss_atcmd
また、コマンド入出力に使用するポートを、コンフィグレーション GNSS Command IO によって切り替えることができます。
│ Prompt: GNSS Command IO │ Location: │ -> Examples │ -> GNSS CXD5603 @command emulator example (EXAMPLES_GNSS_ATCMD [=y])
-
Example uses USB CDC tty : 拡張ボード上の USB ポートを使用 (デフォルト)
-
Example uses STDINOUT for nsh debug UART : メイン基板上の USB ポート (UART1)
-
Example uses UART ttyS0 : メイン基板上の USB ポート (UART1)
-
Example uses UART ttyS1 : 非サポート
-
Example uses UART ttyS2 : メインボード及び拡張ボード上の UART ポート (UART2)
ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
というバイナリファイルが生成されます。
-
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
3.3.2. @コマンド仕様
ホストから送信するコマンドの仕様について説明します。
PC 等のホストから送信されたコマンドを gnss_atcmd アプリケーションが受信し、処理結果をホストに返します。コマンド送信から結果が応答されるまでの期間は、NMEA は出力されません。gnss_atcmd アプリケーションからコマンド完了を示す応答メッセージ (Done または Err ) が返ってくる前に別のコマンドを発行しないようにして下さい。なお、コマンド送信からコマンド応答が返るまでの時間はコマンドの種別およびその時の状態により異なりますが、ワーストケースで約 5 秒かかることがあります。ホストコントローラにてタイムアウトを検出する際は 5 秒にてタイムアウトと判断して下さい。
3.3.2.1. コマンドフォーマット
コマンドの書式は以下の通りです。"@" (アットマーク)に続いてコマンド文字列や引数を送信し、最後に改行コードを送ります。
@Command [Argument0] [Argument1]...<CR><LF>
- Command
-
4 文字以内の文字列です。詳細は下表 コマンド一覧 を参照してください。
- Argument
-
10 進数で表される数値です。文字列の先頭が "0x" の場合は 16 進数を表します。 コマンドによっては複数の引数をとります。
- <CR><LF>
-
改行コードを表します。コマンド行の終わりには CR (Carriage Return) + LF (Line Feed) を付けてください。
3.3.2.2. 正常応答フォーマット
正常応答結果の書式は以下の通りです。[送信したコマンド文字列]に続いて、"Done"の文字列が返ります。
[Command] Done<CR><LF>
- Command
-
受信したコマンド文字列を表します。
- <CR><LF>
-
改行を表します。応答行の終わりには CR (Carriage Return) + LF (Line Feed) が付加されています。
3.3.2.3. エラー応答フォーマット
エラー応答結果の書式は以下の通りです。[送信したコマンド文字列]に続いて、"Err"の文字列とエラーコードが返ります。
[Command] Err ErrorCode<CR><LF>
- Command
-
受信したコマンド文字列を表します。
- ErrorCode
-
負値のエラーコードを表します。
- <CR><LF>
-
改行を表します。応答行の終わりには CR (Carriage Return) + LF (Line Feed) が付加されています。
3.3.2.4. コマンドシーケンス
@GCD のような測位開始のコマンドを発行すると、"Done" の応答を返した後に、定期的に NMEA センテンスが Host へ送られます。

@VER コマンドを発行すると、バージョン情報が送られた後に、"Done" の応答が返ります。

3.3.2.5. コマンド一覧
gnss_atcmd が処理可能なコマンド一覧を下記に示します。
Command | Argument | Description | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@AEXT |
- |
アプリケーションを終了します。本コマンドは測位停止中に実行してください。 |
||||||||||||||||||||||||||||||
@BSSL |
NMEAマスク |
NMEA 0183 (ver 4.00) 規格で定義されているNMEAセンテンスのうち、 出力するNMEAセンテンスをビットマスク値で引数に指定します。 初期状態ではNMEAマスクには0xefが設定されています。
xx は、以下を表します。
コマンド例:
|
||||||||||||||||||||||||||||||
@BUP |
- |
受信済みのエフェメリス及び各種パラメータを Flash へセーブします。セーブされたデータは次回起動時に自動的にリストアされます。
本コマンドは測位停止中に実行して下さい。 |
||||||||||||||||||||||||||||||
@GCD |
- |
Cold Start による測位を開始し、NMEAセンテンスを周期的に出力します。出力されるNMEAセンテンスはNMEAマスクに従います。 |
||||||||||||||||||||||||||||||
@GNS |
衛星マスク |
測位に使用する衛星を引数のビットマスク値で選択します。
NOTE
GLONASS, Galileo, BeiDou に関して同時に使用することはできません。 コマンド例:
|
||||||||||||||||||||||||||||||
@GPOE |
<緯度[度]> |
楕円体座標の受信機現在位置を設定します。 コマンド例:
|
||||||||||||||||||||||||||||||
@GSR |
- |
Hot Start による測位を開始し、NMEAセンテンスを周期的に出力します。 |
||||||||||||||||||||||||||||||
@GSTP |
- |
測位を停止します。 |
||||||||||||||||||||||||||||||
@GSW |
- |
Warm Start による測位を開始し、NMEAセンテンスを周期的に出力します。 |
||||||||||||||||||||||||||||||
@GTIM |
<年> |
UTC時刻を設定します。 コマンド例:
|
||||||||||||||||||||||||||||||
@VER |
- |
ALLゼロのバージョン番号を返します。 |
3.3.3. 動作確認
シリアルターミナルを開いて、gnss_atcmd コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
gnss_atcmd
コマンドを実行します。以下に示す例は、コマンド入出力のターミナルとして NuttShell と同じメイン基板上の USB ポートを使用しています。 前述した GNSS Command IO のコンフィグレーションは、"Example uses STDINOUT for nsh debug UART" を選択しています。
-
Example uses USB CDC tty
-
Example uses STDINOUT for nsh debug UART
-
Example uses UART ttyS0
-
Example uses UART ttyS1
-
Example uses UART ttyS2
-
3.3.3.1. 例: Cold Start による測位の開始と停止
GPS、Glonass、QZSS L1C/A を測位衛星として選び、Cold Start で測位を開始します。 その後 NMEA センテンスが出力され、適当な期間の後、測位を停止して gnss_atcmd を終了します。
nsh> gnss_atcmd (アプリケーション開始)
@GNS 0x0b↵ (測位衛星の選択)
@GCD↵ (Cold Start測位開始)
----- <NMEA出力> ----
@GSTP↵ (測位停止)
@AEXT↵ (アプリケーション終了)
nsh>
3.3.3.2. 例: GNSS 終了後の Hot Start 測位
初めに GPS、Glonass、QZSS L1C/A を測位衛星として選び、Cold Start で測位を開始します。 測位された後に、Spresense の電源は保ちつつ GNSS を終了し、再度 Hot Start で測位を開始します。 Hot Start では測位開始から数秒後に測位が FIX します。
nsh> gnss_atcmd (アプリケーション開始)
@GNS 0x0b↵ (測位衛星の選択)
@GCD↵ (Cold Start測位開始)
----- <NMEA出力> ----
@GSTP↵ (測位停止)
@AEXT↵ (アプリケーション終了)
nsh> gnss_atcmd (アプリケーション開始)
@GSR↵ (Hot Start測位開始)
----- <NMEA出力> ----
@GSTP↵ (測位停止)
@AEXT↵ (アプリケーション終了)
nsh>
3.3.3.3. 例: Spresense 電源 OFF 後の Hot Start 測位
初めに GPS、Glonass、QZSS L1C/A を測位衛星として選び、Cold Start で測位を開始します。 その後、GNSS を終了した後に Spresense の電源を OFF します。
再度 Spresense の電源を入れた後、UTC 時刻と現在位置を入力して Hot Start で測位を開始します。 Hot Start では測位開始から数秒後に測位が FIX します。
nsh> gnss_atcmd (アプリケーション開始)
@GNS 0x0b↵ (測位衛星の選択)
@GCD↵ (Cold Start測位開始)
----- <NMEA出力> ----
@GSTP↵ (測位停止)
@BUP↵ (Flashへバックアップ)
@AEXT↵ (アプリケーション終了)
----- <Power OFF> -----
----- <Power ON> -----
nsh> gnss_atcmd (アプリケーション開始)
@GTIM 2018 11 09 02 45 05↵ (UTC 時刻設定)
@GPOE 35 39 31 139 44 05↵ (現在位置の設定)
@GSR↵ (Hot Start測位開始)
----- <NMEA出力> ----
@GSTP↵ (測位停止)
@AEXT↵ (アプリケーション終了)
nsh>
3.3.3.4. みちびきQZQSMセンテンスの出力
衛星マスクにQZSS L1/CAを選び、NMEAマスクでQZQSMセンテンスを有効にした後、測位を開始します。 受信条件が良ければ10秒弱で最初のQZQSMセンテンスが出力され、その後4秒毎に出力されます。
nsh> gnss_atcmd
@GNS 0x29↵
@BSSL 0x40ef↵
@GCD↵
$GPGGA,000001.00,,,,,0,00,,,,,,,*49
$GNGLL,,,,,000001.00,V,N*55
…
$GNZDA,000008.00,06,01,1980,,*77
$QZQSM,56,9AADF260540002C3F2587F8B101962082C41A588ACB1181623500011439023C*7B
$GPGGA,000009.00,,,,,0,00,,,,,,,*41
…
4. Audio チュートリアル
4.1. Audio Player サンプルアプリケーション
Audio Player サンプルアプリケーションの動作について説明します。
4.1.1. ビルド&ロード手順
ここではコマンドラインによるビルド手順を示します。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/audio_player
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/audio_player make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
-
Audio Playerの場合、デコード処理を行うDSPバイナリのロードが必要です。 DSPバイナリの置き場所は、SDカードか、SPI-Flashのどちらかを選択できますが、 ここでは、SDカードからロードする方法を行います。
DSPバイナリのパスの指定は、アプリケーションコード(audio_player_main.cxx)内で指定します。
audio_player_main.cxx
ではDSPBIN_FILE_PATH
で指定しています。#define DSPBIN_FILE_PATH "/mnt/sd0/BIN"
であれば、SDカードが指定されています。
SPI-flashにしたい場合は、"/mnt/spif/BIN" を指定してください。 この "/mnt/sd0/BIN" は、SDカードをPCで読み込んだ時の、ルートディレクトリの下の
BIN/
です。
このディレクトリを作成し、ここに必要なコーデックのDSPを置きます。MP3を再生(デコード)する場合は、
spresense/sdk/modules/audio/dsp/
の下のMP3DEC
を選択してください。 -
同時に、再生したい音楽ファイルをSDカードに書き込みます。 audio_player_main.cxx では、
PLAYBACK_FILE_PATH
で指定しています。#define PLAYBACK_FILE_PATH "/mnt/sd0/AUDIO"
このため、SDカードをPC上で読み込んだ時に、ルートディレクトリの下の
AUDIO/
以下に、 再生したいオーディオファイルを置いて下さい。サブディレクトリに置くこともできます。 -
現在のAudio Playerサンプルでは、簡易PlayListを利用した再生を行っています。 このため、playlistファイルの置き場所とファイル名を指定して再生します。
audio_player_main.cxx
では、PLAYLIST_FILE_PATH
でパスを指定、PLAYLIST_FILE_NAME
でファイル名を指定しています。#define PLAYLIST_FILE_PATH "/mnt/sd0/PLAYLIST" #define PLAYLIST_FILE_NAME "TRACK_DB.CSV"
このため、SDカードをPC上で読み込んだ時の、ルートディレクトリの下の
PLAYLIST/
以下に、TRACK_DB.CSV
というファイルを作成してください。TRACK_DB.CSV
の中身は、spresense/sdk/modules/audio/playlist/
の下のREADME.txt
を参照してください。
これらすべてを用意することで、音楽再生が行えます。
4.1.2. Audio Playerの動作確認
この nuttx.spk
を実機へロードするとAudio Playerのプログラムが実行されます。
Helloサンプルと同様に、シリアルターミナルを開きます。
minicom -D /dev/ttyUSB0 -b 115200 -s
builtinされている、 audio_player
アプリを実行すると、

というログが表示され、音声が再生されます。
エラーが発生した場合は、オーディオサブシステムのエラーについて を参照してください。
4.1.3. 付録: 独自の信号処理を行う
これまでのチュートリアルで、オーディオプレーヤーとして十分な機能を実現することができました。 ここからは、より高度な処理を行う方法を説明していきます。 |
AudioPlayerでは、再生する音声に対してユーザー独自の信号処理を行うことが出来ます。
これを行いたい場合にはコンフィグメニューで [Use Postprocess]
を有効にする必要があります。
-
Postprocessを有効にします
tools/cofig.py -m
[Use Postprocess]
にチェックを入れます。[Examples] [Audio player example] [Use Postprocess] <= Y
Postrocessの詳細についてはSDKデベロッパーガイドの Set preprocess を参照して下さい。 -
ビルドを行います。
make
全ての手順がうまくいけば、
POSTPROC
バイナリがspresense/examples/audio_player/worker/
の下に作成されます。
これをSDカードの/mnt/sd0/BIN
(PCから見るとBIN/
)フォルダに置いてください。本サンプルアプリケーションでは、 POSTPROC
には簡単なRCfilterがデフォルトで組み込まれています。
独自の信号処理などにカスタムをしたい場合には こちら を参考にして下さい。[Use Postprocess]
の有効、無効で音声ファイルを再生し違いを確認してみてください。
再生方法はこちら を参考にして下さい。
4.1.4. DSPバイナリ(POSTPROC)のカスタムについて
DSPバイナリ(POSTPROC)のカスタム方法について記載します。
4.1.4.1. Step1. POSTPROCのコード編集
POSTPROCのコード構成と編集箇所について説明します。
コードは、ユーザー編集すべき部分とフレームワークとして提供される部分の2つに分かれます。
ユーザーが編集するコード
ユーザーが主に編集すべきコードです。
これらのコードを編集してDSPで信号処理を記述することが出来ます。
worker
ディレクトリの中にDSPのコードがまとまっており、その中に userproc
ディレクトリがあります。
ユーザが信号処理などを書くのは userproc
ディレクトリ内のみで、その他は基本的に変更の必要はありません。
main.cpp
には、起動処理~MainCPUとのデータ通信制御が書かれていますので変更しないで下さい。

起動処理やDSP通信処理などが書かれています。編集の必要は有りません。
DSPとの通信コマンドを定義するヘッダファイルです。
必要なパラメータはこのファイルに記載します。
ユーザーコードのヘッダファイルです。
ユーザーコード本体です。
このファイルに信号処理などを書く、または呼び出します。
ユーザーコードに用意されるインタフェース
userproc.cpp
には、 Init
, Exec
, Flush
, Set
コマンドの枠組みが用意されており
ユーザーコードはそれぞれに対応する中身を書いていくことでDSP内での処理を実現することが出来ます。
ユーザーが記述すべき処理について説明します。
(※デフォルトではサンプルとしてRCフィルタが組み込まれています。)
コマンドによるDSP内部の状態遷移は下図の通り行われます。

各コマンドを使い以下のような流れで処理を行います。
-
AUDCMD_INIT_OUTPUTMIXERがコールされるとDSPが起動します。
-
Init
コマンドで必要なパラメータ(ch数やビット長など)を設定します。 -
再生開始するとキャプチャした音声データが
Exec
コマンドで定期的にDSPに送られるので所望のフィルタ処理をしてください。 -
任意のタイミングでDSP内部のパラメータなどを変更したい場合には、
Set
コマンドを送ることで実装することを想定しています。このコマンドの実行タイミングは、Exec
を含めた受信順になります。+ -
再生停止すると最後の音声データの
Exec
の後、Flush
コマンドが送られるので終端処理の必要がある場合はここで処理をします。
各機能で使用するデータ型は userproc_command.h
に書かれており、中身は自由に書き換えることが出来ます。
各コマンドのフォーマットは下図の様になっています。
先頭の白抜きの部分には最低限必要なパラメータが固定で配置されています。これらは変更しないで下さい。
ユーザーが userproc_command.h
で定義するパラメータは下図の User param
(ピンク色箇所)にあたる部分です。

各コマンドについて説明します。
struct InitParam : public CustomprocCommand::CmdBase
-
Init処理用のパラメータです。
デフォルトではすべてreserveとなっていますが、ch数やビット長など、必要なパラメータに変更してください。
struct ExecParam : public CustomprocCommand::CmdBase
-
Exec処理用のパラメータです。
音声データのアドレス・サイズは上図のExecParam
にある様に継承元のCustomprocCommand::ExecParamBase
に定義されています。
詳細は/sdk/modules/include/audio/dsp_framework/customproc_command_base.h
を参照してください。
struct FlushParam : public CustomprocCommand::CmdBase
-
Flush処理用のパラメータです。
音声データのアドレス・サイズは上図のExecParam
にある様に継承元のCustomprocCommand::FlushParamBase
に定義されています。
詳細は/sdk/modules/include/audio/dsp_framework/customproc_command_base.h
を参照してください。
struct SetParam : public CustomprocCommand::CmdBase
-
Set処理用のパラメータです。
様々な動的に変更したいパラメータを定義します。デフォルトではRCフィルタのOn/Offや係数を定義しています。
下記の関数群は userproc.cpp
に書かれています。中身は自由に書き換えることが出来ます。
それぞれのコマンド定義に従い処理を行います。
void UserProc::init(InitParam *)
-
InitParamに従い初期化を行う処理を書いて下さい。
アプリケーションコードからの AUDCMD_INITMPP コマンドで実行されます。
(デフォルトでは何もしていません。)
void UserProc::exec(ExecParam *)
-
ExecParamに従い信号処理を書いて下さい。
再生を開始するとSDK内部から定期的に呼ばれます。
1フレームはLPCMの場合には640サンプル、MP3の場合には1152(ただし16kHz時は1728)サンプルです。
入力データアドレスからデータを取得し、信号処理を行い、出力データアドレスへ書き出して下さい。
(デフォルトではRCフィルタ処理が書かれています。)
void UserProc::flush(FlushParam *)
-
FlushParamに従いFlush(終端)処理を書いて下さい。
再生の停止時にSDK内部から一度だけ呼ばれます。
IIRやFIRフィルタのように遅延が発生する場合は、最終フレームの後にflush
を行い、遅延分の出力を行います。
出力すべきデータがある場合には、出力データアドレスへ書き出して下さい。
(デフォルトでは何もしていません。)
void UserProc::set(SetParam *)
-
SetParamに従い設定処理を書いてください。
アプリケーションコードからの AUDCMD_SETMPPPARAM コマンドで実行されます。
(デフォルトではRCフィルタの係数を設定しています。)
4.1.4.2. Step2. POSTPROC
バイナリのビルド
Configuration で User Postprocess
を有効にしていれば、本アプリケーションのビルド時に自動で POSTPROC
バイナリが作成されます。
作成されるパスは spresense/examples/audio_player/worker/
の下の POSTPROC
です。
これをSDカードの /mnt/sd0/BIN
(PCから見ると \BIN
)フォルダに置いてください。
4.2. Audio Recorder サンプルアプリケーション
Audio Recorderのサンプルアプリケーションの動作について説明します。
4.2.1. ビルド&ロード手順
ここではコマンドラインによるビルド手順を示します。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/audio_recorder
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/audio_recorder make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
-
Audio Recorderの場合、エンコード処理を行うDSPバイナリのロードが必要です。 DSPバイナリの置き場所は、SDカードか、SPI-Flashのどちらかを選択できますが、 ここでは、SDカードからロードする方法を行います。
DSPバイナリのパスの指定は、アプリケーションコード内で指定します。
audio_recorder_main.cxx
では、DSPBIN_PATH
で設定していますので必要に応じてアプリケーションコードを変更して下さい。#define DSPBIN_PATH "/mnt/sd0/BIN"
であれば、SDカードが指定されています。
この
/mnt/sd0/BIN
は、SDカードをPCで読み込んだ時の、ルートディレクトリの下のBIN/
です。
このディレクトリを作成し、ここに必要なコーデックのDSPを置きます。SPI-flashにしたい場合は、 /mnt/spif/BIN
を指定してください。MP3で録音(エンコード)する場合は、
spresense/sdk/modules/audio/dsp/
の下のMP3ENC
を選択してください。その他のエンコードをする場合のCodec種別とDSPバイナリの組み合わせは下表の通りです。
Codec DSPバイナリ MP3
MP3ENC
LPCM
SRC
4.2.2. Audio Recorderの動作確認
この nuttx.spk
をSpresenseへロードするとAudio Recorderのプログラムが実行されます。
Helloサンプルと同様に、シリアルターミナルを開きます。
minicom -D /dev/ttyUSB0 -b 115200 -s
builtinされている、 audio_recorder
アプリを実行すると、

というログが表示され、音声が記録されます。
記録された音声はPCで再生することが出来ます。その際にはSDカードルートディレクトリの下の REC/
に音声ファイルがあります。
audio_recorder_main.cxx では、 RECFILE_ROOTPATH
で設定していますので必要に応じてアプリケーションコードを変更して下さい。
#define RECFILE_ROOTPATH "/mnt/sd0/REC"
であればSDカードのルートの下の REC/
に音声ファイルが作られます。
エラーが発生した場合は、オーディオサブシステムのエラーについて を参照してください。
4.2.3. 付録: 独自の信号処理を行う
これまでのチュートリアルで、レコーダーとして十分な機能を実現することができました。 ここからは、より高度な処理を行う方法を説明していきます。 |
AudioRecorderでは記録する音声に対してユーザー独自の信号処理を行うことが出来ます。
これを行いたい場合にはコンフィグメニューで [Use preprocess]
を有効にする必要があります。
-
Preprocessを有効にします
コンフィグメニューを開きます。
tools/cofig.py -m
[Use preprocess]
にチェックを入れます。[Examples] [Audio recorder example] [Use preprocess] <= Y
Preprocessの詳細についてはSDKデベロッパーガイドの Set preprocess を参照して下さい。 -
ビルドを行います。
make
全ての手順がうまくいけば、
PREPROC
バイナリがspresense/examples/audio_recorder/worker/
の下に作成されます。
これをSDカードの/mnt/sd0/BIN
(PCから見るとBIN/
)フォルダに置いてください。本サンプルアプリケーションでは、 PREPROC
には簡単なRCfilterがデフォルトで組み込まれています。
独自の信号処理などにカスタムをしたい場合には こちら を参考にして下さい。Preprocessの有効、無効で記録した音声ファイルを再生して、違いを確認してみてください。
記録、再生方法はこちら を参考にして下さい。== DSPバイナリ(PREPROC)のカスタムについて
DSPバイナリ(PREPROC)のカスタム方法について記載します。
4.2.3.1. Step1. PREPROCのコード編集
PREPROCのコード構成と編集箇所について説明します。
コードは、ユーザー編集すべき部分とフレームワークとして提供される部分の2つに分かれます。
ユーザーが編集するコード
ユーザーが主に編集すべきコードです。
これらのコードを編集してDSPで信号処理を記述することが出来ます。
worker
ディレクトリの中にDSPのコードがまとまっており、その中に userproc
ディレクトリがあります。
ユーザが信号処理などを書くのは userproc
ディレクトリ内のみで、その他は基本的に変更の必要はありません。
main.cpp
には、起動処理~MainCPUとのデータ通信制御が書かれていますので変更しないで下さい。

起動処理やDSP通信処理などが書かれています。編集の必要は有りません。
DSPとの通信コマンドを定義するヘッダファイルです。
必要なパラメータはこのファイルに記載します。
ユーザーコードのヘッダファイルです。
ユーザーコード本体です。
このファイルに信号処理などを書く、または呼び出します。
ユーザーコードに用意されるインタフェース
userproc.cpp
には、 Init
, Exec
, Flush
, Set
コマンドの枠組みが用意されており
ユーザーコードはそれぞれに対応する中身を書いていくことでDSP内での処理を実現することが出来ます。
ユーザーが記述すべき処理について説明します。
(※デフォルトではサンプルとしてRCフィルタが組み込まれています。)
コマンドによるDSP内部の状態遷移は下図の通り行われます。

各コマンドを使い以下のような流れで処理を行います。
-
AUDCMD_INIT_MICFRONTENDがコールされるとDSPが起動します。
-
Init
コマンドで必要なパラメータ(ch数やビット長など)を設定します。 -
記録開始するとキャプチャした音声データが
Exec
コマンドで定期的にDSPに送られるので所望のフィルタ処理をしてください。 -
任意のタイミングでDSP内部のパラメータなどを変更したい場合には、
Set
コマンドを送ることで実装することを想定しています。このコマンドの実行タイミングは、Exec
を含めた受信順になります。+ -
記録停止すると最後の音声データの
Exec
の後、Flush
コマンドが送られるので終端処理の必要がある場合はここで処理をします。
各機能で使用するデータ型は userproc_command.h
に書かれており、中身は自由に書き換えることが出来ます。
各コマンドのフォーマットは下図の様になっています。
先頭の白抜きの部分には最低限必要なパラメータが固定で配置されています。これらは変更しないで下さい。
ユーザーが userproc_command.h
で定義するパラメータは下図の User param
(ピンク色箇所)にあたる部分です。

各コマンドについて説明します。
struct InitParam : public CustomprocCommand::CmdBase
-
Init処理用のパラメータです。
デフォルトではすべてreserveとなっていますが、ch数やビット長など、必要なパラメータに変更してください。
struct ExecParam : public CustomprocCommand::CmdBase
-
Exec処理用のパラメータです。
音声データのアドレス・サイズは上図のExecParam
にある様に継承元のCustomprocCommand::ExecParamBase
に定義されています。
詳細は/sdk/modules/include/audio/dsp_framework/customproc_command_base.h
を参照してください。
struct FlushParam : public CustomprocCommand::CmdBase
-
Flush処理用のパラメータです。
音声データのアドレス・サイズは上図のExecParam
にある様に継承元のCustomprocCommand::FlushParamBase
に定義されています。
詳細は/sdk/modules/include/audio/dsp_framework/customproc_command_base.h
を参照してください。
struct SetParam : public CustomprocCommand::CmdBase
-
Set処理用のパラメータです。
様々な動的に変更したいパラメータを定義します。デフォルトではRCフィルタのOn/Offや係数を定義しています。
下記の関数群は userproc.cpp
に書かれています。中身は自由に書き換えることが出来ます。
それぞれのコマンド定義に従い処理を行います。
void UserProc::init(InitParam *)
-
InitParamに従い初期化を行う処理を書いて下さい。
アプリケーションコードからの AUDCMD_INIT_PREPROCESS_DSP コマンドで実行されます。
(デフォルトでは何もしていません。)
void UserProc::exec(ExecParam *)
-
ExecParamに従い信号処理を書いて下さい。
記録を開始するとSDK内部から定期的に呼ばれます。
1フレームは記録の設定がLPCMの場合には768サンプル、MP3の場合には1152(ただし16kHz時は1728)サンプルです。
入力データアドレスからデータを取得し、信号処理を行い、出力データアドレスへ書き出して下さい。
(デフォルトではRCフィルタ処理が書かれています。)
void UserProc::flush(FlushParam *)
-
FlushParamに従いFlush(終端)処理を書いて下さい。
記録の停止時にSDK内部から一度だけ呼ばれます。
IIRやFIRフィルタのように遅延が発生する場合は、最終フレームの後にflush
を行い、遅延分の出力を行います。
出力すべきデータがある場合には、出力データアドレスへ書き出して下さい。
(デフォルトでは何もしていません。)
void UserProc::set(SetParam *)
-
SetParamに従い設定処理を書いてください。
アプリケーションコードからの AUDCMD_SET_PREPROCESS_DSP コマンドで実行されます。
(デフォルトではRCフィルタの係数を設定しています。)
4.2.3.2. Step2. PREPROC
バイナリのビルド
Configuration で Preprocess
を有効にしていれば、本アプリケーションのビルド時に自動で PREPROC
バイナリが作成されます。
作成されるパスは spresense/examples/audio_recorder/worker/
の下の PREPROC
です。
これをSDカードの /mnt/sd0/BIN
(PCから見ると \BIN
)フォルダに置いてください。
4.3. Audio Recognizer サンプルアプリケーション
Audio Recognizer サンプルアプリケーションの動作について説明します。
4.3.1. ビルド&ロード手順
ここではコマンドラインによるビルド手順を示します。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/audio_recognizer
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py examples/audio_recognizer make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
-
Audio Recognizerの場合、音声認識処理を行うDSPバイナリのロードが必要です。 DSPバイナリの置き場所は、SDカードかSPI-Flashのどちらかを選択できますが、 ここでは、SDカードからロードする方法を行いますので、 "/mnt/sd0/BIN" に置きます。
この
/mnt/sd0/BIN
は、SDカードをPCで読み込んだ時の、ルートディレクトリの下のBIN/
です。
このディレクトリを作成し、ここに音声認識に必要なDSPを置きます。本サンプルアプリケーションでは、音声認識のDSPバイナリは、ユーザーカスタムのものを使用する設定となっており、バイナリは spresense/examples/audio_recognizer/worker_recognizer/
の下にRCGPROC
として生成されます。認識処理をカスタムする場合には、RecognizerPROCのカスタムについてを参照してください。
4.3.2. Audio Recognizerの動作確認
ビルドした nuttx.spk
を実機へロードするとAudio Recognizerのプログラムが実行されます。
Helloサンプルと同様に、シリアルターミナルを開きます。
minicom -D /dev/ttyUSB0 -b 115200 -s
builtinされている、 audio_recognizer
アプリを実行すると、

というログが表示され、音声認識が開始されます。
認識結果はアプリケーションコード( audio_recognizer_main.cpp
)中にあるコールバック関数で受け取っています。
受け取るパラメータの構成は音声認識用DSPで決めています。 RecognizerPROC を参照して下さい。
データはMemoryHandleで受信していますので、下記の様に、そのアドレスを参照することでデータを取得することが出来ます。
static void recognizer_find_callback(AsRecognitionInfo info)
{
/* Get Recognition result */
MyRecognizerResultFormat *result =
static_cast<MyRecognizerResultFormat *>(info.getVa())
/* Print result */
...
printf("Data size %d byte\n", info.size);
printf("Data1 : %x, Data2 : %x\n", result->data1, result->data2);
...
}
エラーが発生した場合は、オーディオサブシステムのエラーについて を参照してください。
4.3.3. 付録: 独自の信号処理を行う
これまでのチュートリアルで、Recognizerとして十分な機能を実現することができました。 ここからは、より高度な処理を行う方法を説明していきます。 |
キャプチャした音声はサンプリング周波数が48kHzまたは192kHz、ビット長が16bitまたは32bitです。
Audio Recognizerではこれに対して、認識ライブラリの入力フォーマットに合わせ前処理を行うことが出来ます。
これを行いたい場合にはコンフィグメニューで [Use preprocess]
を有効にする必要があります。
-
Preprocessを有効にします
コンフィグメニューを開きます。
tools/cofig.py -m
[Use preprocess]
にチェックを入れます。[Examples] [Audio recognizer example] [Use preprocess] <= Y
Preprocessの詳細についてはSDKデベロッパーガイドの Set preprocess を参照して下さい。 -
ビルドを行います。
make
全ての手順がうまくいけば、
PREPROC
バイナリがspresense/examples/audio_recognizer/worker_preprocess/
の下に作成されます。
これをSDカードの/mnt/sd0/BIN
(PCから見るとBIN/
)フォルダに置いてください。本サンプルアプリケーションでは、 PREPROC
には簡単なRCfilterがデフォルトで組み込まれています。
独自の信号処理などにカスタムをしたい場合には こちら を参考にして下さい。
4.3.4. DSPバイナリのカスタムについて
audio_recognizerサンプルではPre処理用(以下 PREPROC
)、認識処理用(以下 RCGPROC
)の2つのDSPバイナリを使用します。
それらのカスタム方法について説明します。
4.3.4.1. Step1. PREPROC, RCGPROCのコード編集
PREPROC
, RCGPROC
のコード構成と編集箇所について説明します。
コードは、ユーザー編集すべき部分とフレームワークとして提供される部分の2つに分かれます。
ユーザーが編集するコード
ユーザーが主に編集すべきコードです。
これらのコードを編集してDSPで信号処理や認識処理を記述することが出来ます。
PREPROC
は worker_preprocess
ディレクトリの中に、 RCGPROC
は worker_recognizer
の中にDSPのコードがまとまっており、それぞれその中に userproc
ディレクトリがあります。
ユーザが信号・認識処理などを書くのは userproc
ディレクトリ内のみで、その他は基本的に変更の必要はありません。
main.cpp
には、起動処理~MainCPU(Supervisor)とのデータ通信制御が書かれていますので変更しないで下さい。

起動処理やDSP通信処理などが書かれています。編集の必要は有りません。
Pre処理用DSPとの通信コマンドを定義するヘッダファイルです。
必要なパラメータはこのファイルに記載します。
Pre処理用DSPのユーザーコードのヘッダファイルです。
Pre処理用DSPのユーザーコード本体です。
このファイルに信号処理などを書く、または呼び出します。
認識用DSPとの通信コマンドを定義するヘッダファイルです。
必要なパラメータはこのファイルに記載します。
認識用DSPのユーザーコードのヘッダファイルです。
認識用DSPのユーザーコード本体です。
このファイルに認識処理を書く、または呼び出します。
ユーザーコードに用意されるインタフェース
Init
, Exec
, Flush
, Set
コマンドの枠組みが用意されており
ユーザーコードはそれぞれに対応する中身を書いていくことでDSP内での処理を実現することが出来ます。
ユーザーが記述すべき処理について説明します。
(※デフォルトではサンプルとして PREPROC
にはRCフィルタが組み込まれています。)
コマンドによるDSP内部の状態遷移は下図の通り行われます。

各コマンドを使い以下のような流れで処理を行います。
-
AUDCMD_INIT_RECOGNIZERがコールされると認識用DSPが起動します。
-
Init
コマンドで必要なパラメータ(ch数やビット長など)を設定します。 -
認識処理を開始するとキャプチャした音声データが
Exec
コマンドで定期的にDSPに送られるので所望の認識処理をしてください。 -
任意のタイミングでDSP内部のパラメータなどを変更したい場合には、
Set
コマンドを送ることで実装することを想定しています。このコマンドの実行タイミングは、Exec
を含めた受信順になります。+ -
認識処理を停止すると最後の音声データの
Exec
の後、Flush
コマンドが送られるので終端処理の必要がある場合はここで処理をします。
各機能で使用するデータ型は、 PREPROC
では userproc_command.h
に、 RCGPROC
では rcgproc_command.h
に書かれており、中身は自由に書き換えることが出来ます。
各コマンドのフォーマットは下図の様になっており、これは PREPROC
RCGPROC
で同じです。
先頭の白抜きの部分には最低限必要なパラメータが固定で配置されています。これらは変更しないで下さい。
ユーザーが userproc_command.h
で定義するパラメータは下図の User param
(ピンク色箇所)にあたる部分です。
notification
は Exec
コマンドの応答(認識結果)フラグで、0以外の指定でアプリケーションまで応答を戻します。
例えば、通常は応答を戻さず認識結果の変化点(認識無し→有りになった点)などでのみ応答したい場合などに使用出来ます。

各コマンドについて説明します。
struct InitRcgParam : public CustomprocCommand::CmdBase
-
Init処理用のパラメータです。
デフォルトではch数とビット幅が設定されています。必要なパラメータに変更してください。
struct ExecRcgParam : public CustomprocCommand::CmdBase
-
Exec処理用のパラメータです。
音声データのアドレス・サイズは上図のExecParam
にある様に継承元のCustomprocCommand::ExecParamBase
に定義されています。
詳細は/sdk/modules/include/audio/dsp_framework/customproc_command_base.h
を参照してください。
struct FlushRcgParam : public CustomprocCommand::CmdBase
-
Flush処理用のパラメータです。
音声データのアドレス・サイズは上図のFlushParam
にある様に継承元のCustomprocCommand::FlushParamBase
に定義されています。
詳細は/sdk/modules/include/audio/dsp_framework/customproc_command_base.h
を参照してください。
struct SetRcgParam : public CustomprocCommand::CmdBase
-
Set処理用のパラメータです。
様々な動的に変更したいパラメータを定義します。デフォルトでは認識処理のOn/Offを定義しています。
下記の関数群は rcgproc.cpp
に書かれています。中身は自由に書き換えることが出来ます。
それぞれのコマンド定義に従い処理を行います。
void RcgProc::init(InitRcgParam *)
-
InitRcgParamに従い初期化を行う処理を書いて下さい。
アプリケーションコードからの AUDCMD_INIT_RECOGNIZER_DSP コマンドで実行されます。
(デフォルトではCh数とビット幅の設定をしています。)
void RcgProc::exec(ExecRcgParam *)
-
ExecRcgParamに従い信号処理を書いて下さい。
認識処理を開始するとSDK内部から定期的に呼ばれます。
当サンプルアプリケーションでは1フレームは320サンプルです(アプリケーションで自由に変更できます)。
入力データアドレスからデータを取得し、認識処理を行い、結果を出力データアドレスへ書き出して下さい。
(デフォルトでは入力フレーム内サンプル値の最大・最少・平均値を出力しています。)
void RcgProc::flush(FlushRcgParam *)
-
FlushRcgParamに従いFlush(終端)処理を書いて下さい。
認識処理の停止時にSDK内部から一度だけ呼ばれます。
認識処理にフレーム遅延が発生する場合は、最終フレームの後にflush
を行い遅延分の出力を行います。
出力すべきデータがある場合には、出力データアドレスへ書き出して下さい。
(デフォルトでは何もしていません。)
void RcgProc::set(SetRcgParam *)
-
SetRcgParamに従い設定処理を書いてください。
アプリケーションコードからの AUDCMD_SET_RECOGNIZER_DSP コマンドで実行されます。
(デフォルトでは認識処理のOn/Offを設定しています。)
4.3.4.2. Step2. PREPROC
, RCGPROC
バイナリのビルド
本アプリケーションのビルド時に自動で RCGPROC
バイナリが作成されます。
また、 Configuration で Preprocess
を有効にしていれば PREPROC
バイナリも作成されます。
作成されるパスは worker_recognizer/
の下に RCGPROC
、 worker_preprocess/
の下に PREPROC
です。
これをSDカードの /mnt/sd0/BIN
(PCから見ると \BIN
)フォルダに置いてください。
5. Camera チュートリアル
5.1. camera サンプルアプリケーション
この章では、Spresense Cameraボードを用いたサンプルについて解説します。
このサンプルでは、Spresense Cameraの基本的な使い方を体験していただくために用意しています。
5.1.1. 動作環境
このサンプルを動作させるには、以下のハードウェアを使う前提となっています。
-
Spresense Main Board
-
Spresense Camera Board
-
Spresense Extension Board
-
Arduino UNO LCD Connector board
-
ILI9341 2.2inch LCD
5.1.2. ソースコード
このサンプルのソースコードは、 examples/camera
以下にあります。
ディレクトリの中のファイル構成は以下のようになります。
camera/
. ├── Kconfig ├── Make.defs ├── Makefile ├── README.txt ├── camera_bkgd.c ├── camera_bkgd.h ├── camera_fileutil.c ├── camera_fileutil.h └── camera_main.c
主要なファイル・フォルダの概略は以下のようになります。
ファイル・フォルダ名 | 概要 |
---|---|
camera_main.c |
main()関数が実装されているファイルです。 |
camera_bkgd.c |
NuttXのグラフィクスシステムであるNXを制御するためのユーティリティ関数の実装がされているファイルです。 |
camera_fileutil.c |
イメージセンサから取得したデータをファイルに保存するためのユーティリティ関数が実装されているファイルです。 |
5.1.3. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/camera
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/camera make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
5.1.4. 動作確認
シリアルターミナルを開いて、camera コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
camera
コマンドを実行します。nsh>プロンプトからcameraと入力してEnterを押し、実行します。
nsh> camera
正しく動作すれば、LCDにカメラの画像が表示されます。
なお、デフォルトでは10フレーム表示したのち、終了するようになっています。
カメラの画像を永遠に表示するためには、引数に0を入れて、以下のようにコマンドを実行してください。nsh> camera 0
5.2. multiwebcam サンプルアプリケーション
この章では、multiwebcamに関するサンプルアプリケーションの動作手順を示します。 このサンプルは、IDY Spresense Wi-Fi Add-onボードiS110Bを用いて、Cameraで撮ったJPEG画像をWi-Fiを介して接続先のデバイスに送るサンプルになります。 このサンプルには2つのモードが存在します。
-
1対1の通信で、Motion JPEG over HTTPを転送プロトコルとして用いるモード (ブラウザからSpresenseにアクセスするとカメラ画像をモニターできます)
-
1対多の通信で、独自の転送プロトコルを用いて複数のSpresenseから画像データを取得してPCアプリで表示させるモード (特殊なアプリが必要になりますが、複数のカメラ画像を一画面で見ることができます。)
どちらの場合も、Spresenseは画像を送信するサーバとして動作し、ブラウザもしくはPCツールからサーバに接続して画像を取得することになります。
このサンプルは、以下の技術要素をもとに実装されています。
-
Spresense Camera (V4L2 like I/F)
-
multi pthread programing
-
socket programing
-
Tiny HTTP server
5.2.1. 動作環境
このサンプルを動作させるには、以下のハードウェアを使う前提となっています。
-
Spresense Main Board
-
Spresense Camera Board
-
IDY Wi-Fi Add-on Board iS110B
5.2.2. ソースコード
このサンプルのソースコードは、 examples/multi_webcamera
以下にあります。
ディレクトリの中のファイル構成は以下のようになります。
multi_wabcamera/
├── Kconfig ├── Make.defs ├── Makefile ├── README.txt ├── multiwebcam_main.c ├── multiwebcam_perf.h ├── multiwebcam_server.c ├── multiwebcam_server.h ├── multiwebcam_threads.c ├── multiwebcam_threads.h ├── multiwebcam_util.c ├── multiwebcam_util.h ├── startup_script/ │ └── init.rc └── host/ ├── ImgScaler.py ├── MultiCameraFrame.py ├── NetImgReceiver.py └── test_module/
主要なファイル・フォルダの概略は以下のようになります。
ファイル・フォルダ名 | 概要 |
---|---|
multiwebcam_main.c |
サンプルコードのmain処理の実装ファイル |
multiwebcam_server.c |
ネットワーク処理の実装ファイル |
multiwebcam_threads.c |
イメージセンサーからのJPEGデータを取得するThreadおよび取得したJPEGデータを接続されたクライアントに送信するThreadの実装ファイル |
multiwebcam_util.c |
Thread間でのメッセージ送受信用のQueueの実装ファイル |
startup_script/init.rc |
Spresense起動用サンプル(テンプレート)スクリプト |
host/ |
マルチカメラモードの場合のPC側のサンプルコード(Python) |
5.2.3. ソースコードの解説
この節では、ソースコードの動作内容について解説します。
アプリの全体の概要は以下の図のようになります。

このアプリでは、main()、camera_thread()、jpeg_sender()の3つのThreadが協調して動作しています。 次に3つのそれぞれの動作を解説します。
5.2.3.1. main()
メイン関数。
SpresenseのVideoドライバの初期化を行い(イメージセンサーの初期化含む)、camera_thread()をThreadとして起動します。(上図の緑のブロックの①)
その後、サーバとしてのソケットを生成し accept() 関数を呼び出してクライアントからの接続を待ちます。 (上図の緑のブロックの②)
クライアントから接続されると、JPEGを送信するためのThreadとしてjpeg_sender()を起動します。(上図の緑のブロックの③)
jpeg_sender()起動後、main()内では、jpeg_sender() Threadの終了を待ち、終了したら、再度 accept() にて新たなクライアントからの接続を待ちます。 (上図の緑のブロックの③)
ポイントとなるステップとソースコードを以下に抜粋します。
緑ブロックの番号 | ファイル名:行番号 | コード | 解説 |
---|---|---|---|
① |
multiwebcam_main.c:77 |
video_initialize(VIDEO_DEV_PATH); |
videoドライバ初期化をしています。 |
multiwebcam_main.c:79 |
v_fd = open(VIDEO_DEV_PATH, 0); |
Videoドライバデバイスファイルのオープンをします。 |
|
multiwebcam_main.c:86 |
ret = multiwebcam_prepare_camera_buf(v_fd, |
JPEGデータのバッファの作成とVideoドライバへの登録 |
|
multiwebcam_main.c:105 |
rsock = multiwebcam_initserver(MULTIWEBCAM_PORT_NO /* Port Number */); |
サーバソケットを作成しています。 |
|
multiwebcam_main.c:109 |
cam_thd = multiwebcam_start_camerathread(v_fd); |
camera_thread() Threadの生成 |
|
② |
multiwebcam_main.c:117 |
wsock = multiwebcam_waitconnection(rsock, &client); |
クライアントからの接続待ち、具体的にはaccept()関数を読んで接続待ちをしています。 |
③ |
multiwebcam_main.c:122 |
jpeg_thd = multiwebcam_start_jpegsender(wsock); |
jpeg_sender() Threadの起動を行なっています。 |
④ |
multiwebcam_main.c:123 |
pthread_join(jpeg_thd, NULL); |
jpeg_sender() Threadの終了待ち |
Thread終了後、②に戻ります。 |
5.2.3.2. camera_thread()
イメージセンサーから画像を取得するためのThread。
main()関数から起動されると、Videoドライバに対して、VIDIOC_DQBUFを発行してキャプチャしたデータを取得します。 (上図の青のブロックの①)
その後、jpeg_sender() Threadが起動しているかを確認して、起動していたら、取得したJPEGデータを、jpeg_sender() Threadに渡すために、action_queueにデータを送ります。(上図の青のブロックの②)
データ送信後にempty_queue()から空のバッファを取得します。(上図の青のブロックの③)
その後、VideoドライバにVIDIOC_QBUFで空のバッファをセットして、イメージセンサーからのJPEGデータの取得を待ちます。(上図の青のブロックの④)
あとは、これを繰り返します。
ポイントとなるステップとソースコードを以下に抜粋します。
青ブロックの番号 | ファイル名:行番号 | コード | 解説 |
---|---|---|---|
① |
multiwebcam_thread.c:72 |
multiwebcam_get_picture_buf(v_fd, &buf, V4L2_BUF_TYPE_STILL_CAPTURE); |
VideoドライバからJPEGイメージを取得します。 |
multiwebcam_thread.c:78 |
while (!is_run){ … } |
jpeg_sender() Thread起動待ち |
|
② |
multiwebcam_thread.c:93 |
multiwebcam_push_action(multiwebcam_get_vbuffer(&buf)); |
action_queueに読み出したJPEGデータをプッシュします。 |
③ |
multiwebcam_thread.c:98 |
while (multiwebcam_is_emptyqueue_empty() && is_run){ … } |
empty_queueに使い終わったバッファがプッシュされるまで待ちます。 |
multiwebcam_thread.c:98 |
for (vbuf = multiwebcam_pull_empty(); vbuf != NULL; vbuf = multiwebcam_pull_empty()){ … } |
empty_queueに入っているバッファ全てをVideoドライバに再登録しています。 |
|
Videoドライバに再登録が終わると、①に戻ります。 |
5.2.3.3. jpeg_sender()
クライアントからの接続が確立するとJPEGデータを送信するために動作するThread。
クライアントからの接続が確立したら、main() Threadから起動され、camera_thread()に起動した旨を伝えるために、is_run変数をtrueにします。
その後、action_queueにcamera_thread()がJPEGデータをプッシュするのを待ち、プッシュされたら取り出します。(上図の黄色のブロックの①)
データを取得したら、現在の選択されているプロトコル(Motion JPEG over HTTP、もしくは、独自転送プロトコル)にしたがって、JPEGデータをクライアントに送信します。(上図の黄色のブロックの②)
送信完了後、empty_queueに使い終わったJPEGデータのバッファを送ります。(上図の黄色のブロックの③)
なお、クライアントとの接続が切れた場合、camera_thread()に対して終了を伝えるためis_runをfalseにして、Threadを終了します。(上図の黄色のブロックから緑のブロックに向かっている点線④)
ポイントとなるステップとソースコードを以下に抜粋します。
黄色ブロックの番号 | ファイル名:行番号 | コード | 解説 |
---|---|---|---|
multiwebcam_thread.c:145 |
is_run = true; |
camera_thread() Threadに起動を知らせます。 |
|
multiwebcam_thread.c:149 |
multiwabcam_sendheader(sock); |
接続の最初の1回だけ送信されるべきデータを送ります。 |
|
① |
multiwebcam_thread.c:155 |
while(multiwebcam_is_actionqueue_empty()){ … } |
action_queueが空の間(camera_thread()がJPEGをプッシュするまでの間)待ちます。 |
multiwebcam_thread.c:159 |
buf = multiwebcam_pull_action(); |
action_queueからJPEGデータを取り出します。 |
|
② |
multiwebcam_thread.c:162 |
ret = multiwebcam_sendframe(sock, (char *)buf→start, (int)buf→jpg_len); |
取り出したデータをクライアントに送信します。 |
③ |
multiwebcam_thread.c:166 |
multiwebcam_push_empty(buf); |
送信し終わったバッファをempty_queueにプッシュします。 |
empty_queueにプッシュした後、①に戻ります。 |
5.2.4. ビルドおよび実行手順(1対1のMotion JPEG over HTTPモードの場合)
このサンプルコードは、1対1のMotion JPEG over HTTPで送信するモードと、多対1の独自転送プロトコルで送信するモードの2つのモードが存在します。
この節では、1対1のMotion JPEG over HTTPを用いた通信をさせる場合について解説します。
多対1の独自転送プロトコルモードでの通信を行う場合は、
ビルドおよび実行手順(多対1の独自転送プロトコルモード)
を参照してください。
5.2.4.1. ビルド手順
ここでは、CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/multiwebcam
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/multiwebcam make
-
nuttx.spk
を Spresense ボードへ書き込みます。ビルドが無事に完了すると sdk フォルダの中に nuttx.spk というファイルが生成されるので、これをターゲットのSpresenseに書き込みます。 この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
5.2.4.2. 動作確認
実機側のサンプルアプリを起動するために、シリアルターミナルを開いて、Wi-Fiに接続し、 multiwebcam コマンドを実行します。
-
シリアルターミナルを起動します。
まず、ターミナルソフトから、Spresenseのシリアルポートに接続して、NuttShellに入ります。
以下の例では、ターゲットのSpresenseと繋がっているシリアルポートは /dev/ttyUSB0 を、baudrate として 115200 bps を設定してminicomで接続しています。minicom -D /dev/ttyUSB0 -b 115200
-
Wi-Fi の接続を行います。
下記の例では、APモードでWi-Fiを起動し、SSIDをspresense_net、パスワードを0123456789としています。
Wi-Fiモジュールが正しく起動されると、IPアドレスが設定されるので、それを確認します。 下記の例では、Wi-Fiモジュールの起動が完了するまで、5秒ほど sleep が入っています。
ifconfigコマンドで、下記のように、IPアドレスが割り当てられます。nsh> gs2200m -a 1 spresense_net 0123456789 & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:56:49 at UP inet addr:192.168.11.1 DRaddr:192.168.11.1 Mask:255.255.255.0
上記の例では、 192.168.11.1 が Spresense のIPアドレスになります。
なお、HWaddrは購入されたWi-Fiモジュールによって変わる場合があります。 -
アプリを起動します。
Wi-Fi の設定が完了したら、 multiwebcam アプリを起動します。
nsh> multiwebcam
これで、Spresense 側の準備は完了です。
-
PCやスマホで、作成したWi-Fiのネットワークに接続します。
次に、PCやスマホなどのブラウザでカメラからの画像を見るために、まずは先ほど Spresense で起動した Wi-Fi のネットワークにPCやスマホを接続します。 スマホなどで、Wi-Fiのネットワークに接続します。
接続するWi-FiのSSIDは、先ほど設定した、 spresense_net になります。 PCやスマホの Wi-Fi 接続設定で、 spresense_net を探し、接続を行います。
接続する際の暗号方式は、 WPA/WPA2 を選択してください。
パスワードは、上記で設定した、 0123456789 です。 -
ブラウザで Spresense カメラに接続して Live View を表示します。
無事に Wi-Fi ネットワークに接続ができたら、接続したPCやスマホのブラウザを開き、URL入力欄に、以下のURLを入力することで、カメラの画像を表示させることができます。
http://192.168.11.1
正しく動作すれば、ブラウザ上にカメラの画像が表示されます。
5.2.5. ビルドおよび実行手順(多対1の独自転送プロトコルモード)
続いて多対1の独自プロトコルを用いた場合のビルド方法および実行方法について説明します。
基本的にはMotion JPEG over HTTPとビルド方法は同じです。
ビルド方法の唯一の違いはExampleのConfigメニューにある、"Http MJPEG is used"オプションを無効にすることです。
実機側の使い方についてもほぼ同じで、唯一の違いはWiFiの接続設定をアクセスポイントではなく、ステーションにすることです。
では、ステップごとに説明します。
5.2.5.1. ビルド手順
ここでは、CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションを行います。
引数に
examples/multiwebcam
を指定してコンフィグレーションを実行します。make distclean tools/config.py examples/multiwebcam
その後、以下のコマンドでmenu configを開きます。
make menuconfig
メニューを開いたら、矢印キーでメニューの一番下にある、"Application Configuration"まで移動してEnterキーを押して中のメニューに入ります。Application Configurationの中にある、"Spresense SDK"メニューに同様にして入り、さらに"Examples"に進みます。
"Application Configuration" -> "Spresense SDK" -> "Examples"
Examplesに入ると、 ”[*] Multi Web Camera" というチェックが付いた項目の中に "[*] Http MJPEG is used" という項目があるので、この項目にカーソルを合わせてスペースキーでチェックを外します。
チェックを外したら、"<Exit>"にカーソルを合わせてエンターを押して行き、一番上の階層で<Exit>をすると、"Do you wish to save your new configuration?"と聞かれるので、<Yes>を選択してコンフィグの変更をセーブしてmenuconfigを終了します。
-
ビルドを行います。
コンフィグが完了したら、以下のコマンドでビルドを行います。
make
ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。 -
nuttx.spk
を Spresense ボードへ書き込みます。ビルドが無事に完了すると sdk フォルダの中に nuttx.spk というファイルが生成されるので、これをターゲットのSpresenseに書き込みます。 この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
5.2.5.2. 動作確認
実機側のサンプルアプリを起動するために、シリアルターミナルを開いて、Wi-Fiに接続し、 multiwebcam コマンドを実行します。
-
シリアルターミナルを起動します。
まず、ターミナルソフトから、Spresenseのシリアルポートに接続して、NuttShellに入ります。
以下の例では、ターゲットのSpresenseと繋がっているシリアルポートは /dev/ttyUSB0 を、baudrate として 115200 bps を設定してminicomで接続しています。minicom -D /dev/ttyUSB0 -b 115200
-
Wi-Fi の接続を行います。
下記の例では、STAモードでWi-Fiを起動します。STAモードのため、既存のWi-Fiネットワークに接続を行うことになるので、予め接続するWi-FiネットワークのSSIDとパスワードを準備してください。
この例では、SSIDを hogehoge、パスワードを hogehoge1 として説明しています。
Wi-Fiモジュールが正しく起動されると、IPアドレスが設定されるので、それを確認します。 下記の例では、Wi-Fiモジュールの起動が完了するまで、5秒ほど sleep が入っています。
ifconfigコマンドで、下記のように、IPアドレスが割り当てられます。nsh> gs2200m hogehoge hogehoge1 & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:56:49 at UP inet addr:XXX.XXX.XXX.XXX DRaddr:XXX.XXX.XXX.XXX Mask:255.255.255.0
ifconfigの結果、inet addrに接続された結果としてのIPアドレスが表示されます。
なお、HWaddrは購入されたWi-Fiモジュールによって変わる場合があります。
ここで取得したIPアドレスはPCアプリの設定で必要になるのでメモしておいてください。 -
アプリを起動します。
Wi-Fi の設定が完了したら、 multiwebcam アプリを起動します。
nsh> multiwebcam
これで、Spresense 側の準備は完了です。
複数のSpresenseを用いる場合は同様にWi-Fiの接続とmultiwebcameraの起動を行なってください。
-
PCアプリの起動
PC側のアプリは複数のカメラの画像を表示するために、参考としてPythonで作成されたアプリになっています。このアプリはLinux PCで動作することを確認しています。
実行するには、まずPython 2.7のインストールをしてください。
さらに、Pythonの以下のライブラリが必要になりますので、それぞれインストールをしてください。-
python-wxgtk3.0
-
python-wxtools
Linuxでは以下のコマンドでインストールが行えます。
$ sudo apt install python-wxgtk3.0 python-wxtools
必要なPythonライブラリのインストールが完了したら、まず、接続するSpresenseのIPアドレスを設定します。先ほど実機を起動した際にメモしたIPアドレスを用います。
host/ フォルダの中に移動して、MultiCameraFrame.pyを開きます。
そのファイルの183行目に記載されている、servers = ( ('192.168.11.1', 10080), ('192.168.11.2', 10080), ('192.168.11.3', 10080), ('192.168.11.4', 10080) )
というコードの192.168.11.1 ~ 4と記載されているIPアドレスを、メモしたIPアドレスに書き換えてください。
デバイスが4つまで表示が可能ですが、4つない場合は、持っている数分だけ変更し、残りはそのままで問題ありません。
例としてデバイスが2つで、それぞれ、10.0.0.5、10.0.0.8だった場合servers = ( ('10.0.0.5', 10080), ('10.0.0.8', 10080), ('192.168.11.3', 10080), ('192.168.11.4', 10080) )
となります。
編集が終わったらファイルをセーブしてコマンドプロンプトから以下のコマンドを叩くことで、アプリを起動させることが出来ます。python MultiCameraFrame.py
正しく起動すると、全画面にWindowが表示され、デバイスからの画像の表示が始まります。
なお、当然ながら、PCはデバイスが接続したものと同じWi-Fiネットワークに接続しておく必要があります。
-
5.2.5.3. PC側の側アプリの解説
ここでは、PCアプリの簡単な解説を行います。
まず、PCアプリの構造を以下の図に示します。

ホストアプリは、WindowプログラミングのフレームワークとしてwxPythonを利用しています。MultiCameraFrame.pyに実装されているカスタムパネル:WebCamPanelを持つMultiCamFrameを生成します。
その引数に接続するSpresenseのIPアドレスとポート番号のリストを渡します。
Frameが起動すると、WebCamPanelを生成し、その中で4つのStaticBitmapを生成してフレームに貼り、その後、渡されたIPアドレスとポート番号のリストを元に、4つのNetImgReceiverを生成します。NetImgReceiverには、NetImgReceiver.pyに実装しており、接続するサーバのIPアドレスとポート番号及びStaticBitmapに紐づくID番号が付与されます。
NetImgReceiverは生成された後、receiveThread()がThreadとして起動し、並列動作を始めます。
receiveThread()では、指定されたserver IPとポート番号に基づいて、Spresense デバイス側のサーバに対して接続要求を行います。
接続が確立すると、JPEGの画像の受信を開始します。
JPEGの受信が完了するとWebCamPanelのPictUpdateEventを発生させ、受信したJPEGデータをID番号と共にWebCamPanelに送ります。
WebCamPanel内では、PictUpdateEventが発生するとonPictUpdate()がコールバックされます。この関数では、受信したJPEGデータとID番号を受け取り、画像サイズの調整をしたのち、ID番号に基づいてStaticBitmapに受信した画像を表示します。
5.2.6. Appendix : パケットフォーマット
ここでは、各モードでやりとりされるパケットのフォーマットについて解説します。
5.2.6.1. Motion JPEG over HTTP
こちらは、HTMLの規格として定義されている、”multipart/x-mixed-replace"を用いています。詳しくは以下を参照してください。
https://html.spec.whatwg.org/#read-multipart-x-mixed-replace
5.2.7. Tips : Spresense カメラの自動起動
Spresenseのnshプロンプトで実行しているコマンドは、起動時に自動的に実行することも出来ます。
詳しくは、 アプリケーションの自動起動方法 を参照してください。
6. LTE チュートリアル
6.1. LTE HTTP GET サンプルアプリケーション
6.1.1. 概要
本サンプルプログラムは、LTE通信機能を用いて、HTTP GETを行うサンプルです。
6.1.1.1. 動作環境
-
Spresense メインボード
-
Spresense LTE拡張ボード
-
SIM カード
-
microSD カード
接続方法は、SpresenseメインボードとSpresense LTE拡張ボードの接続方法を参照してください。
本スケッチではネットワークに接続するため、SIM カードが必要です。
LTE-M 動作確認SIM Listをご確認ください。
6.1.2. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/lte_http_get
を指定してコンフィグレーションを実行します。tools/config.py examples/lte_http_get
サンプルアプリケーションのコンフィグレーションを変更します。
tools/config.py -m
-
APNのパラメータを設定します。(ご使用のSIMに合わせて設定してください。)
Application Configuration -> Spresense SDK -> Examples -> HTTP GET method using LTE example - Access Point Name (CONFIG_EXAMPLES_LTE_HTTP_GET_APN_NAME) - IP type Selection - Authentication type Selection - Username used for authentication (CONFIG_EXAMPLES_LTE_HTTP_GET_APN_USERNAME) - Password used for authentication (CONFIG_EXAMPLES_LTE_HTTP_GET_APN_PASSWD)
コンフィグレーション名 説明 Access Point Name
アクセスポイント名
IP type Selection
APNプロトコル。
IPv4
、IPv6
、IPv4/v6
から選択します。Authentication type Selection
認証タイプ。
None
、PAP
、CHAP
から選択します。Username used for authentication
ユーザ名。 認証タイプに
None
を選択した場合、設定は無視されます。Password used for authentication
パスワード。 認証タイプに
None
を選択した場合、設定は無視されます。 -
HTTPSの設定します。(デフォルトのコンフィグではモデムのTLSプロトコルが有効です。)
Application Configuration -> Spresense SDK -> Externals -> mbedTLS connection utility support -> Directory path for TLS certification files (CONFIG_EXTERNALS_MBEDTLS_DEFAULT_CERTS_PATH)
HTTPSで使用するサーバのルート証明書を格納するディレクトリを指定します。
デフォルトの設定では/mnt/spif/CERTSとなっています。ルート証明書の取得方法についてはルート証明書のエクスポート手順を参考にしてください。
SPI-Flashへのファイル転送方法はZmodem を使ったファイル転送を参照してください。
ディレクトリのパスを
/mnt/sd0/CERTS
にすると microSD カードに変更することができます。
microSD カードに変更した場合はCONFIG_CXD56_SDIO
のコンフィグレーションを有効にする必要があります。ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make
-
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
6.1.3. 動作確認
シリアルターミナルを開いて、lte_http_get
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
lte_http_get
コマンドを実行します。lte_http_get コマンドの使い方を以下に示します。
nsh> lte_http_get <url>
- url
-
インターネット上に置かれているファイルのURLを指定します。
http://
もしくはhttps://
から始まる必要があります。urlを指定しない場合、http://example.com/index.html
となります。https://
のURLを指定する場合、事前にHTTPSの設定を行ってください。サーバのルート証明書をコンフィグレーションで記述したディレクトリに格納する必要があります。
本サンプルアプリケーションはurlに指定されたファイルをダウンロードしシリアルターミナルに出力します。
lte_http_get
コマンドを実行した例を以下に示します。
nsh> lte_http_get app_restart_cb called. reason:Modem restart by application. pdn.session_id : 1 pdn.active : 1 pdn.apn_type : 0x202 pdn.ipaddr[0].addr : 10.212.60.255 app_localtime_report_cb called: localtime : "19/12/06 : 18:24:33" set localtime completed: 2019/12/06,18:24:33 <!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html> nsh>
本サンプルアプリケーションの、wget
を wget_post
に変更することによりHTTPのPOSTメソッドが使用できます。
以下の例を参考に wget_post
の第2引数にPOSTするデータを設定してください。
wget_post(url, "Hello spresense world!!" ,g_app_iobuffer, APP_IOBUFFER_LEN, app_wget_cb, NULL);
また、本サンプルアプリケーションはダウンロードしたファイルをシリアルターミナルに出力しますが、
以下の様に app_wget_cb()
関数を一部変更することにより、ファイルに保存することができます。
static void app_wget_cb(FAR char **buffer, int offset, int datend,
FAR int *buflen, FAR void *arg)
{
int fd;
fd = open("/mnt/spif/index.html", (O_WRONLY | O_APPEND));
if ((fd < 0) && (errno == ENOENT))
{
fd = open("/mnt/spif/index.html", (O_CREAT | O_WRONLY), 0666);
}
/* Write HTTP data to local file */
(void)write(fd, &((*buffer)[offset]), datend - offset);
close(fd);
}
上記の例では、 |
6.2. LTE TLS サンプルアプリケーション
6.2.1. 概要
本サンプルプログラムは、LTE通信機能を用いて、TLSプロトコルでサーバに接続し、HTTP POSTを行うサンプルです。
6.2.1.1. 動作環境
-
Spresense メインボード
-
Spresense LTE拡張ボード
-
SIM カード
-
microSD カード
接続方法は、SpresenseメインボードとSpresense LTE拡張ボードの接続方法を参照してください。
本スケッチではネットワークに接続するため、SIM カードが必要です。
LTE-M 動作確認SIM Listをご確認ください。
6.2.2. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/lte_tls
を指定してコンフィグレーションを実行します。tools/config.py examples/lte_tls
サンプルアプリケーションのコンフィグレーションを変更します。
tools/config.py -m
-
APNのパラメータを設定します。(ご使用のSIMに合わせて設定してください。)
Application Configuration -> Spresense SDK -> Examples -> TLS data communication over LTE network example - Access Point Name (CONFIG_EXAMPLES_LTE_TLS_APN_NAME) - IP type Selection - Authentication type Selection - Username used for authentication (CONFIG_EXAMPLES_LTE_TLS_APN_USERNAME) - Password used for authentication (CONFIG_EXAMPLES_LTE_TLS_PASSWD)
コンフィグレーション名 説明 Access Point Name
アクセスポイント名
IP type Selection
APNプロトコル。
IPv4
、IPv6
、IPv4/v6
から選択します。Authentication type Selection
認証タイプ。
None
、PAP
、CHAP
から選択します。Username used for authentication
ユーザ名。 認証タイプに
None
を選択した場合、設定は無視されます。Password used for authentication
パスワード。 認証タイプに
None
を選択した場合、設定は無視されます。 -
HTTPSの設定をします。
モデムのTLSプロトコルを使用することが可能です。
使用する場合は、 モデムのTLSプロトコルを使用する を参照してください。Application Configuration -> Spresense SDK -> Examples -> TLS data communication over LTE network example -> Directory for server certification files (CONFIG_EXAMPLES_LTE_TLS_CERTS_PATH)
HTTPSで使用するサーバのルート証明書を格納するディレクトリを指定します。
デフォルトの設定では/mnt/sd0/CERTSとなっています。ディレクトリのパスを
/mnt/spif/CERTS
にするとSPI-Flashに変更することができます。ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make
-
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
6.2.3. 動作確認
シリアルターミナルを開いて、lte_tls
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
lte_tls
コマンドを実行します。lte_tls コマンドの使い方を以下に示します。
nsh> lte_tls <url>
- url
-
インターネット上に置かれているファイルのURLを指定します。
https://
から始まる必要があります。urlを指定しない場合、https://example.com/post
となります。事前にサーバのルート証明書をコンフィグレーションで記述したディレクトリに格納する必要があります。
本サンプルアプリケーションはHTTPのPOSTメソッドを使用して指定されたurlに任意のデータを送信します。
lte_tls
コマンドを実行した例を以下に示します。正常にデータを送信できた場合は "HTTP status code = 200" が出力されます。
nsh> lte_tls https://httpbin.org/post app_restart_cb called. reason:Modem restart by application. app_radio_on_cb called. result: 0 app_activate_pdn_cb called. result: 0 pdn.session_id : 1 pdn.active : 1 pdn.apn_type : 0x202 pdn.ipaddr[0].addr : 10.212.60.255 app_localtime_report_cb called: localtime : "19/12/10 : 17:26:18" set localtime completed: 2019/12/10,17:26:18 HTTP status code = 200 app_deactivate_pdn_cb called. result: 0 app_radio_off_cb called. result: 0 nsh>
本サンプルアプリケーションでは、 create_http_post()
の関数でPOSTするデータを作成しています。
static int create_http_post(const char *host,
const char *path,
char *buffer,
size_t buffer_size)
{
const char *post_data = "Spresense!";
const char http_post_request[] = "POST %s HTTP/1.1\r\n"
"HOST: %s\r\n"
"Connection: close\r\n"
"Content-Length: %d\r\n"
"\r\n"
"%s";
return snprintf(buffer, buffer_size,
http_post_request,
path,
host,
strlen(post_data),
post_data);
}
6.3. LTE MQTT サンプルアプリケーション
6.3.1. 概要
本サンプルプログラムは、LTE通信機能を用いて、MQTTブローカに接続し、指定したトピック名に対してサブスクライブするサンプルです。
6.3.1.1. 動作環境
-
Spresense メインボード
-
Spresense LTE拡張ボード
-
SIM カード
接続方法は、SpresenseメインボードとSpresense LTE拡張ボードの接続方法を参照してください。
本スケッチではネットワークに接続するため、SIM カードが必要です。
LTE-M 動作確認SIM Listをご確認ください。
6.3.2. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/lte_mqtt
を指定してコンフィグレーションを実行します。tools/config.py examples/lte_mqtt
サンプルアプリケーションのコンフィグレーションを変更します。
tools/config.py -m
-
APNのパラメータを設定します。(ご使用のSIMに合わせて設定してください。)
Application Configuration -> Spresense SDK -> Examples -> MQTT using LTE example - Access Point Name (CONFIG_EXAMPLES_LTE_MQTT_APN_NAME) - IP type (CONFIG_EXAMPLES_LTE_MQTT_APN_IPTYPE) - Authentication type (CONFIG_EXAMPLES_LTE_MQTT_APN_AUTHTYPE) - Username used for authentication (CONFIG_EXAMPLES_LTE_MQTT_APN_USERNAME) - Password used for authentication (CONFIG_EXAMPLES_LTE_MQTT_APN_PASSWD)
コンフィグレーション名 説明 Access Point Name
アクセスポイント名
IP type
APNプロトコル。0~2の値を設定します。0:
IPv4
, 1:IPv6
2:IPv4/v6
から選択します。Authentication type
認証タイプ。0~2の値を設定します。 0:
None
、1:PAP
、2:CHAP
から選択します。Username used for authentication
ユーザ名。 認証タイプに
None
を選択した場合、設定は無視されます。Password used for authentication
パスワード。 認証タイプに
None
を選択した場合、設定は無視されます。ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make
-
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
6.3.3. 動作確認
シリアルターミナルを開いて、lte_mqtt
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
lte_mqtt
コマンドを実行します。lte_mqtt コマンドの使い方を以下に示します。
nsh> lte_mqtt topicname <options>
- topicname
-
サブスクライブするトピック名
- options
オプション 説明 --host
MQTTブローカのホスト名。デフォルトは
localhost
です。--port
接続先ポート番号。デフォルトは
1883
です。--qos
QOS。0~2の値を指定します。デフォルトは
2
です。--delimiter
区切り文字。 デフォルトは
\n
です。--clientid
クライアントID。 デフォルトは
stdout_subscriber
です。--username
ユーザ名。 デフォルトは 未設定 です。
--password
パスワード。 デフォルトは 未設定 です。
--showtopics
トピック名の表示有無。
on
またはoff
を指定します。デフォルトはoff
です。Spresenseでは
localhost
をサポートしていません。必ず--host
でホスト名を指定してください。
本サンプルアプリケーションはMQTTブローカに接続し、指定したトピック名に対してサブスクライブします。
サブスクライブ完了後、シリアルポートにパブリッシュされたメッセージを表示します。
当該トピック名に対してメッセージをパブリッシュするためには、別途操作が必要です。このアプリケーションでは操作できません。操作の例は後述します。 |
lte_mqtt
コマンドを実行した例を以下に示します。正常にサブスクライブが完了した場合は "Subscribed 0" が出力されます。
nsh> lte_mqtt /test --host mqtt.eclipse.org --clientid test app_restart_cb called. reason:Modem restart by application. app_radio_on_cb called. result: 0 app_activate_pdn_cb called. result: 0 pdn.session_id : 1 pdn.active : 1 pdn.apn_type : 0x202 pdn.ipaddr[0].addr : 10.212.60.255 app_localtime_report_cb called: localtime : "19/12/11 : 11:36:39" set localtime completed: 2019/12/11,11:36:39 Connecting to mqtt.eclipse.org 1883 Connected 0 Subscribing to /test Subscribed 0
サブスクライブしているトピック名に対してパブリッシュします。
ここではUbuntu 16.04で mosquitto_pub
コマンドを実行してパブリッシュする例を示します。
-
以下のコマンドを実行し
mosquitto-clients
をインストールします。
sudo apt-get install mosquitto-clients
-
mosquitto_pub
コマンドを実行してメッセージをパブリッシュします。
mosquitto_pub -t /test -m "Hello Spresense world" -h mqtt.eclipse.org
-
パブリッシュに成功するとシリアルポートに以下のメッセージが出力されます。
Hello Spresense world
6.4. LTE LwM2M サンプルアプリケーション
6.4.1. 概要
本サンプルプログラムは、LTEによる通信機能と WakaamaのLwM2Mライブラリ を用いて、 Leshan などのLwM2Mサーバに接続し、ダミーデバイスの管理を行うサンプルです。
6.4.3. 事前準備
6.4.3.1. デバイスの接続
SpresenseメインボードとSpresense LTE拡張ボードの接続方法、及びSIMカードの挿入方法はこちらを参照してください。 また、ネットワークに接続するためのSIMカードは LTE-M 動作確認SIM List を参照の上準備してください。
6.4.4. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションを行います。
引数に
examples/lte_lwm2m
を指定してコンフィグレーションを実行します。tools/config.py examples/lte_lwm2m
必要に応じてサンプルアプリケーションのコンフィグレーションを変更します。
tools/config.py -m
APNのパラメータを設定します。(ご使用のSIMに合わせて設定してください。)
Application Configuration -> Spresense SDK -> Examples -> LwM2M using LTE example - Access Point Name (CONFIG_EXAMPLES_LTE_LWM2M_APN_NAME) - IP type (CONFIG_EXAMPLES_LTE_LWM2M_APN_IPTYPE) - Authentication type (CONFIG_EXAMPLES_LTE_LWM2M_APN_AUTHTYPE) - Username used for authentication (CONFIG_EXAMPLES_LTE_LWM2M_APN_USERNAME) - Password used for authentication (CONFIG_EXAMPLES_LTE_LWM2M_APN_PASSWD)
コンフィグレーション名 説明 Access Point Name
アクセスポイント名
IP type
APNプロトコル。0~2の値を設定します。
0: IPv4
,1: IPv6
,2: IPv4/v6
から選択します。Authentication type
認証タイプ。0~2の値を設定します。
0: None
,1: PAP
,2: CHAP
から選択します。Username used for authentication
ユーザ名。 認証タイプに
None
を選択した場合、設定は無視されます。Password used for authentication
パスワード。 認証タイプに
None
を選択した場合、設定は無視されます。 -
ビルドを行います。
make
ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。 -
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
6.4.5. 動作確認
シリアルターミナルを開いて、lte_lwm2m
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
lte_lwm2m
コマンドを実行します。lte_lwm2m コマンドの使い方を以下に示します。
nsh> lte_lwm2m <options>
- options
オプション 説明 -n <NAME>
LwM2M のエンドポイント名を指定します。
-h <HOST>
LwM2MサーバのURLを指定します。
-p <PORT>
LwM2Mサーバへの接続ポートを指定します。
-4
LwM2Mサーバへの接続をIPv4で行う場合オプションに追加します。(デフォルトはIPv6接続です。)
-c
このオプションを追加した場合、ダミーのバッテリーレベルを時間経過で上書き更新します。
lte_lwm2m
コマンドを実行した例を以下に示します。
Spresenseターミナル
nsh> lte_lwm2m -h leshan.eclipseprojects.io -p 5683 -4 -c -n Spresense_LwM2M app_restart_cb called. reason:Modem restart by application. app_radio_on_cb called. result: 0 app_activate_pdn_cb called. result: 0 pdn.session_id : 1 pdn.active : 1 pdn.apn_type : 0x202 pdn.ipaddr[0].addr : xxx.xxx.xxx.xxx Trying to bind LWM2M Client to port 56830 LWM2M Client "Spresense_LwM2M" started on port 56830 > New Battery Level: 71 value changed! app_localtime_report_cb called: localtime : "21/04/06 : 20:39:23" set localtime completed: 2021/04/06,20:39:23 -> State: STATE_REGISTERING 22 bytes received from [23.97.187.154]:5683 64 41 70 48 48 70 FB C6 82 72 64 0A 37 69 6D 77 dApHHp...rd.7imw 41 77 73 79 4C 36 AwsyL6 New Battery Level: 41 value changed! -> State: STATE_READY -> State: STATE_READY
6.5. LTE AWS-IoT サンプルアプリケーション
6.5.2. 動作環境
-
Spresense メインボード
-
Spresense LTE拡張ボード
-
SIM カード
-
microSD カード
-
AWS-IoT Core
接続方法は、SpresenseメインボードとSpresense LTE拡張ボードの接続方法を参照してください。
本スケッチではネットワークに接続するため、SIM カードが必要です。
LTE-M 動作確認SIM Listをご確認ください。
また、AWS-IoTを利用するには、AWS-IoTの使用開始および、AWS-IoTへのデバイスの登録が必要です。
開始手順については AWS IoT の使用開始 を参考にしてください。
デバイスの登録については、 Registry でデバイスを登録する の手順で登録し、発行した証明書をダウンロードします。ダウンロードするファイルは以下の3つです。
-
ルート証明書:Amazon_Root_CA_1.pem
-
クライアント証明書:c3c4ff2375.cert.pem
-
秘密鍵:c3c4ff2375.private.key
ダウンロードしたファイルは使用するmicroSD カードにCERTSディレクトリを生成して格納します。
ファイル名は上記リンク先に表示されている例で記載しています。環境によって異なるため適宜読み替えてください。 |
6.5.3. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
examples/lte_awsiot device/sdcard
を指定してコンフィグレーションを実行します。tools/config.py examples/lte_awsiot device/sdcard
サンプルアプリケーションのコンフィグレーションを変更します。
tools/config.py -m
-
APNのパラメータを設定します。(ご使用のSIMに合わせて設定してください。)
Application Configuration -> Spresense SDK -> Examples -> AWS IoT using LTE example - Access Point Name (CONFIG_EXAMPLES_LTE_AWSIOT_APN_NAME) - IP type (CONFIG_EXAMPLES_LTE_AWSIOT_APN_IPTYPE) - Authentication type (CONFIG_EXAMPLES_LTE_AWSIOT_APN_AUTHTYPE) - Username used for authentication (CONFIG_EXAMPLES_LTE_AWSIOT_APN_USERNAME) - Password used for authentication (CONFIG_EXAMPLES_LTE_AWSIOT_APN_PASSWD)
コンフィグレーション名 説明 Access Point Name
アクセスポイント名
IP type
APNプロトコル。0~2の値を設定します。0:
IPv4
, 1:IPv6
2:IPv4/v6
から選択します。Authentication type
認証タイプ。0~2の値を設定します。 0:
None
、1:PAP
、2:CHAP
から選択します。Username used for authentication
ユーザ名。 認証タイプに
None
を選択した場合、設定は無視されます。Password used for authentication
パスワード。 認証タイプに
None
を選択した場合、設定は無視されます。 -
AWS-IoTを利用するためのパラメータを設定します。(ご使用の環境にあわせて設定してください。)
Application Configuration -> Spresense SDK -> Examples -> AWS IoT using LTE example - AWS IoT cert folder (CONFIG_EXAMPLES_LTE_AWSIOT_CERT)
コンフィグレーション名 デフォルト値 説明 AWS IoT cert folder
"/mnt/sd0/CERTS"
AWS-IOTと接続する際に必要な認証用ファイルの置き場所を設定します。
Application Configuration -> Spresense SDK -> Externals -> AWS IoT Device SDK for Embedded C -> AWS-IoT console - AWS_IOT_MQTT_HOST (CONFIG_EXTERNALS_AWSIOT_AWS_IOT_MQTT_HOST) - AWS_IOT_MQTT_PORT (CONFIG_EXTERNALS_AWSIOT_AWS_IOT_MQTT_PORT) - AWS_IOT_MQTT_CLIENT_ID (CONFIG_EXTERNALS_AWSIOT_AWS_IOT_MQTT_CLIENT_ID) - AWS_IOT_MY_THING_NAME (CONFIG_EXTERNALS_AWSIOT_AWS_IOT_MY_THING_NAME) - AWS_IOT_ROOT_CA_FILENAME (CONFIG_EXTERNALS_AWSIOT_AWS_IOT_ROOT_CA_FILENAME) - AWS_IOT_CERTIFICATE_FILENAME (CONFIG_EXTERNALS_AWSIOT_AWS_IOT_CERTIFICATE_FILENAME) - AWS_IOT_PRIVATE_KEY_FILENAME (CONFIG_EXTERNALS_AWSIOT_AWS_IOT_PRIVATE_KEY_FILENAME)
コンフィグレーション名 デフォルト値 説明 AWS_IOT_MQTT_HOST
MQTTブローカー名。ご使用のAWS-IoT環境のエンドポイントを設定します。
AWS_IOT_MQTT_PORT
443
MQTTブローカーのポート番号。AWS-IoTはデフォルト値で接続可能です。
AWS_IOT_MQTT_CLIENT_ID
"AWS-IoT-C-SDK"
MQTTのクライアントID。デバイス毎にユニークである必要があります。
AWS_IOT_MY_THING_NAME
"AWS-IoT-C-SDK"
モノの名前。
AWS_IOT_ROOT_CA_FILENAME
"rootCA.crt"
ルート証明書のファイル名。AWS-IoTサイトからダウンロードしたファイルを指定します。
AWS_IOT_CERTIFICATE_FILENAME
"cert.pem"
クライアント証明書のファイル名。AWS-IoTサイトからダウンロードしたファイルを指定します。
AWS_IOT_PRIVATE_KEY_FILENAME
"privkey.pem"
クライアント認証で用いる秘密鍵のファイル名。AWS-IoTサイトからダウンロードしたファイルを指定します。
ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make
-
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
6.5.4. 動作確認
シリアルターミナルを開いて、lte_awsiot
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
lte_awsiot
コマンドを実行します。lte_awsiot コマンドの使い方を以下に示します。
nsh> lte_awsiot <options>
- options
オプション 説明 -x
パブリッシュの繰り返し回数。デフォルト値は無限回です。
本サンプルアプリケーションはAWS-IoTにMQTTで接続し、"sdkTest/sub"トピックにサブクライブします。
サブスクライブ完了後、"sdkTest/sub"トピックにパブリッシュします。
lte_awsiot
コマンドを実行した例を以下に示します。
nsh> lte_awsiot -x 1 app_restart_cb called. reason:Modem restart by application. app_radio_on_cb called. result: 0 app_activate_pdn_cb called. result: 0 pdn.session_id : 1 pdn.active : 1 pdn.apn_type : 0x202 pdn.ipaddr[0].addr : 10.212.60.255 app_localtime_report_cb called: localtime : "19/12/13 : 14:15:16" set localtime completed: 2019/12/13,14:15:16 app_deactivate_pdn_cb called. result: 0 app_radio_off_cb called. result: 0
送信したパブリッシュメッセージはAWS-IoTコンソール上で確認できます。
動作環境によっては通信状態が不安定になり、正しく動作しないことがあります。 |
6.6. LTE Azure-IoT サンプルアプリケーション
6.6.1. 概要
本サンプルプログラムは、LTEによる通信機能とNuttXのWebClientを用いて、Azure IoT Hubに接続し、メッセージの送受信及びファイルの送受信を行うサンプルです。
6.6.3. 事前準備
6.6.3.1. デバイスの接続
SpresenseメインボードとSpresense LTE拡張ボードの接続方法、及びSIMカードの挿入方法はこちらを参照してください。 また、ネットワークに接続するためのSIMカードは LTE-M 動作確認SIM List を参照の上準備してください。
6.6.3.2. Azure IoT Hub/IoT デバイスの作成
Azure IoT Hubを利用するには、 Azure Portal からAzure IoT Hub及びIoTデバイスを作成しておく必要があります。
Azure IoT HubとIoT デバイスについては Azure Portal を使用して IoT Hub を作成する を参照し作成してください。
6.6.3.3. 接続用ファイルの作成
Azure IoT Hubに接続しSpresenseとデータの送受信を行うには、 Azure IoT サーバ証明書 と Azure IoT 設定ファイル が必要になります。 以下にそれぞれの取得方法及びファイルの保存方法について説明します。
Azure IoT サーバ証明書
Azure IoT Hubサーバへ接続するためには、Azure IoT サーバ証明書をダウンロードし、SDカードに保存しておく必要があります。
サイトAzure Portal https://portal.azure.com/
の Baltimore CyberTrust Root証明書 (ファイル名 portal-azure-com.pem)
を、 SDカードの CERTS
ディレクトリの中にコピーしてください。
SDカード
└── CERTS
└── portal-azure-com.pem
例としてFirefox webブラウザを利用したダウンロード方法を説明します。
-
Azure Portal
https://portal.azure.com
にアクセスします。 -
Firefoxブラウザのアドレスバー左横の認証ボタンをクリックします。
-
安全な接続
から詳細を表示
をクリックします。 -
セキュリティ
から証明書を表示
をクリックします。 -
Baltimore CyberTrust Root
からPEM (証明書)
をクリックしportal-azure-com.pem
をダウンロードします。 -
SDカード直下に
CERTS
ディレクトリを作成し、その中にダウンロードしたportal-azure-com.pem
をコピーします。 -
コピーしたSDカードをSpresense LTE拡張ボードに挿入します。
Azure IoT 設定ファイル
lte_azureiotサンプルでAzure IoT Hubへ接続するためには、IoT Hub及びIoT デバイス名、IoT デバイスのプライマリ対象共有アクセスキー情報を含んだファイルをSDカードにコピーする必要があります。
Azure Portalで作成したAzure IoT Hub名 <IoT Hub Name>
及びIoT デバイス名 <Device ID>
と、プライマリ対象共有アクセスキー <Primary Key>
を以下のフォーマット通りに記載し resources.txt
として保存します。(プライマリ対象共有アクセスキーは、作成したIoT デバイス情報の中の 主キー
になります。)
<IoT Hub Name>
<Device ID>
<Primary Key>
そして、SDカードに azureiot
を作成しその中に resources.txt
をコピーします。
SDカード
└── azureiot
└── resources.txt
6.6.4. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションを行います。
引数に
examples/lte_azureiot
を指定してコンフィグレーションを実行します。tools/config.py examples/lte_azureiot
必要に応じてサンプルアプリケーションのコンフィグレーションを変更します。
tools/config.py -m
APNのパラメータを設定します。(ご使用のSIMに合わせて設定してください。)
Application Configuration -> Spresense SDK -> Examples -> Azure IoT using LTE example - Access Point Name (CONFIG_EXAMPLES_LTE_AZUREIOT_APN_NAME) - IP type Selection (CONFIG_EXAMPLES_LTE_AZUREIOT_APN_IPTYPE_*) - Authentication type Selection (CONFIG_EXAMPLES_LTE_AZUREIOT_APN_AUTHTYPE_*) - Username used for authentication (CONFIG_EXAMPLES_LTE_AZUREIOT_APN_USERNAME) - Password used for authentication (CONFIG_EXAMPLES_LTE_AZUREIOT_APN_PASSWD)
コンフィグレーション名 説明 Access Point Name
アクセスポイント名
IP type Selection
APNプロトコル。0~2の値を設定します。
IPv4
,IPv6
,IPv4/v6
から選択します。Authentication type Selection
認証タイプ。0~2の値を設定します。
None
,PAP
,CHAP
から選択します。Username used for authentication
ユーザ名。 認証タイプに
None
を選択した場合、設定は無視されます。Password used for authentication
パスワード。 認証タイプに
None
を選択した場合、設定は無視されます。 -
ビルドを行います。
make
ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。 -
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
6.6.5. 動作確認
シリアルターミナルを開いて、lte_azureiot
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
lte_azureiot
コマンドを実行します。lte_azureiot コマンドの使い方を以下に示します。
nsh> lte_azureiot <options> <arg1> <arg2>
- options
オプション 説明 send
Azure IoT Hubに対してメッセージを送信します。メッセージ内容は
<arg0>
に"Hello!"
などのようにコマンドを実行します。recv
Azure IoTからのメッセージを受信します。
upload
Azure IoT Hubのコンテナにファイルをアップロードします。アップロードするファイルは
<arg1>
, コンテナ上でのファイル名を<arg2>
として指定します。download
Azure IoT Hubのコンテナからファイルをダウンロードします。ダウンロードするファイル名は
<arg1>
, ダウンロードしたファイルの置き場所を<arg2>
として指定します。lte_azureiot
コマンドを実行した例を以下に示します。
6.6.5.1. メッセージを送信する場合
Azure Cloud Shell上で az iot hub monitor-events
コマンドを実行してモニターします。
6.6.5.2. メッセージを受信する場合
Azure Cloud Shell上で az iot device c2d-message send
コマンドを実行してメッセージを送信します。
Azure Cloud Shell
azure_user@Azure:~ az iot device c2d-message send -d <Device ID> --data "spresense hello azure" -n <IoT Hub Name>
Spresenseターミナル
nsh> lte_azureiot recv LTE connect... LTE connect...OK Successful Recv message: spresense hello azure LTE disconnect... lte_radio_off lte_power_off lte_finalize LTE disconnect...OK
動作環境によっては通信状態が不安定になり、正しく動作しないことがあります。 |
6.7. LTEのネットワークデーモンを使ってネットワーク接続を行う
LTEのネットワークデーモンを使ってネットワーク接続するコマンドについて説明します。
ネットワーク接続に成功するとwgetなどのコマンドを使用してデータ通信が可能となります。
6.7.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
feature/lte
を指定してコンフィグレーションを実行します。tools/config.py feature/lte
ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
LTEを使用したexample(examples/lte_http_getなど)のコンフィグレーションでも
CONFIG_LTE_DAEMON
が有効になっているためそのままお使い頂けます。
6.7.2. 動作確認
シリアルターミナルを開いて、lte_daemon
コマンドを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
lte_daemon
コマンドを実行します。lte_daemon コマンドの使い方を以下に示します。
nsh> lte_daemon <options> <action>
- options(オプションパラメータ、actionがstartの時のみ有効)
オプション 説明 -a
アクセスポイント名。
-t
APNタイプ。16進数の値を設定します。詳細な値については LTE API リファレンスを参照してください。
指定がなければIA
とDEFAULT
の論理和が使用されます。-i
APNプロトコル。0~2の値を設定します。(0:
IPv4
, 1:IPv6
, 2:IPv4/v6
)
指定がなければデフォルトは0:IPv4
です。-v
認証タイプ。0~2の値を設定します。 (0:
None
, 1:PAP
, 2:CHAP
)
指定がなければデフォルトは0:None
です。-u
ユーザ名。 認証タイプに 0:
None
を選択した場合、設定は無視されます。-p
パスワード。 認証タイプに 0:
None
を選択した場合、設定は無視されます。各オプションのデフォルト値は変更することが可能です。(APNタイプを除く)
詳細は APN設定をデフォルト設定から変更する手順について をご参照ください。- action(必須パラメータ)
action 説明 start
LTEのネットワークデーモンを開始します。
stop
LTEのネットワークデーモンを停止します。
-
ネットワーク接続する場合、NuttShell から
lte_daemon start
コマンドとifup
コマンドを実行します。ifconfig
コマンドを実行することでコマンドを実行したタイミングでのインターフェースの状態が確認できます。nsh> ifconfig nsh> nsh> lte_daemon -a internet -v 2 -u user -p pass start nsh> nsh> ifconfig eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at DOWN inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0 inet6 addr: ::/0 inet6 DRaddr: ::/0 nsh> nsh> ifup eth0 ifup eth0...OK nsh> nsh> ifconfig eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at UP inet addr:100.92.28.11 DRaddr:0.0.0.0 Mask:0.0.0.0 inet6 addr: ::/0 inet6 DRaddr: ::/0 nsh>
-
ネットワークに接続した状態で、NuttShell から
wget
コマンドを実行してインターネット上に置かれているファイルのURLを指定しファイルをダウンロードします。nsh> ifconfig eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at UP inet addr:100.92.28.11 DRaddr:0.0.0.0 Mask:0.0.0.0 inet6 addr: ::/0 inet6 DRaddr: ::/0 nsh> nsh> wget -o /mnt/spif/index.html http://www.example.com/index.html nsh> nsh> nsh> cat /mnt/spif/index.html <!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html> nsh> nsh>
-
ネットワーク切断する場合、NuttShell から
ifdown
コマンドを実行します。nsh> ifconfig eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at UP inet addr:100.92.28.11 DRaddr:0.0.0.0 Mask:0.0.0.0 inet6 addr: ::/0 inet6 DRaddr: ::/0 nsh> nsh> ifdown eth0 ifdown eth0...OK nsh> nsh> ifconfig eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at DOWN inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0 inet6 addr: ::/0 inet6 DRaddr: ::/0 nsh>
-
LTEのネットワークデーモンを終了させる場合、NuttShell から
lte_daemon stop
コマンドを実行します。nsh> ifconfig eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 at DOWN inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0 inet6 addr: ::/0 inet6 DRaddr: ::/0 nsh> nsh> nsh> lte_daemon stop nsh> nsh> ifconfig nsh>
6.7.3. APN設定をデフォルト設定から変更する手順について
ここではlte_daemonの引数に指定するAPN設定のデフォルト値を変更する手順を示します。
-
lte_daemonのコンフィグレーションを変更します。
tools/config.py -m
-
APNのパラメータを設定します。(ご使用のSIMに合わせて設定してください。)
Application Configuration -> Spresense SDK -> System tools -> lte_daemon - Access Point Name (CONFIG_LTE_DAEMON_APN_NAME) - IP type Selection - Authentication type Selection - Username used for authentication (CONFIG_LTE_DAEMON_APN_USERNAME) - Password used for authentication (CONFIG_LTE_DAEMON_APN_PASSWD)
コンフィグレーション名 デフォルト値 説明 Access Point Name
アクセスポイント名
IP type Selection
0:
IPv4
APNプロトコル。0~2の値を設定します。0:
IPv4
, 1:IPv6
2:IPv4/v6
から選択します。Authentication type Selection
0:
None
認証タイプ。0~2の値を設定します。 0:
None
、1:PAP
、2:CHAP
から選択します。Username used for authentication
ユーザ名。 認証タイプに
None
を選択した場合、設定は無視されます。Password used for authentication
パスワード。 認証タイプに
None
を選択した場合、設定は無視されます。
-
7. Network チュートリアル
7.1. ftp サンプルアプリケーション
この章では、NuttXの標準サンプルである、ftpc及びftpdに関するサンプルアプリケーションの動作手順を示します。
7.1.1. ソースコードパス
このサンプルのソースコードは、
-
FTP Client側:
sdk/apps/examples/ftpc
-
FTP Server側:
sdk/apps/examples/ftpd
にそれぞれ入っています。
7.1.2. 動作環境
このサンプルを動作させるには、以下のハードウェアを使う前提となっています。 サーバ用とクライアント用の2セット用意するか、サーバ用に1セットとクライアント用にftp clientがインストールされたPCを1台用意する必要があります。
Spresense Main Board
IDY Wi-Fi Add-on Board iS110B
7.1.3. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/ftp
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/ftp make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
Spresenseをもう1台使う場合はそちらにも同じnuttx.spkを書き込んでください。
7.1.4. 動作確認
シリアルターミナルを開いて、Wi-Fiに接続し、ftpd_start
コマンドを実行して、
クライアントの接続を待ちます。
この例では、SpresenseのSPI Flash上に適当なファイル(test_ftp.txt)を作成して、
それをクライアントが取得(get)し、また、PC側からSpresenseに対して適当なファイルを送信(put)する動作を確認します。
-
シリアルターミナルを起動します。
下記の例では、シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定してminicomで接続しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShellでSPI Flash上に適当なテキストファイルを作成します。
以下のコマンドを叩いて、test_ftp.txtというファイルを作成します。
nsh> echo This is Spresense FTPD > /mnt/spif/test_ftp.txt nsh> echo Everything is OK. >> /mnt/spif/test_ftp.txt
catコマンドを使って、正しくファイルが作られているかを確認します。
nsh> cat /mnt/spif/test_ftp.txt This is Spresense FTPD Everything is OK.
-
NuttShell から Wi-Fi接続を行い、
ftpd_start
コマンドを実行します。実機をAPモードでWi-Fiの設定を行い、ftpd_startでFTPデーモンを起動してClientからの接続待ち状態にします。 下記の例では、APモードでWi-Fiを起動し、SSIDをspresense_net、パスワードを0123456789としています。 ifconfigコマンドでIPアドレスを確認して、FTPデーモンを起動します。
nsh> gs2200m -a 1 spresense_net 0123456789 & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:56:49 at UP inet addr:192.168.11.1 DRaddr:192.168.11.1 Mask:255.255.255.0 nsh> ftpd_start Initializing the network Starting the FTP daemon FTP daemon [10] started Adding accounts: 1. Root account: USER=root PASSWORD=abc123 HOME=(none) 2. User account: USER=ftp PASSWORD=(none) HOME=(none) 3. User account: USER=anonymous PASSWORD=(none) HOME=(none)
このftpdのサンプルでは、上記3つのアカウントが登録されています。これらのアカウント情報は、クライアントから接続する際に必要になります。
-
PCからSpresenseのFTPサーバに接続します。
上記の状態でPC側からSpresenseと同一のSSIDにWi-Fiを接続し、ftpコマンドでSpresense側に接続します。
以下、Spresense側のIPアドレスが192.168.11.1として説明します。お使いの環境に合わせて適宜読み替えてください。 PCから接続すると、ユーザ名とパスワードが要求されるので、上記の3つのアカウントから好きなものを選び入力して接続を行なってください。以下の例では、rootアカウントを利用しています。
(なお、お使いのPC環境によって、メッセージの出方は異なります)ftp 192.168.11.1 Connected to 192.168.11.1. 220 NuttX FTP Server Name (192.168.11.1:user): root 331 Password required for root Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp>
あとは通常のftpのコマンドでファイルを取り出したり書き込んだりすることが出来ます。 まず、先ほど作成した/mnt/spif/test_ftp.txtを取得してみます。
ftp> cd /mnt/spif 250 CWD command successful ftp> get test_ftp.txt local: test_ftp.txt remote: test_ftp.txt 229 Entering Extended Passive Mode (|||50000|). 150 Opening data connection 100% |**************************************************************************************************************************| 41 0.50 KiB/s 00:00 ETA 226 Transfer complete 41 bytes received in 00:00 (0.50 KiB/s)
無事に転送が成功すると、上記のようなメッセージがPC側に出て来ます。
FTPクライアントアプリを終了し、test_ftp.txtがあるか、中身が同じものかを確認します。ftp> quit 221 Good-bye $ ls test_ftp.txt test_ftp.txt $ cat test_ftp.txt This is Spresense FTPD Everything is OK.
無事に取得が出来たことがわかります。
続いて、ファイルの書き込みを行なってみます。 まず、PC側でファイルを準備します。(ファイル名:test_pc.txt)echo "This is Host PC." > test_pc.txt echo "Nothing wrong with me." >> test_pc.txt cat test_pc.txt This is Host PC. Nothing wrong with me
再度FTPクライアントを接続し、作成したファイルをputコマンドでSpresenseに転送します。
ftp 192.168.11.1 Connected to 192.168.11.1. 220 NuttX FTP Server Name (192.168.11.1:user): root 331 Password required for root Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> put test_pc.txt /mnt/spif/test_pc.txt local: test_pc.txt remote: /mnt/spif/test_pc.txt 229 Entering Extended Passive Mode (|||50000|). 150 Opening data connection 100% |**************************************************************************************************************************| 40 63.61 KiB/s 00:00 ETA 226 Transfer complete 40 bytes sent in 00:00 (0.84 KiB/s)
無事に転送が完了すると上記のようなメッセージがPC側で表示されます。
Spresense側で転送されたファイルを見てみます。
Spresenseに接続しているminicomターミナル上で以下のように確認が出来ます。 (nsh> というプロンプトが見えない場合、Enterキーを押せば出て来ます。)nsh> cat /mnt/spif/test_pc.txt This is Host PC. Nothing wrong with me. nsh>
-
もう1台のSpresenseからクライアント接続する場合
もう1台のSpresenseからクライアント接続を行う場合を説明します。
サーバ側のSpresenseは上記のままで、Client側のSpresenseにminicomで接続し、Wi-Fi接続します。 サーバ側のSpresense同様にminicomでSpresenseのターミナルに接続してください。この例では、シリアルポートとして /dev/ttyUSB1 を、baudrate として 115200 bps を設定してminicomで接続しています。minicom -D /dev/ttyUSB1 -b 115200
続いて、Wi-Fiに接続後、ftpcコマンドでサーバに接続します。
nsh> gs2200m spresense_net 0123456789 & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:56:49 at UP inet addr:192.168.11.2 DRaddr:192.168.11.1 Mask:255.255.255.0 nsh> nsh> ftpc 192.168.11.1 NuttX FTP Client:
NuttX標準のftpクライアントでは、特にプロンプト等は表示されません。
この状態でログインを行います。この例では、アカウントrootでログインしています。login root abc123
特になんの応答もありませんが、これでログインは成功します。
先ほどPCで取得したサーバ側のSpreseneにある、/mnt/spif/test_ftp.txtを取得してみます。get /mnt/spif/test_ftp.txt /mnt/spif/test_ftp.txt
login同様になんの応答もありませんが、これでファイルの取得が成功しています。
ftpcコマンドから抜けて、ファイルが取得出来たかを確認します。quit nfc> Exiting... nsh> cat /mnt/spif/test_ftp.txt This is Spresense FTPD Everything is OK.
無事に転送が出来ていれば、上記のようにサーバ側で作成したファイルを見ることが出来ます。
7.1.5. Tips 既存のWi-Fiネットワークに接続する場合
場合によっては、APモードではなく、Spresenseを既存でお使いのWi-Fiネットワークに接続したい場合もあるかと思います。 その場合は、実機側でのコマンド入力を以下のようにしてください。
nsh> gs2200m <接続したいSSID> <SSIDのパスワード> & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:56:49 at UP inet addr:XXX.XXX.XXX.XXX DRaddr:XXX.XXX.XXX.XXX Mask:XXX.XXX.XXX.XXX nsh> ftpd_start Initializing the network Starting the FTP daemon FTP daemon [10] started Adding accounts: 1. Root account: USER=root PASSWORD=abc123 HOME=(none) 2. User account: USER=ftp PASSWORD=(none) HOME=(none) 3. User account: USER=anonymous PASSWORD=(none) HOME=(none)
IPアドレスやネットマスクは、そのSSIDによって割り振られ、ifconfigで確認できます。
7.2. tcpecho サンプルアプリケーション
この章では、NuttXの標準サンプルである、tcpechoに関するサンプルアプリケーションの動作手順を示します。 TCPのシンプルなエコーサーバのサンプルになります。
7.2.2. 動作環境
このサンプルを動作させるには、以下のハードウェアを使う前提となっています。
Spresense Main Board
IDY Wi-Fi Add-on Board iS110B
ホストPC (telnetクライアントがインストールされていること)
7.2.3. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/tcpecho
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/tcpecho make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
7.2.4. 動作確認
シリアルターミナルを開いて、Wi-Fiに接続し、tcpecho コマンドを実行して、クライアントから接続してechoバックを確認します。
-
シリアルターミナルを起動します。
まず、シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定してminicomで接続しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
tcpecho
コマンドを実行します。実機をAPモードでWi-Fiの設定を行い、tcpechoを起動してClientからの接続待ち状態にします。 下記の例では、APモードでWi-Fiを起動し、SSIDをspresense_net、パスワードを0123456789としています。 ifconfigコマンドでIPアドレスを確認して、tcpechoを起動します。
nsh> gs2200m -a 1 spresense_net 0123456789 & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:56:49 at UP inet addr:192.168.11.1 DRaddr:192.168.11.1 Mask:255.255.255.0 nsh> tcpecho
この状態でPC側から上記のSSIDにWi-Fiを接続し、telnetで192.168.11.1のポート80番に接続します。
telnet 192.168.11.1 80 Trying 192.168.11.1... Connected to 192.168.11.1. Escape character is '^]'.
後はPCで適当な文字を打ってEnterキーを打てば、エコーバックが帰ってきます。
hello hello <- エコーバック文字列 Spresense Spresense <- エコーバック文字列
7.3. tcpblaster サンプルアプリケーション
この章では、NuttXの標準サンプルである、tcpblasterに関するサンプルアプリケーションの動作手順を示します。 TCPで接続したserver / client間でデータの送受信を行い、その転送レートを計測するサンプルです。
7.3.2. 動作環境
このサンプルを動作させるには、以下のハードウェアを2セット使う前提となっています。 なお、対向をPCにして、1セットのみで動作させることも可能です。 最後にTipsとして、コンフィグの変更方法を載せています。
Spresense Main Board
IDY Wi-Fi Add-on Board iS110B
7.3.3. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/tcpblaster
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/tcpblaster make
-
nuttx.spk
を Spresense ボードへ書き込みます。2つの機材に同じプログラムを焼き込みます。 この例では シリアルポートとして /dev/ttyUSB0, /dev/ttyUSB1 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk tools/flash.sh -c /dev/ttyUSB1 -b 500000 nuttx.spk
7.3.4. 動作確認
シリアルターミナルを開いて、Wi-Fiに接続し、tcpserver / tcpclient コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、2つのminicom ターミナルを使用する例です。 まず、一つ目のターミナルから、シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定してminicomで接続しています。
minicom -D /dev/ttyUSB0 -b 115200
まず、二つ目も同様に、シリアルポートを /dev/ttyUSB1 として接続しています。
minicom -D /dev/ttyUSB1 -b 115200
-
それぞれのNuttShell から
tcpserver
もしくはtcpclient
コマンドを実行します。まず、片方の実機をAPモードでWi-Fiの設定を行います。 下記の例では、APモードでWi-Fiを起動し、SSIDをspresense_net、パスワードを0123456789としています。 Wi-Fiモジュールが正しく起動されると、IPアドレスが設定されるので、それを確認します。 ifconfigコマンドで、下記のように、IPアドレスが割り当てられます。
★ターミナル1 nsh> gs2200m -a 1 spresense_net 0123456789 & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:56:49 at UP inet addr:192.168.11.1 DRaddr:192.168.11.1 Mask:255.255.255.0
続いてもう一方のminicomのターミナルに対して、上記で作成したAPにSTAモードで接続し、同様に割り当てられたIPアドレスを確認します。 gs2200mにてWi-Fiの設定を行なった後、5秒程度待ちます。これは、Wi-Fi APからのDHCPでのIPアドレスが付与されるなどを待つのが目的です。 無事に接続が上手く出来ると、下記のように、デフォルトルーターが上記APのアドレスになって、自己のIPアドレスが割り振られます。
★ターミナル2 nsh> gs2200m spresense_net 0123456789 & nsh> sleep 5 nsh> ifconfig eth0 Link encap:Ethernet HWaddr 3c:95:09:00:64:91 at UP inet addr:192.168.11.2 DRaddr:192.168.11.1 Mask:255.255.255.0
この状態で、tcpserverを起動してClientからの接続待ち状態にします。
★ターミナル1 nsh> tcpserver Binding to IPv4 Address: 00000000 server: Accepting connections on port 5471
続いて、tcpclientを起動します。引数に接続先のIPアドレスを設定します。 ターミナル1側のIPアドレス(この例では、192.168.11.1)を設定しています。 正しく動作すると、データの送受信が開始され、通信レートが算出されて表示されます。
★ターミナル2 nsh> tcpclient 192.168.11.1 Connecting to IPv4 Address: 010ba8c0 client: Connected Sent 50 buffers: 50.0 Kb (avg 1.0 Kb) in 0.25 Sec ( 195.1 Kb/Sec) Sent 50 buffers: 50.0 Kb (avg 1.0 Kb) in 0.16 Sec ( 308.8 Kb/Sec) Sent 50 buffers: 50.0 Kb (avg 1.0 Kb) in 0.15 Sec ( 329.8 Kb/Sec) Sent 50 buffers: 50.0 Kb (avg 1.0 Kb) in 0.17 Sec ( 282.6 Kb/Sec) Sent 50 buffers: 50.0 Kb (avg 1.0 Kb) in 0.17 Sec ( 286.9 Kb/Sec)
7.3.4.1. Tips 対向機をPCにする方法
この例では2セットのSpresenseを用いて速度計測をしていましたが、 片方をPCにすることも可能です。
その場合、上記コンフィグ手順まで終わった状態で、 menuconfigを開いて、以下のようにビルド設定を変更します。 spresense/sdk以下で、
make menuconfig
とし、
Application Configuration -> Examples -> TCP Performance Test
にある、
Second endpoint is a target
のチェックを外します。 これで、一旦cleanしてから再度ビルドを行います。
make clean make
無事にビルドが完了すると、ホスト側のプログラムとして、tcpclient
が、sdk/apps/examples/tcpblasterの下にできています。
この使い方は、上記のtcpclientと同様です。
Spresense側でtcpserverを立ち上げておき、PCからtcpclientで接続することで、
動作可能です。
8. Graphics チュートリアル
8.1. NX サンプルアプリケーション
この章では、NuttXのグラフィックスシステムである、NXに関するサンプルアプリケーションの動作手順を示します。 NuttXのグラフィックスサブシステムに関する詳細は、 NuttX NX Graphic Subsystem を参照してください。
Spresenseで動作確認をしているNXに関するサンプルコードとそれぞれのソースコードのディレクトリパスは、 下記の様になります。
サンプル名 | ソースコードパス | デフォルトコンフィグ名 | 概要 |
---|---|---|---|
fb |
sdk/apps/examples/fb |
examples/fb |
フレームバッファをダイレクトに操作するサンプル |
nx |
sdk/apps/examples/nx |
examples/nx |
NXのWindowシステムの描画に関するサンプル |
nxdemo |
sdk/apps/examples/nxdemo |
examples/nxdemo |
NXの描画に関するサンプル |
nxhello |
sdk/apps/examples/nxhello |
examples/nxhello |
NXのテキスト描画に関するサンプル |
nximage |
sdk/apps/examples/nximage |
examples/nximage |
NXのイメージ描画に関するサンプル |
nxlines |
sdk/apps/examples/nxlines |
examples/nxlines |
NXの直線描画に関するサンプル |
nxtext |
sdk/apps/examples/nxtext |
examples/nxtext |
NXのテキスト描画とポップアップウィンドウの描画に関するサンプル |
8.1.1. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に 上記の表の
デフォルトコンフィグ名
に記載されている値を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py <デフォルトコンフィグ名> make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
8.1.2. 動作環境
このサンプルを動作させるには、以下のハードウェアを使う前提となっています。
Spresense Main Board
Spresense Extension Board
Arduino UNO LCD Connector board
ILI9341 2.2inch LCD
8.1.3. 動作確認
シリアルターミナルを開いて、nx コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
8.1.3.1. NuttShell から それぞれのコマンドを実行します。
-
fb
サンプルの場合以下の様なメッセージとともに、LCDディスプレイに様々な色の矩形が描画されます。
nsh> fb VideoInfo: fmt: 11 xres: 320 yres: 240 nplanes: 1 PlaneInfo (plane 0): fbmem: 0xd0353c0 fblen: 153600 stride: 640 display: 0 bpp: 16 Mapped FB: 0xd0353c0 0: ( 0, 0) (319,239) 1: ( 29, 21) (290,218) 2: ( 58, 42) (261,197) 3: ( 87, 63) (232,176) 4: (116, 84) (203,155) 5: (145,105) (174,134) Test finished
-
nx
サンプルの場合以下の様なメッセージとともに、LCDディスプレイにWindowが描画されます。
nsh> nx nx_main: NX handle=0xd032050 nx_main: Set background color=8087790 nx_main: Create window #1 nx_main: hwnd1=0xd03aeb0 nx_main: Screen resolution (319,239) nx_main: Set window #1 size to (159,119) nx_main: Sleeping nxeg_position1: hwnd=0xd03aeb0 size=(159,119) pos=(4,4) bounds={(0,0),(319,239)} nxeg_position1: hwnd=0xd03aeb0 size=(159,119) pos=(4,4) bounds={(0,0),(319,239)} nxeg_redraw1: hwnd=0xd03aeb0 rect={(0,0),(158,118)} more=false nx_main: Set window #1 position to (39,29) nx_main: Sleeping nxeg_position1: hwnd=0xd03aeb0 size=(159,119) pos=(39,29) bounds={(0,0),(319,239)} nxeg_redraw1: hwnd=0xd03aeb0 rect={(0,0),(158,118)} more=false nx_main: Add toolbar to window #1 nx_main: Sleeping nxeg_redraw1: hwnd=0xd03aeb0 rect={(0,0),(158,102)} more=false nxeg_tbredraw1: hwnd=0xd03aeb0 rect={(0,0),(158,15)} more=false nx_main: Create window #2 nx_main: hwnd2=0xd03af10 nx_main: Sleeping nxeg_position2: hwnd=0xd03af10 size=(0,0) pos=(0,4) bounds={(0,0),(319,239)} nx_main: Set hwnd2 size to (159,119) nx_main: Sleeping nxeg_position2: hwnd=0xd03af10 size=(159,119) pos=(4,4) bounds={(0,0),(319,239)} nxeg_redraw2: hwnd=0xd03af10 rect={(0,0),(158,118)} more=false nx_main: Set hwnd2 position to (121,91) nx_main: Sleeping nxeg_position2: hwnd=0xd03af10 size=(159,119) pos=(121,91) bounds={(0,0),(319,239)} nxeg_redraw2: hwnd=0xd03af10 rect={(0,0),(158,118)} more=false nxeg_redraw1: hwnd=0xd03aeb0 rect={(0,0),(158,41)} more=false nxeg_tbredraw1: hwnd=0xd03aeb0 rect={(0,0),(158,15)} more=false nxeg_redraw1: hwnd=0xd03aeb0 rect={(0,42),(77,102)} more=false nx_main: Add toolbar to window #2 nx_main: Sleeping nxeg_redraw2: hwnd=0xd03af10 rect={(0,0),(158,102)} more=false nxeg_tbredraw2: hwnd=0xd03af10 rect={(0,0),(158,15)} more=false nx_main: Lower window #2 nx_main: Sleeping nxeg_redraw1: hwnd=0xd03aeb0 rect={(78,42),(158,102)} more=false nx_main: Raise window #2 nx_main: Sleeping nxeg_redraw2: hwnd=0xd03af10 rect={(0,0),(158,102)} more=false nxeg_tbredraw2: hwnd=0xd03af10 rect={(0,0),(158,15)} more=false nx_main: Close window #2 nx_main: Close window #1 nx_main: Disconnect from the server nxeg_redraw1: hwnd=0xd03aeb0 rect={(78,42),(158,102)} more=false nx_listenerthread: Lost server connection: 117
-
nxdemo
サンプルの場合以下の様なメッセージがターミナルに表示され、LCDディスプレイに様々な模様が描画されます。
nsh> nxdemo nxdemo_listener: Connected nxdemo_main: NX handle=0xd031440 nxdemo_main: Screen resolution (320,240) nxdemo_main: Disconnect from the server nxdemo_listener: Lost server connection: 117
-
nxhello
サンプルの場合以下の様なメッセージがターミナルに表示され、LCDディスプレイの中央に
Hello, World!
という文字が描画されます。nsh> nxhello nxhello_main: NX handle=0xd031440 nxhello_main: Set background color=31581 nxhello_main: Screen resolution (320,240) nxhello_hello: Position (114,105) nxhello_main: Disconnect from the server nxhello_listener: Lost server connection: 117
-
nximage
サンプルの場合このサンプルでは、コマンドが
nxhello
となります。 実行すると以下の様なメッセージがターミナルに表示され、LCDディスプレイの中央にNuttXのロゴマークが描画されます。nsh> nxhello nximage_main: NX handle=0xd033d80 nximage_main: Set background color=0 nximage_listener: Connected nximage_main: Screen resolution (320,240) nximage_main: Disconnect from the server nximage_listener: Lost server connection: 117
-
nxlines
サンプルの場合以下の様なメッセージがターミナルに表示され、LCDディスプレイに円と円の中央に線が描画され続けます。
nsh> nxlines Angle: 0002bfaa vector: (184,60)->(136,180) Angle: 0002f1ed vector: (172,57)->(148,183) Angle: 00032430 vector: (160,56)->(160,184) Angle: 00035673 vector: (147,57)->(173,183) Angle: 000388b6 vector: (135,60)->(185,180) Angle: 0003baf9 vector: (124,66)->(196,174) Angle: 0003ed3c vector: (114,74)->(206,166) Angle: 00041f7f vector: (106,84)->(214,156) Angle: 000451c2 vector: (100,95)->(220,145) Angle: 00048405 vector: (97,107)->(223,133) Angle: 0004b648 vector: (96,119)->(224,121) Angle: 0004e88b vector: (97,132)->(223,108) Angle: 00051ace vector: (100,144)->(220,96) Angle: 00054d11 vector: (106,155)->(214,85) Angle: 00057f54 vector: (114,165)->(206,75)
-
nxtext
サンプルの場合以下の様なメッセージがターミナルに表示され、LCDディスプレイに様々な文字が描画されると共にポップアップ矩形が描画されます。
nsh> nxtext nxtext_initialize: Starting NX server nxtext_main: NX handle=0xd032450 nxtext_main: Set background color=31581 nxtext_listener: Connected nxtext_main: Screen resolution (320,240) nxpu_open: Create pop-up nxpu_open: Set pop-up position to (22,99) nxtext_main: Close pop-up nxpu_open: Create pop-up nxpu_open: Set pop-up position to (90,46) nxtext_main: Close pop-up nxpu_open: Create pop-up nxpu_open: Set pop-up position to (171,136) nxtext_main: Close pop-up nxpu_open: Create pop-up nxpu_open: Set pop-up position to (42,164) nxtext_main: Close pop-up nxpu_open: Create pop-up nxpu_open: Set pop-up position to (100,16) nxtext_main: Close pop-up nxpu_open: Create pop-up nxpu_open: Set pop-up position to (132,67) nxtext_main: Close pop-up nxpu_open: Create pop-up
8.1.4. Tips LCD画面のオリエンテーションの変更方法
作成されるアプリケーションによって、LCD画面の前後左右を変更したい場合、
以下のコンフィグを変更することで、LCDのオリエンテーションを変更することが可能です。
tools/config.py -m
でコンフィグメニューを開き、下記の階層にある、 LCD Orientation
の設定値を変更してください。
Device Drivers -> LCD Driver Support -> Graphic LCD Driver Support -> LCD driver selection -> LCD Orientation ()
9. FileSystem チュートリアル
9.1. SmartFS
SPI-Flash のファイルシステムに使用している SmartFS について説明します。
SmartFS ファイルシステムの詳細については以下のNuttX Wikiを参照してください。
9.1.1. 初期化&マウント処理
起動時に呼ばれる cxd56_bringup() 関数から board_flash_initialize() を呼び出します。
File: nuttx/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
#ifdef CONFIG_CXD56_SFC
ret = board_flash_initialize();
if (ret < 0)
{
_err("ERROR: Failed to initialize SPI-Flash. %d\n", errno);
}
#endif
board_flash_initialize() 関数の中で、SPI-Flash を SmartFS ファイルシステムとして
初期化し、/mnt/spif
ディレクトリへマウントします。
File: nuttx/boards/arm/cxd56xx/common/src/cxd56_flash.c
int board_flash_initialize(void)
{
int ret;
FAR struct mtd_dev_s *mtd;
mtd = cxd56_sfc_initialize(); (1)
if (!mtd)
{
ferr("ERROR: Failed to initialize SFC. %d\n ", ret);
return -ENODEV;
}
/* use the FTL layer to wrap the MTD driver as a block driver */
ret = ftl_initialize(CONFIG_SFC_DEVNO, mtd);
if (ret < 0)
{
ferr("ERROR: Initializing the FTL layer: %d\n", ret);
return ret;
}
#if defined(CONFIG_FS_SMARTFS)
/* Initialize to provide SMARTFS on the MTD interface */
ret = smart_initialize(CONFIG_SFC_DEVNO, mtd, NULL); (2)
if (ret < 0)
{
ferr("ERROR: SmartFS initialization failed: %d\n", ret);
return ret;
}
ret = mount("/dev/smart0d1", "/mnt/spif", "smartfs", 0, NULL); (3)
if (ret < 0)
{
ferr("ERROR: Failed to mount the SmartFS volume: %d\n", errno);
return ret;
}
#elif defined(CONFIG_FS_NXFFS)
1 | Memory Technology Device (MTD) デバイスとして登録します。 |
2 | MTD デバイスを SmartFS ファイルシステムとして初期化します。 |
3 |
/dev/smart0d1 デバイスファイルを /mnt/spif へマウントします。 |
9.1.2. コンフィグレーション
SmartFS を使用するにあたり、いくつかのコンフィグレーションが存在します。
SDK としてデフォルトで設定している推奨構成(sdk/configs/default/defconfig
)を以下に示します。
Configuration | Value | Description |
---|---|---|
CONFIG_FS_SMARTFS |
y |
SmartFS ファイルシステムを有効にします |
CONFIG_SMARTFS_ERASEDSTATE=0xff |
0xff |
SPI-Flashの値が0xFFのときにErase状態を意味します。 |
CONFIG_SMARTFS_MAXNAMLEN |
30 |
ファイル名の最大長は30文字です。 |
CONFIG_SMARTFS_MULTI_ROOT_DIRS |
y |
マルチルートディレクトリをサポートしていますが、 デフォルトでは 1 つのルートディレクトリエントリを使用しています。 |
CONFIG_MTD_SMART |
y |
MTD デバイスとして SmartFS を使用します |
CONFIG_MTD_SMART_SECTOR_SIZE |
4096 |
1 セクタのサイズは 4096 バイトです。ファイルの最小単位として 1 セクタ分を使用します。 このサイズを小さくすると管理できるファイル数は増えますが、 小さくしすぎるとファイルのサーチ処理に時間がかかるようになります。 |
CONFIG_MTD_SMART_WEAR_LEVEL |
n |
これを有効にすると Read-only ファイルについても定期的にセクタ移動を行います。 Read-only ファイルについても移動中に電源がOffされてファイルが消去される可能性があるため、 途中で電源断が発生し得るシステムの場合は Disable することを推奨します。 |
CONFIG_MTD_SMART_ENABLE_CRC |
y |
CRCを使用して書き込み不良のチェックを行います。 |
CONFIG_MTD_SMART_FSCK |
y |
ファイル操作中に電源断が発生した場合など、ファイルシステムとして不整合のある状態が発生します。 これを有効にすると、起動時にファイルシステムの整合性をチェックし、ファイルとして成立していない ファイルを削除してファイルシステムを整合性の取れた状態に保ちます。 |
CONFIG_MTD_SMART_MINIMIZE_RAM |
n |
論物変換セクタをキャッシュする操作ですが、有効にするとアクセス速度が低下するため デフォルトではdisableしています。 |
9.1.3. 動作確認
NuttShell プロンプトから df
コマンドによって Filesystem を確認することができます。
nsh> df -h Filesystem Size Used Available Mounted on smartfs 4M 68K 4028K /mnt/spif procfs 0B 0B 0B /proc
/mnt/spif
が smartfs
ファイルシステムとしてマウントされていること、
トータル 4Mバイトのサイズのうち、使用サイズ (Used)、空きサイズ (Available) を確認することができます。
- ファイルを作成する
nsh> echo "This is a test file." > /mnt/spif/test.txt
- 作成されたファイルのサイズを確認する
nsh> ls -l /mnt/spif /mnt/spif: -rw-rw-rw- 21 test.txt
- ファイルの内容を確認する
nsh> cat /mnt/spif/test.txt This is a test file.
プログラムからファイル操作を行う場合は、 open/read/write/closeといった低水準入出力関数や fopen/fread/fwrite/fcloseといったファイル入出力関数を使うことができます。
9.1.4. フォーマット手順
SPI-Flash は工場出荷時に SmartFS ファイルシステムとして使用できるように初期化されています。
SPI-Flash をクリーンアップしたいときには mksmartfs
コマンドを利用することができます。
- Usage
nsh> help mksmartfs mksmartfs usage: mksmartfs [-s <sector-size>] [-f] <path> [<num-root-directories>]
- Example
nsh> mksmartfs -s 4096 -f /dev/smart0d1 1
mksmartfs
コマンドを実行後に、root directory 領域として数セクタが予約され、残りを使用することが可能です。
nsh> df -h Filesystem Size Used Available Mounted on smartfs 4M 28K 4068K /mnt/spif procfs 0B 0B 0B /proc
9.1.5. Flash 消去
起動時に /dev/smart0d1
デバイスファイルが見つからない場合や、
アプリケーションで使用している SPI-Flash 領域を完全に削除したい場合は、
flash_eraseall
コマンドを利用することができます。
flash_eraseall
コマンドを有効にするには、CONFIG_SYSTEM_FLASH_ERASEALL
を有効にしてください。
- Configuration
Application Configuration -> System Libraries and NSH Add-Ons FLASH Erase-all Command (CONFIG_SYSTEM_FLASH_ERASEALL)
- Usage
nsh> flash_eraseall usage: flash_eraseall flash_block_device
- Command
nsh> flash_eraseall /dev/mtdblock0
SPI-Flash を削除した後に SmartFS として使用する場合は、 ボードを再起動した後に、前述したフォーマット手順を参考にしてください。
9.2. FAT ファイルシステム
SD カードのファイルシステムに使用している FAT ファイルシステムについて説明します。
9.2.1. 初期化&マウント処理
起動時に呼ばれる cxd56_bringup() 関数から board_sdcard_initialize() を呼び出します。
File: nuttx/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
#ifdef CONFIG_CXD56_SDIO
ret = board_sdcard_initialize();
if (ret < 0)
{
_err("ERROR: Failed to initialize sdhci. \n");
}
#endif
board_sdcard_initialize() 関数の中で、
SD カードの挿抜検出をするための GPIO 割り込み設定を行います。
SD カードが挿入されている場合は、board_sdcard_enable() 関数が呼ばれ、
SD ホストコントローラを初期化し、SD カードを /mnt/sd0
ディレクトリへマウントします。
SD カードが抜かれた場合は、board_sdcard_disable() が呼ばれ、
SD ホストコントローラの終了処理を行い、/mnt/sd0
をアンマウントします。
File: nuttx/boards/arm/cxd56xx/spresense/src/cxd56_sdcard.c
int board_sdcard_initialize(void)
{
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
/* Configure Interrupt pin with internal pull-up */
cxd56_pin_config(PINCONF_SDIO_CD_GPIO);
ret = cxd56_gpioint_config(PIN_SDIO_CD,
GPIOINT_PSEUDO_EDGE_FALL,
board_sdcard_detect_int,
NULL); (1)
:
}
static void board_sdcard_enable(FAR void *arg)
{
:
g_sdhci.sdhci = cxd56_sdhci_initialize(0); (2)
if (!stat("/dev/mmcsd0", &stat_sdio) == 0)
{
/* Now bind the SDHC interface to the MMC/SD driver */
ret = mmcsd_slotinitialize(0, g_sdhci.sdhci);
finfo("Successfully bound SDHC to the MMC/SD driver\n");
}
/* Handle the initial card state */
cxd56_sdhci_mediachange(g_sdhci.sdhci);
if (stat("/dev/mmcsd0", &stat_sdio) == 0)
{
if (S_ISBLK(stat_sdio.st_mode))
{
ret = mount("/dev/mmcsd0", "/mnt/sd0", "vfat", 0, NULL); (3)
}
}
:
}
static void board_sdcard_disable(FAR void *arg)
{
ret = umount("/mnt/sd0"); (4)
cxd56_sdhci_finalize(0); (5)
}
1 | SD カードの挿抜検出用の GPIO 割り込みを設定します。 |
2 | SD ホストコントローラを初期化します。 |
3 |
/dev/mmcsd0 デバイスファイルを /mnt/sd0 へマウントします。 |
4 |
/mnt/sd0 をアンマウントします。 |
5 | SD ホストコントローラの終了処理を実行します。 |
9.2.2. コンフィグレーション
FAT ファイルシステムを使用するにあたり、いくつかのコンフィグレーションが存在します。
SDK としてデフォルトで設定している推奨構成(sdk/configs/default/defconfig
)を以下に示します。
Configuration | Value | Description |
---|---|---|
CONFIG_CXD56_SDIO |
y |
SD カードの使用を有効にします |
CONFIG_FS_FAT |
y |
FAT ファイルシステムを有効にします |
CONFIG_FAT_LCNAMES |
y |
ファイル名の大文字/小文字を区別します |
CONFIG_FAT_LFN |
y |
FAT ロングファイルネームをサポートします |
CONFIG_FAT_MAXFNAME |
64 |
ファイル名の最大文字数を定義します |
CONFIG_FS_FATTIME |
y |
ファイルのタイムスタンプ機能をサポートします。 RTC に現在時刻が設定されている場合 (正確には RTC が1980年1月1日以降のとき) に ファイルの作成日時及び更新日時を記録します。 |
9.2.3. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
device/sdcard
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py device/sdcard make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
9.2.4. 動作確認
NuttShell プロンプトから df
コマンドによって Filesystem を確認することができます。
nsh> df -h Filesystem Size Used Available Mounted on vfat 14G 2762M 11G /mnt/sd0 smartfs 4M 28K 4068K /mnt/spif procfs 0B 0B 0B /proc
/mnt/sd0
が vfat
ファイルシステムとしてマウントされていること、
トータルサイズ (Size) のうち、使用サイズ (Used)、空きサイズ (Available) を確認することができます。
- RTCに時刻を設定する(ファイルのタイムスタンプ機能を使用する)
nsh> date -s "Feb 22 12:34:00 2021" nsh> date Feb 22 12:34:02 2021
- ファイルを作成する
nsh> echo "This is a test file." > /mnt/sd0/test.txt
- 作成されたファイルのサイズを確認する
nsh> ls -l /mnt/sd0/test.txt -rw-rw-rw- 21 /mnt/sd0/test.txt
- ファイルの内容を確認する
nsh> cat /mnt/sd0/test.txt This is a test file.
PC から SD カード内のファイルのプロパティをみると、タイムスタンプが正しく設定されていることが確認できます。
プログラムからファイル操作を行う場合は、 open/read/write/closeといった低水準入出力関数や fopen/fread/fwrite/fcloseといったファイル入出力関数を使うことができます。
9.2.5. フォーマット手順
PC 上で SD メモリーカードフォーマッター等を用いて、FAT ファイルシステムのフォーマットを行ってください。
exFAT ファイルシステムはサポートしていません。
|
ボード上で SD カードのフォーマットを行う場合は、mkfatfs
コマンドを利用することもできます。
- Usage
nsh> help mkfatfs mkfatfs usage: mkfatfs [-F <fatsize>] [-r <rootdirentries>] <block-driver>
FAT32 フォーマットを行う手順を以下に示します。
- Example
nsh> mkfatfs -F 32 /dev/mmcsd0
10. その他のチュートリアル
10.1. json サンプルアプリケーション
この章では、NuttXの標準サンプルである、jsonに関するサンプルアプリケーションの動作手順を示します。 このサンプルは、組み込み向けオープンソースの、 cJSONをライブラリとして利用しています。
cJSONはjsonフォーマットで記載されたテキストをパースするためのライブラリです。+ json形式のファイルはネットなどでのやり取りする情報などの構造化によく用いられています。
ビルド時にcJSONをwgetにてダウンロードされるため、wgetをインストールしておく必要があります。
10.1.1. ソースコードパス
このサンプルのソースコードは、 sdk/apps/examples/json
以下にあります。
また、ダウンロードされるオープンソースcJSONは、 sdk/apps/netutils/cJSON
以下にダウンロードされます。
10.1.2. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/json
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/json make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
10.1.3. 動作確認
シリアルターミナルを開いて、json コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
json
コマンドを実行します。このサンプルコマンドでは、cJSONを用いて、サンプルコード内にハードコードされたjson形式のテキストデータのパースや、 json形式のテキストの生成を行います。
nsh> json { "name": "Jack (\"Bee\") Nimble", "format": { "type": "rect", "width": 1920, "height": 1080, "interlace": false, "frame rate": 24 } } ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] [[0, -1, 0], [1, 0, 0], [0, 0, 1]] { "Image": { "Width": 800, "Height": 600, "Title": "View from 15th Floor", "Thumbnail": { "Url": "http:/*www.example.com/image/481989943", "Height": 125, "Width": "100" }, "IDs": [116, 943, 234, 38793] } } [{ "precision": "zip", "Latitude": 37.7668, "Longitude": -122.3959, "Address": "", "City": "SAN FRANCISCO", "State": "CA", "Zip": "94107", "Country": "US" }, { "precision": "zip", "Latitude": 37.371991, "Longitude": -122.02602, "Address": "", "City": "SUNNYVALE", "State": "CA", "Zip": "94085", "Country": "US" }] { "name": "Jack (\"Bee\") Nimble", "format": { "type": "rect", "width": 1920, "height": 1080, "interlace": false, "frame rate": 24 } } ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] [[0, -1, 0], [1, 0, 0], [0, 0, 1]] { "Image": { "Width": 800, "Height": 600, "Title": "View from 15th Floor", "Thumbnail": { "Url": "http:/*www.example.com/image/481989943", "Height": 125, "Width": "100" }, "IDs": [116, 943, 234, 38793] } } [{ "precision": "zip", "Latitude": 37.7668, "Longitude": -122.3959, "Address": "", "City": "SAN FRANCISCO", "State": "CA", "Zip": "94107", "Country": "US" }, { "precision": "zip", "Latitude": 37.371991, "Longitude": -122.026, "Address": "", "City": "SUNNYVALE", "State": "CA", "Zip": "94085", "Country": "US" }]
10.2. ini_dumper サンプルアプリケーション
この章では、NuttXの標準サンプルである、ini_dumperに関するサンプルアプリケーションの動作手順を示します。 このサンプルは、組み込み向けオープンソースのiniファイルパーサー、 inihを利用しています。
iniファイルはWindowsで設定ファイルとしてよく用いられているフォーマットです。+ アプリ開発を行う際に、複数の機材に対して同じアプリを使い、それぞれの機材に合わせて変更したい場合などに便利です。
ビルド時にinihをwgetにてダウンロードされるため、wgetをインストールしておく必要があります。
10.2.1. ソースコードパス
このサンプルのソースコードは、 sdk/apps/examples/ini_dumper
以下にあります。
また、ダウンロードされるオープンソースinihは、 sdk/apps/fsutils/inih
以下にダウンロードされます。
10.2.2. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/ini_dumper
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/ini_dumper make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
10.2.3. 動作確認
シリアルターミナルを開いて、ini_dumper コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
ini_dumper
コマンドを実行します。このサンプルコマンドは、引数にiniファイルのパスを指定することで、そのファイルをパースして表示してくれます。
このチュートリアルでは、以下のコマンドで、まずは、/mnt/spif/sample.iniを作成し、それをパースしてみます。nsh> echo [System] > /mnt/spif/sample.ini nsh> echo Board = Spresense >> /mnt/spif/sample.ini nsh> echo >> /mnt/spif/sample.ini nsh> echo [Information] >> /mnt/spif/sample.ini nsh> echo ProvidedBy = Sony Semiconductor Solutions >> /mnt/spif/sample.ini
上記コマンドで/mnt/spifにsample.iniが作られているかcatコマンドで確認します。 無事にファイルが作られていれば、以下の様なメッセージが出力されます。
nsh> cat /mnt/spif/sample.ini [System] Board = Spresense [Information] ProvidedBy = Sony Semiconductor Solutions
ファイルが作られていることが確認できたら、サンプルコマンドを使ってそのファイルをパースします。
nsh> ini_dumper /mnt/spif/sample.ini ------ --------------- ------------- --------------------------- line section key value ------ --------------- ------------- --------------------------- 2 System Board Spresense 5 Information ProvidedBy Sony Semiconductor Solutions ------ --------------- ------------- --------------------------- ini_parse() exited with 0
10.3. pdcurses サンプルアプリケーション
この章では、NuttXの標準サンプルである、pdcursesに関するサンプルアプリケーションの動作手順を示します。 このサンプルは、オープンソースのPDCursesをNuttXにポーティングされた PDCursesをNuttXにポーティングされたものを利用しています。
このサンプルには、
charset, newdemo, testcurs, worm, firework, rain, tui, xmas
という8つのデモが含まれています。
10.3.1. ソースコードパス
このサンプルのソースコードは、 sdk/apps/examples/pdcurses
以下にあります。
また、PDCursesのポーティングされたソースコードは、 sdk/apps/graphics/pdcurs34
以下にあります。
10.3.2. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/pdcurses
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/pdcurses make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
10.3.3. 動作環境
このサンプルを動作させるには、以下のハードウェアを使う前提となっています。
Spresense Main Board
Spresense Extension Board
Arduino UNO LCD Connector board
ILI9341 2.2inch LCD
10.3.4. 動作確認
このサンプルには、PDCursesを使った複数のサンプルデモコマンドが用意されています。 シリアルターミナルを開いて、各コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
10.3.4.1. NuttShell から 各サンプルのコマンドを実行します。
-
charset
の実行charset
サンプルコマンドは、PDCursesで扱う文字をLCD画面中央に表示し終了します。nsh> charset
-
newdemo
の実行newdemo
サンプルコマンドは、PDCursesを使って様々なテキストウィンドウを表示したり、 文字を動かしたりします。このコマンドは一度実行すると終了せずに動きっぱなしになります。 別のサンプルコマンドを実行したい場合は、Spresemseメインボードのリセットボタンを押して再起動してください。nsh> newdemo
-
worm
の実行worm
サンプルコマンドは、赤、青、緑のワーム(ミミズの様なもの)がLCD上をうねうねします。 このコマンドは一度実行すると終了せずに動きっぱなしになります。 別のサンプルコマンドを実行したい場合は、Spresemseメインボードのリセットボタンを押して再起動してください。nsh> worm
-
firework
の実行firework
サンプルコマンドは、PDCursesを用いて花火の様なグラフィックを表示します。 このコマンドは一度実行すると終了せずに動きっぱなしになります。 別のサンプルコマンドを実行したい場合は、Spresemseメインボードのリセットボタンを押して再起動してください。nsh> firework
-
rain
の実行rain
サンプルコマンドは、PDCursesを用いて雨の雫が落ちた様なグラフィックを表示します。 このコマンドは一度実行すると終了せずに動きっぱなしになります。 別のサンプルコマンドを実行したい場合は、Spresemseメインボードのリセットボタンを押して再起動してください。nsh> rain
-
tui
の実行tui
サンプルコマンドは、PDCursesを用いてテキストベースのユーザインターフェイスを表示します。 このコマンドは一度実行すると終了せずに動きっぱなしになります。 別のサンプルコマンドを実行したい場合は、Spresemseメインボードのリセットボタンを押して再起動してください。nsh> tui
-
xmas
の実行xmas
サンプルコマンドは、PDCursesを用いクリスマスっぽいアニメーションを表示します。nsh> xmas
10.4. embedlog サンプルアプリケーション
この章では、NuttXの標準サンプルである、embedlogに関するサンプルアプリケーションの動作手順を示します。 このサンプルは、組み込み向けの非常に軽いオープンソースのログライブラリ、 embedlogを利用しています。
ビルド時にembedlogをwgetにてダウンロードされるため、wgetをインストールしておく必要があります。
10.4.1. ソースコードパス
このサンプルのソースコードは、 sdk/apps/examples/embedlog
以下にあります。
また、ダウンロードされるオープンソースembedlogは、 sdk/apps/system/embedlog
以下にダウンロードされます。
10.4.2. ビルド手順
CLI 版を使ったビルド手順について書かれていますが、IDE 版でも同様のコンフィグレーションを選択することにより本サンプルアプリケーションをビルドすることができます。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、コンフィグレーションツールのTab補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
コンフィグレーションとビルドを行います。
引数に
examples/embedlog
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。make distclean tools/config.py examples/embedlog make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして /dev/ttyUSB0 を、書き込み速度の baudrate として 500000 bps を設定しています。
tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
10.4.3. 動作確認
シリアルターミナルを開いて、embedlog コマンドを実行します。
-
シリアルターミナルを起動します。
以下は、minicom ターミナルを使用する例です。 シリアルポートとして /dev/ttyUSB0 を、baudrate として 115200 bps を設定しています。
minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
embedlog
コマンドを実行します。実行すると、以下の様に、サンプルコードの内容にしたがって、様々なフォーマットでのログ出力を確認することができます。
nsh> embedlog i/Right after init, embedlog will print to stderr with just log level information - these are default settings. We can disable information about log level message still will be filtered by log level but there is no way to tell what level message is [24] As every respected logger, we also have timestamps [24] which work well with time from time() [8] or CLOCK_MONOTONIC from POSIX [1970-01-01 00:00:24] we also have long format that works well with time() [1970-01-01 00:00:24] if higher precision is needed we can use CLOCK_REALTIME [24] we can also mix REALTIME with short format [24] and if you don't need high resolution [24] you can disable fractions of seconds to save space! [24.878] or enable only millisecond resolution [24.879011] or enable only microsecond resolution [24.879255804] or enable only nanosecond resolution (not that it makes much sense on nuttx) no time information, if your heart desire it [embedlog_main.c:134] log location is very useful for debugging [1970-01-01 00:00:24.880201831][embedlog_main.c:139] f/Different scenarios need different options [1970-01-01 00:00:24.880690103][embedlog_main.c:140] a/So we can mix options however we want [1970-01-01 00:00:24.888532972][embedlog_main.c:143] f/you can also remove printing new line to join el_oprint and el_oputs in a singld [1970-01-01 00:00:24.901472180][embedlog_main.c:150] d/And if we have [1970-01-01 00:00:24.909162464][embedlog_main.c:151] i/modern terminal [1970-01-01 00:00:24.916822231][embedlog_main.c:152] n/we can enable colors [1970-01-01 00:00:24.924543032][embedlog_main.c:153] w/to spot warnings [1970-01-01 00:00:24.929822473][embedlog_main.c:154] e/or errors [1970-01-01 00:00:24.937543274][embedlog_main.c:155] c/with a quick [1970-01-01 00:00:24.945203041][embedlog_main.c:156] a/glance into [1970-01-01 00:00:24.950482482][embedlog_main.c:157] f/log file [1970-01-01 00:00:24.958142249][embedlog_main.c:160] i/embedlog: you can also use prefixes [1970-01-01 00:00:24.965954601][embedlog_main.c:161] i/embedlog: to every message you send [1970-01-01 00:00:24.973766953][embedlog_main.c:164] i/set prefix to null to disable it [1970-01-01 00:00:24.984020665][embedlog_main.c:196] i/print whole ASCII table [1970-01-01 00:00:24.991802500][embedlog_main.c:197] i/0x0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................ [1970-01-01 00:00:25.002319292][embedlog_main.c:197] i/0x0010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................ [1970-01-01 00:00:25.015258500][embedlog_main.c:197] i/0x0020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !"#$%&'()*+,-./ [1970-01-01 00:00:25.028228225][embedlog_main.c:197] i/0x0030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>? [1970-01-01 00:00:25.038695556][embedlog_main.c:197] i/0x0040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO [1970-01-01 00:00:25.051604247][embedlog_main.c:197] i/0x0050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\]^_ [1970-01-01 00:00:25.064573972][embedlog_main.c:197] i/0x0060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno [1970-01-01 00:00:25.075041303][embedlog_main.c:197] i/0x0070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~. [1970-01-01 00:00:25.087888960][embedlog_main.c:199] i/print memory region that contains string with NULL chars [1970-01-01 00:00:25.098356291][embedlog_main.c:201] i/0x0000 73 6f 6d 65 20 6d 65 73 73 61 67 65 00 74 68 61 some message.tha [1970-01-01 00:00:25.111264982][embedlog_main.c:201] i/0x0010 74 20 63 6f 6e 74 61 69 6e 73 00 6e 75 6c 6c 20 t contains.null [1970-01-01 00:00:25.121701796][embedlog_main.c:201] i/0x0020 63 68 61 72 61 63 74 65 72 73 00 characters. [1970-01-01 00:00:25.134457902][embedlog_main.c:203] i/print the same region but this time with nice ascii table [1970-01-01 00:00:25.144772648][embedlog_main.c:205] i/------ ----------------------------------------------- ---------------- [1970-01-01 00:00:25.157620305][embedlog_main.c:205] i/offset hex ascii [1970-01-01 00:00:25.167935051][embedlog_main.c:205] i/------ ----------------------------------------------- ---------------- [1970-01-01 00:00:25.180874259][embedlog_main.c:205] i/0x0000 73 6f 6d 65 20 6d 65 73 73 61 67 65 00 74 68 61 some message.tha [1970-01-01 00:00:25.191341590][embedlog_main.c:205] i/0x0010 74 20 63 6f 6e 74 61 69 6e 73 00 6e 75 6c 6c 20 t contains.null [1970-01-01 00:00:25.204250281][embedlog_main.c:205] i/0x0020 63 68 61 72 61 63 74 65 72 73 00 characters. [1970-01-01 00:00:25.214595544][embedlog_main.c:205] i/------ ----------------------------------------------- ----------------
11. System tools 一覧
Spresense SDKでは、NuttShell から 各種 System tools を利用することができます。
カテゴリ | System tool名 | 説明 |
---|---|---|
LOG |
ログレベルを動的に変更します。 |
|
BackupSRAMに保存されたロギング情報をダンプします。 |
||
BackupSRAMに保存されたロギング情報をSPI-Flashに保存します。 |
||
GPIO |
||
GPIO割り込みを確認するためのテストコマンドです。 |
||
I2C |
I2Cデバイスとの通信を確認するためのユーティリティツールです。 |
|
PMIC |
||
USB |
||
Zmodem |
||
Stack |
Stack使用量をモニタするためのツールです。 |
|
Network |
12. GPIO ユーティリティツール
GPIO ユーティリティツールを利用して、各ピンの状態を確認したり、GPIO ピンへの入出力を設定することができます。
12.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
feature/gpiotool
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py feature/gpiotool make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
12.2. 動作確認
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
gpio
コマンドを実行します。コマンドオプションを以下に示します。nsh> gpio -h USAGE: gpio command stat [<from_pin>] [<end_pin>] conf <pin> [-m <0|1|2|3>] [-i] [-H] [-p <0|1|2|3>] -m: function mode -i: input enable -H: Higher drive current/slew rate -p: 0=float, 1=pullup, 2=pulldown, 3=buskeeper read <pin> write <pin> <0|1|-1>
gpio stat
コマンドにより、指定したピン番号の設定値を表示します。
gpio conf
コマンドにより、指定したピン番号の設定を変更することができます。
gpio read
コマンドにより、指定したピン番号の入力値を読み出します。
gpio write
コマンドにより、指定したピン番号へ出力値を書き込みます。
12.2.1. gpio stat コマンド
gpio stat
コマンドにより、デジタルピン一覧の状態を表示します。
引数で表示範囲を指定することもできます。
nsh> gpio stat 97 100 ------------------------------------------------------------- ( No)PIN NAME : Mode I/O mA Pull Read IRQ Type NF EN ------------------------------------------------------------- ( 97)PIN_I2S1_BCK : 0 / 2 -- 0 -1 ( 98)PIN_I2S1_LRCK : 0 / 2 -- 0 -1 ( 99)PIN_I2S1_DATA_IN : 0 / 2 -- 0 -1 (100)PIN_I2S1_DATA_OUT : 0 / 2 -- 0 -1
Mode
-
ピンの機能モードを表します。
Mode 0
は GPIO 機能、Mode 1~3
は I2C や UART といった GPIO 以外の機能・用途で使用されます。
各ピンはいくつかのグループに分けられており、Mode はグループ単位で設定されます。
ピンの詳細は、開発ガイド Pin specification を参照してください。 I/O
-
Input はピンの入力が許可されているかどうかを表します。
Output は GPIO モードに設定されたピンの出力が有効かどうかを表します。 mA
-
ドライブ電流 (2mA or 4mA) を表します。
Pull
-
--
:Float,PU
:Pull-Up,PD
:Pull-Down,BK
:Bus-Keeper を表します。 Read
-
読み出した値を表示します。
IRQ
-
GPIO 割り込み機能が設定されている場合、IRQ 番号を表します。
Type
-
GPIO 割り込み機能が設定されている場合、極性を表します。
(High
:レベル,Low
:レベル,Rise
:立ち上がりエッジ,Fall
:立ち下がりエッジ,Both
:両エッジ) NF
-
GPIO 割り込み機能が設定されている場合、チャタリング防止用のノイズフィルタの有効/無効を表します。
EN
-
GPIO 割り込み機能が設定されている場合、割り込みの許可/禁止を表します。
12.2.2. gpio conf コマンド
gpio conf
コマンドは、指定したピン番号に対して、機能モードや入出力設定を変更することができます。
例えば PIN_SEN_IRQ_IN
(37番) ピンを GPIO モードの入力ピン、Pull-Downに設定する場合、gpio conf 37 -m 0 -i -p 2
と入力します。
nsh> gpio conf 37 -m 0 -i -p 2 nsh> gpio stat 37 ------------------------------------------------------------- ( No)PIN NAME : Mode I/O mA Pull Read IRQ Type NF EN ------------------------------------------------------------- ( 37)PIN_SEN_IRQ_IN : 0 I/ 2 PD 0 -1
12.3. プログラミング
12.3.1. GPIO API
GPIO の API の詳細については APIリファレンスマニュアル を参照してください。
GPIO API を使用する場合は、以下のファイルを include してください。
#include <arch/board/board.h>
#include <arch/chip/pin.h>
GPIO API のプロトタイプ宣言はこちらに定義されています
nuttx/boards/arm/cxd56xx/spresense/include/cxd56_gpioif.h
GPIO API で使用するピン名はこちらに定義されています
nuttx/arch/arm/include/cxd56xx/pin.h
12.3.2. GPIO 入力設定
GPIO 入力ピンとして設定してポートの読み出しを行う場合は次のように行います。
/* 入力ピン設定 */
board_gpio_config(PIN_XXX, 0, true, false, PIN_FLOAT); (1)
board_gpio_config(PIN_XXX, 0, true, false, PIN_PULLUP); (2)
board_gpio_config(PIN_XXX, 0, true, false, PIN_PULLDOWN); (3)
board_gpio_config(PIN_XXX, 0, true, false, PIN_BUSKEEPER); (4)
/* ポート入力 */
int status = board_gpio_read(PIN_XXX); (5)
1 | PIN_XXX の入力を許可します。 |
2 | PIN_XXX をPull-Upに設定し入力を許可します。 |
3 | PIN_XXX をPull-Downに設定し入力を許可します。 |
4 | PIN_XXX をBus-Keeperに設定し入力を許可します。 |
5 | PIN_XXX の入力値を読み出します。 |
12.3.3. GPIO 出力設定
GPIO 出力ピンとして設定してポートの書き込みを行う場合は次のように行います。
/* 出力ピン設定 */
board_gpio_config(PIN_XXX, 0, false, true, PIN_FLOAT); (1)
board_gpio_config(PIN_XXX, 0, false, false, PIN_FLOAT); (2)
/* ポート出力 */
board_gpio_write(PIN_XXX, 0); (3)
board_gpio_write(PIN_XXX, 1); (4)
board_gpio_write(PIN_XXX, -1); (5)
1 | PIN_XXX の入力を禁止し、ドライブ電流を4mAに設定します。 |
2 | PIN_XXX の入力を禁止し、ドライブ電流を2mAに設定します。 |
3 | PIN_XXX へ LOW を出力します。 |
4 | PIN_XXX へ HIGH を出力します。 |
5 | PIN_XXX の出力を禁止にします。 |
12.3.4. GPIO 割り込み設定
GPIO 割り込みを使用する場合は次のように行います。
static int gpio_handler(int irq, FAR void *context, FAR void *arg)
{
/* 割り込みハンドラ */
}
/* 割り込み設定 */
board_gpio_intconfig(PIN_XXX, INT_HIGH_LEVEL, false, gpio_handler); (1)
board_gpio_intconfig(PIN_XXX, INT_LOW_LEVEL, false, gpio_handler); (2)
board_gpio_intconfig(PIN_XXX, INT_RISING_EDGE, true, gpio_handler); (3)
board_gpio_intconfig(PIN_XXX, INT_FALLING_EDGE, true, gpio_handler); (4)
board_gpio_intconfig(PIN_XXX, INT_BOTH_EDGE, true, gpio_handler); (5)
board_gpio_int(PIN_XXX, false); (6)
board_gpio_int(PIN_XXX, true); (7)
1 | PIN_XXX を HIGH レベル割り込みを設定し、割り込みハンドラを登録します。 |
2 | PIN_XXX を LOW レベル割り込みを設定、割り込みハンドラを登録します。 |
3 | PIN_XXX を立ち上がりエッジ割り込みを設定し、割り込みハンドラを登録します。ノイズフィルタを有効にしています。 |
4 | PIN_XXX を立ち下がりエッジ割り込みを設定し、割り込みハンドラを登録します。ノイズフィルタを有効にしています。 |
5 | PIN_XXX を両エッジ割り込みを設定し、割り込みハンドラを登録します。ノイズフィルタを有効にしています。 |
6 | PIN_XXX の割り込みを禁止します。 |
7 | PIN_XXX の割り込みを許可します。 |
13. PMIC ユーティリティツール
PMIC ユーティリティツールを利用して、PMIC(CXD5247) に接続されたロードスイッチやGPO出力を設定することができます。
13.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
feature/pmictool
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py feature/pmictool make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
13.2. 動作確認
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
pmic
コマンドを実行します。コマンドオプションを以下に示します。nsh> pmic -h Usage: pmic [-h] [-l] [-e <target>] [-d <target>] [-r <addr>] [-w <addr> -v <value>] Description: PMIC utility tool Options: -l: Show power status of the target -e <target>: Enable power to the target -d <target>: Disable power to the target -z <target>: Set GPO to HiZ to the target -r <addr>: Single read from <addr> -w <addr> -v <value>: Single write <value> to <addr> -h: Show this message
pmic -l
オプションにより、一覧を表示します。nsh> pmic -l Target Name : on/off ----------- : ------ DDC_IO : on LDO_EMMC : on DDC_ANA : off LDO_ANA : on DDC_CORE : on LDO_PERI : off LSW2 : off LSW3 : on LSW4 : on GPO0 : hiz GPO1 : off GPO2 : off GPO3 : off GPO4 : off GPO5 : off GPO6 : off GPO7 : off
pmic -e GPO0
と入力すると GPO0 を Enable に設定します。
pmic -d GPO0
と入力すると GPO0 を Disable に設定します。
pmic -z GPO0
と入力すると GPO0 を Hi-Z に設定します。
13.3. 接続先
ロードスイッチ(LSW) や GPO は主に各種電源コントロールに使用されています。
メインボードや拡張ボードでの接続先についての一覧を表示します。
DDC_CORE, DDC_IO, LDO_ANA についてはそれぞれプロセッサの CORE 電源, IO 電源, アナログ電源に接続されているため、Disable しないでください。 また、LDO_PERI についてはボード上、未接続のため記載を省略しています。 |
Target | 出力電圧 | メインボード | 拡張ボード | LTE 拡張ボード |
---|---|---|---|---|
LDO_EMMC |
3.3V |
ソケット3.3V出力 |
- |
- |
LSW2 |
1.8V |
Audio DVDD |
- |
- |
LSW3 |
SPI-Flash |
- |
- |
|
LSW4 |
TCXO 26MHz |
- |
- |
|
GPO0 |
VSYS(4.0V) |
- |
- |
3.3V LDO |
GPO1 |
- |
Audio 3.3V LDO |
||
GPO2 |
- |
- |
LTE DCDC |
|
GPO3 |
- |
- |
(LTE VBAT) |
|
GPO4 |
Camera LDO |
- |
- |
|
GPO5 |
- |
- |
- |
|
GPO6 |
- |
Audio Headphone Amp. |
||
GPO7 |
- |
- |
- |
13.4. プログラミング
13.4.1. PMIC API
PMIC 制御 API を使用する場合は、以下のファイルを include してください。
#include <arch/board/board.h>
PMIC API のプロトタイプ宣言はこちらに定義されています
nuttx/boards/arm/cxd56xx/spresense/include/cxd56_power.h
PMIC API で使用するターゲット名はボード依存ファイルの中で POWER_LTE
のようなエイリアス名が定義されています
nuttx/boards/arm/cxd56xx/spresense/include/board.h
13.4.2. GPO 出力設定
GPO 出力ピンに書き込みを行う場合は次のように行います。
ON/OFF する場合は、board_power_control(), board_power_control_tristate() のどちらを使用しても構いません。
HiZ へ設定する場合は、board_power_control_tristate() 関数を使用してください。
/* GPOポート出力 */
board_power_control(PMIC_GPO(0), true); (1)
board_power_control(PMIC_GPO(0), false); (2)
board_power_control_tristate(PMIC_GPO(0), 1); (3)
board_power_control_tristate(PMIC_GPO(0), 0); (4)
board_power_control_tristate(PMIC_GPO(0), -1); (5)
1 | GPO0 を Enable します。 |
2 | GPO0 を Disable します。 |
3 | GPO0 を Enable します。 |
4 | GPO0 を Disable します。 |
5 | GPO0 を HiZ へ設定します。 |
13.4.3. GPO 出力モニタ
GPO 出力ピンの状態を読み出す場合は次のように行います。
ON/OFF を読み出す場合は、board_power_monitor(), board_power_monitor_tristate() のどちらを使用しても構いません。
HiZ 状態も読み出す場合は、board_power_monitor_tristate() 関数を使用してください。
/* GPOポート出力モニタ */
bool bstate = board_power_monitor(PMIC_GPO(0)); (1)
int istate = board_power_monitor_tristate(PMIC_GPO(0)); (2)
1 | GPO0 の設定値を読み出します。true のときは Enable、false のときは Disable です。 |
2 | GPO0 の設定値を読み出します。1 のときは Enable、0 のときは Disable、-1 のときは Hi-Z です。 |
14. USB MSC 機能を使う
USB MSC (Mass Storage Class) 機能を使うためのユーティリティコマンドについて説明します。
USB MSC 機能を有効にするとホスト PC からSpresense ボード上の SD カードへ直接アクセスすることができます。
14.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
feature/usbmsc
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py feature/usbmsc make
SD カードを USB MSC としてマウントするので SD カード機能も有効化しています。
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
14.2. 動作確認
拡張ボードに SD カードが挿入されている状態で、拡張ボードの USB 端子とホスト PC とを USB ケーブルで接続します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
USB MSC 機能を開始する場合、NuttShell から
msconn
コマンドを実行します。nsh> msconn mcsonn_main: Creating block drivers mcsonn_main: Configuring with NLUNS=1 mcsonn_main: handle=d038d50 mcsonn_main: Bind LUN=0 to /dev/mmcsd0 mcsonn_main: Connected
ホスト PC に新たなリムーバブルディスクが認識され、 ホスト PC から拡張ボードの SD カードの内容にアクセスすることができます。
-
USB MSC 機能を終了する場合、NuttShell から
msdis
コマンドを実行します。nsh> msdis msdis: Disconnected
15. USB CDC/ACM 機能を使う
USB CDC/ACM 機能を使うためのユーティリティコマンドについて説明します。
USB CDC/ACM 機能を有効にすると拡張ボードの USB をシリアルポートとして使用することができます。
15.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
feature/usbcdcacm
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py feature/usbcdcacm make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
15.2. 動作確認
拡張ボードの USB 端子とホスト PC とを USB ケーブルで接続します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
USB CDC/ACM 機能を開始する場合、NuttShell から
sercon
コマンドを実行します。nsh> sercon sercon: Registering CDC/ACM serial driver sercon: Successfully registered the CDC/ACM serial driver
Spresense ボード上に
/dev/ttyACM0
が追加され、ホスト PC には新たな COM ポートが見つかります。 そのポートを使って、USB 経由でシリアル通信をすることができるようになります。 -
USB CDC/ACM 機能を終了する場合、NuttShell から
serdis
コマンドを実行します。nsh> serdis serdis: Disconnected
16. Zmodem を使ったファイル転送
この章では、Zmodem 転送を利用して HostPC と Spresense ボードとの間でファイルを送受信する方法について示します。
16.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
feature/zmodem
を指定してコンフィグレーションを実行します。
ビルドに成功するとsdk
フォルダ直下にnuttx.spk
ファイルが生成されます。tools/config.py feature/zmodem make
-
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
16.2. 動作手順
Zmodem 転送機能に対応したシリアルターミナルを使用してください。
ここでは、minicom を例にとって説明します。
minicom や lrzsz がインストールされていない場合は事前にインストールしてください。
sudo apt install minicom lrzsz
minicom を起動します。
minicom -D /dev/ttyUSB0 -b 115200
NuttShell から Zmodem の rz (受信), sz (送信) コマンドを使用することができます。
- rz コマンドの使い方
-
- sz コマンドの使い方
-
16.2.1. HostPC から Spresense ボードへのファイル転送
HostPC から Spresense ボードへファイルを転送する手順を以下に示します。
-
minicom 上で
CTRL-a
を押下した後にz
キーを押してメニューを開きます。(このショートカットキーの割り当てはユーザー側で変更可能です。詳細は minicom のマニュアルを参照してください。)
続けてs
キーを押して Send files (ファイル送信) を選択します。 -
カーソルキーで zmodem を選択して
Enter
キーで実行します。 -
カーソルキーとスペースキーでフォルダを移動をして転送したいファイルを選択します。
カーソルキーでフォルダを選びスペースキーを2回押すとフォルダへ移動できます。
カーソルキーでファイルを選びスペースキーで選択した後にEnter
キーを押すと転送を開始します。もしくは、
Enter
キーを押してファイル名を入力して転送を実行することもできます。 -
ファイル転送が始まり、Transfer complete と表示されれば転送完了です。
-
Spresense ボード上のファイルの転送先は、CONFIG_SYSTEM_ZMODEM_MOUNTPOINT で変更することができます。
デフォルトのコンフィギュレーションでは、Flash 上の/mnt/spif
以下にファイルが転送されます。
TeraTerm を使用する場合は、TeraTerm メニューから ファイル → 転送 → ZMODEM → 送信 から選択したファイルを送信することができます。
|
16.2.2. Spresense ボードから HostPC へのファイル転送
Spresense ボードから HostPC へファイルを転送する手順を以下に示します。
-
NuttShell 上で、
sz
コマンドの引数に転送したいファイルを指定して実行します。
ファイル名は / から始まるフルパス名を入力してください。
以下の例は、-x 1
バイナリ転送オプションを付けています。nsh> sz -x 1 /mnt/spif/test00.dat
-
ファイル転送が始まり、Transfer complete と表示されれば転送完了です。
-
HostPC 上の minicom を実行したフォルダにファイルが転送されます。
TeraTerm を使用する場合は、NuttShell から sz コマンドを入力した後に、ファイル → 転送 → ZMODEM → 受信 によりファイルを受信することができます。HostPC 側のファイル受信ディレクトリは、ファイル → ディレクトリを変更 によって指定可能です。
|
17. アプリケーションの自動起動方法
この章では、電源投入時に NuttShell プロンプトではなくユーザーアプリケーションを自動的に起動する方法について記述します。 NuttShellでは、簡単なシェルスクリプトを実行することが出来、かつ、特定のスクリプトを起動時に実行する機能を持っています。 この章では、その機能を用いた、自動起動について解説します。
NuttShell 上で利用できる基本的なコマンドや、if, whileといった制御構文については、 NuttShell (NSH) documentation を参照してください。
17.1. Spresense SDK でのスタートアップスクリプトの使い方
NuttX で自動起動スクリプトを利用するには、コンフィグでその機能を有効にする必要があります。 Spresense SDK では、自動起動を有効にするためのデフォルトとなるコンフィグを提供しています。
この章での例としては、"hello" ビルドインコマンドを自動起動スクリプトを使って、 起動後、3秒おきにhelloを表示させるスクリプトを作成してみます。
17.1.1. コンフィグレーション
まずは、今回の例で使用する "hello" ビルドインコマンドと、自動起動を有効にするデフォルトコンフィグを使って、
SDKのコンフィグを行います。
spresense/sdk ディレクトリに移動して、以下のようにconfig.pyに2つのパラメータを指定してを実行してください。
./tools/config.py examples/hello feature/startup_script
一つ目のパラメータ examples/hello は "hello" ビルドインコマンドを有効にするオプションで、2つ目のパラメータ feature/startup_script は、自動起動の仕組みを有効にするオプションになります。
このように、Spresense SDK の config.py では、オプションに色々と追加していくことでSDKとして用意しているデフォルトコンフィグを追加していく、ということが出来るようになっています。 |
17.1.2. ビルドとフラッシュ
コンフィグが完了したら、同じ spresense/sdk ディレクトリ下で、以下のコマンドを実行して nuttx.spk を実機に書き込みます。
make tools/flash.sh -c /dev/ttyUSB0 nuttx.spk >>> Install files ... install -b 115200 Install nuttx.spk |0%-----------------------------50%------------------------------100%| ###################################################################### xxxxx bytes loaded. Package validation is OK. Saving package to "nuttx" updater# sync updater# Restarting the board ... reboot
17.1.3. 動作確認(自動起動なし)
nuttx.spk を書き込んだだけでは、自動的に起動することはありません。 ここでは、まずは書き込んだ nuttx.spk が正しく "hello" ビルドインコマンドを含んでいるか、 確認してみます。 まず、適当なターミナルソフト(以下の例は minicom を使用しています)を使って、実機のUARTポートに接続します。この例では、実機のポートは、 /dev/ttyUSB0 としていますが、お使いの環境に合わせて設定してください。
minicom -D /dev/ttyUSB0 -b 115200
実機に接続すると、以下のメッセージが出て、 nsh> プロンプトが表示されます。
No /mnt/spif/init.rc. NuttShell (NSH) NuttX-8.2 nsh>
ターミナルによっては、接続時にボードにリセットをかけないものもあるようです。上記のメッセージはリセット直後に表示されるものなので、表示されないような場合は、ターミナルは接続したまま、Spresenseボードのリセットを押してみてください。 |
この状態で "help" と叩くと以下のように Builtin Apps: の中に hello があることが確認できます。
nsh> help help usage: help [-v] [<cmd>] [ dirname free mb mv set unset ? date help mkdir mw sh usleep basename dd hexdump mkfatfs poweroff sleep xd break df ifconfig mkfifo ps test cat echo ifdown mkrd pwd time cd exec ifup mksmartfs reboot true cp exit kill mh rm uname cmp false ls mount rmdir umount Builtin Apps: hello nsh nsh>
ここで、 hello を実行して、動作を確認します。
nsh> hello Hello, World!! nsh>
これで、 hello が動作することは確認できました。 次に、これを3秒おきに実行するスクリプトを作成して、実機で動作させます。
17.1.4. 動作確認(自動起動)
前の節で hello の動作を確認したら、一度ターミナルから抜け、スクリプトファイルを作成します。
スクリプトファイル名は、 init.rc としてください。 以下のようなスクリプトを作成します。
-
init.rc
while true do sleep 3 hello done
シンプルなスクリプトですが、 while true で無限ループを作り、 sleep 3 で3秒待ち、 hello を実行する、というのを延々と繰り返すスクリプトになります。
このスクリプトをSpresenseメインボードのSPIフラッシュに書き込みます。 init.rc が spresense/sdk ディレクトリ内にあるとして、spresense/sdk ディレクトリ内で、以下のようなコマンドを実行してください。
./tools/flash.sh -w init.rc xmodem >>> Install files ... nsh> xmodem /mnt/spif/init.rc Install init.rc |0%-----------------------------50%------------------------------100%| ###################################################################### nsh>
flash.sh は、 -w オプションを指摘することで、その後の引数で指定されたファイルを、実機のSPIフラッシュに書き込みを行います。
flash.shを -w で実行すると、nuttx.spk を再度書き込む必要が出てきます。 すでにビルド済みの nuttx.spk が spresense/sdk にあるので、それを再度書き込みます。
tools/flash.sh -c /dev/ttyUSB0 nuttx.spk >>> Install files ... install -b 115200 Install nuttx.spk |0%-----------------------------50%------------------------------100%| ###################################################################### xxxxx bytes loaded. Package validation is OK. Saving package to "nuttx" updater# sync updater# Restarting the board ... reboot
この状態で再度ターミナルに接続してみます。
Run /mnt/spif/init.rc. sh [8:100] NuttShell (NSH) NuttX-8.2 nsh> Hello, World!! Hello, World!! Hello, World!! Hello, World!! Hello, World!!
繋ぐと、3秒おきに、意図した通り、 "Hello, World!!" というメッセージが表示されることが確認できます。
17.2. TIPS: Application エントリーポイント
スタートアップスクリプトとは別に CONFIG_USER_ENTRYPOINT を変更するという方法もあります。
デフォルトのコンフィギュレーションでは、CONFIG_USER_ENTRYPOINT=spresense_main となっています。
これを例えば hello_main に変更すると、起動時に hello アプリケーションを起動するように変更できます。

エントリーポイントの関数名は、サンプルコードのMakefileで定義している PROGNAME 変数に入っている文字列に、_main を付けたものになります。例:spresense/sdk/apps/examples/hello/Makefileに、PROGNAMEの定義が $(CONFIG_EXAMPLES_HELLO_PROGNAME) となっています。これは、Kconfigのパラメータで名前が確定しており、spresense/sdk/apps/examples/Kconfigを見ると、config EXAMPLES_HELLO_PROGNAME の欄に、default "hello" と記載されています。この場合、PROGNAMEがhelloとなるため、 "hello_main"がエントリー関数名となります。 |
起動時にアプリケーションの初期化処理が必要です。以下を参考に、#include <sys/boardctl.h> を追加し、ユーザーエントリーポイント関数の中から boardctl(BOARDIOC_INIT, 0); を呼び出してください。 |
#include <sys/boardctl.h>
int main(int argc, FAR char *argv[])
{
/* Initialize apllication */
boardctl(BOARDIOC_INIT, 0);
printf("Hello, World!!\n");
return 0;
}
18. ローダブルELFチュートリアル
ローダブルELFとは、OSとアプリケーションを別々のバイナリで作成し、動作時にアプリケーションをロードして実行できる機能です。
アプリケーションをローダブルELFとして作成すると、必要に応じてメモリにロードすることが可能になるため、実行時の総メモリ量を抑えたり、アプリケーションを単独で更新することができるようになります。ただし、アプリケーションの起動時間が伸びたり、ロード/アンロードを繰り返す事によるメモリの断片化が発生する可能性もあるため注意が必要です。
ASMP ELFとの互換性はありません。起動するアプリケーションはメインコアでのみ実行されます。 |
このチュートリアルでは、アプリケーションのELFファイルの格納場所にSDカードを使用します。
18.1. ビルド手順
ここではコマンドラインによるビルド手順を示します。
IDE を使用してビルドする場合、以下に示すコンフィグレーション情報を参考にしてください。
-
sdk
ディレクトリへ移動します。build-env.sh
スクリプトを読み込むことで、config.py
ツールの Tab 補完機能が有効になります。cd spresense/sdk source tools/build-env.sh
-
SDK のコンフィグレーションとビルドを行います。
引数に
feature/loadable
device/sdcard
を指定してコンフィグレーションを実行します。tools/config.py feature/loadable device/sdcard tools/config.py -m
メニューコンフィグを開き、
Hello, World! example
を有効にします。この時、Hello, World! example
がM
となるように設定するとそのアプリケーションがローダブルELFとしてビルドされます。[Application Configuration] [Examples] ["Hello, World!" example] => M
コンフィグレーションが完了したらビルドします。
make
ビルドに成功すると
sdk
フォルダ直下にnuttx.spk
ファイルが、sdk/apps/bin
以下に ELFファイルhello
がそれぞれ生成されます。hello
は別途SDカードにコピーしてください。 -
nuttx.spk
を Spresense ボードへ書き込みます。この例では シリアルポートとして
/dev/ttyUSB0
を、書き込み速度の baudrate に500000
bps を設定しています。お使いの環境に合わせて変更してください。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
18.2. 動作確認
シリアルターミナルを開いて、hello
アプリケーションを実行します。
-
シリアルターミナルを起動します。
シリアルポートに
/dev/ttyUSB0
を、baudrate に115200
bps を指定して、 minicom ターミナルを使用する例を示します。minicom -D /dev/ttyUSB0 -b 115200
-
NuttShell から
hello
アプリケーションを実行します。SDカードにある
hello
ELFファイルまでのフルパスを指定します。nsh> /mnt/sd0/hello Hello, World!!
18.3. PATH変数を使用する
NuttShellでは、bashの環境変数と同様 PATH
変数を用いてELFファイルを検索するパスの設定ができます。 feature/loadable
にはこれを使用するための設定が含まれていますが、実際に使用するパスはユーザー自身で設定する必要があります。
メニューコンフィグを開いて PATH
変数にSDカードのパスを設定します。この設定を行うことでSDカードの直下に置かれているアプリケーションはフルパスを指定しなくても実行することができるようになります。
[Binary Loader] [Initial PATH Value] => "/mnt/sd0"
ビルドして nuttx.spk
を書き込んでください。起動後、NuttShellから hello
とタイプするだけでSDカード上の hello
アプリケーションを起動することができるようになります。
nsh> hello Hello, World!!