ネットワークプロトコルソフトウェアマニュアル
1.HTTP/HTTPS
1.1. HTTP/HTTPSの概要
HTTP(Hyper Text Transfer Protocol、ハイパーテキスト転送プロトコル)は、インターネット上で最も広く使われているネットワークプロトコルです。クライアントとサーバー間のリクエストおよびレスポンスの標準であり、WWWサーバーからローカルへハイパーテキストを転送するための通信プロトコルです。
一方、HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer)は、セキュリティを目的としたHTTPチャネルであり、従来のHTTPをベースに通信の暗号化と身元認証(SSL/TLSセキュリティプロトコルの追加)を行うことで、通信プロセスにおける安全性を保証します。
1.1.1 HTTPとHTTPSの違い
HTTPとHTTPSの違いは以下の表の通りです。
| プロトコル | HTTP | HTTPS |
|---|---|---|
| CA証明書 | 不要 | 必要 |
| 通信の暗号化方式 | 平文通信、暗号化なし | SSL/TLS暗号化通信 |
| 接続方式 | ポート番号 80 を使用 | ポート番号 443 を使用 |
| 接続状態 | ステートレス(無状態) | SSL+HTTPプロトコルで構築された、暗号化通信および身元認証が可能なネットワークプロトコル |
1.1.2 リクエストとレスポンス
典型的なHTTP/HTTPS通信は、ブラウザとWebサーバー間で行われます。ブラウザは「クライアント」として機能し、リクエストの送信、メッセージの受信、そして表示のレンダリングを担当します。Webサーバーは「サーバー」として機能し、リクエストへの応答、サーバーファイルの管理、具体的な業務処理を担当します。特定の状況下では、HTTPは情報交換のための通信ルールとして機能することもあります。
クライアントがリソースを必要とする際に送信するものが「リクエストメッセージ(Request)」であり、サーバーがリクエストを受信した後にクライアントへ返すものが「レスポンスメッセージ(Response)」です。HTTPでは、これらリクエストメッセージとレスポンスメッセージのフォーマットが規定されています。

リクエストメッセージフォーマット
リクエストメッセージのフォーマットは以下の通りです。
| メッセージ要素 | 説明 |
|---|---|
| リクエスト行 (Request Line) | リクエストメソッド: 一般的なメソッドは以下の通りです。 ・GET: サーバーのリソースを検索・取得するために使用します。リクエスト内容はURL上に表示されます。 ・POST: サーバー上にコンテンツを作成または更新するために使用します。リクエスト内容はURL上には表示されず、メッセージボディ(主体)内に含まれます。 URL: サーバーの仮想ファイルパスです。詳細は次のセクションで説明します。 |
レスポンスメッセージの主な構成要素は以下の通りです。
-
ステータス行: プロトコルバージョン、ステータスコード、ステータスフレーズを含みます。
-
レスポンスヘッダー: キーバリューペア(キーと値のペア)の形式で存在します(例:日時、データ型、データ長など)。
-
空行: ヘッダーとボディを区別するための空行です。
-
レスポンスボディ (本文): Webページの場合は通常HTMLコードですが、音声・動画ファイルや画像の場合もあります。通常、ヘッダーの Content-Type で指定されます。

レスポンスメッセージフォーマット
1.1.3 URL
ある環境モニタリングサーバーシステムを構築し、市内各観測点の環境データを収集・記録すると仮定します。パブリックネットワーク上のドメイン名を www.huanjin.com とし、サーバー内に2つのデバイスがあり、各デバイスに異なる日付の気温データが保存されているとします。クライアントが特定のデバイスの特定のデータを呼び出す際、サーバーに検索させるための一意のパスを送信する必要があります。この一意のパスが URL です。

環境モニタリングサーバーのURL構成例
URL(Uniform Resource Locator、統一資源位置指定子)は、リクエストメッセージのリクエスト行に配置され、道しるべの役割を果たします。Webページを閲覧して様々なコンポーネントをクリックすると、ブラウザは自動的に異なるURLを補完してくれます。完全なURLは、プロトコル部分、URL(ドメイン)部分、ファイルアドレスで構成されます。

