AM Daemon ライブラリリファレンス
CanTarget.h
[詳解]
1 /// @file
2 /// @brief CANボード単体の通信処理を提供するクラス CanTarget のヘッダ。
3 ///
4 /// Copyright(C)SEGA
5 
6 #ifndef AMDAEMON_CANTARGET_H
7 #define AMDAEMON_CANTARGET_H
8 
9 #include "amdaemon/env.h"
10 #include "amdaemon/CanDef.h"
12 #include "amdaemon/CanAck.h"
13 #include "amdaemon/RequestState.h"
14 #include "amdaemon/util/traits.h"
16 
17 #include <algorithm>
18 #include <type_traits>
19 #include <cstdint>
20 #include <cstddef>
21 
22 namespace amdaemon
23 {
24 /// @addtogroup g_can
25 /// @{
26 
27  // 内部クラスの前方宣言
28  class InnerIndexHolder;
29 
30  /// @brief CANボード単体の通信処理を提供するクラス。
31  /// @see CanPort
32  ///
33  /// このクラスのインスタンスをアプリ側で直接生成することはできない。
34  /// CanPort クラスのメンバ関数 CanPort#getTarget から取得すること。
35  ///
36  /// @par 送信すべきでない命令コード
37  /// メンバ関数 #send を用いて任意の命令コードをリクエスト可能である。
38  /// しかし下記コマンドについてはDaemonプロセスの誤動作を招く恐れがあるため
39  /// 送信すべきではない。
40  /// @par
41  /// - 0xFD : ブートモード遷移
42  /// - 0xFE : ファーム更新
43  /// - 0x10 : ボードリセット
44  /// - 0x83 : 自動送信設定(CAN I/O ボード 837-15257)
45  /// @par
46  /// ボードリセットと自動送信設定についてはDaemonプロセスが必要に応じて送信する。
47  /// @par
48  /// ファーム更新は非対応である。ファーム更新を実装する必要がある場合は
49  /// AM Daemon サポートに相談すること。
50  ///
51  /// @par 送信する必要のない命令コード
52  /// 下記コマンドについてはDaemonプロセスが自動的に送信して情報を取得済みであるため、
53  /// わざわざアプリ側で送信する必要はない。
54  /// @par
55  /// - 0xF0 : ボード品番取得
56  /// - 0xF2 : ファーム情報取得
57  /// - 0xF3 : カスタムチップ品番取得
58  /// @par
59  /// これらの情報はメンバ関数 #getProperty によって取得できる。
60  ///
61  /// @par エミュレータ環境における動作
62  /// エミュレータ環境においては、アクノリッジパケットルールが定義されていれば
63  /// その定義通りのアクノリッジパケットを返す。
64  /// @par
65  /// アクノリッジパケットルールが定義されていない命令コードのうち、
66  /// 下記の命令コードについては実ボード動作をエミュレートする。
67  /// @par
68  /// - 0xF0 : ボード品番取得
69  /// - 0xF2 : ファーム情報取得
70  /// - 0xF3 : カスタムチップ品番取得
71  /// - 0xF4 : エラーレポート
72  /// - 0x10 : ボードリセット(直近のエラーレポートのリセットのみ行う)
73  /// @par
74  /// それ以外の命令コードについては非サポートエラーを返す。
75  class CanTarget
76  {
77  public:
78  /// @brief コンストラクタ。
79  /// @note アプリ側からは利用できない。
80  CanTarget(InnerIndexHolder, InnerIndexHolder);
81 
82  // 下記は暗黙の定義を用いる。
83  //‾CanTarget() = default;
84 
85  /// @brief ボード情報を取得する。
86  /// @return ボード情報。
87  const CanTargetProperty& getProperty() const;
88 
89  /// @brief リクエストパケットの送信を要求する。
90  /// @param[in] command 命令コード。
91  /// @param[in] data パケットデータ。不要ならば nullptr を指定可能。
92  /// @param[in] dataSize
93  /// パケットデータサイズ。
94  /// amdaemon::MaxCanPacketDataSize 以下。データが不要ならば 0 。
95  /// @param[in] priority
96  /// パケットのプライオリティ値。 0 以上 amdaemon::MaxCanPacketPriority 以下。
97  /// 通常は指定を省略し、既定値 amdaemon::DefaultCanPacketPriority を用いること。
98  /// @return 要求状態値。
99  ///
100  /// @exception Exception
101  /// - 引数 data に nullptr を指定した上で引数 dataSize に 0 以外の値を指定した場合。
102  /// - 引数 dataSize に amdaemon::MaxCanPacketDataSize より大きい値を指定した場合。
103  /// - 引数 priority に amdaemon::MaxCanPacketPriority より大きい値を指定した場合。
104  ///
105  /// この関数で任意の命令コードをリクエスト可能であるが、
106  /// いくつかの命令コードについては呼び出すべきでない等、注意すべき点がある。
107  /// 詳しくは CanTarget クラスの説明を参照すること。
108  ///
109  /// この関数の呼び出しに成功した場合、
110  /// 引数 command と同じ命令コードを持つアクノリッジパケット情報が破棄される。
111  /// 過去のアクノリッジパケットを今回のリクエストパケットに対するものと
112  /// 誤認しないようにこのような挙動となっている。
113  ///
114  /// この関数を呼び出す度に要求が内部キューに蓄えられ、順次Daemonプロセスへ送られる。
115  /// 複数の要求はまとめられ、最大 16 要求まで一度に送信されるが、
116  /// あまりに多くの要求を高頻度で行うと送信が追い付かない可能性がある。
117  /// 1 フレームあたり最大でも 8 要求程度に留めること。
118  ///
119  /// 戻り値の要求状態値は、DaemonプロセスがCANポートへリクエストパケットを送信した
120  /// 時点で処理完了状態となり、送信処理の成否を確認できるようになる。
121  /// コマンド自体の成否を確認できるわけではないことに注意。
122  ///
123  /// 個々のコマンドの成否は、メンバ関数 #getAck でアクノリッジパケットを取得可能に
124  /// なってから、そのメンバ関数 CanAck#isError を用いて確認すること。
126  std::uint8_t command,
127  const void* data,
128  std::size_t dataSize,
129  std::uint8_t priority = DefaultCanPacketPriority);
130 
131  /// @brief リクエストパケットの送信を要求する。
132  /// @param[in] command 命令コード。
133  /// @param[in] data パケットデータ。
134  /// @param[in] dataSize
135  /// パケットデータサイズ。既定値は SIZE_MAX (std::size_t 型の最大値)。
136  /// この値と data.size() のうち小さい方の値が実際のサイズとして利用される。
137  /// @param[in] priority
138  /// パケットのプライオリティ値。 0 以上 amdaemon::MaxCanPacketPriority 以下。
139  /// 通常は指定を省略し、既定値 amdaemon::DefaultCanPacketPriority を用いること。
140  /// @return 要求状態値。
141  ///
142  /// @exception Exception
143  /// - 引数 dataSize に amdaemon::MaxCanPacketDataSize より大きい値を指定し、
144  /// かつ引数 data の要素数も amdaemon::MaxCanPacketDataSize より大きい場合。
145  /// - 引数 priority に amdaemon::MaxCanPacketPriority より大きい値を指定した場合。
146  ///
147  /// パケットデータを可変長配列型で指定するオーバロード。
148  /// 挙動は
149  /// send(std::uint8_t, const void*, std::size_t, std::uint8_t)
150  /// オーバロードに準ずる。
152  std::uint8_t command,
153  const std::vector<std::uint8_t>& data,
154  std::size_t dataSize = SIZE_MAX,
155  std::uint8_t priority = DefaultCanPacketPriority)
156  {
157  return
158  this->send(command, data.data(), std::min(dataSize, data.size()), priority);
159  }
160 
161  /// @brief リクエストパケットの送信を要求する。
162  /// @tparam Data パケットデータ型。後述の要件を満たす型でなければならない。
163  /// @param[in] command 命令コード。
164  /// @param[in] data パケットデータ。
165  /// @param[in] dataSize
166  /// パケットデータサイズ。既定値は sizeof(Data) 。
167  /// この値と sizeof(data) のうち小さい方の値が実際のサイズとして利用される。
168  /// @param[in] priority
169  /// パケットのプライオリティ値。 0 以上 amdaemon::MaxCanPacketPriority 以下。
170  /// 通常は指定を省略し、既定値 amdaemon::DefaultCanPacketPriority を用いること。
171  /// @return 要求状態値。
172  ///
173  /// @exception Exception
174  /// - 引数 dataSize に amdaemon::MaxCanPacketDataSize より大きい値を指定し、
175  /// かつ sizeof(data) も amdaemon::MaxCanPacketDataSize より大きい場合。
176  /// - 引数 priority に amdaemon::MaxCanPacketPriority より大きい値を指定した場合。
177  ///
178  /// パケットデータを任意のデータ型(固定長配列等)で指定するオーバロード。
179  /// 挙動は
180  /// send(std::uint8_t, const void*, std::size_t, std::uint8_t)
181  /// オーバロードに準ずる。
182  ///
183  /// 型 Data から参照性を取り除いた型(例えば型 Data が int& ならば int)は
184  /// 下記の要件をすべて満たす必要がある。
185  ///
186  /// - オブジェクト型(スカラ型、配列、クラス&構造体、共用体のいずれか)である。
187  /// - トリビアルコピー可能な型である。
188  /// - ポインタ型ではない。
189  /// - std::nullptr_t 型ではない。
190  ///
191  /// 要するに、安全に std::memcpy によるコピーが可能な型である必要がある。
192  /// 1つでも満たしていない場合はコンパイルエラーとなる。
193  template<class Data>
194  auto send(
195  std::uint8_t command,
196  Data&& data,
197  std::size_t dataSize = sizeof(Data),
198  std::uint8_t priority = DefaultCanPacketPriority)
199  ->
200  typename std::enable_if<
202  typename std::remove_reference<Data>::type>::value,
203  RequestState>::type
204  {
205  return this->send(command, &data, std::min(dataSize, sizeof(data)), priority);
206  }
207 
208  /// @brief リクエストパケットの送信を要求する。
209  /// @param[in] command 命令コード。
210  /// @return 要求状態値。
211  ///
212  /// パケットデータを持たないコマンド用のオーバロード。
213  /// 挙動は
214  /// send(std::uint8_t, const void*, std::size_t, std::uint8_t)
215  /// オーバロードに準ずる。
216  ///
217  /// パケットのプライオリティ値は amdaemon::DefaultCanPacketPriority 固定となる。
218  RequestState send(std::uint8_t command)
219  {
220  return this->send(command, nullptr, 0);
221  }
222 
223  /// @brief 直近の送信要求において指定したパケットデータを取得する。
224  /// @param[in] command 対象の命令コード。
225  /// @param[out] dataSize パケットデータサイズの設定先。不要ならば nullptr 。
226  /// @return パケットデータ。一度も送信要求の開始に成功していない場合は nullptr 。
227  /// @see send
228  ///
229  /// 送信要求の開始にさえ成功していれば、送信処理自体の成否は問わない。
230  ///
231  /// パケットデータを持たないコマンドを送信要求した場合でも、サイズ 0 のデータが返る。
232  /// 一度も送信要求の開始に成功していない場合を除き、 nullptr が返ることはない。
233  const void* getLastSentData(
234  std::uint8_t command,
235  std::size_t* dataSize = nullptr) const;
236 
237  /// @brief アクノリッジパケット情報を取得する。
238  /// @param[in] command 対象の命令コード。
239  /// @return アクノリッジパケット情報。
240  ///
241  /// 引数 command で指定した命令コードを持つアクノリッジパケットを取得する。
242  /// 存在しない場合、戻り値のメンバ関数 CanAck#exists が false を返す。
243  ///
244  /// この関数が返すアクノリッジパケット情報が更新されるタイミングは次の2通りとなる。
245  ///
246  /// - メンバ関数 #send (オーバロード含む)の呼び出しに成功した時。
247  /// - 同じ命令コードのアクノリッジパケットが存在する場合に破棄する。
248  /// - Core クラスのメンバ関数
249  /// Core#execute 呼び出しによってアクノリッジパケットを新しく受け取った時。
250  /// - 同じ命令コードのアクノリッジパケットが存在する場合は上書きする。
251  ///
252  /// なお、コマンド処理に失敗した場合、CAN通信の仕様により
253  /// エラーレポート取得コマンド(命令コード値は amdaemon::CanErrorReportCommand)の
254  /// アクノリッジパケットが返ってくるが、
255  /// その情報についてもこの関数の戻り値が内包している。
256  /// そのためエラーレポート取得コマンドのアクノリッジパケットを監視する必要はない。
257  ///
258  /// アクノリッジパケットを返さないコマンドの処理に成功した場合、
259  /// 通信仕様通り、この関数がアクノリッジパケット情報を返すことはない。
260  /// 処理に失敗した場合は他のコマンドと同じくエラーレポート情報を返す。
261  const CanAck& getAck(std::uint8_t command) const;
262 
263  private:
264  std::size_t _portIndex; ///< ポート定義インデックス。
265  std::size_t _targetIndex; ///< ターゲット定義インデックス。
266 
267  private:
268  // コピー禁止
269  CanTarget(const CanTarget&); // 宣言のみ
270  CanTarget& operator=(const CanTarget&); // 宣言のみ
271  };
272 
273 /// @}
274 } // namespace amdaemon
275 
276 #endif // AMDAEMON_CANTARGET_H
RequestState send(std::uint8_t command, const std::vector< std::uint8_t > &data, std::size_t dataSize=SIZE_MAX, std::uint8_t priority=DefaultCanPacketPriority)
リクエストパケットの送信を要求する。
Definition: CanTarget.h:151
CAN通信に関する情報を定義するヘッダ。
const CanAck & getAck(std::uint8_t command) const
アクノリッジパケット情報を取得する。
Daemonプロセスへの処理要求状態を保持するクラス。
Definition: RequestState.h:37
型に関するメタ関数を定義するヘッダ。
auto send(std::uint8_t command, Data &&data, std::size_t dataSize=sizeof(Data), std::uint8_t priority=DefaultCanPacketPriority) -> typename std::enable_if< ::amdaemon::util::IsBinaryCopyable< typename std::remove_reference< Data >::type >::value, RequestState >::type
リクエストパケットの送信を要求する。
Definition: CanTarget.h:194
Daemonライブラリの環境定義を行うヘッダ。
AM Daemon ライブラリクラス群の基底名前空間。
Definition: Log.h:13
Daemonプロセスへの処理要求状態を保持するクラス RequestState のヘッダ。
const void * getLastSentData(std::uint8_t command, std::size_t *dataSize=nullptr) const
直近の送信要求において指定したパケットデータを取得する。
CanTarget(InnerIndexHolder, InnerIndexHolder)
コンストラクタ。
型 T がバイナリベースでコピー可能な型であるか否かを調べるメタ関数。
Definition: traits.h:34
CANボード単体の通信処理を提供するクラス。
Definition: CanTarget.h:75
RequestState send(std::uint8_t command, const void *data, std::size_t dataSize, std::uint8_t priority=DefaultCanPacketPriority)
リクエストパケットの送信を要求する。
CANボード単体の情報を提供するクラス CanTargetProperty のヘッダ。
コンテナクラス関連の便利処理を提供するヘッダ。
CANボードから送信されたアクノリッジパケット情報を提供するクラス CanAck のヘッダ。 ...
CANボードから送信されたアクノリッジパケット情報を提供するクラス。
Definition: CanAck.h:41
const CanTargetProperty & getProperty() const
ボード情報を取得する。
static const std::uint8_t DefaultCanPacketPriority
CAN通信パケットの既定プライオリティ値。
Definition: CanDef.h:26
CANボード単体の情報を提供するクラス。
Definition: CanTargetProperty.h:28
RequestState send(std::uint8_t command)
リクエストパケットの送信を要求する。
Definition: CanTarget.h:218