API Programming Interface
The Alius USB2CAN Dual-Channel Debugger provides an open-source CANAL API DLL, allowing developers to control the device through programming. This document details the API usage, function descriptions, and code examples to help you quickly integrate the Alius USB2CAN Debugger into your application.
CANAL API Overview
CANAL (CAN Abstraction Layer) is an open-source CAN bus abstraction layer API that provides a unified set of interface functions for accessing various CAN interface devices. The Alius USB2CAN Debugger fully supports the CANAL API, enabling developers to write hardware-independent applications.
API Features
- Cross-Platform: Supports Windows and Linux operating systems
- Multi-Language Support: Supports C/C++, C#, Python, Java, LabVIEW, and other programming languages
- Open Source: Source code is open and can be modified and customized as needed
- Easy to Use: Provides simple and intuitive API functions
Installation and Configuration
Windows Environment
- Copy the CANAL API DLL (usually
canal.dll) to your application directory or system directory (e.g.,C:\Windows\System32) - Add the CANAL API header file (
canal.h) to your project - Configure the project to link to the CANAL API library
Linux Environment
- Install the CANAL API shared library (usually
libcanal.so) - Include the CANAL API header file in your project
- Link to the CANAL API library when compiling (use the
-lcanaloption)
API Function Description
1. Open Connection
long CanalOpen(char *pDevice, unsigned long flags);
Function: Open a connection to the CAN device
Parameters:
pDevice: Device name or path (e.g., COM port number)flags: Open flags (usually set to 0)
Return Value:
- Success: Returns device handle (> 0)
- Failure: Returns 0
Example:
long hDevice = CanalOpen("COM3", 0);
if (0 == hDevice) {
printf("Unable to open device\n");
return -1;
}
2. Close Connection
int CanalClose(long handle);
Function: Close the connection to the CAN device
Parameters:
handle: Device handle (returned byCanalOpen)
Return Value:
- Success: Returns 1
- Failure: Returns 0
Example:
if (0 == CanalClose(hDevice)) {
printf("Failed to close device\n");
}
3. Get Device Status
int CanalGetStatus(long handle, canalsystemstatus *pStatus);
Function: Get the current status of the device
Parameters:
handle: Device handlepStatus: Pointer tocanalsystemstatusstructure
Return Value:
- Success: Returns 1
- Failure: Returns 0
4. Get Statistics
int CanalGetStatistics(long handle, canalstatistics *pStatistics);
Function: Get communication statistics of the device
Parameters:
handle: Device handlepStatistics: Pointer tocanalstatisticsstructure
Return Value:
- Success: Returns 1
- Failure: Returns 0
5. Send CAN Message
int CanalSend(long handle, canalmsg *pCanMsg);
Function: Send a CAN message
Parameters:
handle: Device handlepCanMsg: Pointer tocanalmsgstructure
Return Value:
- Success: Returns 1
- Failure: Returns 0
Example:
canalmsg canMsg;
memset(&canMsg, 0, sizeof(canalmsg));
canMsg.id = 0x100; // CAN message ID
canMsg.flags = 0; // Standard frame, no RTR
canMsg.sizeData = 8; // Data length
canMsg.data[0] = 0x01; // Data byte 0
canMsg.data[1] = 0x02; // Data byte 1
// ... set other data bytes
if (0 == CanalSend(hDevice, &canMsg)) {
printf("Failed to send message\n");
}
6. Receive CAN Message
int CanalReceive(long handle, canalmsg *pCanMsg);
Function: Receive a CAN message
Parameters:
handle: Device handlepCanMsg: Pointer tocanalmsgstructure
Return Value:
- Success: Returns 1
- Failure: Returns 0
- No message: Returns 0 (need to check
pCanMsg->sizeData)
Example:
canalmsg canMsg;
memset(&canMsg, 0, sizeof(canalmsg));
if (CanalReceive(hDevice, &canMsg)) {
printf("Received message: 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("Failed to receive message or no message\n");
}
7. Set Filter
int CanalSetFilter(long handle, unsigned long filter);
Function: Set hardware acceptance filter
Parameters:
handle: Device handlefilter: Filter value
Return Value:
- Success: Returns 1
- Failure: Returns 0
8. Set Mask
int CanalSetMask(long handle, unsigned long mask);
Function: Set acceptance mask
Parameters:
handle: Device handlemask: Mask value
Return Value:
- Success: Returns 1
- Failure: Returns 0
Data Structures
canalmsg Structure
typedef struct {
unsigned long id; // CAN message ID
unsigned char flags; // Flag bits
unsigned char sizeData; // Data length (0-8)
unsigned char data[8]; // Data bytes
unsigned long timestamp; // Timestamp (ms)
} canalmsg;
Flag Bit Definitions:
0x00: Standard frame (11-bit ID)0x01: Extended frame (29-bit ID)0x02: Remote frame (RTR)
canalsystemstatus Structure
typedef struct {
unsigned long channel_status; // Channel status
unsigned long lasterrorcode; // Last error code
unsigned long lasterrorsource;// Last error source
unsigned long errorcounter; // Error counter
} canalsystemstatus;
canalstatistics Structure
typedef struct {
unsigned long cntReceiveFrames; // Receive frame count
unsigned long cntTransmitFrames; // Transmit frame count
unsigned long cntReceiveData; // Receive data byte count
unsigned long cntTransmitData; // Transmit data byte count
unsigned long cntOverruns; // Overrun count
unsigned long cntBusWarnings; // Bus warning count
unsigned long cntBusOff; // Bus off count
} canalstatistics;
Code Examples
C++ Example
#include <stdio.h>
#include "canal.h"
int main() {
// Open device
long hDevice = CanalOpen("COM3", 0);
if (0 == hDevice) {
printf("Unable to open device\n");
return -1;
}
printf("Device opened successfully, handle: %ld\n", hDevice);
// Send message
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("Message sent successfully\n");
} else {
printf("Failed to send message\n");
}
// Receive messages (wait 1 second)
canalmsg rxMsg;
memset(&rxMsg, 0, sizeof(canalmsg));
for (int i = 0; i < 100; i++) {
if (CanalReceive(hDevice, &rxMsg)) {
printf("Received message: ID=0x%X, DLC=%d, Data: ", rxMsg.id, rxMsg.sizeData);
for (int j = 0; j < rxMsg.sizeData; j++) {
printf("%02X ", rxMsg.data[j]);
}
printf("\n");
}
Sleep(10); // Wait 10 ms
}
// Close device
CanalClose(hDevice);
return 0;
}
Python Example
import ctypes
import time
# Load CANAL DLL
canal = ctypes.CDLL("canal.dll")
# Define data structure
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)
]
# Open device
hDevice = canal.CanalOpen("COM3", 0)
if 0 == hDevice:
print("Unable to open device")
exit(-1)
print(f"Device opened successfully, handle: {hDevice}")
# Send message
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("Message sent successfully")
else:
print("Failed to send message")
# Receive messages
rxMsg = CanalMsg()
for i in range(100):
if canal.CanalReceive(hDevice, ctypes.byref(rxMsg)):
print(f"Received message: ID=0x{rxMsg.id:X}, DLC={rxMsg.sizeData}, Data: ", end="")
for j in range(rxMsg.sizeData):
print(f"{rxMsg.data[j]:02X} ", end="")
print()
time.sleep(0.01)
# Close device
canal.CanalClose(hDevice)
Advanced Features
1. Multi-Channel Operation
The Alius USB2CAN Debugger supports two independent CAN channels. You can operate both channels simultaneously by opening multiple device handles.
2. Error Handling
During use, you may encounter various errors, such as bus off, receive overflow, etc. It is recommended that you regularly check the device status and take appropriate measures based on the error type.
3. Performance Optimization
- Use hardware filters to reduce unnecessary data reception
- Use larger receive buffers
- Process received data in a separate thread
Frequently Asked Questions
Question 1: Unable to Load CANAL DLL
Solution: Ensure the DLL file is in the correct path and check if the DLL dependencies are satisfied.
Question 2: Failed to Send Message
Solution: Check if the device is opened, if the CAN bus is connected correctly, and if the baud rate matches.
Question 3: Lost Received Messages
Solution: Increase the receive buffer size, process received messages in time, and lower the baud rate.
Technical Support
If you encounter any problems during use, please contact the Alius technical support team. We are dedicated to serving you.