APIプログラミングインターフェース
Alius USB2CANデュアルチャンネルデバッガーは、オープンソースのCANAL API DLLを提供し、開発者がプログラミング方式でデバイスを制御できるようにします。このドキュメントでは、APIの使用方法、関数説明、コード例を詳細に紹介し、Alius USB2CANデバッガーをアプリケーションに迅速に統合するのに役立ちます。
CANAL API概要
CANAL(CAN Abstraction Layer)は、さまざまなCANインターフェースデバイスにアクセスするための統一されたインターフェース関数セットを提供するオープンソースのCANバス抽象化レイヤーAPIです。Alius USB2CANデバッガーは、CANAL APIを完全にサポートしているため、開発者はハードウェアに依存しないアプリケーションを作成できます。
APIの特徴
- クロスプラットフォーム:WindowsとLinuxオペレーティングシステムをサポート
- 多言語サポート:C/C++、C#、Python、Java、LabVIEWなど、複数のプログラミング言語をサポート
- オープンソース:ソースコードは開放されており、必要に応じて変更およびカスタマイズ可能
- 使いやすさ:シンプルで直感的なAPI関数を提供
インストールと設定
Windows環境
- CANAL API DLL(通常は
canal.dll)をアプリケーションディレクトリまたはシステムディレクトリ(例:C:\Windows\System32)にコピーします - プロジェクトにCANAL APIヘッダーファイル(
canal.h)を追加します - プロジェクトがCANAL APIライブラリにリンクするように設定します
Linux環境
- CANAL API共有ライブラリ(通常は
libcanal.so)をインストールします - プロジェクトにCANAL APIヘッダーファイルを含めます
- コンパイル時にCANAL APIライブラリにリンクします(
-lcanalオプションを使用)
API関数説明
1. 接続を開く
long CanalOpen(char *pDevice, unsigned long flags);
機能:CANデバイスへの接続を開く
パラメーター:
pDevice:デバイス名またはパス(例:COMポート番号)flags:オープンフラグ(通常は0に設定)
戻り値:
- 成功:デバイスハンドル(> 0)を返します
- 失敗:0を返します
例:
long hDevice = CanalOpen("COM3", 0);
if (0 == hDevice) {
printf("デバイスを開けません\n");
return -1;
}
2. 接続を閉じる
int CanalClose(long handle);
機能:CANデバイスへの接続を閉じる
パラメーター:
handle:デバイスハンドル(CanalOpenが返したもの)
戻り値:
- 成功:1を返します
- 失敗:0を返します
例:
if (0 == CanalClose(hDevice)) {
printf("デバイスを閉じることができません\n");
}
3. デバイスステータスを取得する
int CanalGetStatus(long handle, canalsystemstatus *pStatus);
機能:デバイスの現在のステータスを取得する
パラメーター:
handle:デバイスハンドルpStatus:canalsystemstatus構造体へのポインター
戻り値:
- 成功:1を返します
- 失敗:0を返します
4. 統計情報を取得する
int CanalGetStatistics(long handle, canalstatistics *pStatistics);
機能:デバイスの通信統計情報を取得する
パラメーター:
handle:デバイスハンドルpStatistics:canalstatistics構造体へのポインター
戻り値:
- 成功:1を返します
- 失敗:0を返します
5. CANメッセージを送信する
int CanalSend(long handle, canalmsg *pCanMsg);
機能:CANメッセージを送信する
パラメーター:
handle:デバイスハンドルpCanMsg:canalmsg構造体へのポインター
戻り値:
- 成功:1を返します
- 失敗:0を返します
例:
canalmsg canMsg;
memset(&canMsg, 0, sizeof(canalmsg));
canMsg.id = 0x100; // CANメッセージID
canMsg.flags = 0; // 標準フレーム、RTRなし
canMsg.sizeData = 8; // データ長
canMsg.data[0] = 0x01; // データバイト0
canMsg.data[1] = 0x02; // データバイト1
// ... 他のデータバイトを設定
if (0 == CanalSend(hDevice, &canMsg)) {
printf("メッセージの送信に失敗しました\n");
}
6. CANメッセージを受信する
int CanalReceive(long handle, canalmsg *pCanMsg);
機能:CANメッセージを受信する
パラメーター:
handle:デバイスハンドルpCanMsg:canalmsg構造体へのポインター
戻り値:
- 成功:1を返します
- 失敗:0を返します
- メッセージなし:0を返します(
pCanMsg->sizeDataを確認する必要があります)
例:
canalmsg canMsg;
memset(&canMsg, 0, sizeof(canalmsg));
if (CanalReceive(hDevice, &canMsg)) {
printf("メッセージを受信しました:ID=0x%X, DLC=%d\n", canMsg.id, canMsg.sizeData);
for (int i = 0; i < canMsg.sizeData; i++) {
printf("%02X ", canMsg.data[i]);
}
printf("\n");
} else {
printf("メッセージの受信に失敗するか、メッセージがありません\n");
}
7. フィルターを設定する
int CanalSetFilter(long handle, unsigned long filter);
機能:ハードウェア受信フィルターを設定する
パラメーター:
handle:デバイスハンドルfilter:フィルター値
戻り値:
- 成功:1を返します
- 失敗:0を返します
8. マスクを設定する
int CanalSetMask(long handle, unsigned long mask);
機能:受信マスクを設定する
パラメーター:
handle:デバイスハンドルmask:マスク値
戻り値:
- 成功:1を返します
- 失敗:0を返します
データ構造
canalmsg構造体
typedef struct {
unsigned long id; // CANメッセージID
unsigned char flags; // フラグビット
unsigned char sizeData; // データ長(0-8)
unsigned char data[8]; // データバイト
unsigned long timestamp; // タイムスタンプ(ms)
} canalmsg;
フラグビット定義:
0x00:標準フレーム(11ビットID)0x01:拡張フレーム(29ビットID)0x02:リモートフレーム(RTR)
canalsystemstatus構造体
typedef struct {
unsigned long channel_status; // チャンネルステータス
unsigned long lasterrorcode; // 最後のエラーコード
unsigned long lasterrorsource;// 最後のエラーソース
unsigned long errorcounter; // エラーカウンター
} canalsystemstatus;
canalstatistics構造体
typedef struct {
unsigned long cntReceiveFrames; // 受信フレームカウント
unsigned long cntTransmitFrames; // 送信フレームカウント
unsigned long cntReceiveData; // 受信データバイトカウント
unsigned long cntTransmitData; // 送信データバイトカウント
unsigned long cntOverruns; // オーバーランカウント
unsigned long cntBusWarnings; // バス警告カウント
unsigned long cntBusOff; // バスオフカウント
} canalstatistics;
コード例
C++例
#include <stdio.h>
#include "canal.h"
int main() {
// デバイスを開く
long hDevice = CanalOpen("COM3", 0);
if (0 == hDevice) {
printf("デバイスを開けません\n");
return -1;
}
printf("デバイスが正常に開きました、ハンドル:%ld\n", hDevice);
// メッセージを送信する
canalmsg txMsg;
memset(&txMsg, 0, sizeof(canalmsg));
txMsg.id = 0x100;
txMsg.sizeData = 8;
for (int i = 0; i < 8; i++) {
txMsg.data[i] = i;
}
if (CanalSend(hDevice, &txMsg)) {
printf("メッセージが正常に送信されました\n");
} else {
printf("メッセージの送信に失敗しました\n");
}
// メッセージを受信する(1秒待つ)
canalmsg rxMsg;
memset(&rxMsg, 0, sizeof(canalmsg));
for (int i = 0; i < 100; i++) {
if (CanalReceive(hDevice, &rxMsg)) {
printf("メッセージを受信しました:ID=0x%X, DLC=%d, データ:", rxMsg.id, rxMsg.sizeData);
for (int j = 0; j < rxMsg.sizeData; j++) {
printf("%02X ", rxMsg.data[j]);
}
printf("\n");
}
Sleep(10); // 10 ms待つ
}
// デバイスを閉じる
CanalClose(hDevice);
return 0;
}
Python例
import ctypes
import time
# CANAL DLLをロードする
canal = ctypes.CDLL("canal.dll")
# データ構造を定義する
class CanalMsg(ctypes.Structure):
_fields_ = [
("id", ctypes.c_ulong),
("flags", ctypes.c_ubyte),
("sizeData", ctypes.c_ubyte),
("data", ctypes.c_ubyte * 8),
("timestamp", ctypes.c_ulong)
]
# デバイスを開く
hDevice = canal.CanalOpen("COM3", 0)
if 0 == hDevice:
print("デバイスを開けません")
exit(-1)
print(f"デバイスが正常に開きました、ハンドル:{hDevice}")
# メッセージを送信する
txMsg = CanalMsg()
txMsg.id = 0x100
txMsg.sizeData = 8
for i in range(8):
txMsg.data[i] = i
if canal.CanalSend(hDevice, ctypes.byref(txMsg)):
print("メッセージが正常に送信されました")
else:
print("メッセージの送信に失敗しました")
# メッセージを受信する
rxMsg = CanalMsg()
for i in range(100):
if canal.CanalReceive(hDevice, ctypes.byref(rxMsg)):
print(f"メッセージを受信しました:ID=0x{rxMsg.id:X}, DLC={rxMsg.sizeData}, データ:", end="")
for j in range(rxMsg.sizeData):
print(f"{rxMsg.data[j]:02X} ", end="")
print()
time.sleep(0.01)
# デバイスを閉じる
canal.CanalClose(hDevice)
高度な機能
1. マルチチャンネル操作
Alius USB2CANデバッガーは、2つの独立したCANチャンネルをサポートしています。複数のデバイスハンドルを開くことで、両方のチャンネルを同時に操作できます。
2. エラー処理
使用中に、バスオフ、受信オーバーフローなどのさまざまなエラーが発生する可能性があります。デバイスのステータスを定期的に確認し、エラーの種類に応じて適切な措置を講じることをお勧めします。
3. 性能最適化
- ハードウェアフィルターを使用して、不必要なデータ受信を減らす
- より大きな受信バッファーを使用する
- 別のスレッドで受信したデータを処理する
よくある質問
質問1:CANAL DLLをロードできない
解決方法:DLLファイルが正しいパスにあることを確認し、DLLの依存関係が満たされているか確認してください。
質問2:メッセージの送信に失敗した
解決方法:デバイスが開いているか、CANバスが正しく接続されているか、ボーレートが一致しているか確認してください。
質問3:受信メッセージが失われた
解決方法:受信バッファーサイズを大きくする、受信したメッセージを適時に処理する、ボーレートを下げる。
技術サポート
使用中に問題が発生した場合は、Alius技術サポートチームにお問い合わせください。喜んで対応いたします。