URL構成要素の例
具体的な内容は以下の通りです。
| 構成部分 | 説明 |
|---|---|
| プロトコル | // で区切られます。一般的なものに http と https があります。 |
| URL (ドメイン) | パブリックネットワーク上で唯一無二のドメイン名です。 |
| ファイルアドレス | ドメイン名の後の最初の / から、最後の / の前までの内容は「仮想ディレクトリ」と呼ばれます。 最後の / の後から # の前までが「ファイル名」となります。 |
例えば、環境モニタリングサーバーにある「デバイス1」の「12月25日」のデータを取得したい場合、GETリクエストを使用し、URLは http://www.huanjin.com/Device-1/日付データ/20211225 のようになります。
URLには変数情報(URLクエリストリング)を含めることも可能です。形式は以下の通りです。
https://www.Adblock.com/s?a=123&b=234変数はURLの末尾に配置され、? で始まり、パラメータ名=値 のキーバリューペア形式で格納されます。複数のパラメータは & で区切られます。
1.1.4 HTTPS使用の要点
上記の説明から、HTTPSを使用する際は以下の点を常に意識する必要があります。
-
CA証明書: HTTPSプロトコルはSSL/TLSを使用します。
-
データ送信: POSTリクエストを使用し、サーバーアドレスはURL形式で表現します。
-
データ・ファイルの受信: GETリクエストを使用し、サーバーアドレスはURL形式で表現します。
当社の easyeai-api ソフトウェア・オープンソースライブラリは、複雑なメッセージフォーマットや送受信操作を統一的にカプセル化しており、お客様がシンプルで便利な呼び出し方法でHTTP/HTTPS通信機能を実現できるようにしています。
1.2. クイックスタート
1.2.1 開発環境の準備
このドキュメントを初めて読む場合は、『スタートガイド/開発環境の準備/Easy-Eaiコンパイル環境の準備と更新』を一読し、その手順に従ってコンパイル環境の構築を行ってください。
PC上のUbuntuシステムで run スクリプトを実行し、EASY-EAIコンパイル環境に入ります。詳細は以下の通りです。
cd ~/develop_environment./run.sh 22041.2.2 ソースコードのダウンロードとサンプルのコンパイル
EASY-EAIコンパイル環境下で、ソースコードリポジトリを管理するディレクトリを作成します。
cd /optmkdir EASY-EAI-Toolkitcd EASY-EAI-ToolkitDemos.zip 上記のリンクから Demos.zip 圧縮ファイルをダウンロードし、仮想マシンの /opt/EASY-EAI-Toolkit ディレクトリにアップロードして解凍します。 対応するサンプルのディレクトリに移動し、コンパイル操作を実行します。具体的なコマンドは以下の通りです。
cd EASY-EAI-Toolkit-1126B/Demos/netProtocol-http/./build.sh💡 注意 : 依存ライブラリがボード上に配置されているため、クロスコンパイル中は必ず /mnt のマウントを維持してください。

HTTPサンプルのビルド結果
1.2.3 サンプルの実行
シリアルデバッグまたはSSHデバッグを通じてボードのバックグラウンドに入り、サンプルが配置されている場所に移動します。以下の通りです。
cd /userdata/Demo/netProtocol-http
HTTPサンプルディレクトリ
サンプルの実行コマンドは以下の通りです。
./test-http_server & ./test-http_client1.2.4 実行結果
実行結果は以下のようになります。

