いよいよ BeagleBoneBlack の I/O 制御にとりかかります.手始めとして,まずはボード上の 4つの LED(USR0 ~ USR3)チカチカを試してみます.

WS000269

マニュアル操作で LED チカチカ

まずはマニュアルでボード上の4つのLED制御をためしてみます.
LED制御は,Debian OS 上で /sys/class/leds 以下にある,各 LED に対応したデバイスファイルに適宜書き込みをすることで下記のようにして操作します.
まず,デフォルトではこれらの LED は内部のプログラムから制御されてピカピカしているのでこれを止めます.tirgger ファイルに none を指定することですべての LED が消灯します.

# echo none > /sys/class/leds/beaglebone\:green\:usr0/trigger
# echo none > /sys/class/leds/beaglebone\:green\:usr1/trigger
# echo none > /sys/class/leds/beaglebone\:green\:usr2/trigger
# echo none > /sys/class/leds/beaglebone\:green\:usr3/trigger

次に,brightness ファイルに,LED を点灯させる場合は  1 , 消灯させる場合は 0 を書込みます.

// 点灯
# echo 1 > /sys/class/leds/beaglebone\:green\:usr0/brightness
// 消灯
# echo 0 > /sys/class/leds/beaglebone\:green\:usr0/brightness

Bone Script で LED チカチカ

cloud9

LED の制御方法がわかったので,ここからプログラムを組んで LED チカチカにとりかかります.まずは Bone Script を使った簡単操作方法を試します.
BeagleBoneBlackでは,BoneScript という仕組みを使うことで簡単にボードの I/O を制御することができます.この方法では,ブラウザから Cloud9 IDE と呼ばれる IDE にアクセスし javascript によるプログラムを作成,それを BeagleBone Black 上で実行します.
BeagleBoneBlack と PC を USB で接続し,PC 上のブラウザから 192.168.7.2:3000 にアクセス,または BeagleBone Black 上でブラウザからこの URL にアクセスすると, 右のように Cluoud9 開発環境が立ち上がります.
通常のソフト開発用 IDE と同じように新規フォルダ・ソースファイルを作成し,javascript でプログラムを記述し,.js ファイルとして保存します.以下はボード上の LED チカチカのプログラム例です.

var b = require('bonescript');
var p = '/sys/class/leds/beaglebone:green:usr';
var led0 = "USR0";
var led1 = "USR1";
var led2 = "USR2";
var led3 = "USR3";
// pin mode setting (output)
b.pinMode(led0, 'out');
b.pinMode(led1, 'out');
b.pinMode(led2, 'out');
b.pinMode(led3, 'out');
// set initial value (all LED OFF)
b.digitalWrite(led0, 0);
b.digitalWrite(led1, 0);
b.digitalWrite(led2, 0);
b.digitalWrite(led3, 0);
var count = 0;
// LED toggle function
var toggleLED = function()
{
count++;
b.digitalWrite(led0, (count & 0x01));
b.digitalWrite(led1, (count & 0x02) >> 1);
b.digitalWrite(led2, (count & 0x04) >> 2);
b.digitalWrite(led3, (count & 0x08) >> 3);
console.log('count : ' + count);
};
// toggle interval setting to 50ms
var timer = setInterval(toggleLED, 50);
console.log('LED toggle start!!');
// LED toggle stop function
var stopTimer = function()
{
clearInterval(timer);
b.digitalWrite(led0, 0);
b.digitalWrite(led1, 0);
b.digitalWrite(led2, 0);
b.digitalWrite(led3, 0);
b.writeTextFile(p+'0/trigger', 'heartbeat');
b.writeTextFile(p+'1/trigger', 'mmc0');
b.writeTextFile(p+'2/trigger', 'cpu0');
b.writeTextFile(p+'3/trigger', 'mmc1');
console.log('LED toggle finish!!');
};
// timer will be stopped after 10[s]
setTimeout(stopTimer, 10000);

