Browse Source

"change g29zlgchassistest. add speed, zlgcan fail, not complete."

yuchuli 1 week ago
parent
commit
9fe887dfe9

+ 32 - 0
src/tool/g29zlgchassistest/cancard.cpp

@@ -0,0 +1,32 @@
+#include "cancard.h"
+
+#include <iostream>
+#include <QLibrary>
+
+cancard::cancard()
+{
+    LoadAPI();
+}
+
+void cancard::LoadAPI()
+{
+    std::cout<<"Load Logi g29 API"<<std::endl;
+    QLibrary xlib("./zlgcan.dll");
+    if(!xlib.load())
+    {
+        std::cout<<" load zlgcan fail."<<xlib.errorString().toStdString()<< std::endl;
+        return ;
+    }
+
+    ZCAN_OpenDevice =(ZCAN_OpenDeviceFunc)xlib.resolve("ZCAN_OpenDevice");
+
+    if(ZCAN_OpenDevice == NULL)
+    {
+        std::cout<<" no ZCAN_OpenDevice api."<<std::endl;
+        return;
+    }
+    else
+    {
+        std::cout<<" Load ZCAN_OpenDevice API Successfully. "<<std::endl;
+    }
+}

+ 22 - 0
src/tool/g29zlgchassistest/cancard.h

@@ -0,0 +1,22 @@
+#ifndef CANCARD_H
+#define CANCARD_H
+
+#include "config.h"
+#include "canframe.h"
+#include "typedef.h"
+
+#include "zlgcanlib.h"
+
+class cancard
+{
+public:
+    cancard();
+
+private:
+    ZCAN_OpenDeviceFunc ZCAN_OpenDevice;
+
+private:
+    void LoadAPI();
+};
+
+#endif // CANCARD_H

+ 125 - 0
src/tool/g29zlgchassistest/canframe.h

@@ -0,0 +1,125 @@
+#ifndef CANFRAME_H_
+#define CANFRAME_H_
+
+
+#include "typedef.h"
+
+/* special address description flags for the MAKE_CAN_ID */
+#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
+#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
+#define CAN_ERR_FLAG 0x20000000U /* error message frame */
+#define CAN_ID_FLAG  0x1FFFFFFFU /* id */
+
+/* valid bits in CAN ID for frame formats */
+#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
+#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
+#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
+
+/*
+* Controller Area Network Identifier structure
+*
+* bit 0-28	: CAN identifier (11/29 bit)
+* bit 29	: error message frame flag (0 = data frame, 1 = error message)
+* bit 30	: remote transmission request flag (1 = rtr frame)
+* bit 31	: frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
+*/
+typedef UINT canid_t;
+
+#define CAN_SFF_ID_BITS		11
+#define CAN_EFF_ID_BITS		29
+
+/*
+* Controller Area Network Error Message Frame Mask structure
+*
+* bit 0-28	: error class mask (see include/linux/can/error.h)
+* bit 29-31	: set to zero
+*/
+typedef UINT can_err_mask_t;
+
+/* CAN payload length and DLC definitions according to ISO 11898-1 */
+#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+/* CAN FD payload length and DLC definitions according to ISO 11898-7 */
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+
+ // make id
+#define MAKE_CAN_ID(id, eff, rtr, err) (id | (!!(eff) << 31) | (!!(rtr) << 30) | (!!(err) << 29))
+#define IS_EFF(id) (!!(id & CAN_EFF_FLAG)) //1:extend frame 0:standard frame
+#define IS_RTR(id) (!!(id & CAN_RTR_FLAG)) //1:remote frame 0:data frame
+#define IS_ERR(id) (!!(id & CAN_ERR_FLAG)) //1:error frame 0:normal frame
+#define GET_ID(id) (id & CAN_ID_FLAG)
+
+/* TX_DELAY_SEND_FLAG apply to can_frame.__pad and canfd_frame.flags, only apply to tx frames */
+#define TX_DELAY_SEND_FLAG 0x80 /* indicat tx frame in delay send mode, 1:send in device queue; 0:send direct to bus */
+#define IS_DELAY_SEND(flag) (!!(flag & TX_DELAY_SEND_FLAG)) //1:delay send frame with delay time in __res0/__res0 0:normal frame
+#define TX_DELAY_SEND_TIME_UNIT_FLAG 0x40 /* indicat tx delay send time unit, 1:time unit is 100us; 0:time unit is 1ms */
+#define IS_DELAY_SEND_TIME_UNIT_MS(flag) (!(flag & TX_DELAY_SEND_TIME_UNIT_FLAG))       //0: time unit 100us 1: time unit 1ms
+#define IS_DELAY_SEND_TIME_UNIT_100US(flag) (!!(flag & TX_DELAY_SEND_TIME_UNIT_FLAG))   //1: time unit 100us 0: time unit 1ms
+
+/* TX_ECHO_FLAG apply to can_frame.__pad and canfd_frame.flags, apply to tx and rx frames */
+#define TX_ECHO_FLAG 0x20 /* indicat tx frame will be echoed(recieved) when tx frame trasmit to the bus*/
+#define IS_TX_ECHO(flag) (!!(flag & TX_ECHO_FLAG))       //0: normal recieved frame 1: tx echoed frame
+
+/**
+* struct can_frame - basic CAN frame structure
+* @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+* @can_dlc: frame payload length in byte (0 .. 8) aka data length code
+*           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
+*           mapping of the 'data length code' to the real payload length
+* @__pad:   padding
+* @__res0:  reserved / padding
+* @__res1:  reserved / padding
+* @data:    CAN frame payload (up to 8 byte)
+*/
+typedef struct {
+	canid_t can_id;  /* 32 bit MAKE_CAN_ID + EFF/RTR/ERR flags */
+	BYTE    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
+	BYTE    __pad;   /* padding */
+	BYTE    __res0;  /* reserved / padding */
+	BYTE    __res1;  /* reserved / padding */
+	BYTE    data[CAN_MAX_DLEN]/* __attribute__((aligned(8)))*/;
+}can_frame;
+
+/*
+* defined bits for canfd_frame.flags
+*
+* The use of struct canfd_frame implies the Extended Data Length (EDL) bit to
+* be set in the CAN frame bitstream on the wire. The EDL bit switch turns
+* the CAN controllers bitstream processor into the CAN FD mode which creates
+* two new options within the CAN FD frame specification:
+*
+* Bit Rate Switch - to indicate a second bitrate is/was used for the payload
+* Error State Indicator - represents the error state of the transmitting node
+*
+* As the CANFD_ESI bit is internally generated by the transmitting CAN
+* controller only the CANFD_BRS bit is relevant for real CAN controllers when
+* building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
+* sense for virtual CAN interfaces to test applications with echoed frames.
+*/
+#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
+#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
+
+/**
+* struct canfd_frame - CAN flexible data rate frame structure
+* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+* @len:    frame payload length in byte (0 .. CANFD_MAX_DLEN)
+* @flags:  additional flags for CAN FD
+* @__res0: reserved / padding
+* @__res1: reserved / padding
+* @data:   CAN FD frame payload (up to CANFD_MAX_DLEN byte)
+*/
+typedef struct {
+	canid_t can_id;  /* 32 bit MAKE_CAN_ID + EFF/RTR/ERR flags */
+	BYTE    len;     /* frame payload length in byte */
+	BYTE    flags;   /* additional flags for CAN FD,i.e error code */
+	BYTE    __res0;  /* reserved / padding */
+	BYTE    __res1;  /* reserved / padding */
+	BYTE    data[CANFD_MAX_DLEN]/* __attribute__((aligned(8)))*/;
+}canfd_frame;
+
+#define CAN_MTU		(sizeof(struct can_frame))
+#define CANFD_MTU	(sizeof(struct canfd_frame))
+
+#endif //CANFRAME_H_

+ 136 - 0
src/tool/g29zlgchassistest/config.h

