STM32でNUTTXを使ってみる

オンボードLEDの利用


Nuttxの周辺機器のサポートは非常に限定的、かつボードに依存しています。
例えばF4 Discoveryで利用できる周辺機器については、こちらに記載が有りますが、非常に分かりにくいです。
$HOME/nuttxspace/nuttx/boards/arm/stm32/stm32f4discovery/README.txt

ソースを直接見た方が分かりやすいです。
F4 Discoveryの周辺機器の初期化は以下のコードです。
$HOME/nuttxspace/nuttx/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c

他のボードの初期化も同様の場所にあります。
$HOME/nuttxspace/nuttx/boards/arm/stm32/ボード名/src/xxx_bringup.c

このコードを見るとどのような周辺機器をサポートしているかわかります。
そこで、一例としてUSERLEDを有効にする手順を紹介します。
ソースを見ると以下でLED driver(/dev/userleds)の登録を行っています。
#ifdef CONFIG_USERLED
  /* Register the LED driver */

  ret = userled_lower_initialize("/dev/userleds");
  if (ret < 0)
    {
      syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret);
    }
#endif

そこで、メニューでCONFIG_USERLED変数を有効にしますが、メニューに表示される名前と
変数名は全然一致していません。
こ ちらに 変数名一覧が公開されていますが、これを検索して変数名からメニュー名を調べる必要が有ります。

1.5.187.1 CONFIG_USERLED: LED driver

メニューでLED driverを有効にします。






ここでmakeすると以下のエラーとなります。

stm32_bringup.c: In function 'stm32_bringup':
stm32_bringup.c:251:9: warning: implicit declaration of function 'userled_lower_initialize' [-Wimplicit-function-declaration]
   ret = userled_lower_initialize("/dev/userleds");

ここからはソースと格闘することになります。
userled_lower_initialize関数は以下に定義されています。
$HOME/nuttxspace/nuttx/drivers/leds/userled_lower.c

ソースを見ると
#ifdef CONFIG_USERLED_LOWER

(中略)

int userled_lower_initialize(FAR const char *devname)
{
  g_lednum = board_userled_initialize();
  return userled_register(devname, &g_userled_lower);
}

#endif /* CONFIG_USERLED_LOWER */

となっています。
そこで、またこ ちらか らCONFIG_USERLED_LOWER変数のメニュー名を調べます。

1.5.187.2 CONFIG_USERLED_LOWER: Generic Lower Half LED Driver

以下のメニューでGeneric Lower Half LED Driveを有効にします。


makeすると以下のエラーとなります。

ake[2]: ディレクトリ '/home/nop/NuttX/nuttx/configs/stm32f4discovery/src' から 出ます
LD: nuttx
/home/nop/NuttX/nuttx/staging/libdrivers.a(userled_lower.o): In function `userled_lower_initialize':
userled_lower.c:(.text+0x16): undefined reference to `board_userled_initialize'
/home/nop/NuttX/nuttx/staging/libdrivers.a(userled_lower.o): In function `userled_ledset':
userled_lower.c:(.text+0x6): undefined reference to `board_userled_all'
/home/nop/NuttX/nuttx/staging/libdrivers.a(userled_lower.o): In function `userled_led':
userled_lower.c:(.text+0xe): undefined reference to `board_userled'
Makefile:202: recipe for target 'nuttx' failed

board_userled関数は以下に定義されています。
$HOME/nuttxspace/nuttx/boards/arm/stm32/stm32f4discovery/src/stm32_userleds.c

ソースを見ると
#ifdef CONFIG_ARCH_LEDS

(中略)

void board_userled(int led, bool ledon)
{
  if ((unsigned)led < BOARD_NLEDS)
    {
      stm32_gpiowrite(g_ledcfg[led], ledon);
    }
}

(中略)
#endif /* CONFIG_ARCH_LEDS */

となっています。
そこで、またこ ちらか らCONFIG_ARCH_LEDS変数のメニュー名を調べます。

1.3.3 CONFIG_ARCH_LEDS: Board LED Status support

以下のメニューでBoard LED Status supportを無効にします。


これでよくやくmakeが通ります。
カーネルをビルドして、ビルドしたカーネルを書き込むと、/dev/userledsのデバイスが出現します。





今度は$HOME/nuttxspace/apps/examplesディレクトリで[userleds]を使っているアプリを探します。
examples/ledsがこのデバイスを利用するアプリです。
examples/leds/Kconfigでメニュー名を確認します。

config EXAMPLES_LEDS
        tristate "LED driver example"
        default n
        depends on ARCH_HAVE_LEDS && !ARCH_LEDS
        ---help---
                Enable the LED driversexample

LED driver exampleがメニュー名です。


カーネルをビルドすると以下のアプリが追加されます。


このアプリを実行するとオンボードの4つのLEDが順番に点灯します。


続く...