HTTPサンプル実行結果
1.3. HTTPSライブラリ関数の説明
本章では、EASY EAIのHTTPSライブラリ関数の使用方法について説明します。
1.3.1 インクルード/参照方法
EASY EAI api ライブラリは、本リポジトリの easyeai-api ディレクトリにあります。お客様がローカルプロジェクトで EASY EAI api ライブラリを直接呼び出せるように、プロジェクト内でリンクする必要があるライブラリやヘッダーファイル等を以下にリストアップしています。
| 説明 | CMakeでの記述 | Makefileでの記述 |
|---|---|---|
| api.cmake | ${netProtocol_root}/http/api.cmake | 無し |
| ヘッダーファイルディレクトリ | ${HTTP_INCLUDE_DIRS} | -I ../../easyeai-api/netProtocol/http |
| ソースファイルディレクトリ | ${HTTP_SOURCE_DIRS} | ../../easyeai-api/netProtocol/http |
| ライブラリファイルディレクトリ | 無し | 無し |
| ライブラリリンクパラメータ | ${HTTP_LIBS} | 無し |
APIソースコードのパスは EASY-EAI-Toolkit-1126B/easyeai-api/netProtocol/http/ です。ユーザーはソースコードを通じてインターフェースの実装を確認でき、ソースコードを直接変更することも可能です。
1.3.2 証明書の設定
証明書を設定する関数のプロトタイプは以下の通りです。
void set_customer_crt(const char \*crt_file);具体的な説明は以下の通りです。
| 関数名:set_customer_crt() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/http/https_request.h |
| 入力パラメータ | crt_file:証明書のパス |
| 戻り値 | 無し |
| 注意事項 | 無し |
1.3.3 HTTP/HTTPSサーバーへのform-dataデータの送信
1.3.3.1 form_dataキャッシュのクリア
キャッシュをクリアする関数のプロトタイプは以下の通りです。
void clear_multipart();具体的な説明は以下の通りです。
| 関数名:clear_multipart() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/http/https_request.h |
| 入力パラメータ | 無し |
| 戻り値 | 無し |
| 注意事項 | form-dataのキャッシュは1つしか存在しないため、どこで実行してもform-dataキャッシュは空になります。複数スレッドでこの関数を実行する場合は、スレッドの同期問題に注意してください。 |
1.3.3.2 form_dataキャッシュの追加 (パディング)
キャッシュを追加する関数のプロトタイプは以下の通りです。送信するデータはキーバリューペア形式で追加します。
void add_multipart_form_data(const char \*key, const char \*value);具体的な説明は以下の通りです。
| 関数名:add_multipart_form_data() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/http/https_request.h |
| 入力パラメータ | key: form-dataデータのキー名 value: form-dataデータの内容 |
| 戻り値 | 無し |
| 注意事項 | form-dataのキャッシュは1つしか存在しません。clear_multipart() を実行すると、それまでキャッシュに追加されたform-dataデータはすべてクリアされます。複数スレッドで実行する場合は、スレッドの同期問題に注意してください。 |
1.3.3.3 form-dataデータの送信
HTTPとHTTPSでは暗号化方式が異なるため、パラメータは同じですが2つの関数が定義されています。関数のプロトタイプは以下の通りです。
int32_t send_data_to_Http(const char *server, const char *func, char *result, uint32_t result_lenth);int32_t send_data_to_Https(const char *server, const char *func, char *result, uint32_t result_lenth);具体的な説明は以下の通りです。
| HTTP送信関数:send_data_to_Http() HTTPS送信関数:send_data_to_Https() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/https/https_request.h (※原文のまま記載) |
| 入力パラメータ | server: サーバーのURL func: メソッド(パス/API名) result: HTTP/HTTPSからの返答ボディデータを保存するバッファ result_lenth: ボディデータ用にユーザーが割り当てたバッファの最大サイズ |
| 戻り値 | -1: 失敗 0: 成功。関数内部で自動的に clear_multipart() が呼び出され、キャッシュがクリアされます。 |
| 注意事項 | このインターフェースはHTTP/HTTPS POSTリクエストをカプセル化したもので、form-dataのキャッシュを送信します。呼び出し成功後にキャッシュをクリアします。マルチスレッド環境では同期に注意してください。 |
1.3.4 HTTP/HTTPSサーバーへのJSONデータの送信
HTTPとHTTPSで暗号化方式が異なるため、それぞれ関数が定義されています(パラメータは同一です)。
int32_t send_json_to_Http(const char *server, const char *func, const char *json, char *result, uint32_t result_length);int32_t send_json_to_Https(const char *server, const char *func, const char *json, char *result, uint32_t result_length);具体的な説明は以下の通りです。
| HTTP送信関数:send_json_to_Http() HTTPS送信関数:send_json_to_Https() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/https/https_request.h |
| 入力パラメータ | server: サーバーのURL func: メソッド(パス/API名) json: 送信するJSON文字列 result: 返答ボディデータを保存するバッファ result_lenth: ボディデータ用にユーザーが割り当てたバッファの最大サイズ |
| 戻り値 | -1: 失敗 0: 成功 |
| 注意事項 | 無し |
1.3.5 HTTP/HTTPSサーバーからのファイル取得
HTTPとHTTPSで暗号化方式が異なるため、それぞれ関数が定義されています(パラメータは同一です)。
int32_t get_file_from_https(const char *url, const char *func, const char *filePath);int32_t get_file_from_http(const char *url, const char *func, const char *filePath);具体的な説明は以下の通りです。
| HTTPファイル取得関数:get_file_from_https() (※原文のまま記載) HTTPSファイル取得関数:get_file_from_http() (※原文のまま記載) | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/https/https_request.h |
| 入力パラメータ | url: サーバーのURLパス func: メソッド(パス) filePath: 取得したファイルを保存するローカルパス |
| 戻り値 | Success, Unknown, Connection, BindIPAddress, ReadWrite, ExceedRedirectCount, Canceled, SSLConnection, SSLLoadingCerts, SSLServerVerification, UnsupportedMultipartBoundaryChars, Compression など |
| 注意事項 | このインターフェースはHTTP/HTTPS GETリクエストをカプセル化したものです。 |
1.4. 使用例
サンプルコードのパスは EASY-EAI-Toolkit-1126B/Demos/netProtocol-http/test-http_client.c です。
1.4.1 CRTキーファイル(証明書)の設定
キーファイルの設定操作は以下の通りです。
set_customer_crt("/userdata/customer.crt");1.4.2 form_dataデータの送信
1.4.2.1 データの追加
form_dataデータバッファをクリアし、その後form_dataバッファにデータを追加します。
clear_multipart();add_multipart_form_data("name", "gzlmo");add_multipart_form_data("id", "888888");add_multipart_form_data("pwd", "123456");1.4.2.2 データの送信
送信操作は以下の通りです。
send_data_to_Http("192.168.3.191:50000", "/add", res, sizeof(res));1.4.3 JSONデータの送信
JSONデータの送信操作は以下の通りです。
send_json_to_Http("192.168.3.191:50000", "/add", "{name : \\gzlmo\\}", res, sizeof(res));2.MQTT
2.1. MQTTの概要
MQTT(Message Queuing Telemetry Transport)は、パブリッシュ/サブスクライブ(publish/subscribe)モデルに基づく「軽量」な通信プロトコルです。MQTTの最大の利点は、極めて少ないコードと限られた帯域幅で、リモートデバイスの接続に対してリアルタイムかつ信頼性の高いメッセージサービスを提供できることです。オーバーヘッドや帯域幅の消費が少ないインスタント通信プロトコルとして、IoT(モノのインターネット)、小型デバイス、モバイルアプリなどで広く応用されています。
2.1.1 パブリッシュとサブスクライブ
MQTTが採用しているパブリッシュ/サブスクライブのメッセージモデルは、1対多のメッセージ配信メカニズムを提供し、アプリケーション間の疎結合を実現します。これは、メッセージが送信側から受信側へ直接(ピアツーピアで)送信されるのではなく、MQTTサーバー(別名:MQTTブローカー)を介して配信されるメッセージ伝達モデルです。
-
MQTTの通信プロセスには、パブリッシャー(Publisher:発行者)、ブローカー(Broker:仲介者)、サブスクライバー(Subscriber:購読者)の3つの役割が存在します。
-
MQTTで転送されるメッセージは、トピック(Topic)とペイロード(Payload)の2つの部分に分かれます。