@@ -0,0 +1,136 @@
+#ifndef ZLG_CONFIG_INTF_H
+#define ZLG_CONFIG_INTF_H
+
+struct _Meta;
+struct _Pair;
+struct _Options;
+struct _ConfigNode;
+
+typedef struct _Meta Meta;
+typedef struct _Pair Pair;
+typedef struct _Options Options;
+typedef struct _ConfigNode ConfigNode;
+
+/**
+ *  \struct Options
+ * 节点mata的可选项。
+ */
+struct _Options
+{
+	/*! 可选项的数据类型*/
+	const char * type;
+
+	/*! 可选项的值*/
+	const char * value;
+
+	/*! 可选项的描述信息*/
+	const char * desc;
+};
+
+/**
+ *  \struct Meta
+ * 节点mata信息。
+ */
+struct _Meta
+{
+	/*! 配置项的数据类型 */
+	const char * type;
+
+	/*! 配置项的说明性信息 */
+	const char * desc;
+
+	/*! 配置项是否是只读的,缺省为可读写 */
+	int read_only;
+
+	/*! 配置项输入格式的提示 */
+	const char * format;
+
+	/*! 对于数值类型的配置项来说是最小值,对字符串的配置项来说是最小长度(字节数)。 */
+	double min_value;
+
+	/*! 对于数值类型的配置项来说是最大值,对字符串的配置项来说是最大长度(字节数)。 */
+	double max_value;
+
+	/*! 配置项的单位 */
+	const char * unit;
+
+	/*! 通过旋钮/滚轮等方式修改配置项时的增量 */
+	double delta;
+
+    /*! 配置项是否可见, true可见,false不可见,也可以绑定表达式(表达式使用参考demo3),缺省可见 */
+    const char* visible;
+    
+    /*! 该配置项是否使能, true使能,false不使能,也可以绑定表达式(表达式使用参考demo3)。缺省使能 */
+    const char* enable;
+
+	/*! 配置项的可选值,仅但『type』为间接类型时有效 */
+	int editable;
+
+	/*! 配置项的可选值,仅但『type』为间接类型时有效,以NULL结束 */
+	Options** options;
+};
+
+/**
+ *  \struct Pair
+ *  属性的KeyValue对。
+ */
+struct _Pair
+{
+	const char * key;
+	const char * value;
+};
+
+/**
+ *  \struct ConfigNode 
+ *  ConfigNode
+ */
+struct _ConfigNode
+{
+	/*! 节点的名字 */
+	const char * name;
+	/*! 节点的值 同样可以绑定表达式*/
+	const char * value;
+    /*! 节点值的表达式,当有该表达式时,value由此表达式计算而来*/
+    const char* binding_value;
+	/*! 该节点的路径 */
+	const char * path;
+	/*! 配置项信息 */
+	Meta* meta_info;
+	/*! 该节点的子节点, 以NULL结束*/
+	ConfigNode** children;
+	/*! 该节点的属性, 以NULL结束*/
+	Pair** attributes;
+};
+
+/**
+ * \brief 获取属性的描述信息。
+ *
+ * \retval ConfigNode
+ */
+typedef const ConfigNode* (*GetPropertysFunc)();
+
+/**
+ * \brief 设置指定路径的属性的值。
+ * \param[in] path  : 属性的路径。
+ * \param[in] value : 属性的值。
+ *
+ * \retval 成功返回1,失败返回0。
+ */
+typedef int (*SetValueFunc)(const char* path, const char* value);
+
+/**
+ * \brief 获取指定路径的属性的值。
+ * \param[in] path  : 属性的路径。
+ * \retval 成功返回属性的值,失败返回NULL。
+ */
+typedef const char* (*GetValueFunc)(const char* path);
+
+typedef struct  tagIProperty
+{
+	SetValueFunc     SetValue;
+	GetValueFunc     GetValue;
+	GetPropertysFunc GetPropertys;
+}IProperty;
+
+#endif/*ZLG_CONFIG_INTF_H*/
+

+ 10 - 2
src/tool/g29zlgchassistest/g29zlgchassistest.pro

@@ -16,13 +16,21 @@ DEFINES += QT_DEPRECATED_WARNINGS
 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 
 SOURCES += \
+    cancard.cpp \
     joyreadthread.cpp \
     main.cpp \
-    mainwindow.cpp
+    mainwindow.cpp \
+    speed.cpp
 
 HEADERS += \
+    cancard.h \
+    canframe.h \
+    config.h \
     joyreadthread.h \
-    mainwindow.h
+    mainwindow.h \
+    speed.h \
+    typedef.h \
+    zlgcanlib.h
 
 FORMS += \
     mainwindow.ui

+ 1 - 68
src/tool/g29zlgchassistest/joyreadthread.cpp

@@ -178,7 +178,7 @@ int JoyReadThread::GetShift()
 #include "joyreadthread.h"
 
 #ifdef Q_OS_WIN
-extern HWND gwnd;
+//extern HWND gwnd;
 #endif
 
 //void JoyReadThread::LoadAPI()
@@ -237,74 +237,7 @@ void JoyReadThread::run()
 
     return;
 
-     msleep(3000);
-//    bool bStart = LogiSteeringInitialize(false);
 
-
-
-    bool bStart = LogiSteeringInitializeWithWindow(false,gwnd);
-    std::cout<<" init. "<<bStart<<std::endl;
-
-    int nFail = 0;
-    while(!QThread::isInterruptionRequested())
-    {
-
-        double angle,acc,brake;
-        if((LogiUpdate())&&(LogiIsConnected(0)))
-        {
-            std::cout<<"get state."<<std::endl;
-            DIJOYSTATE2* wheel = LogiGetState(0);
-            angle = wheel->lX;
-            acc = wheel->lY;
-            brake = wheel->lRz;
-            if(angle>100)
-            {
-                int force;
-                if(angle>3000)force = 30;
-                else
-                {
-                    force = angle*30/3000;
-                }
-                LogiPlayConstantForce(0,force);
-            }
-            else
-            {
-                if(angle<-100)
-                {
-                    int force;
-                    if(angle<-3000)force = -30;
-                    else
-                    {
-                        force = angle*30/3000;
-                    }
-                   LogiPlayConstantForce(0,force);
-                }
-                else
-                {
-                    LogiStopConstantForce(0);
-                }
-            }
-
-            mfWheel = angle;
-            mfAcc = acc;
-            mfBrake = brake;
-            nFail = 0;
-            mbJoyOK = true;
-        }
-        else
-        {
-            nFail++;
-        }
-        if(nFail>10)
-        {
-            mbJoyOK = false;
-        }
-        msleep(20);
-
-    }
-
-    LogiSteeringShutdown();
-    mbJoyOK = false;
 }
 
 bool JoyReadThread::isOK()

+ 57 - 0
src/tool/g29zlgchassistest/mainwindow.cpp

@@ -15,6 +15,8 @@ MainWindow::MainWindow(QWidget *parent)
     bool bStart = LogiSteeringInitializeWithWindow(false,hwnd);
     std::cout<<" init. "<<bStart<<std::endl;
 
+    CreateView();
+
     setWindowTitle("Chassis Test Use G29 & ZLG");
 }
 
@@ -68,4 +70,59 @@ void MainWindow::LoadAPI()
 
 }
 
