RP-01_Flutter/lib/CanLib/toomoss_can.dart

245 lines
10 KiB
Dart
Raw Normal View History

2025-04-29 16:32:14 +08:00
import 'abstract_can_device.dart';
import 'device_info.dart';
2025-04-30 17:01:25 +08:00
import 'canfd_init_config.dart';
import 'can_fd_msg.dart';
2025-04-29 16:32:14 +08:00
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
2025-04-30 17:01:25 +08:00
bool start({required int canIndex,required int canChannel , required int baudrate}) {
2025-04-29 16:32:14 +08:00
// 实现启动逻辑
2025-04-30 17:01:25 +08:00
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;
}
2025-04-29 16:32:14 +08:00
return true;
}
@override
2025-04-30 17:01:25 +08:00
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;
}
2025-04-29 16:32:14 +08:00
}
@override
2025-04-30 17:01:25 +08:00
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);
}
2025-04-29 16:32:14 +08:00
}
@override
2025-04-30 17:01:25 +08:00
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!);
2025-04-29 16:32:14 +08:00
}
}