MQTTパブリッシュ・サブスクライブモデル
パブリッシャーはブローカー(MQTT Broker)に対して特定のトピックのメッセージを発行し、ブローカーはそのトピックを購読しているすべてのサブスクライバーにメッセージをプッシュします。
- メッセージを発行するクライアントがパブリッシャーであり、トピックのメッセージを購読するクライアントがサブスクライバーです。
2.1.2 サービス品質 (QoS: Quality of Service levels)
サービス品質はMQTTの重要な特性の一つです。TCP/IPを使用する場合、接続はある程度保護されています。しかし、ワイヤレスネットワークでは切断や干渉が頻繁に発生するため、MQTTのQoSレベルが情報の損失を防ぐのに役立ちます。
2.1.2.1 QoS 0
「最大1回(At most once)」。メッセージの配信は基盤となるTCP/IPネットワークに完全に依存します。メッセージの損失や重複が発生する可能性があります。このレベルは、環境センサーのデータなど、すぐに次のデータが送信されるため1回程度の記録漏れが問題にならない状況で使用されます。

MQTT QoS 0 通信フロー
2.1.2.2 QoS 1
「少なくとも1回(At least once)」。メッセージの到達を保証しますが、メッセージが重複して到達する可能性があります。

MQTT QoS 1 通信フロー
2.1.2.3 QoS 2
「正確に1回(Exactly once)」。メッセージが確実に1回だけ到達することを保証します。このレベルは、課金システムなど、メッセージの重複や損失が誤った結果を招く状況で使用されます。

MQTT QoS 2 通信フロー
- 一意のメッセージIDを持つメッセージは、送信側と受信側の両方で保存されます。QoSレベル2は、送信側と受信側で2つのフローを必要とするため、ネットワーク上のオーバーヘッドが最も高くなります。
2.1.3 オープンソースプロジェクトの紹介
広く使用されておりコミュニティも活発なものとして、Eclipse Paho Cライブラリが現在最も一般的で人気のあるC言語用MQTTクライアントのオープンソースライブラリです。Windows、MAC、Linux、FreeRTOS、ESP32などのプラットフォームに適用可能です。
-
公式サイト: https://www.eclipse.org/
-
GitHubリポジトリ: https://github.com/eclipse-paho/paho.mqtt.c
Ubuntuシステムでは、GitHubリポジトリを直接コンパイルして必要なライブラリやヘッダーファイルを取得することもできますが、以下のコマンドで直接インストールすることも可能です(この手順は省略可能です):
sudo apt-get updatesudo apt-get install libpaho-mqtt-devPaho Cはサポートするプラットフォームが充実しており互換性が高いという利点がありますが、【APIが低レイヤー寄り】であり、使い勝手が悪く、さらに独自のラップ処理(カプセル化)が必要になるという制限もあります。
そのため、本ドキュメントではEclipse傘下のもう一つのMQTTプロジェクトである mosquitto を採用します。このプロジェクトはリソースが限られた組み込みデバイスにより適しており、Paho Cほど網羅的ではありませんが基本要件を満たし、かつ非常に使いやすいのが特徴です。
- 公式サイト: https://mosquitto.org/
Ubuntuシステムでは、以下のコマンドで関連する開発ライブラリを直接インストールできます:
sudo apt-get updatesudo apt-get install libmosquitto-dev2.1.4 一般的な通信モデル
一般的な使用方法として、MQTT Server(ブローカー)プログラムをクラウドに展開し、ボード(開発ボード)がパブリッシャーおよびサブスクライバーとしてデータの送受信通信を行うモデルがあります。

