このチュートリアルでは、eRPC(埋め込みリモートプロシージャコール)オープンソースプロジェクトを紹介します。
eRPC(Embedded Remote Procedure Call)は、NXPが作成したリモートプロシージャコール(RPC)システムです。RPC は、単純なローカル関数呼び出しを使用してリモートシステム上のソフトウェアルーチンを呼び出すためのメカニズムです。リモートシステムは、ネットワーク経由のサーバー、マルチコアシステム内の別の CPU コアなど、任意の通信チャネルによって接続された任意の CPU です。クライアントにとっては、アプリケーションに組み込まれているライブラリの関数を呼び出すのと同じようなものです。唯一の違いは、通信チャネルによって生じる遅延や信頼性の低下です。
重要なリンク:
eRPC は、マルチコアおよびマルチプロセッサタイプのアプリケーションをサポートしています。
eRPCの例が見つかる場所
Kunal様、あなたの質問がこちらで取り上げられているようです。 eRPCをiMx6sxに実装するためのステップバイステップの手順が必要です。 · 問題 #5 · EmbeddedRPC/erpc-imx-demos · GitHub
HI [email protected],
MPC5748GでのeRPCの公式な使用法についてはわかりません。念のために言っておくと、eRPCはプログラム言語、OS、トランスポート層に依存します。ボード固有のファイルはありません。したがって、FreertosとC言語が使用されている場合、ほぼ問題なく動作します。必要なのは、使用したいトランスポートを移植することだけです(まだである場合)。
Hi Dusan,
eRPCはNXP MPC5748Gに移植されていますか?参照できるサンプルコードはありますか?
よろしくお願いいたします。
Alex
私はこの分野での経験があまりありません。最近、複数のタスクから複数のerpc呼び出しが行われた際に、いくつかのミューテックスを追加する必要がありました。でも、あなたのアイデアは気に入りました。
すぐにソースコードを確認しましたが、ユースケースを指定する必要があります。しかし、これは RPSMG を使用する Mcore と iMX Linux のどちらが優れているかの問題だと思います。この場合、私たちと同じようにミューテックスを追加できると思います(これにより、eRPC呼び出しがシリアル化されます。performRequest 関数のどこかに追加する必要があります。)スレッドごとにエンドポイントを作成するのは良さそうに聞こえますが、解決しなければならない問題がまだあります。より小さなソリューションは次のようになります。トランスポート初期化関数は(タスクの数に基づいて)より多くのエンドポイントを初期化し、クライアント側のeRPC rpmsg送受信機能を未使用のエンドポイントを使用して送信し、同じエンドポイントを使用してメッセージを受信するように変更し、サーバーのeRPC rpmsg受信機能はすべてのエンドポイントでメッセージを待つ必要があります。
あなたにとってこれが簡単な作業なのか、それとももっと複雑な作業なのかわかりませんが、コードを変更しないとマルチスレッド呼び出しができなくなるのではないか心配です。
Hi Dusan,
私はここCubicでチャンディーニと一緒に働いています。複数のスレッドから呼び出されたときに、eRPCに関する追加情報を取得したいと思いました。現在、私たちは単一のエンドポイントを使用しており、次の呼び出しを行う前に完了する一度限りの呼び出しに、これを使用しています。現在、複数のスレッドから複数の呼び出しを行う可能性があるため、これを行う最善の方法を検討しています。
実際、私の知識不足から、同時に他の電話をかけてみましたが、問題が発生するまでそれを行っていることに気づきませんでした。
現在、eRPCから通信失敗エラーコードが返されていることが確認できます。
これには単一のエンドポイントを使用できますか。つまり、クライアント側でスレッドセーフにすべきでしょうか。
そうでない場合、スレッドごとに別々のエンドポイントを使用すべきでしょうか。
それとも、何か他のことをすべきでしょうか?
よろしくお願いします。
リー
Hi [email protected],
お知らせいただきありがとうございます。面白いですね、今日は別のプロジェクトでこのことを読みました(笑顔の顔文字)
Hi Dusan,
迅速なご返信をありがとうございます。
クライアントとサーバーの両方のソケット接続で以下の API 呼び出しを使用して Nagle アルゴリズムを無効にすることで、TCP でより良いパフォーマンス(マイクロ秒単位の応答)を実現できました。
int result = setsockopt(sock, /* 影響を受けるソケット */
IPPROTO_TCP, /* TCPレベルでオプションを設定する */
TCP_NODELAY, /* オプションの名前 */
(char *) &flag、/* キャストは歴史的な名残です */
sizeof(int)); /* オプション値の長さ */
参考資料: TCP_NODELAY: 2018年のTCP最適化のベストプラクティス | ExtraHop
ありがとうございます
サシダラン。
Hi [email protected],
おそらくGitHubで(同じトピックで、または新しいトピックを作成して)質問すると良いでしょう。TCP を使って何かをしている人が少なくとも 2 人います。
github: GitHub - EmbeddedRPC/erpc: Embedded RPC
スレッド1:複数の接続を処理する TCP トランスポートを備えたサーバー · 問題 #32 · EmbeddedRPC/erpc · GitHub
スレッド2: TCP サンプルクライアント/サーバーコード · 問題 #39 · EmbeddedRPC/erpc · GitHub
個人的にこれを見つけましたが、これがあなたのケースに当てはまるか、役立つかどうかはわかりません: linux - Ubuntuでの低遅延TCP設定
Hi Dusan,
eRPCをTCPソケットに移植したいと思います。
仮想シリアル(Linux内)でサンプルテストコード(test_arrays)を実行したところ、シリアルの応答時間は1ミリ秒未満でした。
同じサンプルコードをTCP経由で実行したところ、TCPの応答時間は約90ミリ秒でした。
遅延を減らし、シリアルと同様に TCP 上のパフォーマンスを向上させる方法はありますか。
ありがとうございます
サシダラン。
Hi, Dusan.
助かりました。ちなみに、ヘッダーファイルに例が挙げられていました。
A9 からの関数呼び出しは正常に動作し、M4 はデータを返します。
しかし、現在の問題はM4が関数を呼び出すときに発生します。エラーがA9に表示されています。「MU送信バッファ空のタイムアウトが発生しました。
うーん、imx_mu_rpmsg_send()が失敗しました:-5」。
このエラーの後、他の側でもデータ関数の呼び出しが機能しなくなります: 「rpmsg_multiept rpmsg0: virtqueue_add_outbuf failed: -5」
何を確認すればよいでしょうか?
ご協力ありがとうございます。
Hi Vadim,
一般的には2つのタスクが必要です。1つはクライアント用、もう1つはサーバー用です。問題は、erpc_arbitrated_client_initからの出力をinitサーバーのパラメータとして設定する必要があることです。
こんにちは、ドゥシャンさん、マレクさん、コミュニティの皆様。
eRPC を使用していくつかのアプリケーションを作成しました。M4(クライアント)-A9(サーバー)または M4(サーバー)-A9(クライアント)は問題なく動作しますが、各側でクライアント/サーバーアプリケーションを使用したいと考えています。しかし、今は動作しておらず、片側からの機能が1回しか実行されず、アプリケーションがハングします。
コードの全体的な構造を確認したいです。
何が問題なのでしょう。
M4上でクライアントとサーバーに2つの別々のFreeRTOSタスクを使用すべきですか。
M4
.
.
erpc_transport_t transport = erpc_transport_rpmsg_lite_rtos_remote_init(.....);
erpc_mbf_t message_buffer_factory = erpc_mbf_rpmsg_init(transport);
erpc_server_init(transport, message_buffer_factory);
erpc_add_service_to_server(create_TEST_service());
erpc_arbitrated_client_init(transport, message_buffer_factory);
while (true)
{
erpc_server_poll();
function1(....);
}
A9
.
.
erpc_transport_t transport = erpc_transport_rpmsg_linux_init(......);
erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();
erpc_server_init(transport, message_buffer_factory);
erpc_add_service_to_server(create_TEST_service());
erpc_arbitrated_client_init(transport, message_buffer_factory);
while (true)
{
erpc_server_poll();
function2(....);
}
vadimfilippenko様、Python バージョンの使用にまだ興味がある場合は、こちらのスレッド「MPU パッチをカーネルに追加する - 新しいモジュールが表示されません · 問題 #2 · EmbeddedRPC/erpc-imx-demos · GitHub」をご覧ください。mhanuel26の少なくとも最後の2つのメッセージ では、Pythonアプリケーションを使用できているということですので、あなたにとって興味深い内容となっているでしょう。
Dusan, Marek,
ついに、修正されたeRPCの例を正常に起動することができました。しかし、Linux側ではCを使用し、M4では6つのパラメーターを持つerpc 1.5.0のrpmsg初期化関数を使用しています(6番目のパラメーターに関するDusanのヒントはGitHubにあります)。サポートありがとうございます。まだ質問させていただきます。
Python アプリの前に M4 アプリを実行する必要があります。
Hi Vadim,
こちらに投稿してください:ls /sys/class/rpmsg
ネームサービスが M4 から送信されなかったようです (M4 は正しいファームウェアで実行されていますか?)。このため、M4から動的にアナウンスされたチャネルを持つフォルダが作成されなかったため、Pythonはrpmsgトランスポートを作成できません...M4コアの出力を確認してください。よろしくお願いします。
Marek
Hi Vadim,
他のコメントをご覧のとおり、できるだけ早く回答するよう努めておりますが、今週(そしておそらく来週)は忙しくしております。
ただ、私がエラーで見たところでは、transport.py 内の RpmsgTransport クラスにある init 関数を比較する必要があります。
こちらもご確認ください。 erpc-imx-demos/sysfs.py at master · EmbeddedRPC/erpc-imx-demos · GitHub - クラス RpmsgEndpoint
GitHub - EmbeddedRPC/erpc-imx-demos: eRPC demos for i.MX devices が最新であり、サブリポジトリが erpc-imx-demos と整合しており、コミット時にチェックアウトされていることを確認してください。
おそらく、ここで何が問題なのか、mareknovakが教えてくれるでしょう。
以下のようになります。
| if self.id == -1: | |
| raise Exception() |
is returning -1
以下の問題について、どなたかお手伝いいただけますか。
私は、iMX6COM ボード上の erpc-imx-demos から eRPC デモの例を使用しています。
M4側でデモアプリケーションを開始しています。
"ハードウェアが初期化されました
eRPCが初期化されました
MatrixMultiplyサービスが追加されました"
Linuxでドライバーを追加中です。
"root@imx6sxea-com:~# modprobe -v rpmsg_multiept
insmod /lib/modules/4.1.15-2.0.3+geb0b90b/kernel/drivers/rpmsg/rpmsg_multiept.ko"
(システムから、rpmsgチャネルが作成されたことや、sys/class/rpmsgの下のrpmsgフォルダが空であることに関するフィードバックはありません)
Linuxでapplデモを開始します。
トレースバック(最後の呼び出し):
ファイル「example.py」、
transport = erpc.transport.RpmsgTransport()
ファイル「build/bdist.linux-armv7l/egg/erpc/transport.py」、__init__の199行目
ファイル「build/bdist.linux-armv7l/egg/rpmsg/sysfs.py」__init__ の116行目
例外
例外タイプエラー:
追伸:
cmake と eclipse を使用してM4 eRPC デモアプリを作成しました。
M4 rpmsg デモアプリケーションは正常に動作しています。
Hi Vakul,
申し訳ありません、コメントを見逃しました。現在、暗号化トランスポートはサポートされていません。しかし、eRPC はモジュール式であるため、この機能を eRPC プロジェクトに簡単に追加できると思います。
Hi
eRPC通信は、何らかの暗号化通信プロトコルを使用して保護できますか(例:TLS)。
よろしくお願いします。
Vakul
こんにちは、Evgenyさん。現時点ではその見積もりはありません。しかし、erpc_malloc/erpc_free関数の独自の実装を書くことで、独自のアロケータを作成または使用できると考えています。
Hi Dusan,
erpcMatrixMultiply_shim の生成された同等物など、追加部分に静的メモリ割り当てを追加する予定はありますか。すべての入力引数が、コーデックからデータを入力する前に動的に割り当てられ、関数呼び出し後に解放される場所のはどこですか。
事前に割り当てられたメモリを(ユーザーアプリによって静的に)フレームワークに渡すようなものですか。
ありがとうございます
Evgeny
Evgeny様、これは MCUExpresso プロジェクトファイル/IDE の問題のようです。フォルダー名の最上位層は仮想ディレクトリである必要があり、将来的にはそこに表示されなくなります。ディスク上のパッケージでは、eRPCはGitHubと同様のディレクトリ構造を持つ必要があります。Github のディレクトリ構造が推奨されています。
Hi Dusan,
erpc は実行時に大量の動的メモリ割り当てを使用しているようです。さらに組み込み向けにして、静的メモリ割り当てスキームを追加する予定はありますか。
編集:
最初の質問についてですが、申し訳ありません。リポジトリに erpc_setup_mbf_static.cpp があるのは確認できました。問題は、私のコードはMCUXpresso SDK-frdmk66f_multiprocessor_examples_erpc_server_matrix_multiply_spi & frdmk66f_multiprocessor_examples_erpc_client_matrix_multiply_spiで提供されている例に基づいて作成されているということです。リポジトリ内のコードとはディレクトリ構造がまったく異なります。
再度確認させていただきます。SDKサンプルのディレクトリ構造を使用するべきか、それともリポジトリを使用するべきかですか。これらは大きく違うのですか。
ありがとうございます
Evgeny
Hi Evgeny,
まず、開発ブランチのsmac.erpc(およびここでビルドされたアプリ)を使用していますか。私の場合、このバージョンが動作しています。
現在、erpcgen アプリのバージョンと残りの eRPC コードが接続されています。ですから、GitHubからビルドした新しいerpcgenアプリを使用する場合は、GitHubのerpc_c/*ファイルをGitHubから例にコピーする必要があります。その後、新しい erpcgen アプリでコードを再生成し、アプリケーション(erpc init + transport)関数を更新すれば、すべてが正常に機能するはずです。そうではなく、erpc_c ファイルを更新しない場合は、提供されている erpcgen アプリを使用する必要があります。
このページの下部「はじめに · EmbeddedRPC/erpc Wiki · GitHub」をご覧ください。新しい erpcgen バージョンでは最新の状態になっているはずです。
確証はありませんが、最新のコミットで SPI が変更される可能性があるため、代わりに古い実装を使用してください。
Hey Dusan,
私がビルドした erpcgen.exe を使用すると、smac.erpc の例で同じエラーが発生します。
エラー: ファイル smac.erpc:135:5: 構文エラー、予期しない識別子、'}' を期待しています
私が言及していたディレクトリ構造は、リポジトリの erpc_c で、次のとおりです。
SDKのサンプルでは、どのディレクトリ構造が正しいのでしょうか。新しく生成したファイル(私が作成したもの)を SDK のサンプルコードで使用しても安全でしょうか。
ありがとうございます
Evgeny
Hi evgenyerlihman,
推奨されるコードは常に GitHub の develop ブランチにあります。このコードが新規リリースの要件を満たしたら、マスターブランチにマージし、アプリケーションのバイナリも提供します。開発ブランチでのこれらの更新は、Kinetis SDK のリリースよりも頻繁に行われます。既存の eRPC トランスポートが Kinetis SDK で使用されているトランスポートのバージョンと一致しない場合は、古い eRPC トランスポートと新しいものを比較するか、git リポジトリでファイルの変更を確認できます。
Hey dusancervenka-b51352,
迅速なご返信ありがとうございます。devブランチをクローンしました。erpc_c ディレクトリ構造が Kinetis SDK に付属する例とは大きく異なることがわかります。どちらが好ましいですか。
ありがとうございます
Evgeny
Hi evgenyerlihman,
実のところ、より頻繁に更新を行っています。ブランチを開発するにはスイッチが必要です。 GitHub - EmbeddedRPC/erpc at develop. 最後のコード更新は昨日でした。ただし、そこで erpcgen アプリケーションをビルドする必要があります。そのsmacでIDLは動作するはずです。
複数の NXP Kinetis デバイスを使用する新製品に erpc フレームワークを使用することを検討しています。erpc GitHubの最終更新は6か月前に行われたようです。お尋ねしたいのは、これがまだ保守/修正/開発されているのかどうかです。GitHubのサンプルを試しました。
erpcgen.exe smac.erpc
エラーが発生し、cppソースコードの生成に失敗しました。
erpcgen 実行可能ファイルは、MCUXpresso SDKからのものです。
ありがとうございます
Evgeny
こんにちは、チャンディーニさん
大丈夫です。私も長期休暇中でした。楽しんでいただけたのであれば幸いです。
コミュニティ・メッセージング・システム (プライベート・メッセージ) を通じてあなたにメールを送りました。
メールで詳細を話し合うことができます。基本的には、GitHubでフォークを作成し、開発ブランチにチェックアウトし、変更を適用し、コミットを作成し、プルリクエストを作成する必要があります。私たちはあなたの変更を確認し、変更を提案し、開発ブランチにマージします。
Hi Dusan ,
ご返信が遅くなり、申し訳ございません。長期休暇を取っていました。戻ってきましたところで、ここにいるメンバーと相談しました。リソースを転送できるように、メールアドレスを教えていただけますか。NXPの方針で、あなたの GitHub に直接入れることができません。
よろしくお願い申し上げます。
チャンディーニ
こんにちは、ドゥサンさん
はい、先輩に相談してプルリクエストを作成します。現在休暇中です。返信が遅くなり申し訳ありません。
よろしくお願い申し上げます。
チャンディーニ
Chandini様、ご成功を収められたことを嬉しく思います。もし特別な提案をさせていただけるなら、新しく作成したトランスポートレイヤーを使用して、eRPCのGitHubの開発ブランチにプルリクエストを送信していただけますか。新しい eRPC で動作させるには、多少の作業が必要になるかもしれません。しかし、あなたがそれを更新したくない場合は、こちらでそれを行うことができます。(ウィンクの顔文字) GitHubのプルリクエストを使用すれば、コントリビューター履歴に常に表示される貴重なコントリビューターになっていただけます。eRPC があなたにとって良い解決策となることを願っております。いつでもこちら/または GitHub よりお手伝いさせていただきます(ウインクの顔文字)
Hi dusancervenka-b51352 , b50844 , novakma7
ようやく動作しました。LinuxでC++コードを使ってデモが正常に動作しています。
質問にすべて答えてくださり、本当にありがとうございます。(笑顔の顔文字)
Dusan様に感謝いたします。(笑顔の顔文字)
よろしくお願い申し上げます。
チャンディーニ
HI Dusan ,
他の作業で忙しかったので、昨日は何も試すことができませんでした。今日は試してみて、結果をを知らせします。
自分の機能を少し変えて試してみる必要があると思います。これまでは、送信関数と受信関数に char* だけを渡していました。
すぐにご連絡いたします。![]()
よろしくお願い申し上げます。
チャンディーニ
Chandini様、その通りです。社外にいたので、機能の正確な名前はわかりませんでした。あなたの場合、これはうまく動作していますか。
こんにちは、ドゥサン
お返事ありがとうございます :
write(fd, message->getBuffer() , message->getUsed()
9e18d069aeae19a6e80a5e8783903bc63bd9b567 · EmbeddedRPC/erpc · GitHub の erpc/ message_buffer.h に getused 関数が記載されていますが、getbuffer 関数は見つかりませんでした。
バッファを取得するには以下の関数を使用する必要があると思います。これは正しいでしょうか。
/*!
* @brief この関数は、読み取り/書き込み用のバッファへのポインターを返します。
*
* @return 読み取り/書き込みするバッファへのポインタ。
*/
uint8_t *get() { m_buf を返します; }
そしで、私の関数は次のようになります。
send :erpc_status_t send(MessageBuffer *message) { write(fd, message->get, message->getUsed())};
よろしくお願い申し上げます。
チャンディーニ
こんにちは、chanidi さん。別の方法で行う必要があります。transport.h を使用しなければなりません。それを使わないと、うまくいきません。
おそらく、前述のように ioctl コマンドを使用することができるでしょう。
erpc_status_t receive(MessageBuffer *message)
{int fd = open("/dev/rpmsg_ept1024.1", O_RDWR);}
送信 :erpc_status_t send(MessageBuffer *message) { write(fd, message->getBuffer(), message->getUsed())};
読み取り: erpc_status_t receive(MessageBuffer *message){size_t size = read(fd, message->getBuffer(), 500);message->setUsed(size)};
novakma7 手順を確認いただけますか。
Dusan , Marek
はい、私もそのファイルを言及していますが、
trasport.hを使用して、トランスポートレイヤーを作成しています。しかし、引数の不一致の問題に直面しています。
virtual erpc_status_t receive(MessageBuffer *message) = 0;
virtual erpc_status_t send(MessageBuffer *message) = 0;
RpmsgEndpoint::receive(int maxlen)
RpmsgEndpoint::send(char *buffer,int dst)
私の理解では、Linuxから /dev/rpmsg_ept1024.1デバイスを読み書きするだけでよいと考えています。
ですから、transport.h を使用する代わりに、独自の transport.h バージョンを作成する必要があるのではないかと考えています。
皆様、ありがとうございました。
チャンディーニ
どういたしまして。/erpc-imx-demos/middleware/erpc/transport/フォルダからヒントを得ることができます。いくつかのトランスポート手段があります。
ドゥサンさん、早速返信ありがとうございます![]()
Chandini様、おっしゃる通り、それが正しい手順です。transport.h からクラスを継承するクラスを作成する必要があります。
Hi Marek
私は再び質問があります。
現時点の作業のステータスは以下の通りです。
erpc-imx-demos/MPU/example_erpc at master · EmbeddedRPC/erpc-imx-demos · GitHub の Python example.py で、Transport クラスから継承された RpmsgTransport を呼び出します。
transport.hを使用すべきかどうかというのが質問です。これは、/erpc-imx-demos/middleware/erpc/erpc_c/infra にあり、アプリケーションを動作させています。
そうすることで、RpmsgTransport クラスを作成し、これをクライアントアプリケーションと呼ぶことができるようになります。
この考え方で正しいでしょうか。
よろしくお願いいたします
チャンディーニ
はい、その通りです。
Python が行うのは、ファイルに対する IO 操作(読み取り/書き込み)だけです。これは C/C++ を含むあらゆる言語で実行できます。Python は、Linux ユーザースペースでの人気から、実行方法をを示すために選ばれましたが、もちろん C に移植することも可能です。
これで認識が一致していると思います。
幸運を祈っています。
これからもよろしくお願いいたします。
Marek
こんにちは、マレク
ご返信ありがとうございます。疑問がいくつか解消されました。
freeRTOSを両方使う予定はありません。
私たちのプランは次のようなものです。
M4-FreeRTOS ----これはお客様のデモにあります。
A7-Linux -----デモにはカーネルRPMSG実装を利用するためのPythonコードが含まれています。
私たちに必要なのは、PythonではなくCまたはC++です。
PythonコードはCまたはC++に簡単に移植できるのですよね。
よろしくお願い申し上げます。
チャンディーニ
こんにちはチャンディーニ・インダバラ・バサヴァラジュさん、
RPMSg-Lite は RPMsg プロトコルの実装であり、FreeRTOS またはベアメタルを実行する M4 側のみを対象としています。Linux/A7 側では、カーネル内の RPMsg 実装で問題ないでしょう。(こちらにある通りです: GitHub - EmbeddedRPC/erpc-imx-demos: i.MX デバイス用の eRPC デモ)
それとも、M4コアとA7コアの両方でFreeRTOSを実行する予定ですか。その場合も機能しますが、これは標準的なユースケースではありません。Aコア用の移植レイヤーを作成し、そこでFreeRTOSを実行する必要があります。
これで何らかの方向性が見えることを願っております。
Marek
Hi Marek
どういうわけかあなたのメッセージを見逃してしまいました。申し訳ありません。
どうもありがとうございます。(笑顔の顔文字)すぐに新しいバージョンを試してみます。
RPMSG トランスポート層に関する最後の質問にお答えいただけますか。
ありがとうございます。
チャンディーニ
こんにちは、分かりました。
新しいものを作成する必要があります(また、GitHubのプルリクエストを使用して、必要に応じてリポジトリに追加できます)。
Linux 側では、/dev/ttyRPMSG を使用できます(システムに存在する場合)。
たとえば、こちらの erpc_c/transports で新しいトランスポートを作成します。
init は次のようになります: int fd = open("/dev/ttyRPMSG", O_RDWR);
送信:write(fd, buffer, buffer_size);
read: size_t size = read(fd, buffer, 予想サイズ);
このように名前が付けられたデバイスがない場合は、Python コードからヒントを得ることができます。RPMSGは私の好みではありません。Linuxでどのように使用すべきかわかりません。ご質問をMarekに転送します。
Hi Dusan , Marek
私が計画していること:
M4(freertos)およびA7(Linux)の両方でrpmsg-liteを使用する
必要なもの
M4とA7の両方で使用できるRPMSG Cラッパー(erpc_c/setup内)
M4とA7の両方で使用できるRPMSGトランスポートレイヤー(erpc_c/transports内)
質問があります。
教えていただけますか、そのためのトランスポート層をお持ちですか?
または
rpmsg-pythonを参照して同様に記述する必要がありますか。
どんのようなご提案でもとても役立ちます。
皆様、ありがとうございました。
チャンディーニ
こんにちは。必要なもの(Linux側用のCトランスポート)があるかどうかわかりませんが、新しいものを作成するのは簡単なはずです。/dev/ttyRPMSG から読み取りと書き込みができます(システムに存在する場合)。
以下にその例をご紹介します。
init は次のように見えます: int fd = open("/dev/ttyRPMSG", O_RDWR);
送信:write(fd, buffer, buffer_size);
read: size_t size = read(fd, buffer, expected size)
mareknovakがこの問題にさらに答えをくれるはずです。
Hi Dusan ,
アップデートについてお知らせいただき、ありがとうございます。
今は手元にあるerpcで大丈夫だと思います。rpmsgクライアントアプリケーションが動作するようになったら、erpcのバージョンも更新できます。
rpmsg-lite、M4プラットフォームファイルを含むものを探していたところです。
A7プラットフォーム用の製品はありますか。あるいは、何か情報があれば大変助かります。主な目的は、トランスポートレイヤーとしてRPMSgを使用し、C言語でクライアントアプリケーションを作成することです
よろしくお願い申し上げます。
チャンディーニ
ご自分で問題解決を進めておられるとのこと、嬉しく思います(開発者にとってそれほど複雑ではないということでしょうから)。また、mareknovakは、上記のコメントで言及されている通り、リポジトリ内の imx デモアプリケーションをすでに更新しています。次のステップでは、新しいRPC機能を使用しているため、そのバージョンをお使いいただけます。(ウィンクの絵文字)
返信ありがとうございます、ドゥサン
それが私が探していた情報です。TCP用のCラッパーを作成し、erpcでいくつか修正した後、うまくいきました。
次のステップは、TCP層をrpmsgに置き換えることです。
再度ありがとうございます
チャンディーニ
こんにちはチャンディーニ・インダバラ・バサヴァラジュさん、
GitHub - EmbeddedRPC/erpc-imx-demos: eRPC demos for i.MX devices リポジトリが eRPC 1.4.0 と RPMSg-Lite 1.1.0 を使用するように更新しました。
コード生成に使用されるビルド済みの erpcgen アプリケーションをこちらからダウンロードできます: Release v1.4 · EmbeddedRPC/erpc · GitHub ダウンロードセクションで、アーキテクチャを選択してください。
その後、./erpcgen-gpy nameOfInterfaceDefinitionLanguageFile.erpc のように呼び出します。ERPC、Pythonのシリアル化と逆シリアル化のシムコードが生成されます。-gpy を省略するか、-gc を指定すると、C シムコードが得られます。
ser/des shimコードもerpc-imx-demosリポジトリの最新のコミットで更新されているので、気軽にご利用ください。
プルリクエストの形で変更を送信してください。
よろしくお願いいたします。eRPC & RPMsg-Liteをご利用いただきありがとうございます。
Marek
こんにちは、現在githubリポジトリに例がありませんが、C(c ++)テストがあります。Linux または Mac に慣れていれば、それを例として使用できます。その他のオプションは上記の通りです。
1. サポートされているボード用の SDK をダウンロード -> マルチコア・マルチプロセッサ C/Python の例。
2. この記事をお読みください:はじめに · EmbeddedRPC/erpc Wiki · GitHub
Hi Dusan
PythonではなくCのクライアントアプリケーションのサンプルがあるか、あるいは、作成の予定があるか教えていただけますかすでにあれば、とても便利で役に立ちます。
よろしくお願いいたします
チャンディーニ
ようやく動くようになりました。ご協力いただき、ありがとうございます。(笑顔の顔文字) Dusan
申し訳ありませんが、パッチを添付するためのオプションが見つかりませんでした。以下に貼り付けました。
From 7a5b152524a3c82b5bced4a72ed396f21860b666 Mon Sep 17 00:00:00 2001
日付: 2017年5月8日(月)11:33:05 +0100
件名: [PATCH] eRPC_demo実行のための修正
---
erpc_c/infra/transport.h | 4 +-
erpc_c/setup/erpc_server_setup.cpp | 36 ++++-
erpc_c/setup/erpc_server_setup.h | 2 +-
erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp | 54 +++++++
erpc_c/setup/erpc_transport_setup.h | 18 ++-
erpc_c/transports/rpmsg_lite_rtos_transport.cpp | 158 ++++++++++++++++++
erpc_c/transports/rpmsg_lite_rtos_transport.h | 177 +++++++++++++++++++++
erpc_c/transports/rpmsg_rtos_transport.h |147 +++++++++++++++++
erpc_python/erpc/transport.py | 21 +++
9 ファイル変更、602 挿入(+)、15 削除(-)
作成モード 100644 erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp
作成モード 100644 erpc_c/transports/rpmsg_lite_rtos_transport.cpp
作成モード 100644 erpc_c/transports/rpmsg_lite_rtos_transport.h
作成モード 100644 erpc_c/transports/rpmsg_rtos_transport.h
diff --git a/erpc_c/infra/transport.h b/erpc_c/infra/transport.h
index eb7ec71..fd4862a 100644
--- a/erpc_c/infra/transport.h
+++ b/erpc_c/infra/transport.h
@@ -48,7 +48,7 @@
////////////////////////////////////////////////////////////////////////////////
namespace erpc {
-
+class MessageBuffer;
/*!
* @brief トランスポートレイヤーの抽象インターフェース。
*
@@ -89,7 +89,7 @@ public:
*
* @return 送信の実装に基づいています。
*/
- virtual erpc_status_t send(MessageBuffer *message) = 0;
+ virtual erpc_status_t send(const MessageBuffer *message) = 0;
/*!
* @brief 受信メッセージをポーリングします。
diff --git a/erpc_c/setup/erpc_server_setup.cpp b/erpc_c/setup/erpc_server_setup.cpp
index 51fa799..5cd4346 100644
--- a/erpc_c/setup/erpc_server_setup.cpp
+++ b/erpc_c/setup/erpc_server_setup.cpp
@@ -33,8 +33,10 @@
#include "basic_codec.h"
#include "manually_constructed.h"
#include "simple_server.h"
-#include
+#include "message_buffer.h"
+#include "erpc_config_internal.h"
#include
+#include
#if !(__embedded_cplusplus)
using namespace std;
@@ -43,6 +45,29 @@ using namespace std;
using namespace erpc;
////////////////////////////////////////////////////////////////////////////////
+// Classes
+////////////////////////////////////////////////////////////////////////////////
+
+class BasicMessageBufferFactory : public MessageBufferFactory
+{
+public:
+ virtual MessageBuffer create()
+ {
+ uint8_t *buf = new (nothrow) uint8_t[ERPC_DEFAULT_BUFFER_SIZE];
+ return MessageBuffer(buf, ERPC_DEFAULT_BUFFER_SIZE);
+ }
+
+ virtual void dispose(MessageBuffer *buf)
+ {
+ assert(buf);
+ if (*buf)
+ {
+ delete[] buf->get();
+ }
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////
@@ -50,29 +75,32 @@ using namespace erpc;
static ManuallyConstructed
SimpleServer *g_server;
+static ManuallyConstructed
static ManuallyConstructed
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
-void erpc_server_init(erpc_transport_t transport, erpc_mbf_t message_buffer_factory)
+void erpc_server_init(erpc_transport_t transport)
{
// ファクトリを初期化します。
+ s_msgFactory.construct();
s_codecFactory.construct();
// 提供されたトランスポートでサーバーを初期化します。s_server.construct();
s_server->setTransport(reinterpret_cast
+ s_server->setMessageBufferFactory(s_msgFactory);
s_server->setCodecFactory(s_codecFactory);
- s_server->setMessageBufferFactory(reinterpret_cast
g_server = s_server;
}
-
void erpc_server_deinit()
{
+ s_msgFactory.destroy();
s_codecFactory.destroy();
s_server.destroy();
+
}
void erpc_add_service_to_server(void *service)
diff --git a/erpc_c/setup/erpc_server_setup.h b/erpc_c/setup/erpc_server_setup.h
インデックス 8e6a6ef..e4e9eaa 100644
--- a/erpc_c/setup/erpc_server_setup.h
+++ b/erpc_c/setup/erpc_server_setup.h
@@ -60,7 +60,7 @@ extern "C" {
*
* この関数は、サーバーの実行に必要なすべてのコンポーネントを使用してサーバーを初期化します。
*/
-void erpc_server_init(erpc_transport_t transport, erpc_mbf_t message_buffer_factory);
+void erpc_server_init(erpc_transport_t transport);
/*!
* @brief この関数はサーバーの初期化を解除します。
diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp
new file mode 100644
index 0000000..b480d42
--- /dev/null
+++ b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp
@@ -0,0 +1,54 @@
+ /*
+ * Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
+ *
+ * ソースおよびバイナリ形式での再配布および使用は、変更の有無にかかわらず、+
* 以下の条件を満たしている場合に限り許可されます。
+
*+ * o ソースコードの再配布には、上記の著作権表示、この条件の一覧、および
+ * 以下の免責事項を含める必要があります。
+ *
+ * o バイナリ形式での再配布では、上記の著作権表示、この
+ * 条件リスト、
および以下の免責事項をドキュメントおよび/または
配布物に付属する他の資料に複製する必要があります。+ *
+ * o Freescale Semiconductor, Inc.の名前もその
+ * 貢献者の名前も、この
+ * ソフトウェアから派生した製品の推奨または宣伝に使用することは、書面による事前の特別な許可なしにできません。
+ *
+ * このソフトウェアは、著作権所有者およびコントリビューターによって「現状のまま」提供され、
+ * 明示的であるかまたは黙示的であるかにかかわらず、商品性および特定目的への適合性に関する黙示の
+ * 保証を含むがこれに限定されない、いかなる保証も
+ * 否認されます。いかなる場合も、著作権者またはコントリビューターは、
+ * 直接的、間接的、付随的、特別、例示的、または結果的な損害
+ *(代替の商品やサービスの調達を含むがこれらに限定されない、
+ * 使用、データ、または利益の喪失、あるいは事業の中断を含むが、これらに限定されない)
+ * あらゆる責任理論(契約、厳格責任、または不法行為を含む)について、
+ *(過失を含むか否かにかかわらず)この
+ * ソフトウェアの使用から生じるいかなる形でも、そのような損害の可能性について知らされていたとしても、責任を負わないものとします。+ */
+
+#include "manually_constructed.h"
+#include "rpmsg_lite_rtos_transport.h"
+#include "erpc_transport_setup.h"
+
+using namespace erpc;
+
+////////////////////////////////////////////////////////////////////////////////
+// Variables
+////////////////////////////////////////////////////////////////////////////////
+
+static ManuallyConstructed
+
+////////////////////////////////////////////////////////////////////////////////
+// Code
+////////////////////////////////////////////////////////////////////////////////
+
+erpc_transport_t erpc_transport_rpmsg_lite_rtos_remote_init(
+ unsigned long src_addr, unsigned long dst_addr, void *start_address, int rpmsg_link_id, void (*ready_cb)(void), bool send_nameservice)
+{
+ s_transport.construct();
+ s_transport->init(src_addr, dst_addr, start_address, rpmsg_link_id, ready_cb, send_nameservice);
+ return reinterpret_cast
+}
+
+
diff --git a/erpc_c/setup/erpc_transport_setup.h b/erpc_c/setup/erpc_transport_setup.h
index 798d92f..6c3959e 100644
--- a/erpc_c/setup/erpc_transport_setup.h
+++ b/erpc_c/setup/erpc_transport_setup.h
@@ -34,6 +34,7 @@
#include "erpc_version.h"
#include
+#include
/*!
* @addtogroup transport_setup
@@ -48,7 +49,7 @@
//! @brief 不透明なトランスポートオブジェクトタイプ。
typedef struct ErpcTransport *erpc_transport_t;
//! @brief トランスポートの準備完了コールバックオブジェクトタイプ。
-typedef void (*rpmsg_ready_cb)(void);
+//typedef void (*rpmsg_ready_cb)(void);
////////////////////////////////////////////////////////////////////////////////
// API
@@ -106,21 +107,21 @@ erpc_transport_t erpc_transport_rpmsg_lite_master_init(unsigned long src_addr,
/*!
* @brief RPMsg-Lite ゼロコピー転送を作成します。
*/
-erpc_transport_t erpc_transport_rpmsg_lite_zc_master_init(unsigned long src_addr,
- unsigned long dst_addr,
- int rpmsg_link_id);
+//erpc_transport_t erpc_transport_rpmsg_lite_zc_master_init(unsigned long src_addr,
+// unsigned long dst_addr,
+// int rpmsg_link_id);
/*!
* @brief RPMsg-Lite トランスポートを作成します。
*/
erpc_transport_t erpc_transport_rpmsg_lite_remote_init(
- unsigned long src_addr, unsigned long dst_addr, void *start_address, int rpmsg_link_id, rpmsg_ready_cb ready);
+ unsigned long src_addr, unsigned long dst_addr, void *start_address, int rpmsg_link_id, void (*ready_cb)(void), bool send_nameservice);
/*!
* @brief RPMsg-Lite ゼロコピー・トランスポートを作成します。
*/
-erpc_transport_t erpc_transport_rpmsg_lite_zc_remote_init(
- unsigned long src_addr, unsigned long dst_addr, void *start_address, int rpmsg_link_id, rpmsg_ready_cb ready);
+//erpc_transport_t erpc_transport_rpmsg_lite_zc_remote_init(
+// unsigned long src_addr, unsigned long dst_addr, void *start_address, int rpmsg_link_id, rpmsg_ready_cb ready);
/*!
* @brief RPMsg-Lite RTOS トランスポートを作成します。
@@ -133,7 +134,8 @@ erpc_transport_t erpc_transport_rpmsg_lite_rtos_master_init (unsigned long src_ad * @brief) RPMsg-Lite RTOSトランスポートを作成します。*/
erpc_transport_t erpc_transport_rpmsg_lite_rtos_remote_init(
- unsigned long src_addr, unsigned long dst_addr, void *start_address, int rpmsg_link_id, rpmsg_ready_cb ready);
+ unsigned long src_addr, unsigned long dst_addr, void *start_address, int rpmsg_link_id, void (*ready_cb)(void), bool send_nameservice);
+
//@}
diff --git a/erpc_c/transports/rpmsg_lite_rtos_transport.cpp b/erpc_c/transports/rpmsg_lite_rtos_transport.cpp
new file mode 100644
index 0000000..e04ae91
--- /dev/null
+++ b/erpc_c/transports/rpmsg_lite_rtos_transport.cpp
@@-0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ *
+ * ソース形式およびバイナリ形式での再配布および使用は、変更の有無にかかわらず、
+ * 以下の条件を満たしている場合に限り許可されます。
+ *
+ * o ソースコードの再配布には、上記の著作権表示、この条件の一覧
+ * および以下の免責事項を含める必要があります。
+ *
+ * o バイナリ形式での再配布では、上記の著作権表示、この
+ * 条件リスト、
および以下の免責事項をドキュメントおよび/または
配布物に付属する他の資料に複製する必要があります。
+ *
+ * o Freescale Semiconductor, Inc.の名前もその
+ *コントリビューターの名前も、この
+ *ソフトウェアから派生した製品の推奨または宣伝に使用することは、書面による事前の特別な許可なしにできません。
+ *
+ * このソフトウェアは、著作権所有者およびコントリビューターによって「現状のまま」提供され、
+ * 明示的であるかまたは黙示的であるかにかかわらず、商品性および特定目的への適合性に関する黙示の
+ * 保証を含むがこれに限定されない、いかなる保証も
+ * 否認されます。いかなる場合も、著作権者またはコントリビューターは、
+ * 直接的、間接的、付随的、特別、例示的、または結果的な損害
+ *(代替の商品やサービスの調達を含むがこれらに限定されない、
+ * 使用、データ、または利益の喪失、あるいは事業の中断を含むが、これらに限定されない)
+ * あらゆる責任理論(契約、厳格責任、または不法行為を含む)について、
+ *(過失を含むか否かにかかわらず、このソフトウェアの使用から生じるいかなる形で、そのような損害の可能性について知らされていたとしても、責任を負わないものとします。
+ */
+
+#include "rpmsg_lite_rtos_transport.h"
+#include
+
+#if !(__embedded_cplusplus)
+using namespace std;
+#endif
+
+using namespace erpc;
+
+////////////////////////////////////////////////////////////////////////////////
+// Variables
+////////////////////////////////////////////////////////////////////////////////
+uint8_t RPMsgRTOSTransport::s_initialized = 0;
+struct rpmsg_lite_instance *RPMsgRTOSTransport::s_rpmsg;
+
+////////////////////////////////////////////////////////////////////////////////
+// Code
+////////////////////////////////////////////////////////////////////////////////
+
+RPMsgRTOSTransport::RPMsgRTOSTransport()
+: Transport()
+, m_dst_addr(0)
+{
+}
+
+RPMsgRTOSTransport::~RPMsgRTOSTransport()
+{
+ rpmsg_lite_deinit(s_rpmsg);
+ s_initialized = 0;
+}
+
+erpc_status_t RPMsgRTOSTransport::init(
+ unsigned long src_addr, unsigned long dst_addr, void *base_address, unsigned long length, int rpmsg_link_id)
+{
+ if (!s_initialized)
+ {
+ s_rpmsg = rpmsg_lite_master_init(base_address, length, rpmsg_link_id, RL_NO_FLAGS);
+ s_initialized = 1;
+ }
+
+ m_rpmsg_queue = rpmsg_queue_create(s_rpmsg);
+ m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue);
+
+ m_dst_addr = dst_addr;
+ return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success;
+}
+
+erpc_status_t RPMsgRTOSTransport::init(
+ unsigned long src_addr, unsigned long dst_addr, void *base_address, int rpmsg_link_id, void (*ready_cb)(void), bool send_nameservice)
+{
+ if (!s_initialized)
+ {
+ s_rpmsg = rpmsg_lite_remote_init(base_address, rpmsg_link_id, RL_NO_FLAGS);
+
+ /* 他のコアに準備ができたことを知らせます */
+ if (ready_cb != NULL)
+ {
+ ready_cb();
+ }
+
+ while (!rpmsg_lite_is_link_up(s_rpmsg))
+ {
+ }
+
+ s_initialized = 1;
+ }
+
+ m_rpmsg_queue = rpmsg_queue_create(s_rpmsg);
+ m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue);
+
+ if(send_nameservice)
+ {
+ rpmsg_ns_announce(s_rpmsg, m_rpmsg_ept,
+ "rpmsg-openamp-demo-channel",
+ 0);
+ }
+
+ m_dst_addr = dst_addr;
+ return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success;
+}
+
+erpc_status_t RPMsgRTOSTransport::receive(MessageBuffer *message)
+{
+ int ret_val = rpmsg_queue_recv(s_rpmsg, m_rpmsg_queue, &m_dst_addr, (char *)message->get(), kRpmsgMessageBufferSize,
+ NULL, RL_BLOCK);
+ return ret_val != RL_SUCCESS ? kErpcStatus_ReceiveFailed : kErpcStatus_Success;
+}
+
+erpc_status_t RPMsgRTOSTransport::send(const MessageBuffer *message)
+{
+ int ret_val =
+ rpmsg_lite_send(s_rpmsg, m_rpmsg_ept, m_dst_addr, (char *)message->get(), message->getUsed(), RL_BLOCK);
+ return ret_val != RL_SUCCESS ? kErpcStatus_SendFailed : kErpcStatus_Success;
+}
+
+MessageBuffer RPMsgMessageBufferFactory::create()
+{
+ uint8_t idx = 0;
+ while (((m_freeBufferBitmap & idx) == 0) && (idx < kInitCountMessageBuffers))
+ {
+ idx++;
+ }
+
+ assert(idx < kInitCountMessageBuffers);
+
+ m_freeBufferBitmap &= ~(1 << idx);
+
+ uint8_t *buf;
+ buf = m_buffers[idx];
+
+ assert(NULL != buf);
+ return MessageBuffer(buf, kRpmsgMessageBufferSize);
+}
+
+void RPMsgMessageBufferFactory::dispose(MessageBuffer *buf)
+{
+ assert(buf);
+ uint8_t *tmp = buf->get();
+
+ if (tmp)
+ {
+ uint8_t idx = 0;
+ while ((tmp != m_buffers[idx]) && (idx < kInitCountMessageBuffers))
+ {
+ ++idx;
+ }
+ m_freeBufferBitmap |= 1 << idx;
+ }
+}
diff --git a/erpc_c/transports/rpmsg_lite_rtos_transport.h b/erpc_c/transports/rpmsg_lite_rtos_transport.h
new file mode 100644
index 0000000..f1aec8a
--- /dev/null
+++ b/erpc_c/transports/rpmsg_lite_rtos_transport.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
+ *
+ * ソースおよびバイナリ形式での再配布および使用は、修正の有無にかかわらず、
+ * 以下の条件が満たされている場合に許可されます。
+ *
+ * o ソースコードの再配布には、上記の著作権表示、この条件のリスト、
+ * および以下の免責事項を保持する必要があります。
+ *
+ * o バイナリ形式での再配布では、上記の著作権表示、この
+ * 条件リスト、
および以下の免責事項をドキュメントおよび/または
配布物に付属する他の資料に複製する必要があります。
+ *
+ * o Freescale Semiconductor, Inc.の名前もその
+ *貢献者の名前も、この
+ *ソフトウェアから派生した製品の推奨または宣伝に使用することは、書面による事前の特別な許可なしにできません。
+ *
+ * このソフトウェアは、著作権所有者およびコントリビューターによって「現状のまま」提供されます。
+ * 明示的であるかまたは黙示的であるかにかかわらず、
+ * 商品性および特定目的への適合性に関する黙示の保証を含むがこれに限定されない、いかなる保証も
+ * 否認されます。いかなる場合も、著作権者またはコントリビューターは、
+ * 直接的、間接的、付随的、特別、例示的、または結果的な損害、+ *(代替の商品やサービスの調達を含むがこれらに限定されない、
+ * 使用、データ、または利益の喪失、あるいは事業の中断を含むが、これらに限定されない)+ * あらゆる責任理論(契約、厳格責任、または不法行為を含む)について、
+ *(過失を含むか否かにかかわらず)この
+ * ソフトウェアの使用から生じるいかなる形で、そのような損害の可能性について知らされていたとしても、責任を負わないものとします。
+ */++#ifndef _EMBEDDED_RPC__RPMSG_LITE_RTOS_TRANSPORT_H_+#define _EMBEDDED_RPC__RPMSG_LITE_RTOS_TRANSPORT_H_++#include "transport.h"+#include "message_buffer.h"+#include "rpmsg_lite.h"+#include "rpmsg_queue.h"+#include 「rpmsg_ns.h」+
+/*!
+ * @addtogroup rpmsg_lite_rtos_transport
+ * @{
+ * @file
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+// Definitions
+////////////////////////////////////////////////////////////////////////////////
+
+enum
+{
+ kRpmsgMessageBufferSize = RPMSG_BUFFER_SIZE,
+ kInitCountMessageBuffers = 2,
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Classes
+////////////////////////////////////////////////////////////////////////////////
+
+namespace erpc
+{
+/*!
+ * @brief プロセッサ間メッセージングに RPMsg RTOS API を使用するトランスポート。
+ *
+ * @ingroup rpmsg_lite_rtos_transport
+ */
+class RPMsgRTOSTransport : public Transport
+{
+public:
+ /*!
+ * @brief コンストラクタ。
+ *+ * この関数はオブジェクトの属性を初期化します。+ */+ RPMsgRTOSTransport();++ /*!+ * @brief RPMsgRTOSTransport デストラクタ+ */+ virtual ~RPMsgRTOSTransport();++ /*!+ * @brief この関数は、RPMsg RTOS 初期化関数を呼び出します - RPMsg マスターとして+ *+ * @Param[in] src_addr ソースアドレス。+ * @Param[in] dst_addr 宛先アドレス。
+ * @Param[in] base_address 共有メモリ内の RPMsg ベースアドレス。
+ * @Param[in] length RPMsg 共有メモリ領域の長さ。
+ * @Param[in] rpmsg_link_id どのコア間で通信が行われるかの選択。
+ *+ * @retval kErpcStatus_Success rpmsg init 関数が正常に実行されたとき。
+ * @retval kErpcStatus_InitFailed rpmsg init 関数が正常に実行されなかったとき。
+ */
+ virtual erpc_status_t init(
+ unsigned long src_addr, unsigned long dst_addr, void *base_address, unsigned long length, int rpmsg_link_id);
+
+ /*!
+ * @brief この関数は RPMsg RTOS 初期化関数を呼び出します - RPMsg リモートとして
+ *
+ * @Param[in] src_addr 送信元アドレス。
+ * @Param[in] dst_addr 宛先アドレス。
+ * @Param[in] base_address 共有メモリ内の RPMsg ベースアドレス。
+ * @Param[in] rpmsg_link_id どのコア間で通信が行われるかの選択。
+ * @Param[in] ready_cb RPMsgの初期化が完了し、コアの準備が整った後に呼び出されるコールバック。
+ * @Param[in] send_nameservice true の場合、RPMsg マスターはネームサービスによって通知されます。
+ *
+ * @retval kErpcStatus_Success rpmsg init 関数が正常に実行されたとき。
+ * @retval kErpcStatus_InitFailed rpmsg init 関数が正常に実行されなかったとき。
+ */
+ virtual erpc_status_t init(
+ unsigned long src_addr, unsigned long dst_addr, void *base_address, int rpmsg_link_id, void (*ready_cb)(void), bool send_nameservice);
+
+ /*!
+ * @brief 受信メッセージをメッセージバッファに保存します。
+ *
+ * メッセージが来ない間、ループを繰り返します。
+ *
+ * @Param[in] message 受信メッセージが格納されるメッセージバッファ。
+ *
+ * @retval kErpcStatus_ReceiveFailed メッセージバッファの受信に失敗しました。
+ * @retval kErpcStatus_Success すべてのデータを正常に受信しました。
+ */
+ virtual erpc_status_t receive(MessageBuffer *message);
+
+ /*!
+ * @brief 用意されたメッセージを送信する関数。
+ *
+ * @Param[in] message 送信するメッセージバッファを渡します。
+ *
+ * @retval kErpcStatus_SendFailed メッセージバッファの送信に失敗しました。
+ * @retval kErpcStatus_Success すべてのデータを正常に送信しました。
+ */
+ virtual erpc_status_t send(const MessageBuffer *message);
+
+protected:
+ /* リモートデバイス */
+ struct remote_device *m_rdev; /*!< 2 番目のコアを表すデバイス。*/
+ struct rpmsg_channel *m_app_rp_chnl; /*!< 2つのデバイス(2つのコア)間の接続を表します。*/
+ unsigned long m_dst_addr; /*!< rpmsg が使用する宛先アドレス。*/
+ rpmsg_queue_handle m_rpmsg_queue; /*!< RPMsg キューのハンドル。*/
+ struct rpmsg_lite_endpoint *m_rpmsg_ept; /*!< RPMsg Lite エンドポイント構造体へのポインター。*/
+
+ static struct rpmsg_lite_instance *s_rpmsg; /*!< RPMSG lite のインスタンスへのポインター。*/
+ static uint8_t s_initialized; /*!< rpmsg-lite が初期化されたかどうかを表す情報。*/
+};
+
+class RPMsgMessageBufferFactory : public MessageBufferFactory
+{
+ uint8_t m_freeBufferBitmap;
+ uint8_t m_buffers[kInitCountMessageBuffers][kRpmsgMessageBufferSize];
+
+public:
+ /*!
+ * @brief コンストラクター。
+ */
+ RPMsgMessageBufferFactory()
+ : m_freeBufferBitmap(0xFF)
+ {
+ }
+ /*!
+ * @brief RPMsgMessageBufferFactory destructor
+ */
+ virtual ~RPMsgMessageBufferFactory() {}
+ /*!
+ * @brief この関数は、デバイス間の通信に使用されるメッセージバッファを作成します。
+ */
+ virtual MessageBuffer create();
+ /*!
+ * @brief この関数は、デバイス間の通信に使用されるメッセージバッファを破棄します。
+ */
+ virtual void dispose(MessageBuffer *buf);
+};
+
+} // namespace erpc
+
+/*! @} */
+
+#endif // _EMBEDDED_RPC__RPMSG_LITE_RTOS_TRANSPORT_H_
diff --git a/erpc_c/transports/rpmsg_rtos_transport.h b/erpc_c/transports/rpmsg_rtos_transport.h
new file mode 100644
index 0000000..ad1d229
--- /dev/null
+++ b/erpc_c/transports/rpmsg_rtos_transport.h
@@-0,0 +1,147 @@+/*+ * Copyright (c) 2015, Freescale Semiconductor, Inc.+ *+ * ソースおよびバイナリ形式での再配布および使用は、変更の有無にかかわらず、+ * 以下の条件を満たす場合に許可されます。+ *+ * o ソースコードの再配布には、上記の著作権表示、この条件のリスト+ * および以下の免責事項を含める必要があります。+ *
+ * o バイナリ形式での再配布では、上記の著作権表示、この
+ * 条件リスト、
および以下の免責事項をドキュメントおよび/または
配布物に付属する他の資料に複製する必要があります。
+ *
+ * o Freescale Semiconductor, Inc.の名前もその
+ *貢献者の名前も、この
+ *ソフトウェアから派生した製品の推奨または宣伝に使用することは、書面による事前の特別な許可なしにできません。
+ *
+ * このソフトウェアは、著作権所有者およびコントリビューターによって「現状のまま」提供され、
+ * 明示的であるかまたは黙示的であるかにかかわらず、商品性および特定目的への適合性に関する黙示の
+ * 保証を含むがこれに限定されない、いかなる保証も
+ * 否認されます。いかなる場合も、著作権者またはコントリビューターは、
+ * 直接的、間接的、付随的、特別、例示的、または結果的な損害、
+ *(代替の商品やサービスの調達を含むがこれらに限定されない、
+ * 使用、データ、または利益の喪失、あるいは事業の中断を含むが、これらに限定されない)
+ * あらゆる責任理論(契約、厳格責任、または不法行為を含む)について、
+ *(過失を含むか否かにかかわらず)この
+ * ソフトウェアの使用から生じるいかなる形で、そのような損害の可能性について知らされていたとしても、責任を負わないものとします。
+ */
+
+#ifndef _EMBEDDED_RPC__RPMSG_RTOS_TRANSPORT_H_
+#define _EMBEDDED_RPC__RPMSG_RTOS_TRANSPORT_H_
+
+#include "transport.h"
+#include "message_buffer.h"
+
+extern "C" {
+#include "rpmsg.h"
+#include "rpmsg_rtos.h"
+#include "rpmsg.h"
+}
+
+/*!
+ * @addtogroup rpmsg_rtos_transport
+ * @{
+ * @file
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+// Definitions
+////////////////////////////////////////////////////////////////////////////////
+
+enum
+{
+ kRpmsgMessageBufferSize = RPMSG_BUFFER_SIZE,
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Classes
+////////////////////////////////////////////////////////////////////////////////
+
+namespace erpc
+{
+/*!
+ * @brief プロセッサ間メッセージングに RPMsg RTOS API を使用するトランスポート。
+ *
+ * @ingroup rpmsg_rtos_transport
+ */
+class RPMsgRTOSTransport : public Transport
+{
+public:
+ /*!
+ * @brief コンストラクタ。
+ *
+ * この関数はオブジェクトの属性を初期化します。
+ */
+ RPMsgRTOSTransport();
+
+ /*!
+ * @brief RPMsgRTOSTransport destructor
+ */
+ virtual ~RPMsgRTOSTransport();
+
+ /*!
+ * @brief この関数は rpmsg rtos init 関数を呼び出します。
+ *
+ * @Param[in] dev_id デバイスID番号。
+ * @Param[in] role デバイスロール番号。
+ *
+ * @retval kErpcStatus_Success rpmsg init 関数が正常に実行されたとき。
+ * @retval kErpcStatus_InitFailed rpmsg init 関数が正常に実行されなかったとき。
+ */
+ virtual erpc_status_t init(int dev_id, int role);
+
+ /*!
+ * @brief 受信メッセージをメッセージバッファに保存します。
+ *
+ * メッセージが送信されない間、ループを繰り返します。
+ *
+ * @Param[in] message 受信メッセージが格納されるメッセージバッファ。
+ *
+ * @retval kErpcStatus_ReceiveFailed メッセージバッファの受信に失敗しました。
+ * @retval kErpcStatus_Success すべてのデータを正常に受信しました。
+ */
+ virtual erpc_status_t receive(MessageBuffer *メッセージ);
+
+ /*!
+ * @brief 用意されたメッセージを送信する関数。.
+ *
+ * @Param[in] message 送信するメッセージバッファを渡します。
+ *
+ * @retval kErpcStatus_SendFailed メッセージバッファの送信に失敗しました。
+ * @retval kErpcStatus_Success すべてのデータが正常に送信されました。
+ */
+ virtual erpc_status_t send(const MessageBuffer *メッセージ);
+
+protected:
+ /* リモートデバイス */
+ static struct remote_device *m_rdev; /*!< 2 番目のコアを表すデバイス。*/
+ static struct rpmsg_channel *m_app_rp_chnl; /*!< 2つのデバイス(2つのコア)間の接続を表します。*/
+};
+
+class RPMsgMessageBufferFactory : public MessageBufferFactory
+{
+public:
+ /*!
+ * @brief コンストラクタ。
+ */
+ RPMsgMessageBufferFactory() {}
+ /*!
+ * @brief RPMsgMessageBufferFactory destructor
+ */
+ virtual ~RPMsgMessageBufferFactory() {}
+ /*!
+ * @brief デバイス間の通信に使用するメッセージバッファを作成する関数です。
+ */
+ virtual MessageBuffer create();
+ /*!
+ * @brief この関数は、デバイス間の通信に使用されるメッセージバッファを破棄します。
+ */
+ virtual void dispose(MessageBuffer *buf);
+};
+
+} // namespace erpc
+
+/*! @} */
+
+#endif // _EMBEDDED_RPC__RPMSG_RTOS_TRANSPORT_H_
diff --git a/erpc_python/erpc/transport.py b/erpc_python/erpc/transport.py
index 0765e9f..c335943 100644
--- a/erpc_python/erpc/transport.py
+++ b/erpc_python/erpc/transport.py
@@ -31,6 +31,8 @@
import struct
import serial
+from rpmsg.sysfs import RpmsgEndpoint
+import time
import socket
import threading
from .crc16 import crc16
@@ -107,6 +109,25 @@ class SerialTransport(FramedTransport):
class ConnectionClosed(Exception):
pass
+class RpmsgTransport(Transport):
+ def __init__(self):
+ self.ept = RpmsgEndpoint(
+ RpmsgEndpoint.rpmsg_openamp_channel,
+ RpmsgEndpoint.LOCAL_DEFAULT_ADDRESS,
+ RpmsgEndpoint.Types.DATAGRAM)
+
+ def send(self, message):
+ self.ept.send(message, RpmsgEndpoint.REMOTE_DEFAULT_ADDRESS)
+
+ def receive(self):
+ while True:
+ ret = self.ept.recv(2048)
+ if len(ret[1]) != 0:
+ return ret[1]
+ else:
+ time.sleep(0.001)
+ return ret[1]
+
class TCPTransport(FramedTransport):
def __init__(self, host, port, isServer):
super(TCPTransport, self).__init__()
--
2.7.4
ドゥシャン、ありがとうございます ![]()
再度の返信ありがとうございます。Pythonファイルを受け取りました。デモを実行し、すぐに結果をお知らせします。
こんにちは、その調子です。(笑顔のウィンクの顔文字)必要に応じて、imxデモリポジトリにプルリクエストを作成して修正できます。mareknovak がそれを確認し、リポジトリにマージできます。
Python コードを生成するには、他のアプリケーションと同様に、コマンドラインで「erpcgen --help (-h も機能します)」を実行できます。
python -gpy idl_file -> gpy は Python を生成することを意味します。
素晴らしいですね。更新まで同じ安定したバージョンで作業を続けることができます。
いくつかの修正により、MCUデモがビルドされ、正常に実行されるようになりました。情報を提供していただき、ありがとうございます。
Hi Dusan
修正したら、MCUデモが正常に動作するようになりました。安定したバージョンを教えてくださり、ありがとうございます。
erpcgen ツールを使用して Python コードを生成する方法を教えていただけますか。
よろしくお願い申し上げます。
チャンディーニ
こんにちは、最短で明日です。しかし、明日になるとはお約束できません。私の同僚mareknovakは本日勤務していません。ですが、あまり時間はかからないはずです。
いつ更新するのか教えていただけますか。
こんにちは、関心をお寄せいただきありがとうございます。その後、erpc によって生成されたファイルは、Marek がコミットで提供したものとは異なる erpcgen によって生成されたようです(私たちのミスです)。最善の解決策としては、そのデモを最新の安定した erpc および erpcgen バージョンに更新する必要があるようです。GitHub - EmbeddedRPC/erpc: Embedded RPCのマスターブランチからこれを試していただけます(erpcgen プリビルド 1.4.0 もあります)が、どれだけの変更が必要なのかわかりません。代わりに更新を待っていただくことも可能です。
Hi Dusan
あなたが参照されたのと同じeRPCライブラリを使用していました。
私が従った手順は以下の通りです。
erpc-imx-demosのクローン作成、(eRPC GitHub - 232afb209f0a0cfceb25a1be11879f7d1934e065 の MarekNovakNXP/erpc をクローンする)サブモジュールを含む
1. git clone --recursive https://github.com/EmbeddedRPC/erpc-imx-demos.git
2. erpc-imx-demos/middleware/erpc フォルダに移動し、以下のように erpcgen をビルドしました。
erpcgen を正常に取得しました
3.以下のようにerpc_matrix_multiply.erpcを使用して、独自の出力ファイルの作成を試みました。
以下のファイルを正常に取得しました。
erpc_matrix_multiply.h
erpc_matrix_multiply_server.cpp
erpc_matrix_multiply_server.h
erpc_matrix_multiply_client.cpp
4. MCU/example_erpc/build/armgcc/imx7d_sdb_m4/build_all.shのビルドを試みました。
エラーが発生して失敗しました。
/home/basavarajuc/test/erpc-imx-demos/MCU/example_erpc/service/erpc_matrix_multiply_server.cpp: 関数内 'void* create_MatrixMultiplyService_service()':
/home/basavarajuc/test/erpc-imx-demos/MCU/example_erpc/service/erpc_matrix_multiply_server.cpp:168:56: エラー: 抽象クラス型 'MatrixMultiplyService_service' の new-expression が無効です new (nothrow) MatrixMultiplyService_service() を返します。
再度質問して申し訳ありませんが、きちんと理解したいと考えています。
1. GitHub の eRPC ライブラリ (232afb209f0a0cfceb25a1be11879f7d1934e065 の MarekNovakNXP/erpc) を使用している場合、 デモを正常に実行するには、デモを更新する必要がありますか。
2.erpc-imx-demos/MCU/example_erpc/service at master · EmbeddedRPC/erpc-imx-demos · GitHub からの出力ファイルは、どのバージョンの erpcgen で生成されているか教えていただけますか?
古いerpcgenを使用して、すぐに自分のファイルを作成できるようにしたいのです。
お手数をおかけしますが、どうぞよろしくお願い申し上げます。
チャンディーニ
こんにちは、コメントをありがとうございます。ご指摘の例は、お使いの erpcgen ビルドよりも古いバージョンです。mareknovak は、当時の公式リリースにはなかったいくつかの小さな変更により、公式 eRPC リポジトリのフォークも作成しました。ミドルウェアフォルダーのerpc-imx-demosリポジトリからeRPC参照をクリックすると、eRPCリポジトリにリダイレクトされます。そのバージョンから erpcgen をビルドする必要があります。将来的にはデモを更新したいと考えています。
お役に立てたなら幸いです。ご不明な点がございましたら、どうぞお気軽にお問い合わせください。
Hi
基本的な質問であれば申し訳ございません。
NXP の erpcgen ツールの使用方法を理解しようとしています。
サンプルデモを正常に実行しました。こちらを参照しました:https://github.com/EmbeddedRPC/erpc-imx-demos
次のアプローチは、erpcgen をビルドし、同じ erpc_matrix_multiply.erpcを使用して独自の出力ファイルを作成し、同じデモを再度実行して、erpcgen ツールの使用に慣れることでした。
出力ファイルを取得しましたが、同じ erpc_matrix_multiply.erpc を使用しているにもかかわらず、私のファイルはサンプルファイルと異なります。
変更点は以下の通りです:
例示デモの出力ファイルは次のとおりです (erpc_matrix_multiply_server.h):
erpc_status_t erpcMatrixMultiply_shim(erpc::Codec * in, erpc::Codec * out, uint32_t sequence);
私のファイル(erpc_matrix_multiply_server.h):
erpc_status_t erpcMatrixMultiply_shim(erpc::Codec * codec, uint32_t sequence);
ファイルが異なる理由、欠けている設定があれば教えてください。
erpc_matrix_multiply_server.h および erpc_matrix_multiply_server.cpp を手動で編集する必要がありますか。
よろしくお願いいたします
チャンディーニ