commit dde12bf30bf944e5d7ac308abb77d3b7858f5a62 Author: liyp Date: Tue Aug 25 22:10:31 2026 -0400 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..5d4653d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc 生成活动文件", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "调试器生成的任务。" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2754ace --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.10) +project(UniversalCan VERSION 1.0.0) + +# 设置C标准(纯C工程) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) + +# 公共部分(所有平台共享) +set(COMMON_INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR}/Inc + ${CMAKE_CURRENT_SOURCE_DIR}/OsSample +) + +set(COMMON_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/Src/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/OsSample/*.c +) + +# Windows平台(包括MinGW) +if(WIN32 OR MINGW) + message(STATUS "Configuring for Windows/MinGW") + + # Windows平台特定包含目录 + set(PLATFORM_INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR}/Device/ScHHS + ${CMAKE_CURRENT_SOURCE_DIR}/Device/ScHHS/Port + ${CMAKE_CURRENT_SOURCE_DIR}/Device/Zlg/Port + ) + + # Windows平台特定源文件 + set(PLATFORM_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/Device/ScHHS/Port/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/Device/Zlg/Port/*.c + ) + + # Windows平台链接库 + set(PLATFORM_LIBS + HCanbus # 四川何华盛的库 + ws2_32 # winsock库 + ) + + # Windows平台链接目录 + set(PLATFORM_LINK_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/Device/ScHHS + ) + + # Windows平台定义 + add_definitions(-D_WIN32_WINNT=0x0601) + +# Linux平台 +elseif(UNIX) + message(STATUS "Configuring for Linux") + + # Linux平台特定包含目录(假设有Linux设备目录) + set(PLATFORM_INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR}/Device/Linux + ) + + # Linux平台特定源文件 + set(PLATFORM_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/Device/Linux/*.c + ) + + # Linux平台链接库 + set(PLATFORM_LIBS + pthread + rt + ) + + # Linux平台链接目录 + set(PLATFORM_LINK_DIRS "") +endif() + +# 收集所有源文件 +file(GLOB COMMON_SRC ${COMMON_SOURCES}) +file(GLOB PLATFORM_SRC ${PLATFORM_SOURCES}) + +# 创建可执行文件 +add_executable(${PROJECT_NAME} ${COMMON_SRC} ${PLATFORM_SRC}) + +# 设置包含目录 +target_include_directories(${PROJECT_NAME} PRIVATE + ${COMMON_INCLUDES} + ${PLATFORM_INCLUDES} +) + +# 设置链接目录 +target_link_directories(${PROJECT_NAME} PRIVATE ${PLATFORM_LINK_DIRS}) + +# 链接库 +target_link_libraries(${PROJECT_NAME} ${PLATFORM_LIBS}) diff --git a/Device/ScHHS/HCanbus.dll b/Device/ScHHS/HCanbus.dll new file mode 100644 index 0000000..39a9f30 Binary files /dev/null and b/Device/ScHHS/HCanbus.dll differ diff --git a/Device/ScHHS/HCanbus.h b/Device/ScHHS/HCanbus.h new file mode 100644 index 0000000..510af0a --- /dev/null +++ b/Device/ScHHS/HCanbus.h @@ -0,0 +1,115 @@ + +#ifndef HCANBUS_H +#define HCANBUS_H + +#define LIBUSB_CALL WINAPI + +typedef struct _Dev_Info { + char HW_Type[32]; //设备型号 字符串 + char HW_Ser[32]; //设备序列号 字符串 + char HW_Ver[32]; //硬件版本 字符串 + char FW_Ver[32]; //软件版本 字符串 + char MF_Date[32]; //生产日期 字符串 +} Dev_Info, *PDev_Info; + +typedef struct _Can_Config { + unsigned int Baudrate; + unsigned char Config; //配置信息:0x01接通内部电阻 0x02离线唤醒 0x04自动重传 + unsigned char Pres; // Pres,Tseg1,Tseg2如果与Baudrate不匹配,动态库会自动按 + unsigned char Tseg1; // Baudrate重新计算Pres,Tseg1,Tseg2,SJW并且采样点设置为 + unsigned char Tseg2; // 75%左右。一般情况可以只设置波特率,Pres,Tseg1,Tseg2填0 + unsigned char Model; //工作模式:0 正常模式,1 环回模式,2 静默模式,3 静默环回模式 + unsigned char SJW; + unsigned char Reserved1; //保留 + unsigned char Reserved2; +}Can_Config, *P_Can_Config; + +typedef struct _CanFD_Config { + unsigned int NomBaud; //常规波特率 + unsigned int DatBaud; //数据波特率 + unsigned char NomPre; // NomPre,NomTseg1,NomTseg2如果与NomBaud不匹配,动态库会自动按 + unsigned char NomTseg1; // NomBaud重新计算NomPre,NomTseg1,NomTseg2,NomSJW并且采样点设置为 + unsigned char NomTseg2; // 75%左右。这些值可借助波特率计算器计算后设置 + unsigned char NomSJW; + unsigned char DatPre; // DatPre,DatTseg1,DatTseg2如果与DatBaud不匹配,动态库会自动按 + unsigned char DatTseg1; // DatBaud重新计算DatPre,DatTseg1,DatTseg2,DatSJW并且采样点设置为 + unsigned char DatTseg2; // 75%左右。这些值可借助波特率计算器计算后设置 + unsigned char DatSJW; + unsigned char Config; //配置信息:0x01接通内部电阻 0x02离线唤醒 0x04自动重传 + unsigned char Model; //工作模式:0 正常模式,1 环回模式,2 静默模式,3 静默环回模式 + unsigned char Cantype; //CAN模式:0 CAN,1 IOS CANFD,2 Non-ISO CANFD + unsigned char Reserved; //保留 +}CanFD_Config, *P_CanFD_Config; + +typedef struct _Can_Msg { + unsigned int ID; //报文ID + unsigned int TimeStamp; //微秒级时间戳 + unsigned char FrameType; //帧类型 + unsigned char DataLen; //有效字节数 + unsigned char Data[8]; //报文数据 + unsigned char ExternFlag; //扩展帧标识:0标准帧,1扩展帧 + unsigned char RemoteFlag; //远程帧标识:0数据帧,1远程帧 + unsigned char BusSatus; //总线状态 + unsigned char ErrSatus; //错误状态 + unsigned char TECounter; //发送错误计数 + unsigned char RECounter; //接收错误计数 +}Can_Msg, *P_Can_Msg; + +typedef struct _CanFD_Msg { + unsigned int ID; //报文ID + unsigned int TimeStamp; //微秒级时间戳 + unsigned char FrameType; //帧类型 + unsigned char DLC; //DLC不等于数据长度。最大值15,对于数据长度64 + unsigned char ExternFlag; //扩展帧标识:0标准帧,1扩展帧 + unsigned char RemoteFlag; //远程帧标识:0数据帧,1远程帧 + unsigned char BusSatus; //总线状态 + unsigned char ErrSatus; //错误状态 + unsigned char TECounter; //发送错误计数 + unsigned char RECounter; //接收错误计数 + unsigned char Data[64]; //报文数据 +}CanFD_Msg, *P_CanFD_Msg; + +typedef struct _Can_Status { + unsigned char BusSatus; //总线状态 + unsigned char ErrSatus; //错误状态 + unsigned char TECounter; //发送错误计数 + unsigned char RECounter; //接收错误计数 + unsigned int TimeStamp; //产生状态时的时间戳 +}Can_Status, *P_Can_Status; + +#ifdef __cplusplus +extern "C" { +#endif + +int __stdcall Reg_HotPlug_Func(void(*pfunc)(void)); //热拔插函数 +int __stdcall CAN_ScanDevice(void); //扫描CAN,CANFD设备 +int __stdcall CAN_GeDevType(unsigned int devNum); //获取CAN,CANFD类型 0:常规CAN,1:CANFD +int __stdcall CAN_GeDevPlck(unsigned int devNum); //获取CAN,CANFD主频 + +int __stdcall CAN_OpenDevice(unsigned int devNum); //打开CAN,CANFD设备 +int __stdcall CAN_CloseDevice(unsigned int devNum); //关闭CAN,CANFD设备 +int __stdcall CAN_ReadDevInfo(unsigned int devNum, PDev_Info devinfo); //读取CAN,CANFD设备信息 + +int __stdcall CAN_SetFilter(unsigned int devNum,char namber, char type, unsigned int ftID, unsigned int ftMask, char enable); //设置CAN,CANFD硬件屏蔽 +int __stdcall CAN_Reset(unsigned int devNum); //复位CAN,CANFD设备 +int __stdcall CAN_GetStatus(unsigned int devNum,P_Can_Status status); //获取CAN,CANFD设备状态 + +int __stdcall CAN_Init(unsigned int devNum,P_Can_Config pInitConfig); //初始化CAN设备 +int __stdcall CAN_Transmit(unsigned int devNum, P_Can_Msg canmsg, unsigned int items, int timeou); //发送CAN报文 +int __stdcall CAN_TransmitRt(unsigned int devNum, P_Can_Msg canmsg, unsigned int items, unsigned int *txitems, int timeou); //定时发送CAN报文 +int __stdcall CAN_GetReceiveNum(unsigned int devNum); //获取接收缓冲区中接收到但尚未被读取的帧数量 +int __stdcall CAN_Receive(unsigned int devNum,P_Can_Msg canmsg, int Len, int timeou); //接收CAN报文 + +int __stdcall CANFD_Init(unsigned int devNum, P_CanFD_Config pInitConfig); +int __stdcall CANFD_Transmit(unsigned int devNum, P_CanFD_Msg canmsg, unsigned int items, int timeout); +int __stdcall CANFD_TransmitRt(unsigned int devNum, P_CanFD_Msg canmsg, unsigned int items, unsigned int *txitems, int timeou); //定时发送CAN报文 +int __stdcall CANFD_GetReceiveNum(unsigned int devNum);//获取接收缓冲区中接收到但尚未被读取的帧数量 +int __stdcall CANFD_Receive(unsigned int devNum, P_CanFD_Msg canmsg, unsigned int Len, int timeout); //接收CANFD报文 +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/Device/ScHHS/HCanbus.lib b/Device/ScHHS/HCanbus.lib new file mode 100644 index 0000000..7815181 Binary files /dev/null and b/Device/ScHHS/HCanbus.lib differ diff --git a/Device/ScHHS/Port/ScHHS.c b/Device/ScHHS/Port/ScHHS.c new file mode 100644 index 0000000..4a047e3 --- /dev/null +++ b/Device/ScHHS/Port/ScHHS.c @@ -0,0 +1,45 @@ +#include "ScHHS.h" + +#define PRODUCT "ScHHSUSBCan" + +CAN_DRIVER ScHHScanDriver = +{ + .ScanCanChnl = ScHHSScanCanChnl, + .InitCan = ScHHSInitCan, + .OpenCan = ScHHSOpenCan, + .CloseCan = ScHHSCloseCan, + .ResetCan = ScHHSResetCan, + .SendCan = ScHHSSendCan, + .RecvCan = ScHHSRecvCan +}; + +uint8_t ScHHSScanCanChnl(void) +{ + printf("Scan %s Can\n",PRODUCT); +} +uint8_t ScHHSInitCan(uint8_t chnl) +{ + printf("Init %s Can\n",PRODUCT); +} +uint8_t ScHHSOpenCan(uint8_t chnl) +{ + printf("Open %s Can\n",PRODUCT); +} +uint8_t ScHHSCloseCan(uint8_t chnl) +{ + printf("Close %s Can\n",PRODUCT); +} +uint8_t ScHHSResetCan(uint8_t chnl) +{ + printf("Reset %s Can\n",PRODUCT); +} +uint8_t ScHHSSendCan(uint8_t chnl,CAN_PKG_PTR canPkg) +{ + printf("Send %s Can\n",PRODUCT); +} +uint8_t ScHHSRecvCan(uint8_t chnl,CAN_PKG_PTR canPkg) +{ + printf("Recive %s Can\n",PRODUCT); +} + + diff --git a/Device/ScHHS/Port/ScHHS.h b/Device/ScHHS/Port/ScHHS.h new file mode 100644 index 0000000..6928e5b --- /dev/null +++ b/Device/ScHHS/Port/ScHHS.h @@ -0,0 +1,18 @@ +#ifndef __SCHHS_H__ +#define __SCHHS_H__ + +#include +#include "canDriver.h" +#include "HCanbus.h" + +uint8_t ScHHSScanCanChnl(void); +uint8_t ScHHSInitCan(uint8_t chnl); +uint8_t ScHHSOpenCan(uint8_t chnl); +uint8_t ScHHSCloseCan(uint8_t chnl); +uint8_t ScHHSResetCan(uint8_t chnl); +uint8_t ScHHSSendCan(uint8_t chnl,CAN_PKG_PTR canPkg); +uint8_t ScHHSRecvCan(uint8_t chnl,CAN_PKG_PTR canPkg); + +extern CAN_DRIVER ScHHScanDriver; + +#endif \ No newline at end of file diff --git a/Device/Zlg/ControlCAN.dll b/Device/Zlg/ControlCAN.dll new file mode 100644 index 0000000..5e76a80 Binary files /dev/null and b/Device/Zlg/ControlCAN.dll differ diff --git a/Device/Zlg/ControlCAN.h b/Device/Zlg/ControlCAN.h new file mode 100644 index 0000000..f72c32e --- /dev/null +++ b/Device/Zlg/ControlCAN.h @@ -0,0 +1,262 @@ +#ifndef CONTROLCAN_H +#define CONTROLCAN_H + +//ӿڿͶ +#define VCI_PCI5121 1 +#define VCI_PCI9810 2 +#define VCI_USBCAN1 3 +#define VCI_USBCAN2 4 +#define VCI_USBCAN2A 4 +#define VCI_PCI9820 5 +#define VCI_CAN232 6 +#define VCI_PCI5110 7 +#define VCI_CANLITE 8 +#define VCI_ISA9620 9 +#define VCI_ISA5420 10 +#define VCI_PC104CAN 11 +#define VCI_CANETUDP 12 +#define VCI_CANETE 12 +#define VCI_DNP9810 13 +#define VCI_PCI9840 14 +#define VCI_PC104CAN2 15 +#define VCI_PCI9820I 16 +#define VCI_CANETTCP 17 +#define VCI_PEC9920 18 +#define VCI_PCIE_9220 18 +#define VCI_PCI5010U 19 +#define VCI_USBCAN_E_U 20 +#define VCI_USBCAN_2E_U 21 +#define VCI_PCI5020U 22 +#define VCI_EG20T_CAN 23 +#define VCI_PCIE9221 24 +#define VCI_WIFICAN_TCP 25 +#define VCI_WIFICAN_UDP 26 +#define VCI_PCIe9120 27 +#define VCI_PCIe9110 28 +#define VCI_PCIe9140 29 +#define VCI_USBCAN_4E_U 31 +#define VCI_CANDTU_200UR 32 +#define VCI_CANDTU_MINI 33 +#define VCI_USBCAN_8E_U 34 +#define VCI_CANREPLAY 35 +#define VCI_CANDTU_NET 36 +#define VCI_CANDTU_100UR 37 + +//CAN +#define ERR_CAN_OVERFLOW 0x0001 //CANڲFIFO +#define ERR_CAN_ERRALARM 0x0002 //CAN󱨾 +#define ERR_CAN_PASSIVE 0x0004 //CAN +#define ERR_CAN_LOSE 0x0008 //CANٲöʧ +#define ERR_CAN_BUSERR 0x0010 //CANߴ +#define ERR_CAN_BUSOFF 0x0020 //߹رմ +#define ERR_CAN_BUFFER_OVERFLOW 0x0040 //CANڲBUFFER +//ͨô +#define ERR_DEVICEOPENED 0x0100 //豸Ѿ +#define ERR_DEVICEOPEN 0x0200 //豸 +#define ERR_DEVICENOTOPEN 0x0400 //豸ûд +#define ERR_BUFFEROVERFLOW 0x0800 // +#define ERR_DEVICENOTEXIST 0x1000 //豸 +#define ERR_LOADKERNELDLL 0x2000 //װض̬ʧ +#define ERR_CMDFAILED 0x4000 //ִʧܴ +#define ERR_BUFFERCREATE 0x8000 //ڴ治 + +//CANET +#define ERR_CANETE_PORTOPENED 0x00010000 //˿Ѿ +#define ERR_CANETE_INDEXUSED 0x00020000 //豸Ѿռ +#define ERR_REF_TYPE_ID 0x00030000 //SetReferenceGetReferenceݵRefType +#define ERR_CREATE_SOCKET 0x00030002 //Socketʧ +#define ERR_OPEN_CONNECT 0x00030003 //Socketʱʧܣ豸Ѿ +#define ERR_NO_STARTUP 0x00030004 //豸û +#define ERR_NO_CONNECTED 0x00030005 //豸 +#define ERR_SEND_PARTIAL 0x00030006 //ֻ˲ֵCAN֡ +#define ERR_SEND_TOO_FAST 0x00030007 //ݷ̫죬Socket + +//÷״ֵ̬ +#define STATUS_OK 1 +#define STATUS_ERR 0 + +#define CMD_DESIP 0 +#define CMD_DESPORT 1 +#define CMD_CHGDESIPANDPORT 2 +#define CMD_SRCPORT 2 +#define CMD_TCP_TYPE 4 //tcp ʽ:1 ǿͻ:0 +#define TCP_CLIENT 0 +#define TCP_SERVER 1 +//ʽЧ +#define CMD_CLIENT_COUNT 5 //ϵĿͻ˼ +#define CMD_CLIENT 6 //ϵĿͻ +#define CMD_DISCONN_CLINET 7 //Ͽһ +#define CMD_SET_RECONNECT_TIME 8 //ʹԶ +//CANDTU_NET֧GPS +#define CMD_GET_GPS 9 +#define CMD_GET_GPS_NUM 10 //ȡGPSϢĿ + +typedef unsigned long DWORD, ULONG; +typedef int INT; +typedef void* HANDLE; +typedef unsigned char BYTE; +typedef unsigned short USHORT; +typedef char CHAR; +typedef unsigned int UINT; +typedef unsigned char UCHAR; +typedef unsigned short UINT16; +typedef void* PVOID; + +typedef struct tagRemoteClient{ + int iIndex; + DWORD port; + HANDLE hClient; + char szip[32]; +}REMOTE_CLIENT; + +typedef struct _tagChgDesIPAndPort +{ + char szpwd[10]; + char szdesip[20]; + int desport; + BYTE blistenonly; +}CHGDESIPANDPORT; + +//1.ZLGCANϵнӿڿϢ͡ +typedef struct _VCI_BOARD_INFO{ + USHORT hw_Version; + USHORT fw_Version; + USHORT dr_Version; + USHORT in_Version; + USHORT irq_Num; + BYTE can_Num; + CHAR str_Serial_Num[20]; + CHAR str_hw_Type[40]; + USHORT Reserved[4]; +} VCI_BOARD_INFO,*PVCI_BOARD_INFO; + +//2.CANϢ֡͡ +typedef struct _VCI_CAN_OBJ{ + UINT ID; + UINT TimeStamp; + BYTE TimeFlag; + BYTE SendType; + BYTE RemoteFlag;//ǷԶ֡ + BYTE ExternFlag;//Ƿչ֡ + BYTE DataLen; + BYTE Data[8]; + BYTE Reserved[3]; //Reserved[0] 0λʾĿл߸֡ +}VCI_CAN_OBJ,*PVCI_CAN_OBJ; + +//3.CAN״̬͡ +typedef struct _VCI_CAN_STATUS{ + UCHAR ErrInterrupt; + UCHAR regMode; + UCHAR regStatus; + UCHAR regALCapture; + UCHAR regECCapture; + UCHAR regEWLimit; + UCHAR regRECounter; + UCHAR regTECounter; + DWORD Reserved; +}VCI_CAN_STATUS,*PVCI_CAN_STATUS; + +//4.Ϣ͡ +typedef struct _VCI_ERR_INFO{ + UINT ErrCode; + BYTE Passive_ErrData[3]; + BYTE ArLost_ErrData; +} VCI_ERR_INFO,*PVCI_ERR_INFO; + +//5.ʼCAN +typedef struct _VCI_INIT_CONFIG{ + DWORD AccCode; + DWORD AccMask; + DWORD Reserved; + UCHAR Filter; + UCHAR Timing0; + UCHAR Timing1; + UCHAR Mode; +}VCI_INIT_CONFIG,*PVCI_INIT_CONFIG; + +///////// new add struct for filter ///////// +typedef struct _VCI_FILTER_RECORD{ + DWORD ExtFrame; //ǷΪչ֡ + DWORD Start; + DWORD End; +}VCI_FILTER_RECORD,*PVCI_FILTER_RECORD; + +//ʱԶ֡ṹ +typedef struct _VCI_AUTO_SEND_OBJ{ + BYTE Enable; //ʹܱ 0: 1:ʹ + BYTE Index; //ı ֧32 + DWORD Interval; //ʱʱ 1msΪλ + VCI_CAN_OBJ obj; // +}VCI_AUTO_SEND_OBJ,*PVCI_AUTO_SEND_OBJ; + +//ָʾ״̬ṹ +typedef struct _VCI_INDICATE_LIGHT{ + BYTE Indicate; //ָʾƱ + BYTE AttribRedMode:2; //Red LED//˸/Կ + BYTE AttribGreenMode:2; //Green LED//˸/Կ + BYTE AttribReserved:4; //ʱ + BYTE FrequenceRed:2; //Red LED˸Ƶ + BYTE FrequenceGreen:2; //Green LED˸Ƶ + BYTE FrequenceReserved:4; //ʱ +} VCI_INDICATE_LIGHT,*PVCI_INDICATE_LIGHT; + +//תṹ +typedef struct _VCI_CAN_OBJ_REDIRECT{ + BYTE Action; //ʶֹͣת + BYTE DestCanIndex; //CANĿͨ +} VCI_CAN_OBJ_REDIRECT,*PVCI_CAN_OBJ_REDIRECT; + +typedef struct _CANDTUTIME { + UINT16 wYear; + UINT16 wMonth; + UINT16 wDay; + UINT16 wHour; + UINT16 wMinute; + UINT16 wSecond; +} CANDTUTIME; + +//GPSݽṹ +typedef struct _tagCANDTUGPSData +{ + float fLatitude; //γ + float fLongitude; // + float fSpeed; //ٶ + CANDTUTIME candtuTime; +}CANDTUGPSData, *PCANDTUGPSData; + +//ȡGPSṹ +typedef struct _VCI_CANDTU_GPS_DATA +{ + PCANDTUGPSData pGPSData; //ûṩGPSݵĻַ + ULONG nGPSDataCnt; //ɵGPSݸ +}VCI_CANDTU_GPS_DATA, *PVCI_CANDTU_GPS_DATA; + +#ifdef __cplusplus +#define EXTERNC extern "C" +#define DEF(a) = a +#else +#define EXTERNC +#define DEF(a) +#endif + +EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved); +EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd); +EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig); + +EXTERNC DWORD __stdcall VCI_ReadBoardInfo(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo); +EXTERNC DWORD __stdcall VCI_ReadErrInfo(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_ERR_INFO pErrInfo); +EXTERNC DWORD __stdcall VCI_ReadCANStatus(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_STATUS pCANStatus); + +EXTERNC DWORD __stdcall VCI_GetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData); +EXTERNC DWORD __stdcall VCI_SetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData); + +EXTERNC ULONG __stdcall VCI_GetReceiveNum(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); +EXTERNC DWORD __stdcall VCI_ClearBuffer(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); + +EXTERNC DWORD __stdcall VCI_StartCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); +EXTERNC DWORD __stdcall VCI_ResetCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); + +EXTERNC ULONG __stdcall VCI_Transmit(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,ULONG Len); +EXTERNC ULONG __stdcall VCI_Receive(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,ULONG Len,INT WaitTime DEF(-1)); + +#endif diff --git a/Device/Zlg/ControlCAN.lib b/Device/Zlg/ControlCAN.lib new file mode 100644 index 0000000..5aa03ea Binary files /dev/null and b/Device/Zlg/ControlCAN.lib differ diff --git a/Device/Zlg/Port/Zlg.c b/Device/Zlg/Port/Zlg.c new file mode 100644 index 0000000..e69de29 diff --git a/Device/Zlg/Port/Zlg.h b/Device/Zlg/Port/Zlg.h new file mode 100644 index 0000000..66f6ba0 --- /dev/null +++ b/Device/Zlg/Port/Zlg.h @@ -0,0 +1,6 @@ +#ifndef __ZLG_H__ +#define __ZLG_H__ + + + +#endif diff --git a/Device/Zlg/kerneldlls/CANDTU_NET.dll b/Device/Zlg/kerneldlls/CANDTU_NET.dll new file mode 100644 index 0000000..8744fe4 Binary files /dev/null and b/Device/Zlg/kerneldlls/CANDTU_NET.dll differ diff --git a/Device/Zlg/kerneldlls/CANETE.dll b/Device/Zlg/kerneldlls/CANETE.dll new file mode 100644 index 0000000..2d23077 Binary files /dev/null and b/Device/Zlg/kerneldlls/CANETE.dll differ diff --git a/Device/Zlg/kerneldlls/CANET_TCP.dll b/Device/Zlg/kerneldlls/CANET_TCP.dll new file mode 100644 index 0000000..fccc72f Binary files /dev/null and b/Device/Zlg/kerneldlls/CANET_TCP.dll differ diff --git a/Device/Zlg/kerneldlls/CANWIFI_TCP.dll b/Device/Zlg/kerneldlls/CANWIFI_TCP.dll new file mode 100644 index 0000000..f110391 Binary files /dev/null and b/Device/Zlg/kerneldlls/CANWIFI_TCP.dll differ diff --git a/Device/Zlg/kerneldlls/CANWIFI_UDP.dll b/Device/Zlg/kerneldlls/CANWIFI_UDP.dll new file mode 100644 index 0000000..452263e Binary files /dev/null and b/Device/Zlg/kerneldlls/CANWIFI_UDP.dll differ diff --git a/Device/Zlg/kerneldlls/USBCAN.dll b/Device/Zlg/kerneldlls/USBCAN.dll new file mode 100644 index 0000000..6b8252d Binary files /dev/null and b/Device/Zlg/kerneldlls/USBCAN.dll differ diff --git a/Device/Zlg/kerneldlls/USBCAN_8E_U_x64.dll b/Device/Zlg/kerneldlls/USBCAN_8E_U_x64.dll new file mode 100644 index 0000000..423f133 Binary files /dev/null and b/Device/Zlg/kerneldlls/USBCAN_8E_U_x64.dll differ diff --git a/Device/Zlg/kerneldlls/kerneldll.ini b/Device/Zlg/kerneldlls/kerneldll.ini new file mode 100644 index 0000000..d739ae5 --- /dev/null +++ b/Device/Zlg/kerneldlls/kerneldll.ini @@ -0,0 +1,42 @@ +[KERNELDLL] +COUNT=40 +1=PCI5121.dll +2=PCI9810.dll +3=USBCAN.dll +4=USBCAN.dll +5=PCI9820.dll +6=CAN232.dll +7=PCI5121.dll +8=CANLite.dll +9=ISA9620B.dll +10=ISA5420.dll +11=PC104CAN.dll +12=CANETE.dll +13=DNP9810B.dll +14=PCI9840B.dll +15=PC104C2.dll +16=PCI9820I.dll +17=CANET_TCP.dll +18=pec9920.dll +19=pci5010u.dll +20=USBCAN_E_64.dll +21=USBCAN_E_64.dll +22=pci50xx_u_x64.dll +23=topcliff_can_x64.dll +24=pcie9221_X64.dll +25=CANWIFI_TCP.dll +26=CANWIFI_UDP.dll +27=pcie9120.dll +28=pcie9110.dll +29=pcie9140.dll +30=pci5010p_x64.dll +31=USBCAN_4E_U_X64.dll +32=CANDTU_x64.dll +33=CANDTU_MINI_x64.dll +34=USBCAN_8E_U_x64.dll +35=CAN_REPLAY_x64.dll +36=CANDTU_NET.dll +37=CANDTU_x64.dll +38=zpcfd_x64.dll +39=zpcfd_x64.dll +40=zpcfd_x64.dll diff --git a/Device/Zlg/kerneldlls/pci9810b.dll b/Device/Zlg/kerneldlls/pci9810b.dll new file mode 100644 index 0000000..33a0bd3 Binary files /dev/null and b/Device/Zlg/kerneldlls/pci9810b.dll differ diff --git a/Device/Zlg/kerneldlls/pci9820b.dll b/Device/Zlg/kerneldlls/pci9820b.dll new file mode 100644 index 0000000..0529552 Binary files /dev/null and b/Device/Zlg/kerneldlls/pci9820b.dll differ diff --git a/Device/Zlg/kerneldlls/pci9820i.dll b/Device/Zlg/kerneldlls/pci9820i.dll new file mode 100644 index 0000000..ecfe7c3 Binary files /dev/null and b/Device/Zlg/kerneldlls/pci9820i.dll differ diff --git a/Device/Zlg/kerneldlls/pci9840b.dll b/Device/Zlg/kerneldlls/pci9840b.dll new file mode 100644 index 0000000..7879345 Binary files /dev/null and b/Device/Zlg/kerneldlls/pci9840b.dll differ diff --git a/Device/Zlg/kerneldlls/pcie9140_x64.dll b/Device/Zlg/kerneldlls/pcie9140_x64.dll new file mode 100644 index 0000000..737dddc Binary files /dev/null and b/Device/Zlg/kerneldlls/pcie9140_x64.dll differ diff --git a/Device/Zlg/kerneldlls/pec9920.dll b/Device/Zlg/kerneldlls/pec9920.dll new file mode 100644 index 0000000..694d11b Binary files /dev/null and b/Device/Zlg/kerneldlls/pec9920.dll differ diff --git a/Inc/canDriver.h b/Inc/canDriver.h new file mode 100644 index 0000000..365d392 --- /dev/null +++ b/Inc/canDriver.h @@ -0,0 +1,43 @@ +#ifndef CAN_DRIVER_H +#define CAN_DRIVER_H + +#include "OsSample.h" + +#define SC_HHS 0 //四川和华盛的USB CAN +#define ZLG_USB_CAN_II 1 //周立功的USB CAN II & PRO +#define GC_USB_CAN_II 2 //广诚科技的USB CAN II + +// CAN包长度 +#define CAN_DATA_LEN 8 +#define CANFD_DATA_LEN 64 + +// CAN包结构体 +typedef struct +{ + char data[CANFD_DATA_LEN]; +}CAN_PKG,*CAN_PKG_PTR; + +typedef struct +{ + // 扫描通道,返回通道数量或状态 + uint8_t (*ScanCanChnl)(void); + // 初始化硬件 + uint8_t (*InitCan)(uint8_t); + // 打开/启动 CAN + uint8_t (*OpenCan)(uint8_t); + // 关闭 CAN + uint8_t (*CloseCan)(uint8_t); + // 复位 CAN + uint8_t (*ResetCan)(uint8_t); + // 发送数据包 + uint8_t (*SendCan)(uint8_t chnl, CAN_PKG_PTR canPkg); + // 接收数据包 + uint8_t (*RecvCan)(uint8_t chnl, CAN_PKG_PTR canPkg); +}CAN_DRIVER,*CAN_DRIVER_PTR; + +Status CanProcessInit(void); +Status CanFuncRegister(uint8_t DeviceType); + +extern CAN_DRIVER can; + +#endif \ No newline at end of file diff --git a/Inc/network.h b/Inc/network.h new file mode 100644 index 0000000..e2f2a52 --- /dev/null +++ b/Inc/network.h @@ -0,0 +1,20 @@ +#ifndef NETWORK_H +#define NETWORK_H + +#include "OsSample.h" +#include "SocketSample.h" + +#define PKG_LEN 73 //报文长度 + +#define PKG_HEART 0xFF //心跳包索引 +#define PKG_OPEN_CAN 0x00 //打开CAN +#define PKG_CLOSE_CAN 0x01 //关闭CAN +#define PKG_CTRL_CAN 0x02 //收发CAN + +#define PHEAD 0x55 //报文头 +#define PEND 0xAA //报文尾 + +Status NetProcessInit(uint32_t Port); +Status CanFuncOpen(uint8_t chnl); + +#endif \ No newline at end of file diff --git a/Inc/work.h b/Inc/work.h new file mode 100644 index 0000000..22849c7 --- /dev/null +++ b/Inc/work.h @@ -0,0 +1,19 @@ +#ifndef WORK_H +#define WORK_H + +#include "OsSample.h" + +#define LISTEN_PORT 12345 //监听端口 +#define SEND_PORT 54321 //发送端口 + +typedef struct +{ + uint8_t canFd; //是否CAN_FD + uint8_t status; //开关状态 + uint8_t product; //当前厂商 + uint8_t chnlNum; //通道个数 +}WORK_STATUS,*WORK_STATUS_PTR; + +extern WORK_STATUS work; + +#endif \ No newline at end of file diff --git a/OsSample/OsSample.c b/OsSample/OsSample.c new file mode 100644 index 0000000..feed4ce --- /dev/null +++ b/OsSample/OsSample.c @@ -0,0 +1,174 @@ +#include "OsSample.h" + +// --- 1. vTaskDelay --- +void vTaskDelay(const TickType_t xTicksToDelay) { + #ifdef _WIN32 + Sleep(xTicksToDelay); + #elif defined(__linux__) + struct timespec ts; + ts.tv_sec = xTicksToDelay / 1000; + ts.tv_nsec = (xTicksToDelay % 1000) * 1000000L; + nanosleep(&ts, NULL); + #endif +} + +// --- 2. xTaskCreate --- +// 内部包装函数:为了适配系统线程接口并防止任务返回导致进程奔溃 +#ifdef _WIN32 +DWORD WINAPI prvTaskWrapper(LPVOID lpParam) { + TaskFunction_t pxTask = (TaskFunction_t)(((void**)lpParam)[0]); + void* pvParams = ((void**)lpParam)[1]; + free(lpParam); + pxTask(pvParams); + return 0; +} +#else +void* prvTaskWrapper(void* lpParam) { + TaskFunction_t pxTask = (TaskFunction_t)(((void**)lpParam)[0]); + void* pvParams = ((void**)lpParam)[1]; + free(lpParam); + pxTask(pvParams); + return NULL; +} +#endif + +BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask) { + // 准备参数包 + void** args = malloc(sizeof(void*) * 2); + args[0] = (void*)pvTaskCode; + args[1] = pvParameters; + + #ifdef _WIN32 + HANDLE hThread = CreateThread(NULL, usStackDepth, prvTaskWrapper, args, 0, NULL); + if (pxCreatedTask) *pxCreatedTask = (TaskHandle_t)hThread; + return (hThread != NULL) ? pdPASS : pdFAIL; + #elif defined(__linux__) + pthread_t threadId; + int res = pthread_create(&threadId, NULL, prvTaskWrapper, args); + if (pxCreatedTask) *pxCreatedTask = (TaskHandle_t)threadId; + return (res == 0) ? pdPASS : pdFAIL; + #endif +} + +// --- 3. xQueueCreate (简易内存模拟) --- +// 注意:实际生产环境建议使用互斥锁保护。这里仅展示逻辑框架。 +typedef struct { + uint8_t* storage; + uint32_t length; + uint32_t item_size; + uint32_t write_idx; // 写指针 + uint32_t read_idx; // 读指针 + uint32_t count; // 当前元素数量 +#ifdef _WIN32 + HANDLE mutex; // 保护结构体内部数据 + HANDLE sem_fill; // 计数信号量:当前有多少数据可读 +#else + pthread_mutex_t mutex; + sem_t sem_fill; +#endif +} SimulatedQueue; + +// --- xQueueCreate --- +QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize) { + SimulatedQueue* q = (SimulatedQueue*)malloc(sizeof(SimulatedQueue)); + if (!q) return NULL; + + q->storage = (uint8_t*)malloc(uxQueueLength * uxItemSize); + q->length = uxQueueLength; + q->item_size = uxItemSize; + q->write_idx = 0; + q->read_idx = 0; + q->count = 0; + +#ifdef _WIN32 + q->mutex = CreateMutex(NULL, FALSE, NULL); + q->sem_fill = CreateSemaphore(NULL, 0, uxQueueLength, NULL); +#else + pthread_mutex_init(&q->mutex, NULL); + sem_init(&q->sem_fill, 0, 0); +#endif + return (QueueHandle_t)q; +} + +// --- xQueueSend --- +BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait) { + SimulatedQueue* q = (SimulatedQueue*)xQueue; + if (!q) return pdFAIL; + + // 1. 进入临界区保护数据 +#ifdef _WIN32 + WaitForSingleObject(q->mutex, INFINITE); +#else + pthread_mutex_lock(&q->mutex); +#endif + + // 检查队列是否已满 + if (q->count >= q->length) { +#ifdef _WIN32 + ReleaseMutex(q->mutex); +#else + pthread_mutex_unlock(&q->mutex); +#endif + return errQUEUE_FULL; + } + + // 2. 拷贝数据到环形缓冲区 + memcpy(q->storage + (q->write_idx * q->item_size), pvItemToQueue, q->item_size); + q->write_idx = (q->write_idx + 1) % q->length; + q->count++; + + // 3. 释放信号量通知接收方,退出临界区 +#ifdef _WIN32 + ReleaseSemaphore(q->sem_fill, 1, NULL); + ReleaseMutex(q->mutex); +#else + sem_post(&q->sem_fill); + pthread_mutex_unlock(&q->mutex); +#endif + + return pdPASS; +} + +// --- xQueueReceive --- +BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait) { + SimulatedQueue* q = (SimulatedQueue*)xQueue; + if (!q) return pdFAIL; + + // 1. 等待信号量(是否有数据可读) +#ifdef _WIN32 + DWORD res = WaitForSingleObject(q->sem_fill, (xTicksToWait == portMAX_DELAY) ? INFINITE : xTicksToWait); + if (res != WAIT_OBJECT_0) return pdFAIL; + WaitForSingleObject(q->mutex, INFINITE); // 进入临界区 +#else + // Linux 简化处理,直接阻塞等 + sem_wait(&q->sem_fill); + pthread_mutex_lock(&q->mutex); +#endif + + // 2. 拷贝数据 + memcpy(pvBuffer, q->storage + (q->read_idx * q->item_size), q->item_size); + q->read_idx = (q->read_idx + 1) % q->length; + q->count--; + + // 3. 退出临界区 +#ifdef _WIN32 + ReleaseMutex(q->mutex); +#else + pthread_mutex_unlock(&q->mutex); +#endif + + return pdPASS; +} + +// 在 OsSample.c 中实现 +void vTaskStartScheduler(void) { + #ifdef _WIN32 + // Windows: 挂起主线程,直到进程结束 + Sleep(INFINITE); + #elif defined(__linux__) + // Linux: 使用 pause() 挂起,等待信号,或者用死循环 + while(1) { + pause(); + } + #endif +} \ No newline at end of file diff --git a/OsSample/OsSample.h b/OsSample/OsSample.h new file mode 100644 index 0000000..514eb65 --- /dev/null +++ b/OsSample/OsSample.h @@ -0,0 +1,79 @@ +#ifndef OS_SAMPLE_H +#define OS_SAMPLE_H + +#include +#include +#include +#include +#include + +#ifdef _WIN32 + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN // 阻止 windows.h 包含旧版 winsock.h + #endif + #include + #include +#elif defined(__linux__) + #include + #include + #include +#endif + +/** + * @brief 状态返回码枚举 + */ +typedef enum { + #ifndef ERROR + ERROR = 0, + #endif + #ifndef SUCCESS + SUCCESS = 1 + #endif +} Status; + +// 常用公共宏定义 +#define ENABLE 1 +#define DISABLE 0 + +/* 时间常数定义 */ +#define portMAX_DELAY (TickType_t)0xFFFFFFFFUL + +/* FreeRTOS 基础类型模拟 */ +typedef int32_t BaseType_t; +typedef uint32_t TickType_t; +typedef uint32_t UBaseType_t; +typedef void* TaskHandle_t; +typedef void* QueueHandle_t; + +#define pdTRUE 1 +#define pdFALSE 0 +#define pdPASS 1 +#define pdFAIL 0 +#define errQUEUE_FULL 0 // 或者根据你现有的定义调整 + +/* 任务函数指针定义 */ +typedef void (*TaskFunction_t)(void *); + +/* --- 严格一致的接口声明 --- */ + +// 延时 (ms) +void vTaskDelay(const TickType_t xTicksToDelay); + +// 创建任务 +BaseType_t xTaskCreate( + TaskFunction_t pvTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask +); + +void vTaskStartScheduler(void); + +// 队列操作 +QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize); +BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait); +BaseType_t xQueueReceive(QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait); + +#endif \ No newline at end of file diff --git a/OsSample/SocketSample.c b/OsSample/SocketSample.c new file mode 100644 index 0000000..a5d6dc0 --- /dev/null +++ b/OsSample/SocketSample.c @@ -0,0 +1,85 @@ +#include "SocketSample.h" +#include +#include + +// --- 1. xSocketInitEnvironment --- +int xSocketInitEnvironment(void) { +#ifdef _WIN32 + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + return SOCKET_FAIL; + } +#endif + return SOCKET_SUCCESS; +} + +// --- 2. xSocketCreateUDP --- +Socket_t xSocketCreateUDP(void) { + Socket_t xSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + return xSocket; +} + +// --- 3. xSocketBind --- +int xSocketBind(Socket_t xSocket, uint16_t usPort) { + struct sockaddr_in xLocalAddr; + memset(&xLocalAddr, 0, sizeof(xLocalAddr)); + xLocalAddr.sin_family = AF_INET; + xLocalAddr.sin_port = htons(usPort); + xLocalAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡 + + if (bind(xSocket, (struct sockaddr*)&xLocalAddr, sizeof(xLocalAddr)) == SOCKET_ERROR_HANDLE) { + return SOCKET_FAIL; + } + return SOCKET_SUCCESS; +} + +// --- 4. vSocketClose --- +void vSocketClose(Socket_t xSocket) { + if (xSocket == INVALID_SOCKET_HANDLE) return; +#ifdef _WIN32 + closesocket(xSocket); +#else + close(xSocket); +#endif +} + +// --- 5. xSocketSendTo --- +int32_t xSocketSendTo(Socket_t xSocket, const void* pvBuffer, uint32_t ulLength, + const char* pcIPAddress, uint16_t usPort) { + struct sockaddr_in xDestAddr; + memset(&xDestAddr, 0, sizeof(xDestAddr)); + xDestAddr.sin_family = AF_INET; + xDestAddr.sin_port = htons(usPort); + xDestAddr.sin_addr.s_addr = inet_addr(pcIPAddress); + + int res = sendto(xSocket, (const char*)pvBuffer, (int)ulLength, 0, + (struct sockaddr*)&xDestAddr, sizeof(xDestAddr)); + + if (res == SOCKET_ERROR_HANDLE) return SOCKET_FAIL; + return (int32_t)res; +} + +// --- 6. xSocketReceiveFrom --- +int32_t xSocketReceiveFrom(Socket_t xSocket, void* pvBuffer, uint32_t ulLength, + char* pcIPAddress, uint16_t* pusPort) { + struct sockaddr_in xSourceAddr; +#ifdef _WIN32 + int xAddrLen = sizeof(xSourceAddr); +#else + socklen_t xAddrLen = sizeof(xSourceAddr); +#endif + + int res = recvfrom(xSocket, (char*)pvBuffer, (int)ulLength, 0, + (struct sockaddr*)&xSourceAddr, &xAddrLen); + + if (res != SOCKET_ERROR_HANDLE) { + if (pcIPAddress) { + char* ip = inet_ntoa(xSourceAddr.sin_addr); + if (ip) strcpy(pcIPAddress, ip); + } + if (pusPort) *pusPort = ntohs(xSourceAddr.sin_port); + } else { + return SOCKET_FAIL; + } + return (int32_t)res; +} \ No newline at end of file diff --git a/OsSample/SocketSample.h b/OsSample/SocketSample.h new file mode 100644 index 0000000..02fb106 --- /dev/null +++ b/OsSample/SocketSample.h @@ -0,0 +1,45 @@ +#ifndef SOCKET_SAMPLE_H +#define SOCKET_SAMPLE_H + +#include + +#ifdef _WIN32 + #include + #include + typedef SOCKET Socket_t; + #define INVALID_SOCKET_HANDLE INVALID_SOCKET + #define SOCKET_ERROR_HANDLE SOCKET_ERROR +#else + #include + #include + #include + #include + typedef int Socket_t; + #define INVALID_SOCKET_HANDLE -1 + #define SOCKET_ERROR_HANDLE -1 +#endif + +#define SOCKET_SUCCESS 0 +#define SOCKET_FAIL -1 + +// 环境初始化(Win必须,Linux为空操作) +int xSocketInitEnvironment(void); + +// 创建 UDP Socket +Socket_t xSocketCreateUDP(void); + +// 绑定端口(接收端必备) +int xSocketBind(Socket_t xSocket, uint16_t usPort); + +// 关闭 Socket +void vSocketClose(Socket_t xSocket); + +// UDP 发送数据 +int32_t xSocketSendTo(Socket_t xSocket, const void* pvBuffer, uint32_t ulLength, + const char* pcIPAddress, uint16_t usPort); + +// UDP 接收数据 +int32_t xSocketReceiveFrom(Socket_t xSocket, void* pvBuffer, uint32_t ulLength, + char* pcIPAddress, uint16_t* pusPort); + +#endif \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce6146b --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +mkdir build && cd build +cmake .. -G "MinGW Makefiles" -DCMAKE_C_COMPILER="C:/Applications/Program Custom/msys2/mingw64/bin/gcc.exe" +mingw32-make + + +mkdir build && cd build +cmake .. +make \ No newline at end of file diff --git a/Src/canDriver.c b/Src/canDriver.c new file mode 100644 index 0000000..17a660b --- /dev/null +++ b/Src/canDriver.c @@ -0,0 +1,43 @@ +#include "OsSample.h" +#include "canDriver.h" +#include "ScHHS.h" + +CAN_DRIVER can; + +#define CAN_QUEUE_RECV_NUM 100000 //CAN接收队列长度 +#define CAN_QUEUE_SEND_NUM 100000 //CAN发送队列长度 + +QueueHandle_t CanRecvQueue; +QueueHandle_t CanSendQueue; + +//初始化CAN任务相关队列,数组等等 +Status CanProcessInit(void) +{ + CanRecvQueue = xQueueCreate(CAN_QUEUE_RECV_NUM, sizeof(CAN_PKG)); + CanSendQueue = xQueueCreate(CAN_QUEUE_SEND_NUM, sizeof(CAN_PKG)); +} +//关联驱动函数 +Status CanFuncRegister(uint8_t DeviceType) +{ + switch (DeviceType) + { + case SC_HHS: + //四川和华盛的USB CAN + can = ScHHScanDriver; + return SUCCESS; + case ZLG_USB_CAN_II: + //周立功的USB CAN II & PRO + return SUCCESS; + case GC_USB_CAN_II: + //广诚科技的USB CAN II + return SUCCESS; + default: + return ERROR; + } +} + +//打开CAN +Status CanFuncOpen(uint8_t chnl) +{ + +} \ No newline at end of file diff --git a/Src/main.c b/Src/main.c new file mode 100644 index 0000000..7df79fb --- /dev/null +++ b/Src/main.c @@ -0,0 +1,69 @@ +#include "OsSample.h" +#include "work.h" +#include "canDriver.h" +#include "network.h" + +#define APP_NAME "UniversalCan" + +int SearchPreProcess(const char* processName); +void KillPreProcess(const char* processName); + +int main(void) +{ + //此程序必须只有一个进程在运行 + while (SearchPreProcess(APP_NAME) == ENABLE) + { + //杀死上一个进程 + KillPreProcess(APP_NAME); + printf("Kill Pre Process\n"); + //等待进程里面的socket和内存被释放 + vTaskDelay(500); + } + // 初始化队列和任务等等 + // 初始化网络 + NetProcessInit(LISTEN_PORT); + // 初始化CAN + CanProcessInit(); + // 初始化network + + vTaskStartScheduler(); +} + +// 查找是否有指定名称的进程在运行(排除自身) +int SearchPreProcess(const char* processName) +{ + char cmd[512]; + +#ifdef _WIN32 + DWORD currentPID = GetCurrentProcessId(); + // Windows 下通常需要 .exe 后缀,建议传入时带上或在这里处理 + snprintf(cmd, sizeof(cmd), + "tasklist | findstr \"%s\" | findstr /v \"%lu\" > nul", + processName, currentPID); +#elif defined(__linux__) + snprintf(cmd, sizeof(cmd), + "pgrep -x \"%s\" | grep -v %d > /dev/null 2>&1", + processName, getpid()); +#endif + + return system(cmd) == 0 ? ENABLE : DISABLE; +} + +// 杀死指定名称的同名进程(排除自身) +void KillPreProcess(const char* processName) +{ + char cmd[512]; // 稍微加大 buffer 以防万一 + +#ifdef _WIN32 + DWORD currentPID = GetCurrentProcessId(); + // 逻辑不变,仅参数化进程名 + snprintf(cmd, sizeof(cmd), + "for /f \"tokens=2\" %%a in ('tasklist ^| findstr \"%s\"') do if not %%a==%lu taskkill /F /PID %%a", + processName, currentPID); +#elif defined(__linux__) + snprintf(cmd, sizeof(cmd), + "pgrep -x \"%s\" | grep -v %d | xargs -r kill -9 > /dev/null 2>&1", + processName, getpid()); +#endif + system(cmd); +} \ No newline at end of file diff --git a/Src/network.c b/Src/network.c new file mode 100644 index 0000000..acd0b24 --- /dev/null +++ b/Src/network.c @@ -0,0 +1,182 @@ +#include "network.h" +#include "work.h" + +Socket_t context; + +#define SOCKET_QUEUE_SEND_NUM 100000 //SOCKET接收队列长度 +#define SOCKET_QUEUE_RECV_NUM 100000 //SOCKET发送队列长度 + +QueueHandle_t SocketRecvQueue; +QueueHandle_t SocketSendQueue; + +void NetLoopTask(void *p); +void NetReciveTask(void *p); +void NetAnalysis(char *data); +void NetPkgSend(char *data); +void NetReciveQueueTask(void *p); +void NetSendQueueTask(void *p); + +Status NetProcessInit(uint32_t Port) +{ + //初始化 + if (xSocketInitEnvironment() == SOCKET_SUCCESS) + { + printf("socket init success\n"); + } + else + { + printf("socket init error\n"); + return ERROR; + } + // 创建 + context = xSocketCreateUDP(); + // 绑定 + if (xSocketBind(context,Port) == SOCKET_SUCCESS) + { + printf("socket listen success\n"); + } + else + { + printf("socket listen error\n"); + return ERROR; + } + + SocketRecvQueue = xQueueCreate(SOCKET_QUEUE_RECV_NUM, PKG_LEN); + SocketSendQueue = xQueueCreate(SOCKET_QUEUE_SEND_NUM, PKG_LEN); + + //开启任务 + xTaskCreate(NetReciveTask, /*!< 任务函数 */ + "NetReciveTask", /*!< 任务名 */ + 1024, /*!< stack大小,单位word,也就是4字节 */ + NULL, /*!< 任务参数 */ + 0, /*!< 任务优先级, 数字越大优先级越高*/ + NULL); /*!< 任务句柄 */ + + xTaskCreate(NetReciveQueueTask, /*!< 任务函数 */ + "NetReciveQueueTask", /*!< 任务名 */ + 1024, /*!< stack大小,单位word,也就是4字节 */ + NULL, /*!< 任务参数 */ + 0, /*!< 任务优先级, 数字越大优先级越高*/ + NULL); /*!< 任务句柄 */ + + xTaskCreate(NetSendQueueTask, /*!< 任务函数 */ + "NetSendQueueTask", /*!< 任务名 */ + 1024, /*!< stack大小,单位word,也就是4字节 */ + NULL, /*!< 任务参数 */ + 0, /*!< 任务优先级, 数字越大优先级越高*/ + NULL); /*!< 任务句柄 */ + + //网络循环执行任务 + xTaskCreate(NetLoopTask, /*!< 任务函数 */ + "NetLoopTask", /*!< 任务名 */ + 1024, /*!< stack大小,单位word,也就是4字节 */ + NULL, /*!< 任务参数 */ + 0, /*!< 任务优先级, 数字越大优先级越高*/ + NULL); /*!< 任务句柄 */ +} + +//udp接收任务 +void NetReciveTask(void *p) +{ + char PcRecvBuf[PKG_LEN]; // 接收缓冲区 + char PcRemoteIP[16]; // 存放谁发过来的 IP + uint16_t PcRemotePort; //存放谁发过来的端口 + int PkgLen; //接收长度 + + while (1) + { + PkgLen = xSocketReceiveFrom(context,PcRecvBuf,PKG_LEN,PcRemoteIP,&PcRemotePort); + if (PkgLen == PKG_LEN) + { + xQueueSend(SocketRecvQueue,PcRecvBuf,portMAX_DELAY); + } + } +} + +//udp解析函数 +void NetAnalysis(char *data) +{ + switch (data[1]) + { + case PKG_OPEN_CAN: + //打开CAN + CanFuncRegister(data[2]); + CanFuncOpen(data[3]); + break; + case PKG_CLOSE_CAN: + //关闭CAN + break; + case PKG_CTRL_CAN: + //收发CAN + break; + default: + return; + } +} + +//心跳包 +void NetHeart(void) +{ + static char heart[PKG_LEN]; + heart[0] = PHEAD; + heart[1] = PKG_HEART; + heart[2] = work.status; + heart[3] = work.product; + heart[4] = work.chnlNum; + heart[5] = work.canFd; + + for (uint8_t i = 6; i < PKG_LEN; i++) + { + heart[i] = DISABLE; + } + + heart[PKG_LEN - 1] = PEND; + + NetPkgSend(heart); +} + +//网络循环任务 +void NetLoopTask(void *p) +{ + while (1) + { + //发送心跳包 + // NetHeart(); + vTaskDelay(500); + } +} + +//udp队列接收任务 +void NetReciveQueueTask(void *p) +{ + char PcRecvBuf[PKG_LEN]; // 接收缓冲区 + + while(1) + { + xQueueReceive(SocketRecvQueue,&PcRecvBuf,portMAX_DELAY); + + NetAnalysis(PcRecvBuf); + } +} + +//网络数据包发送 +void NetPkgSend(char *data) +{ + data[0] = PHEAD; + data[PKG_LEN - 1] = PEND; + xQueueSend(SocketSendQueue,data,portMAX_DELAY); +} + +//网络数据包发送队列 +void NetSendQueueTask(void *p) +{ + static uint16_t SendPort = SEND_PORT; + char PcSendBuf[PKG_LEN]; // 接收缓冲区 + + while(1) + { + xQueueReceive(SocketSendQueue,&PcSendBuf,portMAX_DELAY); + + xSocketSendTo(context,PcSendBuf,PKG_LEN,"127.0.0.1",SendPort); + } +} \ No newline at end of file diff --git a/Src/work.c b/Src/work.c new file mode 100644 index 0000000..f6f86e6 --- /dev/null +++ b/Src/work.c @@ -0,0 +1,3 @@ +#include "work.h" + +WORK_STATUS work; \ No newline at end of file diff --git a/doc/模拟报文.txt b/doc/模拟报文.txt new file mode 100644 index 0000000..5708680 --- /dev/null +++ b/doc/模拟报文.txt @@ -0,0 +1 @@ +1、心跳包 diff --git a/doc/通信协议.xlsx b/doc/通信协议.xlsx new file mode 100644 index 0000000..dc043ca Binary files /dev/null and b/doc/通信协议.xlsx differ