MQTT通信モデル
ローカルネットワーク(LAN)内で使用したい場合は、PCプラットフォーム(Windows/Linux)上にMQTT Serverを展開し、ボードがパブリッシャーおよびサブスクライバーとして通信を行うこともできます。
例えば、Ubuntuシステムで以下のコマンドを実行し、MQTT Serverを展開できます:
sudo apt-get updatesudo apt-get install mosquittosudo systemctl start mosquittoMQTT ServerをUbuntuの起動時に自動起動させたい場合は、以下のコマンドを追加で実行します:
sudo systemctl enable mosquitto2.1.5 デモの説明
本ドキュメントでは、デモの解説を簡単にするため、【ブローカー】、【サブスクライバー】、【パブリッシャー】のすべてを【同一のボードデバイス上】に展開します。
まず、ボードの電源を入れ、ネットワークに接続します。次に、シリアルポートまたはSSHを通じてボードのバックグラウンドに入り、MQTT関連のリソースをインストールします:
sudo apt-get updatesudo apt-get install libmosquitto-dev mosquittosudo systemctl enable mosquitto && sudo systemctl start mosquitto2.2. クイックスタート
2.2.1 開発環境の準備
このドキュメントを初めて読む場合は、『スタートガイド/開発環境の準備/Easy-Eaiコンパイル環境の準備と更新』を一読し、その手順に従ってコンパイル環境の構築を行ってください。
PC上のUbuntuシステムで run スクリプトを実行し、EASY-EAIコンパイル環境に入ります。
cd ~/develop_environment./run.sh 22042.2.2 ソースコードのダウンロードとサンプルのコンパイル
EASY-EAIコンパイル環境下で、ソースコードリポジトリを管理するディレクトリを作成します。
cd /optmkdir EASY-EAI-Toolkitcd EASY-EAI-ToolkitDemos.zip 上記のリンクから Demos.zip 圧縮ファイルをダウンロードし、仮想マシンの /opt/EASY-EAI-Toolkit ディレクトリにアップロードして解凍します。 該当するサンプルのディレクトリに移動し、コンパイル操作を実行します。
cd EASY-EAI-Toolkit-1126B/Demos/netProtocol-mqtt/./build.sh
MQTTサンプルのビルド結果
💡 注意 : 依存ライブラリがボード上に配置されているため、クロスコンパイル中は必ず /mnt のマウントを維持してください。コンパイルに失敗し mosquitto.h が見つからないというエラーが出た場合は、1.5 デモの説明 の項を確認してください。
2.2.3 サンプルの実行
シリアルデバッグまたはSSHを通じてボードのバックグラウンドに入り、サンプルプログラムの場所に移動します。
cd /userdata/Demo/netProtocol-mqtt
MQTTサンプルディレクトリ
まず、【サブスクライバー】プログラムを実行します:
./test-mqtt_subscription &
MQTTサブスクライバー起動結果
💡 注意 :実行に失敗し「Connection refused (接続拒否)」と表示された場合は、1.5 デモの説明 の項を確認してください。サブスクライバーはバックグラウンドで動作するため、再実行する場合は事前に kill コマンドでプロセスを終了させてください。
続いて、【パブリッシャー】プログラムを実行します:
./test-mqtt_publish2.2.4 実行結果
実行結果として、パブリッシャーが送信したメッセージをサブスクライバーが正常に受信して出力する様子が確認できます