+void MainWindow::CreateView()
+{
+    mpWheel = new Speed(ui->groupBox_rem);
+    mpWheel->settitle(QStringLiteral("Wheel"));
+    mpWheel->setminvalue(450);
+    mpWheel->setmaxvalue(-450);
+
+    mpAcc = new Speed(ui->groupBox_rem);
+
+    mpAcc->settitle(QStringLiteral("油门"));
+    mpAcc->updatevalue(0);
+    mpAcc->setminvalue(-100);
+    mpAcc->setmaxvalue(100);
+
+    mpBrake = new Speed(ui->groupBox_rem);
+    mpBrake->settitle(QStringLiteral("刹车"));
+    mpBrake->updatevalue(0);
+    mpBrake->setminvalue(0);
+    mpBrake->setmaxvalue(100);
+
+    mpVehSpeed = new Speed(ui->centralwidget);
+    mpVehSpeed->settitle(QStringLiteral("车速(km/h)"));
+    mpVehSpeed->updatevalue(0);
+    mpVehSpeed->setminvalue(0);
+    mpVehSpeed->setmaxvalue( mnSpeedMax);
+}
+
+void MainWindow::resizeEvent(QResizeEvent *event)
+{
+    (void)event;
+    QSize sizemain = ui->centralwidget->size();
+    qDebug("size x = %d y=%d",sizemain.width(),sizemain.height());
+
+    int grouppos_x =  30;
+    int grouppos_y =  100;
+    int grouppos_width = (sizemain.width() - 2*grouppos_x) *3/4;
+    int grouppos_height = sizemain.height() - grouppos_y - 30;
+    if(grouppos_width < (grouppos_height * 4))grouppos_height = grouppos_width/4;
+
+    int speed_width = grouppos_width/4;
+    if(speed_width > (grouppos_height *9/10))speed_width = grouppos_height * 9/10;
+    int space = (grouppos_width - 3*speed_width)/4;
+ //   int spacebetw = space + speed_width;
+    int ypos = (grouppos_height - speed_width)/2;
+
+    mpWheel->setGeometry(space,ypos ,speed_width,speed_width);
+    mpBrake->setGeometry(space + 1*speed_width + space,ypos ,speed_width,speed_width);
+    mpAcc->setGeometry(space + 2*speed_width + 2* space,ypos,speed_width,speed_width);
+
+    mpVehSpeed->setGeometry(grouppos_width + grouppos_x + space,grouppos_y + ypos,speed_width,speed_width);
+
+    ui->groupBox_rem->setGeometry(grouppos_x,grouppos_y,grouppos_width,grouppos_height);
+
+}
+
 

+ 19 - 0
src/tool/g29zlgchassistest/mainwindow.h

@@ -5,6 +5,9 @@
 #include <QLibrary>
 
 #include "joyreadthread.h"
+#include "speed.h"
+
+#include "cancard.h"
 
 QT_BEGIN_NAMESPACE
 namespace Ui { class MainWindow; }
@@ -32,5 +35,21 @@ private:
     LogiStopConstantForceFunction LogiStopConstantForce;
     LogiSteeringInitializeWithWindowFunction LogiSteeringInitializeWithWindow;
     void LoadAPI();
+
+private:
+    Speed * mpWheel, * mpAcc, * mpBrake;
+
+    Speed * mpVehSpeed;
+
+    int mnSpeedMax = 100;
+
+public:
+     void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
+
+private:
+    void CreateView();
+
+    cancard zlgcancard;
+
 };
 #endif // MAINWINDOW_H

+ 38 - 2
src/tool/g29zlgchassistest/mainwindow.ui

@@ -13,8 +13,44 @@
   <property name="windowTitle">
    <string>MainWindow</string>
   </property>
-  <widget class="QWidget" name="centralwidget"/>
-  <widget class="QMenuBar" name="menubar"/>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QCheckBox" name="checkBox">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>30</y>
+      <width>71</width>
+      <height>41</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>线控</string>
+    </property>
+   </widget>
+   <widget class="QGroupBox" name="groupBox_rem">
+    <property name="geometry">
+     <rect>
+      <x>30</x>
+      <y>180</y>
+      <width>681</width>
+      <height>261</height>
+     </rect>
+    </property>
+    <property name="title">
+     <string>仪表</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>800</width>
+     <height>23</height>
+    </rect>
+   </property>
+  </widget>
   <widget class="QStatusBar" name="statusbar"/>
  </widget>
  <resources/>

+ 199 - 0
src/tool/g29zlgchassistest/speed.cpp

