first commit

This commit is contained in:
liyp
2026-08-25 22:10:31 -04:00
commit dde12bf30b
41 changed files with 1379 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
build/
+28
View File
@@ -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"
}
+91
View File
@@ -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})
Binary file not shown.
+115
View File
@@ -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:常规CAN1CANFD
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
Binary file not shown.
+45
View File
@@ -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);
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef __SCHHS_H__
#define __SCHHS_H__
#include <stdint.h>
#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
Binary file not shown.
+262
View File
@@ -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 //SetReference或GetReference传递的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
Binary file not shown.
View File
+6
View File
@@ -0,0 +1,6 @@
#ifndef __ZLG_H__
#define __ZLG_H__
#endif
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+42
View File
@@ -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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+43
View File
@@ -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
+20
View File
@@ -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
+19
View File
@@ -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
+174
View File
@@ -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
}
+79
View File
@@ -0,0 +1,79 @@
#ifndef OS_SAMPLE_H
#define OS_SAMPLE_H
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN // 阻止 windows.h 包含旧版 winsock.h
#endif
#include <semaphore.h>
#include <windows.h>
#elif defined(__linux__)
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#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
+85
View File
@@ -0,0 +1,85 @@
#include "SocketSample.h"
#include <stdio.h>
#include <string.h>
// --- 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;
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef SOCKET_SAMPLE_H
#define SOCKET_SAMPLE_H
#include <stdint.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
typedef SOCKET Socket_t;
#define INVALID_SOCKET_HANDLE INVALID_SOCKET
#define SOCKET_ERROR_HANDLE SOCKET_ERROR
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
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
+8
View File
@@ -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
+43
View File
@@ -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)
{
}
+69
View File
@@ -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);
}
+182
View File
@@ -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);
}
}
+3
View File
@@ -0,0 +1,3 @@
#include "work.h"
WORK_STATUS work;
+1
View File
@@ -0,0 +1 @@
1、心跳包
Binary file not shown.