SPRESENSE SDKでArduinoを使わずにとりあえずLチカする

SPRESENSE SDKでArduinoを使わずにとりあえずLチカする

概要

Arduino IDEとかいうぬるま湯に浸かりたくない人や,SPRESENSE SDKを使って自作のアプリケーションをCやC++で書いてみたい人向けの記事です. Arduino信者はお帰りください.

今回は,最も基本的な例としてLチカとシェルへの文字列の出力を扱います.

この記事では,SDKのインストールができているという前提で進めます.
参考→ SPRESENSE SDKをArch Linuxにセットアップする

準備

一旦適当なサンプルをビルドして手順を確認します. すでにSPRESENSE SDKで何かを試している場合は一旦設定を退避させておいてください. 以下のコマンドのうち make distclean でNuttXカーネルとアプリケーションの設定が消えるので注意してください.

$ cd /path/to/spresense/sdk
$ make distclean
$ tools/config.py --kernel release
$ tools/config.py examples/hello
$ make buildkernel
$ make

これによって,Hello WorldのサンプルアプリケーションがNuttXのコマンドとして追加されます.

nsh> help
help usage: help [-v] [<cmd>]

[ date help mh rmdir umount
? dd hexdump mount set unset
basename df kill mv sh usleep
break echo ls mw shutdown xd
cat printf mb poweroff sleep
cd exec mkdir ps test
cp exit mkfatfs pwd time
cmp false mkrd reboot true
dirname free mksmartfs rm uname

Builtin Apps:
hello
nsh> hello
Hello, World!!
nsh>

NuttXへのアプリケーションディレクトリの登録

NuttXは通常,自分でアプリケーションを書こうとするといろいろと面倒な設定が必要なのですが,SPRESENSEには便利なツールが用意されています.

9.3. ツールを使用する: Spresense SDK デベロッパーガイド - Spresense - Sony Developer World

sdkと同じ階層に myapps というディレクトリを作成し,その中に test_gpio というアプリケーションを作成します. 以下のコマンドでこの操作ができます(クォートで囲まれている説明文は適宜自由に設定してください).

$ tools/mkappsdir.py myapps 'My Apps'
$ tools/mkcmd.py -d myapps test_gpio 'Test LED App'

どのアプリケーションをビルドするかはmenuconfigで設定できます.

$ make menuconfig

矢印キーで選択,Enterで下の階層に入り,Escを2回押して上の階層に戻れます.スペースでチェックを付け外します.

'My Apps’から’Test LED App’にチェックを入れます. 早速ビルドしてみましょう.

$ make

nuttx.spk ができたら準備は完了です.

設定の保存

設定を保存して再度config.pyから利用できるようにするには,以下のツールを使用すると楽です.

$ tools/mkdefconfig.py myconfig

myconfig の部分は好きな名前に変えてください.

GPIOを操作するコードを書く

先ほど作成した test_gpio アプリケーションの中身を書いていきます. ファイルはsdkと同じ階層のmyapps/test_gpioの中にあります.

#include <sdk/config.h>
#include <stdio.h>

#include <arch/board/board.h>
#include <arch/chip/pin.h>

#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int test_gpio_main(int argc, char *argv[])
#endif
{
    board_gpio_config(97, 0, false, true, 0);
    printf("Hello, GPIO!\n");

    for(int i=0; i<10; i++){
        board_gpio_write(97, 1);
        usleep(1000*1000);
        board_gpio_write(97, 0);
        usleep(1000*1000);
    }
    return 0;
}

GPIO関係のAPIは,SDKの中の bsp/board/common/src/cxd56_gpioif.c の中にあります[1]. その他のペリフェラルについても同じディレクトリの中に出揃っているので,Doxygenで生成されたドキュメントを読むのに疲れた際にはこちらを参照すると良いと思います.

さて,CXD56のGPIOには「モード」があり,GPIOとしてピンを使用するかペリフェラルの機能を持ったピンとして使用するかが選択できます. それとは別に,入力ピンとして使用するか,ドライブ電流を大きくするか,プルアップ/ダウンをどうするか等が選択できます.

上記のコードの中で使用している board_gpio_config 関数は以下のような書式になっています.

board_gpio_config(/*ピン番号*/, /*モード*/, /*入力ピン:true*/, /*ドライブ電流大:true*/, /*プルアップ/ダウン設定*/);

ピン番号(の名前)についてはこちらから確認できます.

LED1に相当するピンは I2S1_BCK で,この定数は bsp/include/arch/chip/pin.h の中に 97 と定義されています[2]

NuttXはPOSIX互換ですので,usleep を使用してディレイを実現できます. ハードウェアタイマーを使用して正確なタイミングを生成する方法は,また後日書ければ書きます.

実行する

ビルドして書き込みます.

$ make
$ config/flash.sh -c /dev/ttyUSB0 nuttx.spk

picocomやminicomでコンソールを開いて,nsh上でビルドしたコマンドを実行します.

nsh> test_gpio
Hello, GPIO!

メッセージが表示されるとともに,LEDの点灯状態が1秒ごとに切り替わります.

NuttXではコマンドをバックグラウンドで実行できます.

nsh> test_gpio &

とすることで,実行中にもnshを使用することができます.

まとめ

  • 付属ツールで自作アプリケーション用のディレクトリを作成することがおすすめ
  • ペリフェラル関係のファイルは bsp/board/... の中にある
  • POSIX互換である利点を活かしながらコーディングができる

  1. BSP: Board Support Package

  2. この番号ぐらいはドキュメンテーションに書いてほしいなと思います…

Share Comments