@@ -0,0 +1,199 @@
+#include "speed.h"
+
+
+#include <QPainter>
+
+#include <math.h>
+
+Speed::Speed(QWidget *parent) : QWidget(parent)
+{
+    m_background = Qt::black;
+    m_foreground = Qt::green;
+
+    m_startAngle = 60;
+    m_endAngle = 60;
+    m_scaleMajor = 10;
+    m_minValue = 100;
+    m_maxValue = -100;
+    m_scaleMajor = 10;//分度
+    m_scaleMinor = 10;
+    m_units = "";
+    m_title = "Wheel";
+    m_precision = 2;
+    m_value = 0;
+}
+
+void Speed::drawCrown(QPainter *painter) //绘制表冠
+{
+    painter->save();
+    int radius = 100;
+    QLinearGradient lg1(0, -radius, 0, radius);
+
+    lg1.setColorAt(0, Qt::white); //设置渐变的颜色和路径比例
+    lg1.setColorAt(1, Qt::gray); //只是粗略的颜色,具体的可以参考RGB颜色查询对照表
+
+    painter->setBrush(lg1); // 创建QBrush对象,把这个渐变对象传递进去:
+    painter->setPen(Qt::NoPen); //边框线无色
+    painter->drawEllipse(-radius, -radius, radius << 1, radius << 1);
+    painter->setBrush(m_background = Qt::black);
+    painter->drawEllipse(-92, -92, 184, 184);
+    painter->restore();
+}
+
+void Speed::drawScaleNum(QPainter *painter) //绘制刻度数字
+{
+    painter->save();
+    painter->setPen(m_foreground);
+    //m_startAngle是起始角度,m_endAngle是结束角度,m_scaleMajor在一个量程中分成的刻度数
+    double startRad = ( 270-m_startAngle) * (3.14 / 180);
+    double deltaRad = (360 - m_startAngle - m_endAngle) * (3.14 / 180) / m_scaleMajor;
+    double sina,cosa;
+    int x, y;
+    QFontMetricsF fm(this->font());
+    double w, h, tmpVal;
+    QString str;
+
+    for (int i = 0; i <= m_scaleMajor; i++)
+    {
+        sina = sin(startRad - i * deltaRad);
+        cosa = cos(startRad - i * deltaRad);
+
+        tmpVal = 1.0 * i *((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;
+        // tmpVal = 50;
+        str = QString( "%1" ).arg(tmpVal);  //%1作为占位符   arg()函数比起 sprintf()来是类型安全的
+        w = fm.size(Qt::TextSingleLine,str).width();
+        h = fm.size(Qt::TextSingleLine,str).height();
+        x = 82 * cosa - w / 2;
+        y = -82 * sina + h / 4;
+        painter->drawText(x, y, str); //函数的前两个参数是显示的坐标位置,后一个是显示的内容,是字符类型""
+
+    }
+    painter->restore();
+}
+
+void Speed::drawScale(QPainter *painter) //绘制刻度线
+{
+    painter->save();
+    painter->rotate(m_startAngle);
+    int steps = (m_scaleMajor * m_scaleMinor); //相乘后的值是分的份数
+    double angleStep = (360.0 - m_startAngle - m_endAngle) / steps; //每一个份数的角度
+
+    // painter->setPen(m_foreground); //m_foreground是颜色的设置
+    // QPen pen = painter->pen(); //第一种方法
+    QPen pen ;
+    pen.setColor(Qt::green); //推荐使用第二种方式
+    for (int i = 0; i <= steps; i++)
+    {
+        if (i % m_scaleMinor == 0)//整数刻度显示加粗
+        {
+            pen.setWidth(1); //设置线宽
+            painter->setPen(pen); //使用面向对象的思想,把画笔关联上画家。通过画家画出来
+
+            painter->drawLine(0, 62, 0, 72); //两个参数应该是两个坐标值
+        }
+        else
+        {
+            pen.setWidth(0);
+            painter->setPen(pen);
+            painter->drawLine(0, 67, 0, 72);
+        }
+        painter->rotate(angleStep);
+    }
+    painter->restore();
+
+}
+
+void Speed::drawTitle(QPainter *painter)
+{
+    painter->save();
+    painter->setPen(m_foreground);
+    //painter->setBrush(m_foreground);
+    QString str(m_title); //显示仪表的功能
+    QFontMetricsF fm(this->font());
+    double w = fm.size(Qt::TextSingleLine,str).width();
+    painter->drawText(-w / 2, -30, str);
+    painter->restore();
+}
+
+void Speed::drawNumericValue(QPainter *painter)
+{
+    QString str = QString("%1 %2").arg(m_value, 0, 'f', m_precision).arg(m_units);
+    QFontMetricsF fm(font());
+    double w = fm.size(Qt::TextSingleLine,str).width();
+    painter->setPen(m_foreground);
+    painter->drawText(-w / 2, 42, str);
+}
+
+void Speed::drawIndicator(QPainter *painter)
+{
+    painter->save();
+    QPolygon pts;
+    pts.setPoints(3, -2, 0, 2, 0, 0, 60);	/* (-2,0)/(2,0)/(0,60) *///第一个参数是 ,坐标的个数。后边的是坐标
+
+    painter->rotate(m_startAngle);
+    double degRotate = (360.0 - m_startAngle - m_endAngle) / (m_maxValue - m_minValue)*(m_value - m_minValue);
+
+    //画指针
+    painter->rotate(degRotate);  //顺时针旋转坐标系统
+    QRadialGradient haloGradient(0, 0, 60, 0, 0);  //辐射渐变
+    haloGradient.setColorAt(0, QColor(60, 60, 60));
+    haloGradient.setColorAt(1, QColor(160, 160, 160)); //灰
+    painter->setPen(Qt::white); //定义线条文本颜色  设置线条的颜色
+    painter->setBrush(haloGradient);//刷子定义形状如何填满 填充后的颜色
+    painter->drawConvexPolygon(pts); //这是个重载函数,绘制多边形。
+    painter->restore();
+
+    //画中心点
+    QColor niceBlue(150, 150, 200);
+    QConicalGradient coneGradient(0, 0, -90.0);  //角度渐变
+    coneGradient.setColorAt(0.0, Qt::darkGray);
+    coneGradient.setColorAt(0.2, niceBlue);
+    coneGradient.setColorAt(0.5, Qt::white);
+    coneGradient.setColorAt(1.0, Qt::darkGray);
+    painter->setPen(Qt::NoPen);  //没有线,填满没有边界
+    painter->setBrush(coneGradient);
+    painter->drawEllipse(-5, -5, 10, 10);
+}
+
+void Speed ::paintEvent(QPaintEvent *)
+{
+    QPainter painter(this);//一个类中的this表示一个指向该类自己的指针
+    painter.setRenderHint(QPainter::Antialiasing);  /* 使用反锯齿(如果可用) */
+    painter.translate(width() / 2, height() / 2);   /* 坐标变换为窗体中心 */
+    int side = qMin(width(), height());
+    painter.scale(side / 200.0, side / 200.0);      /* 比例缩放 */
+
+   drawCrown(&painter);                                 /* 画表盘边框 */
+   drawScaleNum(&painter);                          /* 画刻度数值值 */
+   drawScale(&painter);                                 /* 画刻度线 */
+   drawTitle(&painter);                                     /* 画单位 */
+   drawNumericValue(&painter);                      /* 画数字显示 */
+   drawIndicator(&painter);                             /* 画表针 */
+
+}
+
+void Speed::setminvalue(int value)
+{
+    m_minValue = value;
+}
+
+void Speed::setmaxvalue(int value)
+{
+    m_maxValue = value;
+}
+
+void Speed::updatevalue(double value)
+{
+    m_value = value;
+    update();
+}
+
+void Speed::setunits(QString strunits)
+{
+    m_units = strunits;
+}
+
+void Speed::settitle(QString strtitle)
+{
+    m_title = strtitle;
+}

+ 51 - 0
src/tool/g29zlgchassistest/speed.h

@@ -0,0 +1,51 @@
+#ifndef SPEED_H
+#define SPEED_H
+
+#include <QWidget>
+
+class Speed : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit Speed(QWidget *parent = nullptr);
+
+protected:
+    void paintEvent(QPaintEvent *);
+
+    void drawCrown(QPainter *painter);
+    void drawBackground(QPainter *painter);
+    void drawScale(QPainter *painter);
+    void drawScaleNum(QPainter *painter);
+    void drawTitle(QPainter *painter);
+    void drawIndicator(QPainter *painter);
+    void drawNumericValue(QPainter *painter);
+
+private:
+    QColor m_background;
+    QColor m_foreground;
+
+
+    int m_maxValue;
+    int m_minValue;
+    int m_startAngle;
+    int m_endAngle;
+
+    int m_scaleMajor;
+    int m_scaleMinor;
+    double m_value;
+    int m_precision;
+    QTimer *m_updateTimer;
+    QString m_units;
+    QString m_title;
+    public Q_SLOTS:
+//	void UpdateAngle();
+
+public:
+    void setminvalue(int value);
+    void setmaxvalue(int value);
+    void updatevalue(double value);
+    void setunits(QString strunits);
+    void settitle(QString strtitle);
+};
+
+#endif // SPEED_H

+ 11 - 0
src/tool/g29zlgchassistest/typedef.h

@@ -0,0 +1,11 @@
+#ifndef TYPEDEF_H_
+#define TYPEDEF_H_
+
+typedef unsigned char      BYTE;
+typedef unsigned int       UINT;
+typedef unsigned long      ULONG;
+typedef unsigned long long UINT64;
+typedef unsigned short     USHORT;
+typedef unsigned char      UCHAR;
+
+#endif //TYPEDEF_H_

+ 610 - 0
src/tool/g29zlgchassistest/zlgcanlib.h

@@ -0,0 +1,610 @@
+#ifndef ZLGCAN_H_
+#define ZLGCAN_H_
+
+#include <time.h>
+
+#include "canframe.h"
+#include "config.h"
+
+#define ZCAN_PCI5121                        1
+#define ZCAN_PCI9810                        2
+#define ZCAN_USBCAN1                        3
+#define ZCAN_USBCAN2                        4
+#define ZCAN_PCI9820                        5
+#define ZCAN_CAN232                         6
+#define ZCAN_PCI5110                        7
+#define ZCAN_CANLITE                        8
+#define ZCAN_ISA9620                        9
+#define ZCAN_ISA5420                        10
+#define ZCAN_PC104CAN                       11
+#define ZCAN_CANETUDP                       12
+#define ZCAN_CANETE                         12
+#define ZCAN_DNP9810                        13
+#define ZCAN_PCI9840                        14
+#define ZCAN_PC104CAN2                      15
+#define ZCAN_PCI9820I                       16
+#define ZCAN_CANETTCP                       17
+#define ZCAN_PCIE_9220                      18
+#define ZCAN_PCI5010U                       19
+#define ZCAN_USBCAN_E_U                     20
+#define ZCAN_USBCAN_2E_U                    21
+#define ZCAN_PCI5020U                       22
+#define ZCAN_EG20T_CAN                      23
+#define ZCAN_PCIE9221                       24
+#define ZCAN_WIFICAN_TCP                    25
+#define ZCAN_WIFICAN_UDP                    26
+#define ZCAN_PCIe9120                       27
+#define ZCAN_PCIe9110                       28
+#define ZCAN_PCIe9140                       29
+#define ZCAN_USBCAN_4E_U                    31
+#define ZCAN_CANDTU_200UR                   32
+#define ZCAN_CANDTU_MINI                    33
+#define ZCAN_USBCAN_8E_U                    34
+#define ZCAN_CANREPLAY                      35
+#define ZCAN_CANDTU_NET                     36
+#define ZCAN_CANDTU_100UR                   37
+#define ZCAN_PCIE_CANFD_100U                38
+#define ZCAN_PCIE_CANFD_200U                39
+#define ZCAN_PCIE_CANFD_400U                40
+#define ZCAN_USBCANFD_200U                  41
+#define ZCAN_USBCANFD_100U                  42
+#define ZCAN_USBCANFD_MINI                  43
+#define ZCAN_CANFDCOM_100IE                 44
+#define ZCAN_CANSCOPE                       45
+#define ZCAN_CLOUD                          46
+#define ZCAN_CANDTU_NET_400                 47
+#define ZCAN_CANFDNET_TCP                   48
+#define ZCAN_CANFDNET_200U_TCP              48
+#define ZCAN_CANFDNET_UDP                   49
+#define ZCAN_CANFDNET_200U_UDP              49
+#define ZCAN_CANFDWIFI_TCP                  50
+#define ZCAN_CANFDWIFI_100U_TCP             50
+#define ZCAN_CANFDWIFI_UDP                  51
+#define ZCAN_CANFDWIFI_100U_UDP             51
+#define ZCAN_CANFDNET_400U_TCP              52
+#define ZCAN_CANFDNET_400U_UDP              53
+#define ZCAN_CANFDBLUE_200U                 54
+#define ZCAN_CANFDNET_100U_TCP              55
+#define ZCAN_CANFDNET_100U_UDP              56
+#define ZCAN_CANFDNET_800U_TCP              57
+#define ZCAN_CANFDNET_800U_UDP              58
+#define ZCAN_USBCANFD_800U                  59
+#define ZCAN_PCIE_CANFD_100U_EX             60
+#define ZCAN_PCIE_CANFD_400U_EX             61
+#define ZCAN_PCIE_CANFD_200U_MINI           62
+#define ZCAN_PCIE_CANFD_200U_M2             63
+#define ZCAN_CANFDDTU_400_TCP               64
+#define ZCAN_CANFDDTU_400_UDP               65
+#define ZCAN_CANFDWIFI_200U_TCP             66
+#define ZCAN_CANFDWIFI_200U_UDP             67
+#define ZCAN_CANFDDTU_800ER_TCP             68
+#define ZCAN_CANFDDTU_800ER_UDP             69
+#define ZCAN_CANFDDTU_800EWGR_TCP           70
+#define ZCAN_CANFDDTU_800EWGR_UDP           71
+#define ZCAN_CANFDDTU_600EWGR_TCP           72
+#define ZCAN_CANFDDTU_600EWGR_UDP           73
+
+#define ZCAN_OFFLINE_DEVICE                 98
+#define ZCAN_VIRTUAL_DEVICE                 99
+
+#define ZCAN_ERROR_CAN_OVERFLOW             0x0001
+#define ZCAN_ERROR_CAN_ERRALARM             0x0002
+#define ZCAN_ERROR_CAN_PASSIVE              0x0004
+#define ZCAN_ERROR_CAN_LOSE                 0x0008
+#define ZCAN_ERROR_CAN_BUSERR               0x0010
+#define ZCAN_ERROR_CAN_BUSOFF               0x0020
+#define ZCAN_ERROR_CAN_BUFFER_OVERFLOW      0x0040
+
+#define ZCAN_ERROR_DEVICEOPENED             0x0100
+#define ZCAN_ERROR_DEVICEOPEN               0x0200
+#define ZCAN_ERROR_DEVICENOTOPEN            0x0400
+#define ZCAN_ERROR_BUFFEROVERFLOW           0x0800
+#define ZCAN_ERROR_DEVICENOTEXIST           0x1000
+#define ZCAN_ERROR_LOADKERNELDLL            0x2000
+#define ZCAN_ERROR_CMDFAILED                0x4000
+#define ZCAN_ERROR_BUFFERCREATE             0x8000
+
+#define ZCAN_ERROR_CANETE_PORTOPENED        0x00010000
+#define ZCAN_ERROR_CANETE_INDEXUSED         0x00020000
+#define ZCAN_ERROR_REF_TYPE_ID              0x00030001
+#define ZCAN_ERROR_CREATE_SOCKET            0x00030002
+#define ZCAN_ERROR_OPEN_CONNECT             0x00030003
+#define ZCAN_ERROR_NO_STARTUP               0x00030004
+#define ZCAN_ERROR_NO_CONNECTED             0x00030005
+#define ZCAN_ERROR_SEND_PARTIAL             0x00030006
+#define ZCAN_ERROR_SEND_TOO_FAST            0x00030007
+
+#define STATUS_ERR                          0
+#define STATUS_OK                           1
+#define STATUS_ONLINE                       2
+#define STATUS_OFFLINE                      3
+#define STATUS_UNSUPPORTED                  4
+
+#define CMD_DESIP                           0
+#define CMD_DESPORT                         1
+#define CMD_CHGDESIPANDPORT                 2
+#define CMD_SRCPORT                         2
+#define CMD_TCP_TYPE                        4
+#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
+
+#define TYPE_CAN                            0
+#define TYPE_CANFD                          1
+#define TYPE_ALL_DATA                       2
+
+typedef void * DEVICE_HANDLE;
+typedef void * CHANNEL_HANDLE;
+
+typedef struct tagZCAN_DEVICE_INFO {
+    USHORT hw_Version;                      //硬件版本
+    USHORT fw_Version;                      //固件版本
+    USHORT dr_Version;                      //驱动版本
+    USHORT in_Version;                      //动态库版本
+    USHORT irq_Num;
+    BYTE   can_Num;
+    UCHAR  str_Serial_Num[20];
+    UCHAR  str_hw_Type[40];
+    USHORT reserved[4];
+}ZCAN_DEVICE_INFO;
+
+typedef struct tagZCAN_CHANNEL_INIT_CONFIG {
+    UINT can_type;                          //type:TYPE_CAN TYPE_CANFD
+    union
+    {
+        struct
+        {
+            UINT  acc_code;
+            UINT  acc_mask;
+            UINT  reserved;
+            BYTE  filter;
+            BYTE  timing0;
+            BYTE  timing1;
+            BYTE  mode;
+        }can;
+        struct
+        {
+            UINT   acc_code;
+            UINT   acc_mask;
+            UINT   abit_timing;
+            UINT   dbit_timing;
+            UINT   brp;
+            BYTE   filter;
+            BYTE   mode;
+            USHORT pad;
+            UINT   reserved;
+        }canfd;
+    };
+}ZCAN_CHANNEL_INIT_CONFIG;
+
+typedef struct tagZCAN_CHANNEL_ERR_INFO {
+    UINT error_code;
+    BYTE passive_ErrData[3];
+    BYTE arLost_ErrData;
+} ZCAN_CHANNEL_ERR_INFO;
+
+typedef struct tagZCAN_CHANNEL_STATUS {
+    BYTE errInterrupt;
+    BYTE regMode;
+    BYTE regStatus;
+    BYTE regALCapture;
+    BYTE regECCapture;
+    BYTE regEWLimit;
+    BYTE regRECounter;
+    BYTE regTECounter;
+    UINT Reserved;
+}ZCAN_CHANNEL_STATUS;
+
+typedef struct tagZCAN_Transmit_Data
+{
+    can_frame   frame;
+    UINT        transmit_type;
+}ZCAN_Transmit_Data;
+
+typedef struct tagZCAN_Receive_Data
+{
+    can_frame   frame;
+    UINT64      timestamp;                  //us
+}ZCAN_Receive_Data;
+
+typedef struct tagZCAN_TransmitFD_Data
+{
+    canfd_frame frame;
+    UINT        transmit_type;
+}ZCAN_TransmitFD_Data;
+
+typedef struct tagZCAN_ReceiveFD_Data
+{
+    canfd_frame frame;
+    UINT64      timestamp;                  //us
+}ZCAN_ReceiveFD_Data;
+
+typedef struct tagZCAN_AUTO_TRANSMIT_OBJ{
+    USHORT enable;
+    USHORT index;                           //0...n
+    UINT   interval;                        //ms
+    ZCAN_Transmit_Data obj;
+}ZCAN_AUTO_TRANSMIT_OBJ, *PZCAN_AUTO_TRANSMIT_OBJ;
+
+typedef struct tagZCANFD_AUTO_TRANSMIT_OBJ{
+    USHORT enable;
+    USHORT index;                           //0...n
+    UINT interval;                          //ms
+    ZCAN_TransmitFD_Data obj;
+}ZCANFD_AUTO_TRANSMIT_OBJ, *PZCANFD_AUTO_TRANSMIT_OBJ;
+
+//用于设置定时发送额外的参数, 目前只支持USBCANFD-X00U系列设备
+typedef struct tagZCAN_AUTO_TRANSMIT_OBJ_PARAM
+{
+    USHORT index;                           // 定时发送帧的索引
+    USHORT type;                            // 参数类型,目前类型只有1:表示启动延时
+    UINT   value;                           // 参数数值
+}ZCAN_AUTO_TRANSMIT_OBJ_PARAM, *PZCAN_AUTO_TRANSMIT_OBJ_PARAM;
+
+//for zlg cloud
+#define ZCLOUD_MAX_DEVICES                  100
+#define ZCLOUD_MAX_CHANNEL                  16
+
+typedef struct tagZCLOUD_CHNINFO
+{
+    BYTE enable;                            // 0:disable, 1:enable
+    BYTE type;                              // 0:CAN, 1:ISO CANFD, 2:Non-ISO CANFD
+    BYTE isUpload;
+    BYTE isDownload;
+} ZCLOUD_CHNINFO;
+
+typedef struct tagZCLOUD_DEVINFO
+{
+    int devIndex;           
+    char type[64];
+    char id[64];
+    char name[64];
+    char owner[64];
+    char model[64];
+    char fwVer[16];
+    char hwVer[16];
+    char serial[64];
+    int status;                             // 0:online, 1:offline
+    BYTE bGpsUpload;
+    BYTE channelCnt;
+    ZCLOUD_CHNINFO channels[ZCLOUD_MAX_CHANNEL];
+}ZCLOUD_DEVINFO;
+
+typedef struct tagZCLOUD_USER_DATA
+{
+    char username[64];
+    char mobile[64];
+    char dllVer[16];                        // cloud dll version
+    size_t devCnt;
+    ZCLOUD_DEVINFO devices[ZCLOUD_MAX_DEVICES];
+}ZCLOUD_USER_DATA;
+
+// GPS
+typedef struct tagZCLOUD_GPS_FRAME
+{
+    float latitude;                         // + north latitude, - south latitude
+    float longitude;                        // + east longitude, - west longitude           
+    float speed;                            // km/h    
+    struct __gps_time {
+        USHORT    year;
+        USHORT    mon;
+        USHORT    day;
+        USHORT    hour;
+        USHORT    min;
+        USHORT    sec;
+    }tm;
+} ZCLOUD_GPS_FRAME;
+//for zlg cloud
+
+//TX timestamp
+typedef struct tagUSBCANFDTxTimeStamp
+{
+    UINT* pTxTimeStampBuffer;               //allocated by user, size:nBufferTimeStampCount * 4,unit:100us
+    UINT  nBufferTimeStampCount;            //buffer size
+}USBCANFDTxTimeStamp;
+
+typedef struct tagTxTimeStamp
+{
+    UINT64* pTxTimeStampBuffer;             //allocated by user, size:nBufferTimeStampCount * 8,unit:1us
+    UINT    nBufferTimeStampCount;          //buffer timestamp count
+    int     nWaitTime;                      //Wait Time ms, -1表示等到有数据才返回
+}TxTimeStamp;
+
+// Bus usage
+typedef struct tagBusUsage
+{
+    UINT64  nTimeStampBegin;                //测量起始时间戳,单位us
+    UINT64  nTimeStampEnd;                  //测量结束时间戳,单位us
+    BYTE    nChnl;                          //通道
+    BYTE    nReserved;                      //保留
+    USHORT  nBusUsage;                      //总线利用率(%),总线利用率*100展示。取值0~10000,如8050表示80.50%
+    UINT    nFrameCount;                    //帧数量
+}BusUsage;
+
+//LIN
+typedef struct _VCI_LIN_MSG{
+    BYTE    ID;
+    BYTE    DataLen;
+    USHORT  Flag;
+    UINT    TimeStamp;
+    BYTE    Data[8];
+}ZCAN_LIN_MSG, *PZCAN_LIN_MSG;
+
+#define LIN_MODE_MASTER                     0
+#define LIN_MODE_SLAVE                      1
+#define LIN_FLAG_CHK_ENHANCE                0x01
+#define LIN_FLAG_VAR_DLC                    0x02
+
+typedef struct _VCI_LIN_INIT_CONFIG
+{
+    BYTE    linMode;
+    BYTE    linFlag;
+    USHORT  reserved;
+    UINT    linBaud;
+}ZCAN_LIN_INIT_CONFIG, *PZCAN_LIN_INIT_CONFIG;
+//end LIN
+
+enum eZCANErrorDEF
+{
+    //总线错误类型
+    ZCAN_ERR_TYPE_NO_ERR                = 0,        //无错误
+    ZCAN_ERR_TYPE_BUS_ERR               = 1,        //总线错误
+    ZCAN_ERR_TYPE_CONTROLLER_ERR        = 2,        //控制器错误
+    ZCAN_ERR_TYPE_DEVICE_ERR            = 3,        //终端设备错误
+
+    //节点状态
+    ZCAN_NODE_STATE_ACTIVE              = 1,        //总线积极
+    ZCAN_NODE_STATE_WARNNING            = 2,        //总线告警
+    ZCAN_NODE_STATE_PASSIVE             = 3,        //总线消极
+    ZCAN_NODE_STATE_BUSOFF              = 4,        //总线关闭
+
+    //总线错误子类型, errType = ZCAN_ERR_TYPE_BUS_ERR
+    ZCAN_BUS_ERR_NO_ERR                 = 0,        //无错误
+    ZCAN_BUS_ERR_BIT_ERR                = 1,        //位错误
+    ZCAN_BUS_ERR_ACK_ERR                = 2,        //应答错误
+    ZCAN_BUS_ERR_CRC_ERR                = 3,        //CRC错误
+    ZCAN_BUS_ERR_FORM_ERR               = 4,        //格式错误
+    ZCAN_BUS_ERR_STUFF_ERR              = 5,        //填充错误
+    ZCAN_BUS_ERR_OVERLOAD_ERR           = 6,        //超载错误
+    ZCAN_BUS_ERR_ARBITRATION_LOST       = 7,        //仲裁丢失
+
+    //控制器错误, errType = ZCAN_ERR_TYPE_CONTROLLER_ERR
+    ZCAN_CONTROLLER_RX_FIFO_OVERFLOW    = 1,        //控制器接收FIFO溢出
+    ZCAN_CONTROLLER_DRIVER_RX_BUFFER_OVERFLOW  = 2, //驱动接收缓存溢出
+    ZCAN_CONTROLLER_DRIVER_TX_BUFFER_OVERFLOW  = 3, //驱动发送缓存溢出
+    ZCAN_CONTROLLER_INTERNAL_ERROR      = 4,        //控制器内部错误
+
+    //终端设备错误, errType = ZCAN_ERR_TYPE_DEVICE_ERR
+    ZCAN_DEVICE_APP_RX_BUFFER_OVERFLOW = 1,         //终端应用接收缓存溢出
+    ZCAN_DEVICE_APP_TX_BUFFER_OVERFLOW = 2,         //终端应用发送缓存溢出
+    ZCAN_DEVICE_APP_AUTO_SEND_FAILED   = 3,         //定时发送失败
+    ZCAN_CONTROLLER_TX_FRAME_INVALID   = 4,         //发送报文无效
+};
+
+enum eZCANDataDEF
+{
+    //数据类型
+    ZCAN_DT_ZCAN_CAN_CANFD_DATA     = 1,            // CAN/CANFD数据
+    ZCAN_DT_ZCAN_ERROR_DATA         = 2,            // 错误数据
+    ZCAN_DT_ZCAN_GPS_DATA           = 3,            // GPS数据
+    ZCAN_DT_ZCAN_LIN_DATA           = 4,            // LIN数据
+
+    //发送延时单位
+    ZCAN_TX_DELAY_NO_DELAY          = 0,            // 无发送延时
+    ZCAN_TX_DELAY_UNIT_MS           = 1,            // 发送延时单位毫秒
+    ZCAN_TX_DELAY_UNIT_100US        = 2,            // 发送延时单位100微秒(0.1毫秒)
+
+};
+
+#pragma pack(push, 1)
+
+// CAN/CANFD数据
+typedef struct tagZCANCANFDData
+{
+    UINT64          timeStamp;                      // 时间戳,数据接收时单位微秒(us),队列延时发送时,数据单位取决于flag.unionVal.txDelay
+    union
+    {
+        struct{
+            UINT    frameType : 2;                  // 帧类型, 0:CAN帧, 1:CANFD帧
+            UINT    txDelay : 2;                    // 队列发送延时, 发送有效. 0:无发送延时, 1:发送延时单位ms, 2:发送延时单位100us. 启用队列发送延时,延时时间存放在timeStamp字段
+            UINT    transmitType : 4;               // 发送类型, 发送有效. 0:正常发送, 1:单次发送, 2:自发自收, 3:单次自发自收. 所有设备支持正常发送,其他类型请参考具体使用手册
+            UINT    txEchoRequest : 1;              // 发送回显请求, 发送有效. 支持发送回显的设备,发送数据时将此位置1,设备可以通过接收接口将发送出去的数据帧返回,接收到的发送数据使用txEchoed位标记
+            UINT    txEchoed : 1;                   // 报文是否是回显报文, 接收有效. 0:正常总线接收报文, 1:本设备发送回显报文.
+            UINT    reserved : 22;                  // 保留
+        }unionVal;
+        UINT    rawVal;                             // 帧标志位raw数据
+    }flag;                                          // CAN/CANFD帧标志位
+    BYTE        extraData[4];                       // 额外数据,暂未使用
+    canfd_frame frame;                              // can/canfd帧ID+数据
+}ZCANCANFDData;
+
+// 错误数据
+typedef struct tagZCANErrorData
+{
+    UINT64  timeStamp;                              // 时间戳, 单位微秒(us)
+    BYTE    errType;                                // 错误类型, 参考eZCANErrorDEF中 总线错误类型 部分值定义
+    BYTE    errSubType;                             // 错误子类型, 参考eZCANErrorDEF中 总线错误子类型 部分值定义
+    BYTE    nodeState;                              // 节点状态, 参考eZCANErrorDEF中 节点状态 部分值定义
+    BYTE    rxErrCount;                             // 接收错误计数
+    BYTE    txErrCount;                             // 发送错误计数
+    BYTE    errData;                                // 错误数据, 和当前错误类型以及错误子类型定义的具体错误相关, 具体请参考使用手册
+    BYTE    reserved[2];                            // 保留
+}ZCANErrorData;
+
+// GPS数据
+typedef struct tagZCANGPSData
+{
+    struct {
+        USHORT  year;                               // 年
+        USHORT  mon;                                // 月
+        USHORT  day;                                // 日
+        USHORT  hour;                               // 时
+        USHORT  min;                                // 分
+        USHORT  sec;                                // 秒
+        USHORT  milsec;                             // 毫秒
+    }           time;                               // UTC时间
+    union{
+        struct{
+            USHORT timeValid : 1;                   // 时间数据是否有效
+            USHORT latlongValid : 1;                // 经纬度数据是否有效
+            USHORT altitudeValid : 1;               // 海拔数据是否有效
+            USHORT speedValid : 1;                  // 速度数据是否有效
+            USHORT courseAngleValid : 1;            // 航向角数据是否有效
+            USHORT reserved:13;                     // 保留
+        }unionVal;
+        USHORT rawVal;
+    }flag;                                          // 标志信息
+    double latitude;                                // 纬度 正数表示北纬, 负数表示南纬
+    double longitude;                               // 经度 正数表示东经, 负数表示西经
+    double altitude;                                // 海拔 单位: 米
+    double speed;                                   // 速度 单位: km/h
+    double courseAngle;                             // 航向角
+} ZCANGPSData;
+
+// LIN数据
+typedef struct tagZCANLINData
+{
+    UINT64          timeStamp;                      // 时间戳,单位微秒(us)
+    union {
+        struct {
+            BYTE    ID:6;                           // 帧ID
+            BYTE    Parity:2;                       // 帧ID校验
+        }unionVal;
+        BYTE    rawVal;                             // 受保护的ID原始值
+    }       PID;                                    // 受保护的ID
+    BYTE    dataLen;                                // 数据长度
+    union{
+        struct{
+            USHORT tx : 1;                          // 控制器发送在总线上的消息, 接收有效
+            USHORT rx : 1;                          // 控制器接收总线上的消息, 接收有效
+            USHORT noData : 1;                      // 无数据区
+            USHORT chkSumErr : 1;                   // 校验和错误
+            USHORT parityErr : 1;                   // 奇偶校验错误, 此时消息中的 chksum 无效
+            USHORT syncErr : 1;                     // 同步段错误 
+            USHORT bitErr : 1;                      // 发送时位错误 
+            USHORT wakeUp : 1;                      // 收到唤醒帧, 此时消息 ID、数据长度、数据域、校验值无效
+            USHORT reserved : 8;                    // 保留
+        }unionVal;                                  // LIN数据标志位(按位表示)
+        USHORT rawVal;                              // LIN数据标志位
+    }flag;                                          // 标志信息
+    BYTE    chkSum;                                 // 数据校验, 部分设备不支持校验数据的获取
+    BYTE    reserved[3];                            // 保留
+    BYTE    data[8];                                // 数据
+}ZCANLINData;
+
+// 合并接收数据数据结构,支持CAN/CANFD/LIN/GPS/错误等不同类型数据
+typedef struct tagZCANDataObj
+{
+    BYTE        dataType;                           // 数据类型, 参考eZCANDataDEF中 数据类型 部分定义
+    BYTE        chnl;                               // 数据通道
+    union{
+        struct{
+            USHORT reserved : 16;                   // 保留
+        }unionVal;
+        USHORT rawVal;
+    }flag;                                          // 标志信息, 暂未使用
+    BYTE        extraData[4];                       // 额外数据, 暂未使用
+    union
+    {
+        ZCANCANFDData           zcanCANFDData;      // CAN/CANFD数据
+        ZCANErrorData           zcanErrData;        // 错误数据
+        ZCANGPSData             zcanGPSData;        // GPS数据
+        ZCANLINData             zcanLINData;        // LIN数据
+        BYTE                    raw[92];            // RAW数据
+    } data;                                         // 实际数据, 联合体,有效成员根据 dataType 字段而定
+}ZCANDataObj;
+
+#pragma pack(pop)
+
+#ifdef __cplusplus 
+#define DEF(a) = a
+#else 
+#define DEF(a)
+#endif 
+
+#define FUNC_CALL __stdcall
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define INVALID_DEVICE_HANDLE 0
+typedef DEVICE_HANDLE (*ZCAN_OpenDeviceFunc)(UINT device_type, UINT device_index, UINT reserved);
+typedef UINT  (*ZCAN_CloseDeviceFunc)(DEVICE_HANDLE device_handle);
+typedef UINT  (*ZCAN_GetDeviceInfFunc)(DEVICE_HANDLE device_handle, ZCAN_DEVICE_INFO* pInfo);
+
+typedef UINT  (*ZCAN_IsDeviceOnLineFunc)(DEVICE_HANDLE device_handle);
+
+#define INVALID_CHANNEL_HANDLE 0
+typedef CHANNEL_HANDLE  (*ZCAN_InitCANFunc)(DEVICE_HANDLE device_handle, UINT can_index, ZCAN_CHANNEL_INIT_CONFIG* pInitConfig);
+typedef UINT  (*ZCAN_StartCANFunc)(CHANNEL_HANDLE channel_handle);
+typedef UINT  (*ZCAN_ResetCANFunc)(CHANNEL_HANDLE channel_handle);
+typedef UINT  (*ZCAN_ClearBufferFunc)(CHANNEL_HANDLE channel_handle);
+typedef UINT  (*ZCAN_ReadChannelErrInfoFunc)(CHANNEL_HANDLE channel_handle, ZCAN_CHANNEL_ERR_INFO* pErrInfo);
+typedef UINT  (*ZCAN_ReadChannelStatusFunc)(CHANNEL_HANDLE channel_handle, ZCAN_CHANNEL_STATUS* pCANStatus);
+typedef UINT  (*ZCAN_GetReceiveNumFunc)(CHANNEL_HANDLE channel_handle, BYTE type);//type:TYPE_CAN, TYPE_CANFD, TYPE_ALL_DATA
+typedef UINT  (*ZCAN_TransmitFunc)(CHANNEL_HANDLE channel_handle, ZCAN_Transmit_Data* pTransmit, UINT len);
+typedef UINT  (*ZCAN_ReceiveFunc)(CHANNEL_HANDLE channel_handle, ZCAN_Receive_Data* pReceive, UINT len, int wait_time);
+typedef UINT  (*ZCAN_TransmitFDFunc)(CHANNEL_HANDLE channel_handle, ZCAN_TransmitFD_Data* pTransmit, UINT len);
+typedef UINT  (*ZCAN_ReceiveFDFunc)(CHANNEL_HANDLE channel_handle, ZCAN_ReceiveFD_Data* pReceive, UINT len, int wait_time);
+
+typedef UINT  (*ZCAN_TransmitDataFunc)(DEVICE_HANDLE device_handle, ZCANDataObj* pTransmit, UINT len);
+typedef UINT  (*ZCAN_ReceiveDataFunc)(DEVICE_HANDLE device_handle, ZCANDataObj* pReceive, UINT len, int wait_time);
+typedef UINT  (*ZCAN_SetValueFunc)(DEVICE_HANDLE device_handle, const char* path, const void* value);
+typedef const void*  (*ZCAN_GetValueFunc)(DEVICE_HANDLE device_handle, const char* path);
+
+//#define INVALID_DEVICE_HANDLE 0
+//DEVICE_HANDLE FUNC_CALL ZCAN_OpenDevice(UINT device_type, UINT device_index, UINT reserved);
+//UINT FUNC_CALL ZCAN_CloseDevice(DEVICE_HANDLE device_handle);
+//UINT FUNC_CALL ZCAN_GetDeviceInf(DEVICE_HANDLE device_handle, ZCAN_DEVICE_INFO* pInfo);
+
+//UINT FUNC_CALL ZCAN_IsDeviceOnLine(DEVICE_HANDLE device_handle);
+
+//#define INVALID_CHANNEL_HANDLE 0
+//CHANNEL_HANDLE FUNC_CALL ZCAN_InitCAN(DEVICE_HANDLE device_handle, UINT can_index, ZCAN_CHANNEL_INIT_CONFIG* pInitConfig);
+//UINT FUNC_CALL ZCAN_StartCAN(CHANNEL_HANDLE channel_handle);
+//UINT FUNC_CALL ZCAN_ResetCAN(CHANNEL_HANDLE channel_handle);
+//UINT FUNC_CALL ZCAN_ClearBuffer(CHANNEL_HANDLE channel_handle);
+//UINT FUNC_CALL ZCAN_ReadChannelErrInfo(CHANNEL_HANDLE channel_handle, ZCAN_CHANNEL_ERR_INFO* pErrInfo);
+//UINT FUNC_CALL ZCAN_ReadChannelStatus(CHANNEL_HANDLE channel_handle, ZCAN_CHANNEL_STATUS* pCANStatus);
+//UINT FUNC_CALL ZCAN_GetReceiveNum(CHANNEL_HANDLE channel_handle, BYTE type);//type:TYPE_CAN, TYPE_CANFD, TYPE_ALL_DATA
+//UINT FUNC_CALL ZCAN_Transmit(CHANNEL_HANDLE channel_handle, ZCAN_Transmit_Data* pTransmit, UINT len);
+//UINT FUNC_CALL ZCAN_Receive(CHANNEL_HANDLE channel_handle, ZCAN_Receive_Data* pReceive, UINT len, int wait_time DEF(-1));
+//UINT FUNC_CALL ZCAN_TransmitFD(CHANNEL_HANDLE channel_handle, ZCAN_TransmitFD_Data* pTransmit, UINT len);
+//UINT FUNC_CALL ZCAN_ReceiveFD(CHANNEL_HANDLE channel_handle, ZCAN_ReceiveFD_Data* pReceive, UINT len, int wait_time DEF(-1));
+
+//UINT FUNC_CALL ZCAN_TransmitData(DEVICE_HANDLE device_handle, ZCANDataObj* pTransmit, UINT len);
+//UINT FUNC_CALL ZCAN_ReceiveData(DEVICE_HANDLE device_handle, ZCANDataObj* pReceive, UINT len, int wait_time DEF(-1));
+//UINT FUNC_CALL ZCAN_SetValue(DEVICE_HANDLE device_handle, const char* path, const void* value);
+//const void* FUNC_CALL ZCAN_GetValue(DEVICE_HANDLE device_handle, const char* path);
+
+//IProperty* FUNC_CALL GetIProperty(DEVICE_HANDLE device_handle);
+//UINT FUNC_CALL ReleaseIProperty(IProperty * pIProperty);
+
+//void FUNC_CALL ZCLOUD_SetServerInfo(const char* httpSvr, unsigned short httpPort, const char* authSvr, unsigned short authPort);
+//// return 0:success, 1:failure, 2:https error, 3:user login info error, 4:mqtt connection error, 5:no device
+//UINT FUNC_CALL ZCLOUD_ConnectServer(const char* username, const char* password);
+//bool FUNC_CALL ZCLOUD_IsConnected();
+//// return 0:success, 1:failure
+//UINT FUNC_CALL ZCLOUD_DisconnectServer();
+//const ZCLOUD_USER_DATA* FUNC_CALL ZCLOUD_GetUserData(int update DEF(0));
+//UINT FUNC_CALL ZCLOUD_ReceiveGPS(DEVICE_HANDLE device_handle, ZCLOUD_GPS_FRAME* pReceive, UINT len, int wait_time DEF(-1));
+
+//CHANNEL_HANDLE FUNC_CALL ZCAN_InitLIN(DEVICE_HANDLE device_handle, UINT can_index, PZCAN_LIN_INIT_CONFIG pLINInitConfig);
+//UINT FUNC_CALL ZCAN_StartLIN(CHANNEL_HANDLE channel_handle);
+//UINT FUNC_CALL ZCAN_ResetLIN(CHANNEL_HANDLE channel_handle);
+//UINT FUNC_CALL ZCAN_TransmitLIN(CHANNEL_HANDLE channel_handle, PZCAN_LIN_MSG pSend, UINT Len);
+//UINT FUNC_CALL ZCAN_GetLINReceiveNum(CHANNEL_HANDLE channel_handle);
+//UINT FUNC_CALL ZCAN_ReceiveLIN(CHANNEL_HANDLE channel_handle, PZCAN_LIN_MSG pReceive, UINT Len,int WaitTime);
+//UINT FUNC_CALL ZCAN_SetLINSlaveMsg(CHANNEL_HANDLE channel_handle, PZCAN_LIN_MSG pSend, UINT nMsgCount);
+//UINT FUNC_CALL ZCAN_ClearLINSlaveMsg(CHANNEL_HANDLE channel_handle, BYTE* pLINID, UINT nIDCount);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //ZLGCAN_H_