-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
599df9a
commit 7207cb9
Showing
4 changed files
with
375 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
--- | ||
title: Elixir Port を使って C 言語プログラムと連携する | ||
tags: | ||
- C | ||
- port | ||
- Elixir | ||
- IoT | ||
- Nerves | ||
private: false | ||
updated_at: '2024-12-08T21:41:38+09:00' | ||
id: 6e0c486cd5907348d321 | ||
organization_url_name: fukuokaex | ||
slide: false | ||
ignorePublish: false | ||
--- | ||
|
||
|
||
## はじめに | ||
|
||
Elixir の [Port](https://hexdocs.pm/elixir/Port.html) を使うと、C 言語などで書かれた外部プログラムと連携できます。 | ||
ただ、どこから手をつければいいのか、全体の構成が掴みにくいことがありますよね。 | ||
|
||
この記事では、Port を使ったプロジェクトの基本構成を学べるように、次の 2 つのプロジェクトを例に解説します。 | ||
|
||
1. **[Blinkchain](https://github.com/GregMefford/blinkchain)**: LED 制御ライブラリで、Port を活用したベストプラクティスの学びが得られます。 | ||
2. **[elixir-sensors/sgp40](https://github.com/elixir-sensors/sgp40)**: Blinkchain の構成を参考にして実装した空気質センサーライブラリ。 | ||
|
||
Port を用いたプロジェクトの全体像を理解し、自分のアイデアに応用できる内容を目指します。 | ||
|
||
## Blinkchain とは | ||
|
||
**Blinkchain** は、Elixir を使って LED ストリップ(WS2812B など)を制御するライブラリです。 | ||
内部では Port を利用して C 言語コードを呼び出し、高速でハードウェア制御を行っています。 | ||
|
||
## Blinkchain の学びが役立った点 | ||
|
||
1. **ディレクトリ構成の整理**: | ||
|
||
- `c_src/` ディレクトリで C プログラムを管理し、Makefile を活用したビルドフローを導入。 | ||
|
||
2. **Port 通信の抽象化**: | ||
|
||
- Port を専用モジュールで管理し、Elixir 側からは API を通じて簡単に操作できる構造を採用。 | ||
|
||
3. **明確な公開 API の設計**: | ||
- ユーザー向けの操作をシンプルにし、利用者が内部の複雑さを意識せずに使えるように設計。 | ||
|
||
|
||
## Blinkchain のディレクトリ構成 | ||
|
||
```plaintext | ||
blinkchain/ | ||
├── c_src/ # **C プログラムのソースコードを格納** | ||
│ └── port_interface.c # **LED 制御ロジック** | ||
├── lib/ | ||
│ ├── blinkchain.ex # **公開 API** | ||
│ └── blinkchain/ # **内部ロジックをモジュール化** | ||
│ └── port.ex # **Port 通信の管理** | ||
├── test/ | ||
│ └── blinkchain_test.exs # **テストコード** | ||
├── Makefile # **C プログラムのビルド設定** | ||
├── mix.exs # プロジェクト設定 | ||
└── README.md # プロジェクトのドキュメント | ||
``` | ||
|
||
## Blinkchain の各ファイルの役割と実装例 | ||
|
||
### C プログラム(`c_src/port_interface.c`) | ||
|
||
以下は、標準入力で受け取ったコマンドを元に LED を制御する C プログラムの簡略化版です。 | ||
|
||
```c | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
int main() { | ||
char command[256]; | ||
while (fgets(command, sizeof(command), stdin)) { | ||
if (strcmp(command, "turn_on") == 0) { | ||
printf("LED turned on"); | ||
} else if (strcmp(command, "turn_off") == 0) { | ||
printf("LED turned off"); | ||
} else { | ||
printf("Unknown command"); | ||
} | ||
fflush(stdout); | ||
} | ||
return 0; | ||
} | ||
``` | ||
|
||
### Makefile(`Makefile`) | ||
|
||
C プログラムを簡単にコンパイルできるように Makefile を用意します。 | ||
|
||
```makefile | ||
all: | ||
gcc -o port_interface c_src/port_interface.c | ||
``` | ||
|
||
`make` コマンドを実行することで、`port_interface` バイナリが生成されます。 | ||
|
||
### Port 管理モジュール(`lib/blinkchain/port.ex`) | ||
|
||
Port を管理する Elixir モジュールです。 | ||
|
||
```elixir | ||
defmodule Blinkchain.Port do | ||
def send_command(command) do | ||
port = Port.open({:spawn, "./port_interface"}, [:binary]) | ||
|
||
send(port, {self(), {:command, "#{command}"}}) | ||
|
||
receive do | ||
{^port, {:data, response}} -> String.trim(response) | ||
after | ||
5000 -> "Timeout" | ||
end | ||
end | ||
end | ||
``` | ||
|
||
### 公開 API(`lib/blinkchain.ex`) | ||
|
||
ライブラリ利用者向けのシンプルな API を提供します。 | ||
|
||
```elixir | ||
defmodule Blinkchain do | ||
alias Blinkchain.Port | ||
|
||
def turn_on do | ||
Port.send_command("turn_on") | ||
end | ||
|
||
def turn_off do | ||
Port.send_command("turn_off") | ||
end | ||
end | ||
``` | ||
|
||
### テストコード(`test/blinkchain_test.exs`) | ||
|
||
```elixir | ||
defmodule BlinkchainTest do | ||
use ExUnit.Case | ||
alias Blinkchain | ||
|
||
test "turns on the LED" do | ||
assert Blinkchain.turn_on() == "LED turned on" | ||
end | ||
|
||
test "turns off the LED" do | ||
assert Blinkchain.turn_off() == "LED turned off" | ||
end | ||
end | ||
``` | ||
|
||
## elixir-sensors/sgp40 プロジェクトでの応用 | ||
|
||
Blinkchain で学んだ構成や実装パターンを元に、私のプロジェクト **[elixir-sensors/sgp40](https://github.com/elixir-sensors/sgp40)** では、空気質センサー SGP40 のデータを Elixir で取得する仕組みを構築しました。 | ||
|
||
```plaintext | ||
sgp40/ | ||
├── c_src/ # **C プログラムのソースコードを格納** | ||
│ └── sgp40.c # **センサー制御ロジック** | ||
├── lib/ | ||
│ ├── sgp40.ex # **公開 API** | ||
│ └── sgp40/ # **内部ロジックをモジュール化** | ||
│ └── port.ex # **Port 通信の管理** | ||
├── test/ | ||
│ └── sgp40_test.exs # **テストコード** | ||
├── Makefile # **C プログラムのビルド設定** | ||
├── mix.exs # プロジェクト設定 | ||
└── README.md # プロジェクトのドキュメント | ||
``` | ||
|
||
:tada: :tada: :tada: | ||
|
||
## おわりに | ||
|
||
この記事では、Elixir の Port を使って C 言語プログラムと連携する方法を解説しました。 | ||
|
||
Port を活用した連携は、ハードウェアや外部プログラムを操作する際に非常に強力です。ぜひ、この記事を参考に、自分のプロジェクトに取り入れてみてください! | ||
|
||
何か氣づいた点や改善提案があれば、コメントで共有していただけると嬉しいです! | ||
|
||
![toukon-qiita-macbook_20230912_091808.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/fd5c55ec-4fe0-8af6-59bc-bab1ef3d182b.jpeg) | ||
|
||
## 関連リンク | ||
|
||
- [Blinkchain GitHub リポジトリ](https://github.com/GregMefford/blinkchain) | ||
- [elixir-sensors/sgp40 GitHub リポジトリ](https://github.com/elixir-sensors/sgp40) | ||
- [Elixir Port 公式ドキュメント](https://hexdocs.pm/elixir/Port.html) | ||
- [elixir_make](https://github.com/elixir-lang/elixir_make) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
--- | ||
title: Nerves システム最新リリースの概要 (v1.29.1) | ||
tags: | ||
- Elixir | ||
- IoT | ||
- Nerves | ||
private: false | ||
updated_at: '2024-12-09T21:32:43+09:00' | ||
id: ff720c8706b13ce29152 | ||
organization_url_name: fukuokaex | ||
slide: false | ||
ignorePublish: false | ||
--- | ||
|
||
## はじめに | ||
|
||
Nerves の共同開発者である Frank Hunleth 氏が[Elixir Forum][elixir_forum_post]で最新の Nerves システムリリース(v1.29.1)の情報を共有されていました。 | ||
|
||
このアップデートには、Erlang/OTP の最新バージョン対応や Buildroot 更新のみならず、他にもいろいろ**エキサイティング**な更新が含まれています。 | ||
|
||
## 主な更新内容 | ||
|
||
### Erlang/OTP 27.1.2 へのアップデート | ||
|
||
Nerves が最新の [Erlang/OTP 27.1.2][erlang_release] に対応しました。これにより、パフォーマンスと安定性がさらに向上しています。 | ||
|
||
### Buildroot 2024.08.2 への更新 | ||
|
||
Buildroot が最新版である [Buildroot 2024.08.2][buildroot_release] にアップデートされました。ツールチェーンやビルドシステムが刷新され、基盤がさらに強化されています。 | ||
|
||
### 802.11x 向けの PKCS11 サポート追加 | ||
|
||
ハードウェアセキュリティモジュール(HSM)がサポートされるようになりました。これにより、802.11x 認証におけるセキュリティ機能が強化されています。 | ||
|
||
### XLA サポートの修正 | ||
|
||
加速線形代数(XLA)の利用に関する問題が修正されました。この改善により、機械学習関連プロジェクトの取り組みがスムーズになります。 | ||
|
||
## 「特にエキサイティング」アップデート | ||
|
||
> Some of the most exciting updates are in the official Nerves systems, though. | ||
最もエキサイティングなアップデートは、公式の Nerves システムに関連するものです。 | ||
|
||
### リアルタイム Linux の PREEMPT_RT パッチ | ||
|
||
リアルタイム Linux(PREEMPT_RT)パッチが導入されました。このパッチにより、カーネル全体のレイテンシが低減され、リアルタイム I/O 応答時間が向上します。 | ||
|
||
この機能をフル活用するには、Linux カーネルや Erlang のオプションを使ってリアルタイムコアを割り当てる必要があります。 | ||
|
||
https://wiki.linuxfoundation.org/realtime/start | ||
|
||
### libcamera への移行 | ||
|
||
Raspberry Pi ユーザーにとって重要なのは、MMAL ベースのカメラドライバから **[libcamera][raspberry_pi_camera]** ベースのものに移行したことです。この変更は、すべての Raspberry Pi システムに影響を与えています。これにより、長年利用されてきた **[picam][picam]** ライブラリが正式に非推奨となりました。 | ||
|
||
Nerves システムには、[Raspberry Pi libcamera ドキュメント][raspberry_pi_camera] に記載されているサンプルカメラアプリケーションが含まれています。ただし、現時点ではこれらを簡単に活用できる Elixir 向けのラッパーライブラリは存在しません。そのため、libcamera の恩恵を受けつつ、最新のコンピュータビジョンやカメラ技術を取り入れるには、アプリケーション側での工夫が必要です。 | ||
|
||
## Frank さんからのお願い | ||
|
||
Nerves システムのサポート対象プラットフォームやデバイスが非常に多いため、全てを完全に網羅するのは簡単ではありません。以下の点で協力をお願いされています。 | ||
|
||
1. **使用中の Nerves システムのリリースノートを確認してください!** | ||
プロジェクトに影響を与える可能性があるため、各システムの[変更履歴][nerves_system_br_releases]をご覧ください。 | ||
|
||
2. **フィードバックをお寄せください!** | ||
万が一、不具合や回帰が発生した場合は、ぜひ報告をお願いします。Nerves プロジェクトをさらに良いものにするために、フィードバックがとても重要です。 | ||
|
||
## Frank さんからの感謝 | ||
|
||
今回のリリースサイクルで Frank さんは、以下のような課題を乗り越えたそうです。 | ||
|
||
- **Web ブラウザのキオスクモード対応** | ||
- **リアルタイム Linux の導入** | ||
- **機械学習サポートの拡張** | ||
- **初の GCC バグへの対応** | ||
|
||
これらの成果は、Nerves ユーザーコミュニティの協力なしでは達成できなかったそうで、関わってくださった全ての方に感謝を伝えたいとのことです。 | ||
|
||
## おわりに | ||
|
||
今回のリリースは、セキュリティやリアルタイム性の強化に加え、最新技術の活用を可能にするアップデートが盛り込まれています。 | ||
詳しくはご自身の目で[Elixir Forum][elixir_forum_post]や公式の[変更履歴][nerves_system_br_releases]をご覧ください。 | ||
|
||
![toukon-qiita-macbook_20230912_091808.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/fd5c55ec-4fe0-8af6-59bc-bab1ef3d182b.jpeg) | ||
|
||
<!-- begin-reusable-link --> | ||
|
||
[elixir_forum_post]: https://elixirforum.com/t/nerves-system-releases/25621/16?u=mnishiguchi | ||
[erlang_release]: https://erlang.org/download/OTP-27.1.2.README.md | ||
[buildroot_release]: https://lore.kernel.org/buildroot/871pzex7gn.fsf@dell.be.48ers.dk/T/ | ||
[raspberry_pi_camera]: https://www.raspberrypi.com/documentation/computers/camera_software.html#libcamera | ||
[nerves_system_br_releases]: https://github.com/nerves-project/nerves_system_br/releases | ||
[picam]: https://hex.pm/packages/picam | ||
|
||
<!-- end-reusable-link --> |
Oops, something went wrong.