SOME/IPのプロトコルを理解しよう ~SOME/IPプロトコル基本編~

SOME/IP,勉強,通信

今回は業務関連でSOME/IPのプロトコルについて理解を深めていきます。

なお、正式なAUTOSARの規格は以下から取得できるので、興味がある方こちらも参考にしてください。

概要

SOME/IPは車両内のECUどうしがEthernet経由でTCP/UDPを使用して通信を行うための規格です。

DoIP通信が診断機とECUの一対一通信が基本であったのに対し、SOME/IPは車両内の多数のECU間における相互通信を前提としています。

ECU間の通信用途(カメラ、バッテリー、地図アプリ等)ごとにSOME/IPが扱うサービスが存在し、それらはService IDと呼ばれるユーザー/システム設計者が決める任意の値によって識別されます。

ECUはこのサービスを提供する側(サーバ)と利用する側(クライアント)に分かれて相互にやり取りを行います。

Method (メソッド)

SOME/IPの主な用途はRemote Procedure Call (RPC)と呼ばれる、あるECU(クライアント)から別のECU(サーバ)へのメソッド呼び出しです。

ここでいうメソッドとはクライアントからサーバに対して要求可能な、サーバの提供する機能のことを指します。

メソッドにはGetterSetterMethod callFire & forgetの4つがあります。

メソッド概要
GetterField(サーバが管理する任意の情報)の値を取得する
SetterField(サーバが管理する任意の情報)の値を更新する
Method call処理を依頼し、処理結果を受け取る
Fire & forge処理を依頼し、処理結果を受け取らない

Event (イベント)

突発的、あるいは周期的なアクションに応じて、ECU(サーバ)からECU(クライアント)向けに送信される単方向のデータ伝送です。

Notifierとして、サーバが管理するField情報の更新を通知するイベントが定義されています。

SOME/IP ヘッダフォーマット

まずはヘッダのフォーマットからざっくりとみていきます。

以下に示すメッセージフォーマットのうち、Message IDからReturn Codeまでの構造はSOME/IPで扱うフレームにおいて共通のヘッダフォーマットとなります。

メッセージIDはサービスの識別に使用される識別子です。

本値でどのサービスのどのメソッド、またはイベントに関するフレームであるかを識別します。

本値は車両内のシステムにおいて一意でなければなりません。

また、メソッドIDは以下のようにサービスID(16bit)とメソッドID(15bit)、もしくはサービスID(16bit)とイベントID(15bit)の連結となっています。

Length

Request IDから SOME/IP メッセージの終わりまでの⻑さがバイト単位で含まれます。

Request ID

リクエストIDは複数ECUから同一のMessage IDによる要求を受け付けた際、サービスを並列して行えるように区別するための識別子です。

サーバはクライアントから通知されたRequest IDを、そのまま応答メッセージへと使用します。

リクエストIDは、以下のようにクライアントID(16bit)とセッションID(16bit)の連結となっています。

Client ID

クライアントID は車両内ECUのうち、どのECUからの要求であるかを識別するための識別子です。

Session ID

セッション ID は、同じECUから連続して送信されたメッセージを区別するための識別⼦です。

セッション処理がアクティブでない場合セッション ID は0x00、アクティブな場合セッション ID は0x1~0xFFFFのいずれかを使用します。

セッションID使用時は呼び出しごとにインクリメントし、0xFFFF に達すると、ラップアラウンドして0x01から再び開始します。

Protcol Version

プロトコルバージョンは、使⽤されるSOME/IPヘッダーフォーマットを識別するための識別子です。

Interface Version

インターフェースバージョンは、SOME/IPメッセージにおけるペイロードの形式を指定するための識別子です。

Message Type

メッセージタイプはメッセージを区別するために使⽤されます。

具体的には以下の表のとおりに用途に応じて値が設定されます。

設定値メッセージタイプ概要
0x00REQUEST応答を必要とする要求(例:Getter、Setter、Method call)
0x01REQUEST_NO_RETURN応答を不要とする要求(例:Fire & forge)
0x02NOTIFICATION応答を不要とする通知(例:Notifier)
0x80RESPONSEREQUESTメッセージに対する応答
0x81ERRORREQUESTメッセージに対するエラー応答
0x20TP_REQUEST応答を必要とする要求(例:Getter、Setter、Method call)
0x21TP_REQUEST_NO_RETURN応答を不要とする要求(例:Fire & forge)
0x22TP_NOTIFICATION応答を不要とする通知(例:Notifier)
0xa0TP_RESPONSETP_REQUESTメッセージに対する応答
0xa1TP_ERRORTP_REQUESTメッセージに対するエラー応答

UDPで1パケットに収まりきらないメッセージを扱う場合、SOME/IPトランスポートプロトコル (SOME/IP-TP)を使用し、より大容量のデータを扱うことが可能です。

メッセージ タイプの上位3 番⽬のビット (=0x20) は TP フラグと呼ばれ、現在のSOME/IPメッセージがSOME/IP-TPであることを⽰すために1に設定されます。

SOME/IP-TPについてはこちらでまとめているため、参考にしてください。

Return Code

リターンコードは、クライアントからサーバに対する要求が正常に処理されたかどうかを通知するために使⽤されます。

応答以外のメッセージにおいては、0x00が固定値として設定されます。

設定値リターンコード概要
0x00E_OK正常
0x01E_NOT_OK予期せぬエラー発生
0x02E_UNKNOWN_SERVICEサービスID不正
0x03E_UNKNOWN_METHODメソッドID不正
0x04E_NOT_READYアプリケーションがまだ起動していない
0x05E_NOT_REACHABLEアプリケーションが異常などにより動作出来ない
0x06E_TIMEOUTアプリケーション異常によるタイムアウト
0x07E_WRONG_PROTOCOL_VERSIONプロトコルバージョン不正
0x08E_WRONG_INTERFACE_VERSIONインターフェースバージョン不正
0x09E_MALFORMED_MESSAGEペイロード不正
0x0aE_WRONG_MESSAGE_TYPEメッセージタイプ不正
0x0bE_E2E_REPEATEDECU間通信におけるやり取り中の異常
0x0cE_E2E_WRONG_SEQUENCEECU間通信におけるやり取り中の異常
0x0dE_E2EECU間通信におけるやり取り中の異常
0x0eE_E2E_NOT_AVAILABLEECU間通信におけるやり取り中の異常
0x0fE_E2E_NO_NEW_DATAECU間通信におけるやり取り中の異常
0x10-1fRESERVED⼀般的な SOME/IPエラーのための予約領域
0x20-5eRESERVEDサービスとメソッドの特定のエラーのための予約領域

E2E関連のエラーについてはさぼりました。

気になる人は以下などが参考になると思います。

Payload

ペイロードは、シリアル化されたパラメータが格納される領域です。

UDPのペイロード長は 0 〜 1400バイトになりますが、前述のSOME/IP-TPを使用することでより大きなサイズのパラメータを扱うことが可能です。

TCPの場合は、もともとペイロードのセグメント化をサポートしているためフレームサイズ以上のデータを扱うことが出来ます。

ペイロードデータのシリアル化に関してもSOME/IPで規定されているのですが、今回は割愛します。

気になる方は冒頭の規格書を確認してください。

最後に

今回はSOME/IPプロトコルの基本的な部分についてまとめてみました。

引き続き、今回詳細まで解説しきれなかった要素(SOME/IP-TP、SOME/IP-SD)についても勉強していく予定です。

pythonをつかってSOME/IPの相互通信が出来るようなツールも作ってみましたため、こちらも参考にしていただければと思います。