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 _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), int Function(Pointer)>('USB_ScanDevice'); final devHandle = calloc(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, Pointer), bool Function(int, Pointer, Pointer)>('DEV_GetDeviceInfo'); final devInfo = calloc(); final funcStr = calloc(256); final success = devGetDeviceInfo(devHandleValue, devInfo, funcStr); if (success) { //final firmwareName = devInfo.ref.firmwareName.cast().toDartString(); //final buildDate = devInfo.ref.buildDate.toDartString(); //final hardwareVersion = devInfo.ref.hardwareVersion; final firmwareVersion = devInfo.ref.firmwareVersion; final serialNumber = List.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 getDeviceList() { // 实现获取设备列表逻辑 return _deviceList; } @override bool start({required int canIndex,required int canChannel , required int baudrate}) { // 实现启动逻辑 try { final canfdInit = _dll.lookupFunction), int Function(int, int, Pointer)>('CANFD_Init'); // 假设这里使用第一个设备的句柄,可根据实际情况修改 if (_deviceList.isNotEmpty) { var canConfig = calloc(); // 初始化 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('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 sendMessage({required int canIndex, required int canChannel, required int canid,required List data}) { if(_deviceList[canIndex].runstatus == false || _deviceList[canIndex].channelstatus[canChannel] == false) { return Future.value(false);//设备/通道未启动 } try { final canfdSendMsg = _dll.lookupFunction, Uint32), int Function(int, int, Pointer, int)>('CANFD_SendMsg'); if (_deviceList.isNotEmpty) { final devHandle = _deviceList[canIndex].devhandle; var canMsg = calloc(); 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 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), int Function(int, int, Pointer, int)>('CANFD_GetMsg'); final bufferSize = 100; final canMsgs = calloc(bufferSize); final result = canfdGetMsg(_deviceList[canIndex].devhandle, canChannel, canMsgs, bufferSize); if (result > 0) { List messages = []; for (int i = 0; i < result; i++) { // 复制消息数据,避免内存释放后访问问题 final msgCopy = calloc(); 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!); } }