MQTT送受信実行結果
2.3. Mosquittoライブラリ関数の説明
本章では、本サンプルで使用する mosquitto ライブラリのインターフェースについて説明します。より詳細なAPIの説明については、公式サイトのAPIドキュメント (https://mosquitto.org/api/files/mosquitto-h.html) を参照してください。
2.3.1 参照方法
EASY EAI api ライブラリは、本リポジトリの easyeai-api ディレクトリにあります。プロジェクト内でリンクする必要があるライブラリやヘッダーファイル等は以下の通りです。
| 説明 | CMakeでの記述 | Makefileでの記述 |
|---|---|---|
| api.cmake | ${netProtocol_root}/mqtt/api.cmake | 無し |
| ヘッダーファイルディレクトリ | ${MQTT_INCLUDE_DIRS} | $SYSROOT/usr/include/ |
| ソースファイルディレクトリ | ${MQTT_SOURCE_DIRS} | 無し |
| ライブラリファイルディレクトリ | 無し | $SYSROOT/usr/lib/aarch64-linux-gnu/ |
| ライブラリリンクパラメータ | ${MQTT_LIBS} | -lmosquitto -lcrypto -lssl -lstdc++ |
APIソースコードのパスは EASY-EAI-Toolkit-1126B/easyeai-api/netProtocol/mqtt/ です。
2.3.2 Mosquittoライブラリの初期化
int mosquitto_lib_init(void);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_lib_init() |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | 無し |
| 戻り値 | MOSQ_ERR_SUCCESS (0): 初期化成功 |
2.3.3 Mosquittoクライアントインスタンスの新規作成
struct mosquitto \*mosquitto_new(const char \*id, bool clean_session, void \*userdata);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_new(const char *id, bool clean_session, void *userdata) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | id: クライアントの識別子(文字列) clean_session: true の場合、切断時にセッション情報をクリアします。false の場合、セッション情報を保持します。 userdata: ユーザー定義データへのポインタ |
| 戻り値 | struct mosquitto * (インスタンスへのポインタ) |
2.3.4 接続コールバック関数の設定
ブローカーとの接続状態の変化を処理します。
void mosquitto_connect_callback_set(struct mosquitto \*mosq, void (\*on_connect)(struct mosquitto \*, void \*,int));| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス on_connect: 接続コールバック関数へのポインタ(戻り値 void、引数:クライアントインスタンス、ユーザーデータ、接続戻り値コード) |
2.3.5 切断コールバック関数の設定
ブローカーとの切断イベントを処理します。
void mosquitto_disconnect_callback_set(struct mosquitto \*mosq, void (\*on_disconnect)(struct mosquitto \*, void \*, int));| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス on_disconnect: 切断コールバック関数へのポインタ(戻り値 void、引数:クライアントインスタンス、ユーザーデータ、切断戻り値コード) |
2.3.6 メッセージ発行コールバック関数の設定
メッセージがブローカーに正常に送信された際のイベントを処理します。
void mosquitto_publish_callback_set(struct mosquitto \*mosq, void (\*on_publish)(struct mosquitto \*, void \*, int));| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)) |
| ヘッダーファイル | netProtocol-mqtt/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス on_publish: メッセージ発行コールバック関数へのポインタ(引数:クライアントインスタンス、ユーザーデータ、メッセージID) |
2.3.7 購読(サブスクライブ)コールバック関数の設定
トピックの購読が成功した際のイベントを処理します。
void mosquitto_subscribe_callback_set(struct mosquitto \*mosq, void (\*on_subscribe)(struct mosquitto \*, void \*, int, int, const int \*));| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス on_subscribe: コールバック関数ポインタ。引数は順に:クライアントインスタンス、ユーザーデータポインタ、メッセージID、成功したトピック数、QoSレベル配列。 |
2.3.8 指定したブローカーへの接続
int mosquitto_connect(struct mosquitto \*mosq, const char \*host, int port, int keepalive);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス host: ブローカーのアドレス port: ブローカーのポート番号 keepalive: キープアライブ時間(秒) |
2.3.9 トピックの購読 (サブスクライブ)
int mosquitto_subscribe(struct mosquitto \*mosq, int \*mid, const char \*sub, int qos);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス mid: メッセージIDを格納する変数へのポインタ(NULL も可) sub: 購読するトピック文字列 qos: 購読のQoSレベル |
| 戻り値 | MOSQ_ERR_SUCCESS で成功、それ以外は失敗 |
2.3.10 指定トピックへのメッセージ発行 (パブリッシュ)
int mosquitto_publish(struct mosquitto \*mosq, int \*mid, const char \*topic, int payloadlen, const void \*payload, int qos, bool retain);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス mid: メッセージID格納用ポインタ(NULL も可) topic: 発行先トピック文字列 payloadlen: メッセージペイロードの長さ payload: メッセージペイロードデータへのポインタ qos: QoSレベル retain: true の場合、メッセージを保持 (Retain) する |
| 戻り値 | MOSQ_ERR_SUCCESS で成功、それ以外は失敗 |
2.3.11 ブローカーからの切断
void mosquitto_destroy(struct mosquitto \*mosq);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_disconnect(struct mosquitto *mosq) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス |
2.3.12 Mosquittoクライアントインスタンスの破棄
void mosquitto_destroy(struct mosquitto \*mosq);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_destroy(struct mosquitto *mosq) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | mosq: クライアントインスタンス |
2.3.13 Mosquittoライブラリ使用リソースのクリーンアップ
void mosquitto_lib_cleanup(void);| 項目 | 詳細 |
|---|---|
| 関数名 | mosquitto_lib_cleanup(void) |
| ヘッダーファイル | $SYSROOT/usr/include/mosquitto.h |
| 入力パラメータ | 無し |
2.4. 使用例
- 送信 (パブリッシュ) サンプルコードのパス:
EASY-EAI-Toolkit-1126B/Demos/netProtocol-mqtt/test-mqtt_publish.c
- 購読 (サブスクライブ) サンプルコードのパス:
EASY-EAI-Toolkit-1126B/Demos/netProtocol-mqtt/test-mqtt_subscription.c
3.MODBUS
3.1. MODBUSの概要
MODBUSは、異なる種類のバスやネットワークを介して接続されたデバイス間でクライアント/サーバー通信を行うためのアプリケーション層メッセージ転送プロトコルです。Modbusが他の通信プロトコルよりも広く使用されている主な理由は、公に発表されており著作権の要求がないこと、展開と保守が容易であること、そしてベンダーにとってローカルなビットやバイトの移動を変更する際の制限が少ないためです。
3.1.1 プロトコルバージョンと内容
現在、Modbusプロトコルには、シリアルポート、イーサネット、およびその他のインターネットプロトコルをサポートするネットワーク用のバージョンが存在します。
ほとんどのModbusデバイスは、シリアルEIA-485物理層を介して通信します。シリアル接続には2つのバリエーションがあり、数値データの表現方法とプロトコルの詳細がわずかに異なります。MODBUSモードは3つのカテゴリに分けられます。1つはRTU(リモート端末装置)モード、もう1つはASCII(米国情報交換標準暗号)モード、そして3つ目はTCP(イーサネット上で動作するプロトコル)モードです。
-
Modbus RTU:バイナリでデータを表現するコンパクトな方式です(Modbusプロトコルで規定されており、デフォルトモードはRTUでなければならず、ASCIIはオプションです)。
-
Modbus ASCII:人間が読める冗長な表現方式です。
これら2つのバリエーションはどちらもシリアル通信(serial communication)を使用します。TCP/IP(イーサネットなど)を介した接続には、複数のModbus/TCPのバリエーションが存在し、この方式ではチェックサムの計算は必要ありません。これら3つの通信プロトコルはすべて、データモデルと関数呼び出しにおいて同一であり、カプセル化の方法のみが異なります。
3.1.2 通信とデバイス
Modbusプロトコルはマスター/スレーブ(master/slave)アーキテクチャのプロトコルです。1つのノードがマスターノードであり、Modbusプロトコルを使用して通信に参加する他のノードはスレーブノードです。各スレーブデバイスは一意のアドレスを持ちます。シリアルネットワークおよびMB+ネットワークでは、マスターノードとして指定されたノードのみがコマンドを開始できます(イーサネット上では、どのデバイスもModbusコマンドを送信できますが、通常は1つのマスターノードデバイスのみがコマンドを開始します)。
Modbusコマンドには、実行対象となるデバイスのModbusアドレスが含まれます。すべてのデバイスがコマンドを受信しますが、指定されたアドレスのデバイスのみがコマンドを実行し、応答します(アドレス0は例外であり、アドレス0を指定したコマンドはブロードキャストコマンドです。コマンドを受信したすべてのデバイスが実行しますが、応答はしません)。すべてのModbusコマンドには、到達したコマンドが破損していないことを確認するためのチェックコードが含まれています。基本的なModbusコマンドは、RTUにそのレジスタの特定の値を変更させたり、I/Oポートを制御または読み取ったり、デバイスにそのレジスタ内の1つまたは複数のデータを送り返すように指示することができます。
3.1.3 MODBUS使用の要点
以上の説明から、Modbusを使用する際は常に以下の点に注意する必要があります。
-
Modbusはマスター・スレーブ方式の通信であり、非同期に通信することはできません。
-
マスターが送信しなければ、バス上にデータ通信は発生しません。
-
デバイスはRTUプロトコルをサポートしている必要があります(これはModbusプロトコル上の規定です)。
-
基本的なフローは以下の通りです。
-
送信:スレーブアドレス + ファンクションコード + レジスタアドレス + レジスタアドレスの数 + チェックコード
-
応答:スレーブアドレス + ファンクションコード + マスターに送信するデータのバイト数 + データ + チェックコード
-
当社のeasyeai-apiソフトウェアオープンソースライブラリは、複雑なメッセージフォーマットや送受信操作を統合的にカプセル化し、お客様がシンプルで便利な呼び出し方法でModbus通信機能を実現できるようにしています。
3.2. クイックスタート
3.2.1 開発環境の準備
PC側のUbuntuシステムでrunスクリプトを実行し、EASY-EAIコンパイル環境に入ります。具体的な手順は以下の通りです。
cd ~/develop_environment./run.sh 22043.2.2 ソースコードのダウンロードとサンプルプログラムのコンパイル
EASY-EAIコンパイル環境で、ソースコードリポジトリを保存する管理ディレクトリを作成します。
cd /optmkdir EASY-EAI-Toolkitcd EASY-EAI-ToolkitDemos.zip 上記のリンクから Demos.zip 圧縮ファイルをダウンロードし、仮想マシンの /opt/EASY-EAI-Toolkit ディレクトリにアップロードして解凍します。
対応するサンプルプログラムのディレクトリに移動し、コンパイル操作を実行します。具体的なコマンドは以下の通りです。
cd EASY-EAI-Toolkit-1126B/Demos/netProtocol-modbus/./build.sh💡 注意 : 依存ライブラリがボード上に配置されているため、クロスコンパイルのプロセス中は必ず /mnt マウントを保持してください。

