245 lines
10 KiB
Dart
245 lines
10 KiB
Dart
import 'abstract_can_device.dart';
|
||
import 'device_info.dart';
|
||
import 'canfd_init_config.dart';
|
||
import 'can_fd_msg.dart';
|
||
import 'dart:ffi';
|
||
import 'package:ffi/ffi.dart';
|
||
import 'package:logging/logging.dart';
|
||
import 'dart:io';
|
||
|
||
|
||
class ToomossCAN extends AbstractCANDevice {
|
||
final Logger _logger = Logger('ToomossCAN');
|
||
late DynamicLibrary _dll;
|
||
bool _loadDll = false;
|
||
List<CANDev> _deviceList = [];
|
||
@override
|
||
bool initialize() {
|
||
// 加载USB2XXX.dll
|
||
try {
|
||
_dll = DynamicLibrary.open('USB2XXX.dll');
|
||
_logger.info("Load DLL success");
|
||
_loadDll = true;
|
||
}
|
||
catch (e) {
|
||
_logger.severe('Failed to load USB2XXX.dll: $e');
|
||
//记录当前工作路径
|
||
_logger.severe('Current working directory: ${Directory.current.path}');
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
@override
|
||
int refresh() {
|
||
// 实现刷新逻辑
|
||
if(_loadDll == false) {
|
||
_logger.info('refresh error:Failed to load USB2XXX.dll');
|
||
_logger.info(_loadDll.toString());
|
||
return 0;
|
||
}
|
||
_logger.info('刷新设备列表');
|
||
final usbScanDevice = _dll.lookupFunction<Int32 Function(Pointer<Int32>), int Function(Pointer<Int32>)>('USB_ScanDevice');
|
||
final devHandle = calloc<Int32>(20);
|
||
final deviceCount = usbScanDevice(devHandle);
|
||
if (deviceCount > 0) {
|
||
_logger.info('当前找到的设备数为: $deviceCount');
|
||
for (int i = 0; i < deviceCount; i++) {
|
||
final devHandleValue = devHandle[i];
|
||
final devGetDeviceInfo = _dll.lookupFunction<Bool Function(Int32, Pointer<ToomossDeviceInfo>, Pointer<Uint8>), bool Function(int, Pointer<ToomossDeviceInfo>, Pointer<Uint8>)>('DEV_GetDeviceInfo');
|
||
final devInfo = calloc<ToomossDeviceInfo>();
|
||
final funcStr = calloc<Uint8>(256);
|
||
final success = devGetDeviceInfo(devHandleValue, devInfo, funcStr);
|
||
if (success) {
|
||
//final firmwareName = devInfo.ref.firmwareName.cast<Utf8>().toDartString();
|
||
//final buildDate = devInfo.ref.buildDate.toDartString();
|
||
//final hardwareVersion = devInfo.ref.hardwareVersion;
|
||
final firmwareVersion = devInfo.ref.firmwareVersion;
|
||
final serialNumber = List<int>.generate(3, (index) => devInfo.ref.serialNumber[index]);
|
||
//final functions = devInfo.ref.Functions;
|
||
//final funcStrDart = funcStr.toDartString();
|
||
final int typp1 = (devHandleValue>>28)&0x0F;
|
||
final int typp2 = (devHandleValue>>24)&0x0F;
|
||
final toomossDevModel = '0${typp1}0$typp2';//型号
|
||
|
||
_deviceList.add(CANDev(
|
||
devname: 'Toomoss-$toomossDevModel',
|
||
devsn: serialNumber.map((num) => num.toRadixString(16).padLeft(2, '0')).join(''),
|
||
devchannel: 2, //
|
||
runstatus: false,
|
||
devhandle: devHandleValue,
|
||
firmwareversion: '${(firmwareVersion >> 24) & 0xFF}.${(firmwareVersion >> 16) & 0xFF}.${firmwareVersion & 0xFFFF}',
|
||
));
|
||
|
||
} else {
|
||
_logger.severe('Failed to get device info for device $i ,device id 0x${devHandleValue.toRadixString(16).toUpperCase()}');
|
||
}
|
||
calloc.free(devInfo);
|
||
calloc.free(funcStr);
|
||
}
|
||
} else {
|
||
_logger.info('无设备连接');
|
||
_deviceList.clear();
|
||
}
|
||
calloc.free(devHandle);
|
||
if(deviceCount > 0) {
|
||
// 遍历设备列表,输出每个设备的具体信息
|
||
for (var device in _deviceList) {
|
||
_logger.info('设备名称: ${device.devname}, 设备序列号: ${device.devsn}, 设备通道数: ${device.devchannel}, 运行状态: ${device.runstatus}, 设备句柄: ${device.devhandle.toRadixString(16).toUpperCase()}, 固件版本: ${device.firmwareversion}');
|
||
}
|
||
}
|
||
return deviceCount;
|
||
}
|
||
|
||
@override
|
||
List<CANDev> getDeviceList() {
|
||
// 实现获取设备列表逻辑
|
||
return _deviceList;
|
||
}
|
||
|
||
@override
|
||
bool start({required int canIndex,required int canChannel , required int baudrate}) {
|
||
// 实现启动逻辑
|
||
try {
|
||
final canfdInit = _dll.lookupFunction<Int32 Function(Int32, Uint8, Pointer<CanFdInitConfig>), int Function(int, int, Pointer<CanFdInitConfig>)>('CANFD_Init');
|
||
// 假设这里使用第一个设备的句柄,可根据实际情况修改
|
||
if (_deviceList.isNotEmpty) {
|
||
var canConfig = calloc<CanFdInitConfig>(); // 初始化 CANFD_INIT_CONFIG
|
||
canConfig.ref.mode = 0; // 正常模式
|
||
canConfig.ref.isocrcEnable = 0; // 禁用 ISO CRC
|
||
canConfig.ref.retrySend = 0; // 禁止重发
|
||
canConfig.ref.resEnable = 1; // 接入内部 120 欧终端电阻
|
||
canConfig.ref.nbtBRP = 1; // 仲裁段波特率参数
|
||
canConfig.ref.nbtSEG1 = 59; // 仲裁段波特率参数
|
||
canConfig.ref.nbtSEG2 = 20; // 仲裁段波特率参数
|
||
canConfig.ref.nbtSJW = 2; // 仲裁段波特率参数
|
||
canConfig.ref.dbtBRP = 2; // 数据段波特率参数
|
||
canConfig.ref.dbtSEG1 = 29; // 数据段波特率参数
|
||
canConfig.ref.dbtSEG2 = 10; // 数据段波特率参数
|
||
canConfig.ref.dbtSJW = 2; // 数据段波特率参数
|
||
final result = canfdInit(_deviceList[canIndex].devhandle, canChannel, canConfig);
|
||
calloc.free(canConfig); // 释放内存
|
||
if (result != 1) {
|
||
_logger.severe('CANFD_Init 初始化失败,返回值: $result');
|
||
return false;
|
||
}
|
||
//初始化成功
|
||
_logger.info('CANFD_Init 初始化成功,返回值: $result');
|
||
_deviceList[canIndex].channelstatus[canChannel] = true;
|
||
_deviceList[canIndex].runstatus = true;
|
||
} else {
|
||
_logger.severe('无可用设备,无法初始化 CANFD_Init');
|
||
return false;
|
||
}
|
||
} catch (e) {
|
||
_logger.severe('调用 CANFD_Init 时发生异常: $e');
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
@override
|
||
bool stop({required int canIndex}) {
|
||
try {
|
||
if (_loadDll && _deviceList.isNotEmpty) {
|
||
final usbCloseDevice = _dll.lookupFunction<Bool Function(Int32), bool Function(int)>('USB_CloseDevice');
|
||
final result = usbCloseDevice(_deviceList[canIndex].devhandle);
|
||
if (!result) {
|
||
_logger.severe('USB_CloseDevice 调用失败,设备句柄: ${_deviceList[canIndex].devhandle.toRadixString(16).toUpperCase()}');
|
||
}
|
||
return result;
|
||
} else {
|
||
_logger.severe('无法调用 USB_CloseDevice,可能 DLL 未加载或无可用设备。');
|
||
return false;
|
||
}
|
||
} catch (e) {
|
||
_logger.severe('调用 USB_CloseDevice 时发生异常: $e');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
@override
|
||
Future<bool> sendMessage({required int canIndex, required int canChannel, required int canid,required List<int> data}) {
|
||
if(_deviceList[canIndex].runstatus == false || _deviceList[canIndex].channelstatus[canChannel] == false) {
|
||
return Future.value(false);//设备/通道未启动
|
||
}
|
||
try {
|
||
final canfdSendMsg = _dll.lookupFunction<Int32 Function(Int32, Uint8, Pointer<CanFdMsg>, Uint32), int Function(int, int, Pointer<CanFdMsg>, int)>('CANFD_SendMsg');
|
||
if (_deviceList.isNotEmpty) {
|
||
final devHandle = _deviceList[canIndex].devhandle;
|
||
var canMsg = calloc<CanFdMsg>();
|
||
canMsg.ref.id = canid;
|
||
canMsg.ref.dlc = data.length.toUnsigned(8);
|
||
for (int i = 0; i < data.length; i++) {
|
||
canMsg.ref.data[i] = data[i].toUnsigned(8);
|
||
}
|
||
final result = canfdSendMsg(devHandle, canChannel, canMsg, 1);
|
||
calloc.free(canMsg);
|
||
if (result >= 0) {
|
||
//_logger.info('CANFD_SendMsg 发送成功,返回值: $result');
|
||
_deviceList[canIndex].errCounter = 0;
|
||
return Future.value(true);
|
||
|
||
} else {
|
||
/*
|
||
//函数返回值错误信息定义
|
||
#define CANFD_SUCCESS (0) //函数执行成功
|
||
#define CANFD_ERR_NOT_SUPPORT (-1) //适配器不支持该函数
|
||
#define CANFD_ERR_USB_WRITE_FAIL (-2) //USB写数据失败
|
||
#define CANFD_ERR_USB_READ_FAIL (-3) //USB读数据失败
|
||
#define CANFD_ERR_CMD_FAIL (-4) //命令执行失败
|
||
*/
|
||
_logger.severe('CANFD_SendMsg 发送失败,返回值: $result');
|
||
_deviceList[canIndex].errCounter++;
|
||
if(_deviceList[canIndex].errCounter > 5) {
|
||
_deviceList[canIndex].channelstatus[canChannel] = false;
|
||
_deviceList[canIndex].runstatus = false;
|
||
}
|
||
return Future.value(false);
|
||
}
|
||
} else {
|
||
_logger.severe('无可用设备,无法调用 CANFD_SendMsg');
|
||
return Future.value(false);
|
||
}
|
||
} catch (e) {
|
||
_logger.severe('调用 CANFD_SendMsg 时发生异常: $e');
|
||
_deviceList[canIndex].channelstatus[canChannel] = false;
|
||
_deviceList[canIndex].runstatus = false;
|
||
return Future.value(false);
|
||
}
|
||
}
|
||
|
||
@override
|
||
Stream<CanFdMsg> receiveMessage({required int canIndex, required int canChannel}) {
|
||
return Stream.periodic(Duration(milliseconds: 10), (_) {
|
||
if(_deviceList[canIndex].runstatus == false || _deviceList[canIndex].channelstatus[canChannel] == false) {
|
||
return null;
|
||
}
|
||
try {
|
||
final canfdGetMsg = _dll.lookupFunction<Int32 Function(Int32, Uint8, Pointer<CanFdMsg>, Int32), int Function(int, int, Pointer<CanFdMsg>, int)>('CANFD_GetMsg');
|
||
final bufferSize = 100;
|
||
final canMsgs = calloc<CanFdMsg>(bufferSize);
|
||
final result = canfdGetMsg(_deviceList[canIndex].devhandle, canChannel, canMsgs, bufferSize);
|
||
if (result > 0) {
|
||
List<CanFdMsg> messages = [];
|
||
for (int i = 0; i < result; i++) {
|
||
// 复制消息数据,避免内存释放后访问问题
|
||
final msgCopy = calloc<CanFdMsg>();
|
||
msgCopy.ref = canMsgs[i];
|
||
messages.add(msgCopy.ref);
|
||
}
|
||
calloc.free(canMsgs);
|
||
return messages;
|
||
} else {
|
||
calloc.free(canMsgs);
|
||
return null;
|
||
}
|
||
} catch (e) {
|
||
_logger.severe('调用 CANFD_GetMsg 时发生异常: $e');
|
||
return null;
|
||
}
|
||
}).where((messages) => messages != null).expand((messages) => messages!);
|
||
}
|
||
|
||
|
||
} |