OCuLinkとは何か? 小型PCやミニPCの購入前に知っておきたいポイントを整理
OCuLinkとは何かを、小型PCやミニPCの購入を検討している人向けに整理します。USB4やThunderboltとの違い、eGPU用途で気にしたいポイント、製品ページでの確認点をまとめています。
この記事で紹介するソースコードは自由に使っていただいて構いません。 アプリケーションの開発や自己学習にお役立て下さい。ただし、当ブログでは掲載するソースコードを流用・利用したことによる損害等につきましては 一切の責任を負いません。自己責任で利用お願いします。
今回は、自作アプリケーションにUBUSのlistenコマンドと同等な処理を実装る方法について紹介します。
UBUSのlistenコマンドはUBUS上でやり取りされるイベント(JSON)をリッスンする処理です。
イベントのリッスン機能を実装すれば、他のプロセスと協調して特定処理を実行することが可能です。 (もちろん、実装に依存するところではありますが)
今回は、そんなUBUSのlistenコマンドと同等な処理のC言語実装について紹介します。
UBUS学習の参考サイト紹介
UBUSの学習に役立つサイトを紹介します。以下のサイトを読むことでコマンドの使用方法だけでなく、その実装方法についても理解できます。
私の記事と併用して読むとより理解に繋がると思います。
今回取り上げるubus-sample02のソースは私のGitHubリポジトリ(UtakamoStudyApps)にあります。
読者ご自身の環境で本アプリをビルド・インストールしてみたい方は私のGitHubリポジトリをダウンロードするか、 次のようにクローンしてください。
OpenWrt:~# git clone https://github.com/utakamo/UtakamoStudyApps.git
なお、ビルド方法に関してはGitHubのリポジトリ説明を参照するか、以下の記事をご覧ください。
【第 6 回】OpenWrt開発入門 自作アプリのパッケージ作成とインストール - パッケージ作成手順
このサイトでは、ラズベリーパイ限定でパッケージを配布しています。 シリーズ別のパッケージを以下に掲載しますので、インストールしてみてください。
| モデル | パッケージ | ハッシュ(SHA256) |
|---|---|---|
| Raspberry Pi1 | ubus-sample02_1.0-1_arm_arm1176jzf-s_vfp.ipk | 34811e5ac41c297a6266d7007d972ea7097fe83df0d0f3c1db062494f10c60b4 |
| Raspberry Pi2 | ubus-sample02_1.0-1_arm_cortex-a7_neon-vfpv4.ipk | 91eb648aa3959c1e3b0963bd472baf8bd7e417ce4857693e2114ae38b879687a |
| Raspberry Pi3 | ubus-sample02_1.0-1_aarch64_cortex-a53.ipk | d45d787795df485c7611544835fcd6bfb08d9a83e5b3b31edbe0b62bbc06ac3a |
| Raspberry Pi4 | ubus-sample02_1.0-1_aarch64_cortex-a72.ipk | c71af3cee5d619ae1db0c5e65c5bb521ad835d7961359e2dfd179433a37427a5 |
次のコマンドを実行すると、パッケージをインストールすることができます。(以下はRaspberry Pi3用パッケージのインストール例です。)
root@OpenWrt:~# wget https://utakamo.com/repo/openwrt/raspi3/ubus/ubus-sample02_1.0-1_aarch64_cortex-a53.ipk root@OpenWrt:~# opkg install ubus-sample02_1.0-1_aarch64_cortex-a53.ipk
このサイトで紹介している他のサンプルプログラムと同じ内容です。
ubus-sample02はprocdによってシステムブート時に優先順位99番目(START=99)に起動され、シャットダウン時に 優先順位10番目(STOP=10)で終了するように設定しています。
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=99
STOP=10
start_service() {
echo 'ubus-sample02 start'
procd_open_instance 'ubus-sample02'
procd_set_param command /usr/bin/ubus-sample02
procd_close_instance
}
今回はubus-sample02と命名したサンプルプログラムにlistenコマンドと同等な処理を実装しました。
UBUSの各コマンド実装は、libubus.hに記述されていますので、これを利用して以下のように listenコマンドの処理をする関数(reply_sample_event)を定義しました。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libubus.h>
#include <libubox/uloop.h>
#include <libubox/blobmsg_json.h>
enum {
TEST_MESSAGE,
TEST_MAX
};
static const struct blobmsg_policy test_policy[] = {
[TEST_MESSAGE] = { .name = "message", .type = BLOBMSG_TYPE_STRING },
};
void ubus_process(void);
static void ubus_sample_handle_signal(int signo);
static void ubus_sample_setup_signals(void);
static int reply_cnt;
static void reply_sample_event(struct ubus_context *, struct ubus_event_handler *, const char *, struct blob_attr *);
struct ubus_event_handler ev = {
.cb = reply_sample_event,
};
int main () {
ubus_sample_setup_signals();
ubus_process();
return 0;
}
void ubus_process(void) {
uloop_init();
struct ubus_context *ctx = ubus_connect(NULL);
ubus_add_uloop(ctx);
ubus_register_event_handler(ctx, &ev, "sample-event");
uloop_run();
uloop_done();
}
static void ubus_sample_handle_signal(int signo)
{
uloop_end();
}
static void ubus_sample_setup_signals(void)
{
struct sigaction s;
memset(&s, 0, sizeof(s));
s.sa_handler = ubus_sample_handle_signal;
s.sa_flags = 0;
sigaction(SIGTERM, &s, NULL);
}
static void reply_sample_event(struct ubus_context *ctx, struct ubus_event_handler *ev,
const char *method, struct blob_attr *msg) {
struct blob_attr *tb[TEST_MESSAGE];
blobmsg_parse(test_policy, TEST_MAX, tb, blob_data(msg), blob_len(msg));
if (!tb[TEST_MESSAGE]) {
return;
}
char *message = blobmsg_get_string(tb[TEST_MESSAGE]);
FILE *fp = NULL;
mkdir("/tmp/ubus-sample02", 0755);
if ((fp = fopen("/tmp/ubus-sample02/reply", "a")) == NULL) {
return;
}
reply_cnt++;
fprintf(fp, "[count:%d], message = %s\n", reply_cnt, message);
fclose(fp);
}
このubus-sample02はイベントのsample-eventをリッスンします。
sample-eventがubusdから通知されると、sample-eventが持つJSONのmessageの 内容を一時ファイルの/tmp/ubus-sample02/replyに描きだします。
受け取ったsample-eventのJSONを受け取り、その内容を一時ファイルに出力する処理がreply_sample_eventです。
reply_sample_eventは受け取ったsample-eventがメッセージデータ場合に限り反応します。 つまり、他のプロセスが次のようにイベントを発行しない限り、ubus-sample02は結果を一時ファイルに出力しません。
ubus send sample-event '{"message":"Hello"}'
reply_sample_eventはイベント受信時にコールバックされるように、ubus-sample02起動時にubus_register_event_handler関数によって 登録する必要があります。
ubus-sample02を実行すると、sample-eventの受信待ちとなります。
そのため、UBUSのsendコマンドで以下のようにsample-eventを送信します。
root@OpenWrt:~# ubus send sample-event '{"message":"Good Morning!"}' root@OpenWrt:~# ubus send sample-event '{"message":"Hello!"}' root@OpenWrt:~# ubus send sample-event '{"message":"Good Bye!"}'
ubus-sample02がsample-eventを受信すると、イベントの受信回数と共にメッセージ内容を/tmp/ubus-sample02/replyに出力します。
root@OpenWrt:~# cat /tmp/ubus-sample02/reply
[count:1], message = Good Morning!
[count:2], message = Hello!
[count:3], message = Good Bye!
今回はUBUSのlistenコマンドと同等な処理を実現するためのC言語実装の方法について紹介しました。
他プロセスと協調して動作する必要があるサービス開発をするときなどで、イベントの受信待ちが必要なケースがあります。
適宜、実装を検討すると良いと思います。
OCuLinkとは何か? 小型PCやミニPCの購入前に知っておきたいポイントを整理
OCuLinkとは何かを、小型PCやミニPCの購入を検討している人向けに整理します。USB4やThunderboltとの違い、eGPU用途で気にしたいポイント、製品ページでの確認点をまとめています。
2026年版 最新おすすめスマートフォン 11選 ローエンドからハイエンドモデルまで
スマートフォンの選び方を、OS、SoC、RAM、AI機能、カメラ、バッテリーなどの基礎知識から整理し、価格帯別の注目モデル11機種を紹介し ます。
2026年版 目元ケアに使いたい アイウォーマー・アイマッサージャーおすすめ5選
アイウォーマー・アイマッサージャーを初めて選ぶ人向けに、温熱、加圧、タッピング、EMS、装着感、安全性を整理し、代表モデル5機種を紹介します。
超格安な日本発のマイコンボード UIAPduinoの紹介
290円という価格が目を引く日本発のマイコンボードについて、主な仕様、安さの背景、向 く用途、定番ボードとの違いをまとめて紹介します。
USB4とは何か? パソコン購入前に知っておきたいポイントを整理
USB4とは何かを、パソコン購入前に知っておきたい人向けに整理します。Thunderbolt 4 / 5との違いや、確認ポイントを分かりやすくまとめて紹介します。
2026年版 ドローンの選び方 基礎知識とおすすめモデル5選
ドローンを初めて購入する人向けに、基礎知識について整理し、DJI・HOVERAir・Potensicの代表モデルを紹介します。