cloud9_002
上記プログラムを作成後,IDE 上の Run ボタンを押すと BeagleBoneBlack 上の 4つの LED(USR0 ~ USR3)が点滅し,IDE のコンソール上に count 変数の値が表示されていきます.このように,BeagleBoneBlack ではブラウザを使用して簡単に各種 I/O 操作が可能になっています.もちろん,GPIO 以外にも I2C,アナログ入出力といった各種 I/O も制御できるようになっています.
BoneScript についての詳細,各種デモプログラム等は本家 BeagleBoard のページで確認できるほか,洋書ですが書籍も出ています.特に本家 BeagleBoard のページでは温度センサやサーボモータなど,具体的なハードウェアの接続例とともにデモプログラムも記載されていますので大変わかりやすいと思います.

C言語アプリからLEDチカチカ

上記マニュアル操作の例でわかるとおり,ボード上の LED 操作はファイル操作を介して行えるので,ユーザのお好みでどのような言語でもプログラムを作成して使用可能です.今回は,将来的に実行速度を追うケースなどで必要かと思い, C 言語で組んだネイティブプログラム動かす方法を検討してみました.エラー処理等々,細部にやっつけ感はありますが下記のような形で制御できます.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
typedef enum LED_t {
USR0,
USR1,
USR2,
USR3
} LED_t;
typedef enum LED_ACTIVE_TRIGGER_t {
NONE,
NAND,
MMC0,
MMC1,
TIMER,
ONESHOT,
HEARTBEAT,
BACKLIGHT,
GPIO,
CPU0,
DEFAULT_ON,
TRANSIENT
} LED_ACTIVE_TRIGGER_t;
char led_trigger_str[][12] = {
"none",
"nand",
"mmc0",
"mmc1",
"timer",
"oneshot",
"heartbeat",
"backlight",
"gpio",
"cpu0",
"default-on",
"transient"
}; 
int led_set_mode(LED_t led, LED_ACTIVE_TRIGGER_t mode)
{
int fd;
FILE *fp;
char file_path[100];
sprintf(file_path, "/sys/class/leds/beaglebone:green:usr%d/trigger", (int)led);
fp = fopen(file_path, "w");
if(fp == NULL) {
return -1;
}
fprintf(fp, "%s", led_trigger_str[mode]);
fclose(fp);
return 0;
}
int led_set_brightness(LED_t led, int value)
{
FILE *fp;
char file_path[100];
sprintf(file_path, "/sys/class/leds/beaglebone:green:usr%d/brightness", (int)led);
fp = fopen(file_path, "w");
if(fp == NULL) {
return -1;
}
fprintf(fp, "%d", value);
fclose(fp);
return 0;
}
/****************************************************************
* Main
****************************************************************/
int main(void)
{
int i;
int count = 0;
int result;
int value;
result = led_set_mode(USR0, NONE);
printf("LED0 mode set : %d\n", result);
result = led_set_mode(USR1, NONE);
printf("LED1 mode set : %d\n", result);
result = led_set_mode(USR2, NONE);
printf("LED2 mode set : %d\n", result);
result = led_set_mode(USR3, NONE);
printf("LED3 mode set : %d\n", result);
for(i = 0; i < 100; i++) {     
led_set_brightness(USR0, (count & 0x01) >> 0);
led_set_brightness(USR1, (count & 0x02) >> 1);
led_set_brightness(USR2, (count & 0x04) >> 2);
led_set_brightness(USR3, (count & 0x08) >> 3);
count++;
usleep(100000);
}
result = led_set_mode(USR0, HEARTBEAT);
printf("LED0 mode set : %d\n", result);
result = led_set_mode(USR1, MMC0);
printf("LED1 mode set : %d\n", result);
result = led_set_mode(USR2, CPU0);
printf("LED2 mode set : %d\n", result);
result = led_set_mode(USR3, MMC1);
printf("LED3 mode set : %d\n", result);
return 0;
}

BeagleBone Black にはデフォルトで gcc, make など開発環境もひと通り使えるようになっていますので,このまますぐにコンパイルして実行可能です.

参考

シリコンリナックス社 技術情報 “BeagleBoneBlack の情報
Controlling the on-board LEDs using C++