MODBUSサンプルのビルド結果
3.2.3 サンプルプログラムの実行
シリアルデバッグまたはsshデバッグを通じてボードのバックグラウンドに入り、サンプルプログラムが展開されている場所に移動します。以下の通りです。
cd /userdata/Demo/netProtocol-modbus
MODBUSサンプルディレクトリ
サンプルプログラムを実行するコマンドは以下の通りです。
./test-modbus_tcp_master & ./test-modbus_tcp_slave3.2.4 実行結果
TCPモードの実行結果は以下のようになります。

MODBUS TCP実行結果
RTUモードに変更する必要がある場合は、コードを自身で変更できます。
- コードパス:EASY-EAI-Toolkit-1126B/Demos/netProtocol-modbus/test-modbus_tcp_slave.c

MODBUS RTUコード変更箇所
APIの詳細な説明およびAPIの呼び出し(このサンプルプログラムのソースコード)については、以下の説明を参照してください。
3.3. MODBUSライブラリ関数の説明
本章では、EASY EAIのMODBUSライブラリ関数の使用方法を紹介します。
3.3.1 引用(インクルード)方法
EASY EAI apiライブラリは、本リポジトリの easyeai-api ディレクトリにあります。お客様がローカルプロジェクトで当社のEASY EAI apiライブラリを直接呼び出せるように、プロジェクトでリンクする必要のあるライブラリやヘッダーファイル等を以下にリストアップします。
| 説明 | CMakeでの記述 | Makefileでの記述 |
|---|---|---|
| api.cmake | ${netProtocol_root}/modbus/api.cmake | 無し |
| ヘッダーディレクトリ | ${MODBUS_INCLUDE_DIRS} | -I ../../easyeai-api/netProtocol/modbus |
| ソースディレクトリ | ${MODBUS_SOURCE_DIRS} | ../../easyeai-api/netProtocol/modbus |
| ライブラリディレクトリ | 無し | 無し |
| リンクパラメータ | ${MODBUS_LIBS} | 無し |
APIのソースコードパスは EASY-EAI-Toolkit-1126B/easyeai-api/netProtocol/modbus/ です。ソースコードを通じてインターフェースの実装を確認したり、ソースコードを変更したりすることも可能です。
3.3.2 インスタンスの作成
TCP方式でModbusインスタンスを作成し、初期化します。
modbus_t\* modbus_new_tcp(const char \*ip, int port);| 関数名:modbus_new_tcp() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ip:IPアドレス port:ポート番号 |
| 戻り値 | 成功:Modbusインスタンス 失敗:NULL |
| 注意事項 | 無し |
3.3.3 スレーブIDの設定
スレーブIDを設定する関数のプロトタイプは以下の通りです。
void modbus_set_slave(modbus_t \*ctx, int slave);| 関数名:modbus_set_slave() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス slave:スレーブID |
| 戻り値 | 成功:0 失敗:-1 |
| 注意事項 | 無し |
3.4 スレーブとの接続
スレーブと接続を確立する関数のプロトタイプは以下の通りです。
void modbus_connect(modbus_t \*ctx);| 関数名:modbus_connect() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス |
| 戻り値 | 成功:0 失敗:-1 |
| 注意事項 | 無し |
3.4.1 レジスタ操作(ファンクションコード対応関数)
3.4.1.1 コイル状態の読み取り(ファンクションコード:0x01)
連続する複数のコイル状態を読み取ることができます。
int modbus_read_bits(modbus_t \*ctx, int addr, int nb, uint8_t \*dest);| 関数名:modbus_read_bits() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:レジスタ開始アドレス nb:レジスタ数 dest:取得した状態値 |
| 戻り値 | 読み取ったレジスタ数(失敗時は-1) |
| 注意事項 | 無し |
3.4.1.2 入力状態の読み取り(ファンクションコード:0x02)
連続する複数の入力状態を読み取ることができます。
int modbus_read_input_bits(modbus_t \*ctx, int addr, int nb, uint8_t \*dest);| 関数名:modbus_read_input_bits() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:レジスタ開始アドレス nb:レジスタ数 dest:取得した状態値 |
| 戻り値 | 成功:nb の値を返す(失敗時は-1) |
| 注意事項 | 無し |
3.4.1.3 保持レジスタの読み取り(ファンクションコード:0x03)
連続する複数の保持レジスタの値を読み取ることができます。
int modbus_read_registers(modbus_t \*ctx, int addr, int nb, uint16_t \*dest);| 関数名:modbus_read_registers() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:レジスタ開始アドレス nb:レジスタ数 dest:取得したレジスタの値 |
| 戻り値 | 成功:読み取ったレジスタの数 失敗:-1 |
| 注意事項 | 無し |
3.4.1.4 入力レジスタの読み取り(ファンクションコード:0x04)
連続する複数の入力レジスタの値を読み取ることができます。
int modbus_read_input_registers(modbus_t \*ctx, int addr, int nb, uint16_t \*dest);| 関数名:modbus_read_input_registers() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:レジスタ開始アドレス nb:レジスタ数 dest:取得したレジスタの値 |
| 戻り値 | 成功:読み取ったレジスタの数 失敗:-1 |
| 注意事項 | 無し |
3.4.1.5 単一コイル状態の書き込み(ファンクションコード:0x05)
int modbus_write_bit(modbus_t \*ctx, int addr, int status);| 関数名:modbus_write_bit() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:コイルアドレス status:コイル状態 |
| 戻り値 | 成功:0 失敗:-1 |
| 注意事項 | 無し |
3.4.1.6 複数の連続コイル状態の書き込み(ファンクションコード:15)
int modbus_write_bits(modbus_t \*ctx, int addr, int nb, const uint8_t \*src);| 関数名:modbus_write_bits() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:コイル開始アドレス nb:コイル数 src:書き込む複数のコイル状態 |
| 戻り値 | 成功:0 失敗:-1 |
| 注意事項 | 無し |
3.4.1.7 単一レジスタの書き込み(ファンクションコード:0x06)
int modbus_write_register(modbus_t \*ctx, int addr, int value);| 関数名:modbus_write_register() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:レジスタアドレス value:レジスタの値 |
| 戻り値 | 成功:0 失敗:-1 |
| 注意事項 | 無し |
3.4.1.8 複数の連続レジスタの書き込み(ファンクションコード:16)
int modbus_write_registers(modbus_t \*ctx, int addr, int nb, const uint16_t \*src);| 関数名:modbus_write_registers() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス addr:レジスタ開始アドレス nb:レジスタ数 src:書き込む複数のレジスタの値 |
| 戻り値 | 成功:0 失敗:-1 |
| 注意事項 | 無し |
3.4.2 ソケットのクローズ
ソケットを閉じる関数のプロトタイプは以下の通りです。
void modbus_close(modbus_t \*ctx);| 関数名:modbus_close() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス |
| 戻り値 | 無し |
| 注意事項 | 無し |
3.4.3 インスタンスの解放
インスタンスを解放する関数のプロトタイプは以下の通りです。
void modbus_free(modbus_t \*ctx);| 関数名:modbus_free() | 詳細 |
|---|---|
| ヘッダーファイル | easyeai-api/netProtocol/modbus/modbus.h |
| 入力パラメータ | ctx:Modbusインスタンス |
| 戻り値 | 無し |
| 注意事項 | 無し |