Преглед на файлове

change driver_can_socket, near ok. add driver_can_nvidia_agx, like driver_can_socket, but not ok.

yuchuli преди 3 години
родител
ревизия
de4924e715

+ 245 - 0
src/driver/driver_can_nvidia_agx_new/canctrl.cpp

@@ -0,0 +1,245 @@
+#include "canctrl.h"
+
+#include <memory>
+
+canctrl * gc;
+static iv::canstate::canstate proCanSt;
+void Listencansend0(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    iv::can::canmsg msg;
+
+    if(false == msg.ParseFromArray(strdata,nSize))
+    {
+        std::cout<<"Listencansend Parse fail."<<std::endl;
+        return;
+    }
+
+    gc->sendmsg(0,msg);
+
+}
+
+void Listencansend1(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    iv::can::canmsg msg;
+
+    if(false == msg.ParseFromArray(strdata,nSize))
+    {
+        std::cout<<"Listencansend Parse fail."<<std::endl;
+        return;
+    }
+
+    gc->sendmsg(1,msg);
+
+}
+
+
+
+
+canctrl::canctrl(const char * strmemsend0,const char * strmemrecv0,const char * strmemsend1,const char * strmemrecv1,const char * strcan0name,const char * strcan1name)
+{
+
+    gc = this;
+
+    mparecv0 = iv::modulecomm::RegisterSend(strmemrecv0,100000,3);
+    mparecv1 = iv::modulecomm::RegisterSend(strmemrecv1,100000,3);
+    mpcanState = iv::modulecomm::RegisterSend("canstate",18,3);
+
+    mpasend0 = iv::modulecomm::RegisterRecv(strmemsend0,Listencansend0);
+    mpasend1 = iv::modulecomm::RegisterRecv(strmemsend1,Listencansend1);
+
+    mpcan = new nvcan(strcan0name,strcan1name);
+    mspcan.reset(mpcan);
+    connect(mpcan,SIGNAL(SIG_CANOPENSTATE(bool,int,const char*)),this,SLOT(onCANState(bool,int,const char*)));
+    mpcan->startdev();
+
+    mptheadstate = new std::thread(&canctrl::threadstate,this);
+}
+
+canctrl::~canctrl()
+{
+    mpcan->stopdev();
+
+    delete mpcan;
+
+    mbstaterun = false;
+    mptheadstate->join();
+
+    iv::modulecomm::Unregister(mpasend0);
+    iv::modulecomm::Unregister(mpcanState);
+    iv::modulecomm::Unregister(mparecv0);
+
+}
+
+void canctrl::threadstate()
+{
+    int ncount = 0;
+    while(mbstaterun)
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        ncount++;
+        if(ncount>=10)
+        {
+            ncount = 0;
+            proCanSt.set_b_canstate(true);
+            int nsize = proCanSt.ByteSize();
+            std::shared_ptr<char > strdata_ptr= std::shared_ptr<char>(new char[nsize]);
+            if(proCanSt.SerializeToArray(strdata_ptr.get(),nsize))
+            {
+                iv::modulecomm::ModuleSendMsg(mpcanState,strdata_ptr.get(),nsize);
+            }
+        }
+    }
+
+    std::cout<<"threadstate exit."<<std::endl;
+}
+
+void canctrl::run()
+{
+
+    QTime xTime;
+    xTime.start();
+    int nOldTime = xTime.elapsed();
+    int i;
+
+    while(!isInterruptionRequested())
+    {
+        if(mbCANOpen)
+        {
+            basecan_msg xmsg[2500];
+            int nRec1,nRec2,nSend1,nSend2;
+            if((nRec1 =mpcan->GetMessage(0,xmsg,2500))>0)
+            {
+                sharecanmsg(mparecv0,xmsg,nRec1,0);
+            }
+
+
+
+            nSend1 = 0;
+            nSend2 = 0;
+
+            msleep(1);
+        }
+        else
+        {
+
+            msleep(1);
+            mpcan->mivlog->error("%s open can card fail",__func__);
+
+            if(xTime.elapsed()>1000)
+            {
+                qDebug("Not Open CANCARD exceed 1 second. so exit program.");
+                exit(-1);
+            }
+        }
+//        mpcan->mfault->SetFaultState(0, 0, "ok");
+    }
+
+    qDebug("thread canctrl complete.");
+
+}
+
+void canctrl::onCANState(bool bCAN, int nR, const char *strres)
+{
+    mbCANOpen = bCAN;
+    mpcan->mivlog->info("can","canstate is %s ",strres);
+}
+
+void canctrl::sendmsg(int index, iv::can::canmsg xmsg)
+{
+
+    std::vector<basecan_msg> * psendmsgvector;
+    QMutex * pMutex;
+
+    pMutex = &mMutexcan1;
+    psendmsgvector = &msendmsgvector1;
+
+
+    if(psendmsgvector->size() > SENDMSGBUFSIZE)
+    {
+        mpcan->mivlog->warn("sendmsg buf full");
+        return;
+    }
+
+
+    pMutex->lock();
+    if(psendmsgvector->size() > 1000)psendmsgvector->clear();
+    int i;
+    for(i=0;i<xmsg.rawmsg_size();i++)
+    {
+        basecan_msg sendmsg;
+        iv::can::canraw x;
+        x.CopyFrom(xmsg.rawmsg(i));
+        sendmsg.id = x.id();
+        sendmsg.isExtern = x.bext();
+        sendmsg.isRemote = x.bremote();
+#ifdef SEND_STAT
+        sendmsg.mSetTime = QDateTime::currentMSecsSinceEpoch();
+#endif
+        int nlen = x.len();
+
+        if((nlen < 0) || (nlen > 8))
+        {
+            nlen = 0;
+            mpcan->mivlog->warn("sendmsg nlen err");
+            continue;
+ //           mpcan->mfault->SetFaultState(1, 0, "sendmsg nlen err");
+        }
+        sendmsg.nLen = nlen;
+        if(sendmsg.nLen > 0)
+        {
+            memcpy(sendmsg.data,x.data().data(),sendmsg.nLen);
+        }
+
+        psendmsgvector->push_back(sendmsg);
+    }
+    pMutex->unlock();
+
+    if(mbCANOpen)
+    {
+        mMutexcan1.lock();
+        for(i=0;i<msendmsgvector1.size();i++)
+        {
+            mpcan->SetMessage(0,&(msendmsgvector1.at(i)));
+        }
+        msendmsgvector1.clear();
+        mMutexcan1.unlock();
+        mpcan->CmdSend();
+    }
+
+
+}
+
+void canctrl::sharecanmsg(void *xpa, basecan_msg * pxmsg,int ncount,int nch)
+{
+    iv::can::canmsg xmsg;
+
+    int i;
+    for(i=0;i<ncount;i++)
+    {
+        iv::can::canraw * praw = xmsg.add_rawmsg();
+        praw->set_id(pxmsg[i].id);
+        praw->set_data(pxmsg[i].data,8);
+        praw->set_bext(pxmsg[i].isExtern);
+        praw->set_bremote(pxmsg[i].isRemote);
+        praw->set_rectime(QDateTime::currentMSecsSinceEpoch());
+        praw->set_len(pxmsg[i].nLen);
+
+    }
+    xmsg.set_channel(nch);
+
+    xmsg.set_index(mindex[nch]);
+    mindex[nch]++;
+
+    int nsize = xmsg.ByteSize();
+    char * strdata = new char[xmsg.ByteSize()];
+    if(xmsg.SerializePartialToArray(strdata,nsize))
+    {
+        iv::modulecomm::ModuleSendMsg(xpa,strdata,nsize);
+    }
+    else
+    {
+        mpcan->mivlog->warn("canctrl::sharecanmsg serialize error");
+//        mpcan->mfault->SetFaultState(1, 0, "sharecanmsg serialize error");
+    }
+    delete strdata;
+}

+ 59 - 0
src/driver/driver_can_nvidia_agx_new/canctrl.h

@@ -0,0 +1,59 @@
+#ifndef CANCTRL_H
+#define CANCTRL_H
+
+#include <QThread>
+#include <QMutex>
+#include <memory>
+#include <QTimer>
+#include <array>
+#include <vector>
+#include <iostream>
+#include "nvcan.h"
+#include "modulecomm.h"
+#include "canmsg.pb.h"
+#include "canraw.pb.h"
+#include "canstate.pb.h"
+
+class canctrl : public QThread
+{
+    Q_OBJECT
+public:
+    canctrl(const char * strmemsend0,const char * strmemrecv0,const char * strmemsend1,const char * strmemrecv1,const char * strcan0name,const char * strcan1name);
+    ~canctrl();
+
+private slots:
+    void onCANState(bool bCAN,int nR,const char * strres);
+
+private:
+    void run();
+
+    basecan * mpcan;
+    std::shared_ptr<basecan> mspcan;
+    bool mbCANOpen = false;
+
+    std::vector<basecan_msg> msendmsgvector1;
+    const int SENDMSGBUFSIZE = 3000;
+
+    QMutex mMutexcan1;
+
+    int mindex[2];
+
+    void * mpasend0,  * mparecv0,  *mpcanState;
+    void * mpasend1,  * mparecv1;
+
+public:
+    void sendmsg(int index,iv::can::canmsg xmsg);
+    void sharecanmsg(void * xpa,basecan_msg * pxmsg,int ncount,int nch);
+
+
+private:
+    void  threadstate();
+    std::thread * mptheadstate;
+    bool mbstaterun = true;
+
+
+
+
+};
+
+#endif // CANCTRL_H

+ 54 - 0
src/driver/driver_can_nvidia_agx_new/driver_can_nvidia_agx_new.pro

@@ -0,0 +1,54 @@
+QT -= gui
+
+QT += network xml dbus
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+QMAKE_LFLAGS += -no-pie
+
+DEFINES += NV
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+!include(../../../include/common.pri ) {
+    error( "Couldn't find the common.pri file!" )
+}
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}
+
+
+DEFINES += TEST_PROG
+
+DEFINES += SEND_STAT
+
+INCLUDEPATH += $$PWD/../../include/base/driver/can
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += main.cpp \
+    nvcan.cpp \
+    canctrl.cpp \
+    ../../include/msgtype/canmsg.pb.cc \
+    ../../include/msgtype/canraw.pb.cc \
+    ../../include/msgtype/canstate.pb.cc \
+    ../../include/base/driver/can/basecan.cpp
+
+HEADERS += \
+    nvcan.h \
+    canctrl.h \
+    ../../include/msgtype/canmsg.pb.h \
+    ../../include/msgtype/canraw.pb.h \
+    ../../include/msgtype/canstate.pb.h \
+    ../../include/base/driver/can/basecan.h
+
+

+ 157 - 0
src/driver/driver_can_nvidia_agx_new/main.cpp

@@ -0,0 +1,157 @@
+#include <QCoreApplication>
+#include <QObject>
+
+#include <signal.h>
+
+#include "nvcan.h"
+#include "canctrl.h"
+
+#include <unistd.h>
+
+#include <thread>
+#include <iostream>
+
+#include <xmlparam.h>
+
+#include "ivversion.h"
+#include "ivexit.h"
+#include <signal.h>
+
+
+static canctrl * gpcanctrl;
+
+void exitfunc()
+{
+    qDebug("enter exit func.");
+    gpcanctrl->requestInterruption();
+
+    QTime  xTime;
+    xTime.start();
+    while(xTime.elapsed()<1000)
+    {
+        if(gpcanctrl->isFinished())
+        {
+            qDebug("canctrl complete.");
+            delete gpcanctrl;
+            break;
+        }
+    }
+
+}
+
+void signal_handler(int sig)
+{
+    if(sig == SIGINT)
+    {
+        exitfunc();
+    }
+}
+
+#ifdef TEST_PROG
+void threadtest()
+{
+    QTimer xTimer;
+    xTimer.setTimerType(Qt::PreciseTimer);
+    void * pa = iv::modulecomm::RegisterSend("cansend0",100000,100);
+    while(true)
+    {
+        iv::can::canmsg xmsg;
+        xmsg.set_channel(0);
+        xmsg.set_mstime(QDateTime::currentMSecsSinceEpoch());
+        xmsg.set_index(0);
+        int i;
+        for(i=0;i<5;i++)
+        {
+            iv::can::canraw * pcanraw = xmsg.add_rawmsg();
+            pcanraw->set_bext(false);
+            pcanraw->set_id(11);
+            pcanraw->set_bremote(false);
+            char xdata[8];
+            xdata[0] = 11;
+            pcanraw->set_data(xdata,8);
+            pcanraw->set_len(8);
+        }
+
+        int nbytesize = xmsg.ByteSize();
+        std::shared_ptr<char> str_ptr = std::shared_ptr<char>(new char[nbytesize]);
+        if(xmsg.SerializeToArray(str_ptr.get(),nbytesize))
+            iv::modulecomm::ModuleSendMsg(pa,str_ptr.get(),nbytesize);
+
+        std::this_thread::sleep_for(std::chrono::milliseconds(5));
+ //       std::this_thread::sleep_for(std::chrono::microseconds(50000));
+    }
+}
+
+void threadtest2()
+{
+    QTimer xTimer;
+    xTimer.setTimerType(Qt::PreciseTimer);
+    void * pa = iv::modulecomm::RegisterSend("cansend1",100000,100);
+    while(true)
+    {
+        iv::can::canmsg xmsg;
+        xmsg.set_channel(0);
+        xmsg.set_mstime(QDateTime::currentMSecsSinceEpoch());
+        xmsg.set_index(0);
+        int i;
+        for(i=0;i<5;i++)
+        {
+            iv::can::canraw * pcanraw = xmsg.add_rawmsg();
+            pcanraw->set_bext(false);
+            pcanraw->set_id(11);
+            pcanraw->set_bremote(false);
+            char xdata[8];
+            xdata[0] = 11;
+            pcanraw->set_data(xdata,8);
+            pcanraw->set_len(8);
+        }
+
+        int nbytesize = xmsg.ByteSize();
+        std::shared_ptr<char> str_ptr = std::shared_ptr<char>(new char[nbytesize]);
+        if(xmsg.SerializeToArray(str_ptr.get(),nbytesize))
+            iv::modulecomm::ModuleSendMsg(pa,str_ptr.get(),nbytesize);
+
+        std::this_thread::sleep_for(std::chrono::milliseconds(5));
+ //       std::this_thread::sleep_for(std::chrono::microseconds(50000));
+    }
+}
+#endif
+
+
+int main(int argc, char *argv[])
+{
+    showversion("driver_can_nvidia_agx");
+    QCoreApplication a(argc, argv);
+
+
+    QString strpath = QCoreApplication::applicationDirPath();
+    if(argc < 2)
+        strpath = strpath + "/driver_can_socket.xml";
+    else
+        strpath = argv[1];
+    std::cout<<strpath.toStdString()<<std::endl;
+    iv::xmlparam::Xmlparam xp(strpath.toStdString());
+
+    std::string strmemsend0 = xp.GetParam("cansend0_agx","cansend0");
+    std::string strmemrecv0 = xp.GetParam("canrecv0_agx","canrecv0");
+    std::string strmemsend1 = xp.GetParam("cansend1_agx","cansend1");
+    std::string strmemrecv1 = xp.GetParam("canrecv1_agx","canrecv1");
+    std::string strcanname0 = xp.GetParam("canname0","can0");
+    std::string strcanname1 = xp.GetParam("canname0","can1");
+
+    gpcanctrl = new canctrl(strmemsend0.data(),strmemrecv0.data(),strmemsend1.data(),strmemrecv1.data(),strcanname0.data(),strcanname1.data());
+    gpcanctrl->start();
+
+    iv::ivexit::RegIVExitCall(exitfunc);
+
+    signal(SIGINT,signal_handler);
+
+#ifdef TEST_PROG
+    std::thread * pthread = new std::thread(threadtest);
+    pthread = new std::thread(threadtest2);
+#endif
+
+ //   std::thread b(func);
+
+    return a.exec();
+}

+ 684 - 0
src/driver/driver_can_nvidia_agx_new/nvcan.cpp

@@ -0,0 +1,684 @@
+#include "nvcan.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <ctype.h>
+#include <libgen.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+#include <net/if.h>
+
+
+#include <linux/can.h>
+#include <linux/can/raw.h>
+
+#include <QDateTime>
+
+#include <iostream>
+#include  <thread>
+
+/* for hardware timestamps - since Linux 2.6.30 */
+#ifndef SO_TIMESTAMPING
+#define SO_TIMESTAMPING 37
+#endif
+
+/* from #include <linux/net_tstamp.h> - since Linux 2.6.30 */
+#define SOF_TIMESTAMPING_SOFTWARE (1<<4)
+#define SOF_TIMESTAMPING_RX_SOFTWARE (1<<3)
+#define SOF_TIMESTAMPING_RAW_HARDWARE (1<<6)
+
+#define MAXSOCK 16    /* max. number of CAN interfaces given on the cmdline */
+#define MAXIFNAMES 30 /* size of receive name index to omit ioctls */
+#define MAXCOL 6      /* number of different colors for colorized output */
+#define ANYDEV "any"  /* name of interface to receive from any CAN interface */
+#define ANL "\r\n"    /* newline in ASC mode */
+
+#define SILENT_INI 42 /* detect user setting on commandline */
+#define SILENT_OFF 0  /* no silent mode */
+#define SILENT_ANI 1  /* silent mode with animation */
+#define SILENT_ON  2  /* silent mode (completely silent) */
+
+#include <QTime>
+
+#define BUF_SIZE 1000
+
+std::string CANNAME[] = {"can0","can1"};
+
+nvcan::nvcan(const char * strcan0name,const char * strcan1name)
+{
+//    qDebug("nvcan");
+//    connect(this,SIGNAL(SIG_CANOPENSTATE(bool,int,const char*)),this,SLOT(onMsg(bool,int,const char*)));
+
+    CANNAME[0] = strcan0name;
+    CANNAME[1] = strcan1name;
+    mfault = new iv::Ivfault("can_agx");
+    mivlog = new iv::Ivlog("can_agx");
+
+
+    mfault->SetFaultState(0,0,"Prepare Initialize.");
+
+//    mpsendthread = new std::thread(&nvcan::threadsend,this);
+
+
+}
+
+void nvcan::ExecRecv(int s)
+{
+
+}
+
+void nvcan::run()
+{
+
+    int currmax = 2;
+    fd_set rdfs;
+    int s[MAXSOCK];
+    int ret;
+    
+    struct sockaddr_can addr;
+    char ctrlmsg[CMSG_SPACE(sizeof(struct timeval) + 3*sizeof(struct timespec) + sizeof(__u32))];
+    struct iovec iov;
+    struct msghdr msg;
+    struct canfd_frame frame;
+    int nbytes, i, maxdlen;
+    struct ifreq ifr;
+    struct timeval tv, last_tv;
+    struct timeval timeout_config = { 0, 0 }, *timeout_current = 0;
+
+    mfault->SetFaultState(0,0,"Initializing.");
+    
+    for(i=0;i<currmax;i++)
+    {
+        s[i] = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+        if (s[i] < 0) {
+            mfault->SetFaultState(2,1,"Create Socket Error.");
+            emit SIG_CANOPENSTATE(false,-1,"Create Socket Error");
+            return;
+        }
+
+        addr.can_family = AF_CAN;
+
+        memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
+        strncpy(ifr.ifr_name, CANNAME[i].data(), 5);
+
+        if (ioctl(s[i], SIOCGIFINDEX, &ifr) < 0) {
+            mfault->SetFaultState(2,2,"SIOCGIFINDEX.");
+            emit SIG_CANOPENSTATE(false,-2,"SIOCGIFINDEX");
+            return;
+        }
+        addr.can_ifindex = ifr.ifr_ifindex;
+
+        if (bind(s[i], (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+            mfault->SetFaultState(2,3,"bind error.");
+            emit SIG_CANOPENSTATE(false,-3,"bind error");
+            return;
+        }
+    }
+
+    mps = &s[0];
+    mbCANOpen = true;
+    mivlog->verbose("open can succesfully.");
+    mfault->SetFaultState(0,0,"CAN OK.");
+    emit SIG_CANOPENSTATE(true,0,"open can card successfully");
+
+    std::cout<<"can open succesfully."<<std::endl;
+
+    iov.iov_base = &frame;
+    msg.msg_name = &addr;
+    msg.msg_iov = &iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = &ctrlmsg;
+
+    qint64 nLastRecv = QDateTime::currentMSecsSinceEpoch();
+    int nRecvState = 0; // 0 Have Data  1 No Data;
+
+    mbRunning = true;
+
+    int nrecvcount = 0;
+
+    qint64 nlastsecond = 0;
+    int nsecondrecvcount = 0;
+
+    qint64 nLastSecond = 0;
+    int nsecondsend = 0;
+    int nretry = 0;
+#ifdef SEND_STAT
+    std::vector<qint64> xvectorlat;
+#endif
+    int secondretrycount = 0;
+
+    while((!QThread::isInterruptionRequested())&&(mbCANOpen))
+    {
+        FD_ZERO(&rdfs);
+        for (i=0; i<currmax; i++)
+            FD_SET(s[i], &rdfs);
+
+        if (timeout_current)
+            *timeout_current = timeout_config;
+
+        timeout_config.tv_sec= 0;
+        timeout_config.tv_usec = 0;;
+        timeout_current = &timeout_config;
+        ret = select(s[currmax-1]+1, &rdfs, NULL, NULL, timeout_current);
+        if (ret < 0) {
+            emit SIG_CANOPENSTATE(false,-4,"select error");
+            mfault->SetFaultState(2,4,"select error.");
+            std::cout<<"select error."<<std::endl;
+            mbCANOpen = false;
+            continue;
+        }
+
+ //       std::cout<<"time: "<<QDateTime::currentMSecsSinceEpoch()<<" ret : "<<ret<<std::endl;
+
+        bool bRecv = false;
+        for (i=0; i<currmax; i++) {  /* check all CAN RAW sockets */
+
+            if (FD_ISSET(s[i], &rdfs)) {
+
+                nLastRecv = QDateTime::currentMSecsSinceEpoch();
+                /* these settings may be modified by recvmsg() */
+                iov.iov_len = sizeof(frame);
+                msg.msg_namelen = sizeof(addr);
+                msg.msg_controllen = sizeof(ctrlmsg);
+                msg.msg_flags = 0;
+
+                mMutexRW.lock();
+                nbytes = recvmsg(s[i], &msg, 0);
+                mMutexRW.unlock();
+
+                if (nbytes < 0) {
+ //                   if ((errno == ENETDOWN) && !down_causes_exit) {
+                    if ((errno == ENETDOWN)) {
+                        mivlog->error("%s interface down", CANNAME[i].data());
+                        mfault->SetFaultState(1, 0, "interface down");
+                        emit SIG_CANOPENSTATE(false,-5,"can card down");
+                        fprintf(stderr, "%s: interface down\n", CANNAME[i].data());
+                        return;
+                    }
+                    continue;
+//                    perror("read");
+//                    return 1;
+                }
+
+                if ((size_t)nbytes == CAN_MTU)
+                    maxdlen = CAN_MAX_DLEN;
+                else if ((size_t)nbytes == CANFD_MTU)
+                    maxdlen = CANFD_MAX_DLEN;
+                else {
+                    mivlog->warn("read incomplete message");
+                    continue;
+                }
+
+                bRecv = true;
+                nrecvcount++;
+ //               qDebug("receive msg.");
+                mMutex.lock();
+
+                basecan_msg msg;
+                msg.id = frame.can_id&0x1fffffff;
+                if((frame.can_id&0x80000000)!= 0)msg.isExtern = true;
+                else msg.isExtern = false;
+                if((frame.can_id&0x40000000)!= 0)msg.isRemote = true;
+                else msg.isRemote = false;
+                msg.nLen = frame.len;
+                nsecondrecvcount++;
+                if((frame.len<9)&&(frame.len>0))memcpy(msg.data,frame.data,frame.len);
+                if(mMsgRecvBuf[i].size()<BUF_SIZE)
+                {
+                    mMsgRecvBuf[i].push_back(msg);
+                }
+
+                mMutex.unlock();
+
+
+
+            }
+        }
+
+        qint64 nsecondnow = QDateTime::currentSecsSinceEpoch();
+        if(nlastsecond != nsecondnow)
+        {
+            nlastsecond = nsecondnow;
+            std::cout<<"second recv count:"<<nsecondrecvcount<<std::endl;
+            nsecondrecvcount = 0;
+        }
+
+        if((QDateTime::currentMSecsSinceEpoch() - nLastRecv)> 1000)
+        {
+            if(nRecvState == 0)
+            {
+                nRecvState = -1;
+                mfault->SetFaultState(0,1,"More than 1 second not receive data.");
+            }
+        }
+        else
+        {
+            if(nRecvState == -1)
+            {
+                nRecvState = 0;
+                mfault->SetFaultState(0,0,"CAN OK.");
+            }
+        }
+
+        if(bRecv)continue;
+
+
+        mWaitMutex.lock();
+        mwc.wait(&mWaitMutex,1);
+        mWaitMutex.unlock();
+
+#ifdef TEST_PROG
+ //       qDebug("send time : %lld",QDateTime::currentMSecsSinceEpoch());
+#endif
+
+        struct canfd_frame framesend[2500];
+#ifdef SEND_STAT
+        qint64 sendsettime[2500];
+#endif
+
+        for(int nch =0;nch<currmax;nch++)
+        {
+            int nsend = 0;
+            mMutex.lock();
+            int nbufsize = mMsgSendBuf[nch].size();
+            if(nbufsize>2500)nbufsize = 2500;
+            for(i=0;i<nbufsize;i++)
+            {
+                if(i>=2500)break;
+                memcpy(framesend[i].data,mMsgSendBuf[nch].at(i).data,8);
+                framesend[i].can_id = mMsgSendBuf[nch].at(i).id;
+                if(mMsgSendBuf[nch].at(i).isExtern)
+                {
+                    framesend[i].can_id = framesend[i].can_id|0x80000000;
+                }
+                else
+                {
+                    framesend[i].can_id = framesend[i].can_id&0x7ff;
+                }
+                if(mMsgSendBuf[nch].at(i).isRemote)
+                {
+                    framesend[i].can_id= framesend[i].can_id|0x40000000;
+                }
+
+                framesend[i].len = mMsgSendBuf[nch].at(i).nLen;
+#ifdef SEND_STAT
+                sendsettime[i] = mMsgSendBuf[nch].at(i).mSetTime;
+#endif
+
+                nsend++;
+            }
+            mMsgSendBuf[nch].clear();
+            mMutex.unlock();
+
+            if(nsend > 0)
+            {
+                for(i=0;i<nsend;i++)
+                {
+                    mMutexRW.lock();
+
+                    if (write(mps[nch], &framesend[i],16) != 16) {
+                        mMutexRW.unlock();
+                        mivlog->error("write error 1");
+ //                       perror("write error 1.");
+
+                        nretry++;
+                        secondretrycount++;
+                        if(nretry > 5)
+                        {
+ //                           std::cout<<"retry fail,retry:"<<nretry<<std::endl;
+                        }
+                        else
+                        {
+
+
+                        }
+                        if(nretry < 5)
+                        {
+                            i--;
+                        }
+                        else
+                        {
+                            nretry = 0;
+//                            std::cout<<"retry more than 100. drop this message."<<std::endl;
+                        }
+                         std::this_thread::sleep_for(std::chrono::microseconds(100));
+ //                       std::cout<<"retry send."<<std::endl;
+                        continue;
+                    }
+                    else
+                    {
+                        mMutexRW.unlock();
+#ifdef SEND_STAT
+                        qint64 nnowms = QDateTime::currentMSecsSinceEpoch();
+                        qint64 nlat = nnowms - sendsettime[i];
+                        xvectorlat.push_back(nlat);
+                        nretry = 0;
+                        nsecondsend++;
+#endif
+                    }
+                }
+            }
+
+                        qint64 nnowsecond = QDateTime::currentSecsSinceEpoch();
+                        if( nnowsecond != nLastSecond)
+                        {
+                            nLastSecond = nnowsecond;
+                            std::cout<<" second send count: "<<nsecondsend<<std::endl;
+                            nsecondsend = 0;
+#ifdef SEND_STAT
+                            int j;
+                            int nsendcount = xvectorlat.size();
+                            if(nsendcount > 0)
+                            {
+                                qint64 xlatmax = 0;
+                                qint64 xlatavg = 0;
+                                for(j=0;j<nsendcount;j++)
+                                {
+                                    if(xvectorlat[j]> xlatmax)xlatmax = xvectorlat[j];
+                                    xlatavg = xlatavg + xvectorlat[j];
+                                }
+                                xlatavg = xlatavg/nsendcount;
+                                std::cout<<" max latency: "<<xlatmax<<" avg latency: "<<xlatavg
+                                        <<" second retry count:"<<secondretrycount<<std::endl;
+
+
+                                xvectorlat.clear();
+                            }
+#endif
+                            secondretrycount = 0;
+                        }
+
+
+        }
+
+
+
+    }
+
+    for (i=0; i<currmax; i++)
+    {
+        close(s[i]);
+    }
+    qDebug("nvcan thread close.");
+    mbRunning = false;
+}
+
+void nvcan::threadsend()
+{
+
+    return;
+    int currmax = 1;
+    int s[MAXSOCK];
+    int i;
+
+    struct sockaddr_can addr;
+    struct ifreq ifr;
+
+    for(i=0;i<currmax;i++)
+    {
+        s[i] = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+        if (s[i] < 0) {
+            return;
+        }
+
+        addr.can_family = AF_CAN;
+
+        memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
+        strncpy(ifr.ifr_name, CANNAME[i].data(), 5);
+
+        if (ioctl(s[i], SIOCGIFINDEX, &ifr) < 0) {
+            return;
+        }
+        addr.can_ifindex = ifr.ifr_ifindex;
+
+        if (bind(s[i], (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+            return;
+        }
+    }
+
+    std::cout<<"threadsend open can success."<<std::endl;
+
+    mps = &s[0];
+
+ //   int currmax = 1;
+ //   int i;
+    while(mbCANOpen == false)
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+    }
+
+    qint64 nLastSecond = 0;
+    int nsecondsend = 0;
+    int nretry = 0;
+#ifdef SEND_STAT
+    std::vector<qint64> xvectorlat;
+#endif
+    int secondretrycount = 0;
+    while(mbSendRun)
+    {
+        mWaitMutex.lock();
+        mwc.wait(&mWaitMutex,100);
+        mWaitMutex.unlock();
+
+#ifdef TEST_PROG
+ //       qDebug("send time : %lld",QDateTime::currentMSecsSinceEpoch());
+#endif
+
+        struct canfd_frame framesend[2500];
+#ifdef SEND_STAT
+        qint64 sendsettime[2500];
+#endif
+
+        for(int nch =0;nch<currmax;nch++)
+        {
+            int nsend = 0;
+            mMutex.lock();
+            int nbufsize = mMsgSendBuf[nch].size();
+            if(nbufsize>2500)nbufsize = 2500;
+            for(i=0;i<nbufsize;i++)
+            {
+                if(i>=2500)break;
+                memcpy(framesend[i].data,mMsgSendBuf[nch].at(i).data,8);
+                framesend[i].can_id = mMsgSendBuf[nch].at(i).id;
+                if(mMsgSendBuf[nch].at(i).isExtern)
+                {
+                    framesend[i].can_id = framesend[i].can_id|0x80000000;
+                }
+                else
+                {
+                    framesend[i].can_id = framesend[i].can_id&0x7ff;
+                }
+                if(mMsgSendBuf[nch].at(i).isRemote)
+                {
+                    framesend[i].can_id= framesend[i].can_id|0x40000000;
+                }
+
+                framesend[i].len = mMsgSendBuf[nch].at(i).nLen;
+#ifdef SEND_STAT
+                sendsettime[i] = mMsgSendBuf[nch].at(i).mSetTime;
+#endif
+
+                nsend++;
+            }
+            mMsgSendBuf[nch].clear();
+            mMutex.unlock();
+
+            if(nsend > 0)
+            {
+                for(i=0;i<nsend;i++)
+                {
+                    mMutexRW.lock();
+
+                    if (write(mps[nch], &framesend[i],16) != 16) {
+                        mMutexRW.unlock();
+                        mivlog->error("write error 1");
+ //                       perror("write error 1.");
+
+                        nretry++;
+                        secondretrycount++;
+                        if(nretry > 30)
+                        {
+ //                           std::cout<<"retry fail,retry:"<<nretry<<std::endl;
+                        }
+                        else
+                        {
+
+
+                        }
+                        if(nretry < 100)
+                        {
+                            i--;
+                        }
+                        else
+                        {
+                            nretry = 0;
+//                            std::cout<<"retry more than 100. drop this message."<<std::endl;
+                        }
+                         std::this_thread::sleep_for(std::chrono::microseconds(100));
+ //                       std::cout<<"retry send."<<std::endl;
+                        continue;
+                    }
+                    else
+                    {
+                        mMutexRW.unlock();
+#ifdef SEND_STAT
+                        qint64 nnowms = QDateTime::currentMSecsSinceEpoch();
+                        qint64 nlat = nnowms - sendsettime[i];
+                        xvectorlat.push_back(nlat);
+                        nretry = 0;
+                        nsecondsend++;
+#endif
+                    }
+                }
+            }
+
+                        qint64 nnowsecond = QDateTime::currentSecsSinceEpoch();
+                        if( nnowsecond != nLastSecond)
+                        {
+                            nLastSecond = nnowsecond;
+                            std::cout<<" second send count: "<<nsecondsend<<std::endl;
+                            nsecondsend = 0;
+#ifdef SEND_STAT
+                            int j;
+                            int nsendcount = xvectorlat.size();
+                            if(nsendcount > 0)
+                            {
+                                qint64 xlatmax = 0;
+                                qint64 xlatavg = 0;
+                                for(j=0;j<nsendcount;j++)
+                                {
+                                    if(xvectorlat[j]> xlatmax)xlatmax = xvectorlat[j];
+                                    xlatavg = xlatavg + xvectorlat[j];
+                                }
+                                xlatavg = xlatavg/nsendcount;
+                                std::cout<<" max latency: "<<xlatmax<<" avg latency: "<<xlatavg
+                                        <<" second retry count:"<<secondretrycount<<std::endl;
+
+
+                                xvectorlat.clear();
+                            }
+#endif
+                            secondretrycount = 0;
+                        }
+
+
+        }
+    }
+
+    std::cout<<"nvcan::threadsend exit."<<std::endl;
+
+}
+
+void nvcan::startdev()
+{
+    start();
+}
+
+void nvcan::stopdev()
+{
+    requestInterruption();
+    QTime xTime;
+    xTime.start();
+    while(xTime.elapsed()<100)
+    {
+        if(mbRunning == false)
+        {
+            mfault->SetFaultState(1, 0, "can closed");
+            mivlog->error("can is closed at %d",xTime.elapsed());
+            qDebug("can is closed.");
+            break;
+        }
+    }
+}
+
+int nvcan::GetMessage(const int nch,basecan_msg *pMsg, const int nCap)
+{
+    if((nch>1)||(nch < 0))return -1;
+    if(mMsgRecvBuf[nch].size() == 0)return 0;
+
+    int nRtn;
+    nRtn = nCap;
+    mMutex.lock();
+    if(nRtn > mMsgRecvBuf[nch].size())nRtn = mMsgRecvBuf[nch].size();
+    int i;
+    for(i=0;i<nRtn;i++)
+    {
+        memcpy(&pMsg[i],&(mMsgRecvBuf[nch].at(i)),sizeof(basecan_msg));
+    }
+
+    std::vector<basecan_msg>::iterator iter;
+    iter = mMsgRecvBuf[nch].begin();
+    for(i=0;i<nRtn;i++)
+    {
+        iter = mMsgRecvBuf[nch].erase(iter);
+    }
+
+    mMutex.unlock();
+
+    return nRtn;
+
+}
+
+int nvcan::SetMessage(const int nch, basecan_msg *pMsg)
+{
+    if((nch>1)||(nch < 0))return -1;
+
+    mMutex.lock();
+    if(mMsgSendBuf[nch].size() > BUF_SIZE)
+    {
+        std::cout<<"buffer full."<<std::endl;
+        mMutex.unlock();
+        return -2;
+    }
+
+    if(mMsgRecvBuf[nch].size() > 100)
+    {
+        std::cout<<"buffer data more 100"<<std::endl;
+    }
+
+
+    mMsgSendBuf[nch].push_back(*pMsg);
+    mMutex.unlock();
+    return 0;
+}
+
+void nvcan::CmdSend()
+{
+    mwc.wakeAll();
+}
+
+void nvcan::onMsg(bool bCAN, int nR, const char *strres)
+{
+    mivlog->verbose("msg is %s ",strres);
+}
+

+ 60 - 0
src/driver/driver_can_nvidia_agx_new/nvcan.h

@@ -0,0 +1,60 @@
+#ifndef NVCAN_H
+#define NVCAN_H
+#include "basecan.h"
+
+#include <vector>
+#include <QMutex>
+
+#include <thread>
+
+#include <QWaitCondition>
+#include <QMutex>
+
+class nvcan : public basecan
+{
+    Q_OBJECT
+public:
+    nvcan(const char * strcan0name,const char * strcan1name);
+public:
+    void startdev();
+    void stopdev();
+
+    int GetMessage(const int nch,basecan_msg * pMsg,const int nCap);
+    int SetMessage(const int nch,basecan_msg * pMsg);
+
+    virtual void CmdSend();
+
+private slots:
+    void onMsg(bool bCAN,int nR,const char * strres);
+
+private:
+    void run();
+    void threadsend();
+    int * mps = 0;
+
+
+    std::vector<basecan_msg> mMsgRecvBuf[2];
+
+    std::vector<basecan_msg> mMsgSendBuf[2];
+
+    QMutex mMutex;
+
+    bool mbCANOpen = false;
+    bool mbRunning = false;
+    int mnDevNum;
+
+private:
+    bool mbSendRun = true;
+
+    QWaitCondition mwc;
+    QMutex mWaitMutex;
+
+    std::thread * mpsendthread;
+
+    QMutex mMutexRW;
+
+private:
+    void ExecRecv(int s);
+};
+
+#endif // NVCAN_H

+ 32 - 19
src/driver/driver_can_socket/canctrl.cpp

@@ -35,6 +35,8 @@ canctrl::canctrl(const char * strmemsend0,const char * strmemrecv0,const char *
     mspcan.reset(mpcan);
     connect(mpcan,SIGNAL(SIG_CANOPENSTATE(bool,int,const char*)),this,SLOT(onCANState(bool,int,const char*)));
     mpcan->startdev();
+
+    mptheadstate = new std::thread(&canctrl::threadstate,this);
 }
 
 canctrl::~canctrl()
@@ -43,12 +45,38 @@ canctrl::~canctrl()
 
     delete mpcan;
 
+    mbstaterun = false;
+    mptheadstate->join();
+
     iv::modulecomm::Unregister(mpasend0);
     iv::modulecomm::Unregister(mpcanState);
     iv::modulecomm::Unregister(mparecv0);
 
 }
 
+void canctrl::threadstate()
+{
+    int ncount = 0;
+    while(mbstaterun)
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        ncount++;
+        if(ncount>=10)
+        {
+            ncount = 0;
+            proCanSt.set_b_canstate(true);
+            int nsize = proCanSt.ByteSize();
+            std::shared_ptr<char > strdata_ptr= std::shared_ptr<char>(new char[nsize]);
+            if(proCanSt.SerializeToArray(strdata_ptr.get(),nsize))
+            {
+                iv::modulecomm::ModuleSendMsg(mpcanState,strdata_ptr.get(),nsize);
+            }
+        }
+    }
+
+    std::cout<<"threadstate exit."<<std::endl;
+}
+
 void canctrl::run()
 {
 
@@ -57,7 +85,6 @@ void canctrl::run()
     int nOldTime = xTime.elapsed();
     int i;
 
-
     while(!isInterruptionRequested())
     {
         if(mbCANOpen)
@@ -74,28 +101,11 @@ void canctrl::run()
             nSend1 = 0;
             nSend2 = 0;
 
-
-
-
-            proCanSt.set_b_canstate(true);
-            int nsize = proCanSt.ByteSize();
-            std::shared_ptr<char > strdata_ptr= std::shared_ptr<char>(new char[nsize]);
-            if(proCanSt.SerializeToArray(strdata_ptr.get(),nsize))
-            {
-                iv::modulecomm::ModuleSendMsg(mpcanState,strdata_ptr.get(),nsize);
-            }
             msleep(1);
         }
         else
         {
-            proCanSt.set_b_canstate(false);
-            int nsize = proCanSt.ByteSize();
-            char * strdata = new char[proCanSt.ByteSize()];
-            if(proCanSt.SerializeToArray(strdata,nsize))
-            {
-                iv::modulecomm::ModuleSendMsg(mpcanState,strdata,nsize);
-            }
-            delete strdata;
+
             msleep(1);
             mpcan->mivlog->error("%s open can card fail",__func__);
 
@@ -146,6 +156,9 @@ void canctrl::sendmsg(int index, iv::can::canmsg xmsg)
         sendmsg.id = x.id();
         sendmsg.isExtern = x.bext();
         sendmsg.isRemote = x.bremote();
+#ifdef SEND_STAT
+        sendmsg.mSetTime = QDateTime::currentMSecsSinceEpoch();
+#endif
         int nlen = x.len();
 
         if((nlen < 0) || (nlen > 8))

+ 6 - 0
src/driver/driver_can_socket/canctrl.h

@@ -45,6 +45,12 @@ public:
     void sharecanmsg(void * xpa,basecan_msg * pxmsg,int ncount,int nch);
 
 
+private:
+    void  threadstate();
+    std::thread * mptheadstate;
+    bool mbstaterun = true;
+
+
 
 
 };

+ 2 - 0
src/driver/driver_can_socket/driver_can_socket.pro

@@ -26,6 +26,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
 
 #DEFINES += TEST_PROG
 
+DEFINES += SEND_STAT
+
 INCLUDEPATH += $$PWD/../../include/base/driver/can
 
 # You can also make your code fail to compile if you use deprecated APIs.

+ 6 - 5
src/driver/driver_can_socket/main.cpp

@@ -53,6 +53,7 @@ void threadtest()
     QTimer xTimer;
     xTimer.setTimerType(Qt::PreciseTimer);
     void * pa = iv::modulecomm::RegisterSend("cansend0",100000,100);
+    return;
     while(true)
     {
         iv::can::canmsg xmsg;
@@ -77,8 +78,8 @@ void threadtest()
         if(xmsg.SerializeToArray(str_ptr.get(),nbytesize))
             iv::modulecomm::ModuleSendMsg(pa,str_ptr.get(),nbytesize);
 
- //       std::this_thread::sleep_for(std::chrono::milliseconds(1));
-        std::this_thread::sleep_for(std::chrono::microseconds(5000));
+        std::this_thread::sleep_for(std::chrono::milliseconds(5));
+ //       std::this_thread::sleep_for(std::chrono::microseconds(50000));
     }
 }
 #endif
@@ -98,9 +99,9 @@ int main(int argc, char *argv[])
     std::cout<<strpath.toStdString()<<std::endl;
     iv::xmlparam::Xmlparam xp(strpath.toStdString());
 
-    std::string strmemsend0 = xp.GetParam("cansend0_agx","cansend0");
-    std::string strmemrecv0 = xp.GetParam("canrecv0_agx","canrecv0");
-    std::string strcanname = xp.GetParam("canname","can0");
+    std::string strmemsend0 = xp.GetParam("cansend0_agx","cansend1");
+    std::string strmemrecv0 = xp.GetParam("canrecv0_agx","canrecv1");
+    std::string strcanname = xp.GetParam("canname","can1");
 
     gpcanctrl = new canctrl(strmemsend0.data(),strmemrecv0.data(),strcanname.data());
     gpcanctrl->start();

+ 257 - 9
src/driver/driver_can_socket/nvcan.cpp

@@ -69,6 +69,11 @@ nvcan::nvcan(const char * strcanname)
     mpsendthread = new std::thread(&nvcan::threadsend,this);
 
 
+}
+
+void nvcan::ExecRecv(int s)
+{
+
 }
 
 void nvcan::run()
@@ -125,6 +130,8 @@ void nvcan::run()
     mfault->SetFaultState(0,0,"CAN OK.");
     emit SIG_CANOPENSTATE(true,0,"open can card successfully");
 
+    std::cout<<"can open succesfully."<<std::endl;
+
     iov.iov_base = &frame;
     msg.msg_name = &addr;
     msg.msg_iov = &iov;
@@ -138,6 +145,17 @@ void nvcan::run()
 
     int nrecvcount = 0;
 
+    qint64 nlastsecond = 0;
+    int nsecondrecvcount = 0;
+
+    qint64 nLastSecond = 0;
+    int nsecondsend = 0;
+    int nretry = 0;
+#ifdef SEND_STAT
+    std::vector<qint64> xvectorlat;
+#endif
+    int secondretrycount = 0;
+
     while((!QThread::isInterruptionRequested())&&(mbCANOpen))
     {
         FD_ZERO(&rdfs);
@@ -148,16 +166,20 @@ void nvcan::run()
             *timeout_current = timeout_config;
 
         timeout_config.tv_sec= 0;
-        timeout_config.tv_usec = 100;;
+        timeout_config.tv_usec = 0;;
         timeout_current = &timeout_config;
         ret = select(s[currmax-1]+1, &rdfs, NULL, NULL, timeout_current);
         if (ret < 0) {
             emit SIG_CANOPENSTATE(false,-4,"select error");
             mfault->SetFaultState(2,4,"select error.");
+            std::cout<<"select error."<<std::endl;
             mbCANOpen = false;
             continue;
         }
 
+ //       std::cout<<"time: "<<QDateTime::currentMSecsSinceEpoch()<<" ret : "<<ret<<std::endl;
+
+        bool bRecv = false;
         for (i=0; i<currmax; i++) {  /* check all CAN RAW sockets */
 
             if (FD_ISSET(s[i], &rdfs)) {
@@ -169,7 +191,9 @@ void nvcan::run()
                 msg.msg_controllen = sizeof(ctrlmsg);
                 msg.msg_flags = 0;
 
+                mMutexRW.lock();
                 nbytes = recvmsg(s[i], &msg, 0);
+                mMutexRW.unlock();
 
                 if (nbytes < 0) {
  //                   if ((errno == ENETDOWN) && !down_causes_exit) {
@@ -194,8 +218,9 @@ void nvcan::run()
                     continue;
                 }
 
+                bRecv = true;
                 nrecvcount++;
-  //              qDebug("receive msg.");
+ //               qDebug("receive msg.");
                 mMutex.lock();
 
                 basecan_msg msg;
@@ -205,6 +230,7 @@ void nvcan::run()
                 if((frame.can_id&0x40000000)!= 0)msg.isRemote = true;
                 else msg.isRemote = false;
                 msg.nLen = frame.len;
+                nsecondrecvcount++;
                 if((frame.len<9)&&(frame.len>0))memcpy(msg.data,frame.data,frame.len);
                 if(mMsgRecvBuf[i].size()<BUF_SIZE)
                 {
@@ -213,9 +239,19 @@ void nvcan::run()
 
                 mMutex.unlock();
 
+
+
             }
         }
 
+        qint64 nsecondnow = QDateTime::currentSecsSinceEpoch();
+        if(nlastsecond != nsecondnow)
+        {
+            nlastsecond = nsecondnow;
+            std::cout<<"second recv count:"<<nsecondrecvcount<<std::endl;
+            nsecondrecvcount = 0;
+        }
+
         if((QDateTime::currentMSecsSinceEpoch() - nLastRecv)> 1000)
         {
             if(nRecvState == 0)
@@ -233,6 +269,137 @@ void nvcan::run()
             }
         }
 
+        if(bRecv)continue;
+
+
+        mWaitMutex.lock();
+        mwc.wait(&mWaitMutex,1);
+        mWaitMutex.unlock();
+
+#ifdef TEST_PROG
+ //       qDebug("send time : %lld",QDateTime::currentMSecsSinceEpoch());
+#endif
+
+        struct canfd_frame framesend[2500];
+#ifdef SEND_STAT
+        qint64 sendsettime[2500];
+#endif
+
+        for(int nch =0;nch<currmax;nch++)
+        {
+            int nsend = 0;
+            mMutex.lock();
+            int nbufsize = mMsgSendBuf[nch].size();
+            if(nbufsize>2500)nbufsize = 2500;
+            for(i=0;i<nbufsize;i++)
+            {
+                if(i>=2500)break;
+                memcpy(framesend[i].data,mMsgSendBuf[nch].at(i).data,8);
+                framesend[i].can_id = mMsgSendBuf[nch].at(i).id;
+                if(mMsgSendBuf[nch].at(i).isExtern)
+                {
+                    framesend[i].can_id = framesend[i].can_id|0x80000000;
+                }
+                else
+                {
+                    framesend[i].can_id = framesend[i].can_id&0x7ff;
+                }
+                if(mMsgSendBuf[nch].at(i).isRemote)
+                {
+                    framesend[i].can_id= framesend[i].can_id|0x40000000;
+                }
+
+                framesend[i].len = mMsgSendBuf[nch].at(i).nLen;
+#ifdef SEND_STAT
+                sendsettime[i] = mMsgSendBuf[nch].at(i).mSetTime;
+#endif
+
+                nsend++;
+            }
+            mMsgSendBuf[nch].clear();
+            mMutex.unlock();
+
+            if(nsend > 0)
+            {
+                for(i=0;i<nsend;i++)
+                {
+                    mMutexRW.lock();
+
+                    if (write(mps[nch], &framesend[i],16) != 16) {
+                        mMutexRW.unlock();
+                        mivlog->error("write error 1");
+ //                       perror("write error 1.");
+
+                        nretry++;
+                        secondretrycount++;
+                        if(nretry > 5)
+                        {
+ //                           std::cout<<"retry fail,retry:"<<nretry<<std::endl;
+                        }
+                        else
+                        {
+
+
+                        }
+                        if(nretry < 5)
+                        {
+                            i--;
+                        }
+                        else
+                        {
+                            nretry = 0;
+//                            std::cout<<"retry more than 100. drop this message."<<std::endl;
+                        }
+                         std::this_thread::sleep_for(std::chrono::microseconds(100));
+ //                       std::cout<<"retry send."<<std::endl;
+                        continue;
+                    }
+                    else
+                    {
+                        mMutexRW.unlock();
+#ifdef SEND_STAT
+                        qint64 nnowms = QDateTime::currentMSecsSinceEpoch();
+                        qint64 nlat = nnowms - sendsettime[i];
+                        xvectorlat.push_back(nlat);
+                        nretry = 0;
+                        nsecondsend++;
+#endif
+                    }
+                }
+            }
+
+                        qint64 nnowsecond = QDateTime::currentSecsSinceEpoch();
+                        if( nnowsecond != nLastSecond)
+                        {
+                            nLastSecond = nnowsecond;
+                            std::cout<<" second send count: "<<nsecondsend<<std::endl;
+                            nsecondsend = 0;
+#ifdef SEND_STAT
+                            int j;
+                            int nsendcount = xvectorlat.size();
+                            if(nsendcount > 0)
+                            {
+                                qint64 xlatmax = 0;
+                                qint64 xlatavg = 0;
+                                for(j=0;j<nsendcount;j++)
+                                {
+                                    if(xvectorlat[j]> xlatmax)xlatmax = xvectorlat[j];
+                                    xlatavg = xlatavg + xvectorlat[j];
+                                }
+                                xlatavg = xlatavg/nsendcount;
+                                std::cout<<" max latency: "<<xlatmax<<" avg latency: "<<xlatavg
+                                        <<" second retry count:"<<secondretrycount<<std::endl;
+
+
+                                xvectorlat.clear();
+                            }
+#endif
+                            secondretrycount = 0;
+                        }
+
+
+        }
+
 
 
     }
@@ -247,8 +414,43 @@ void nvcan::run()
 
 void nvcan::threadsend()
 {
+
+    return;
     int currmax = 1;
+    int s[MAXSOCK];
     int i;
+
+    struct sockaddr_can addr;
+    struct ifreq ifr;
+
+    for(i=0;i<currmax;i++)
+    {
+        s[i] = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+        if (s[i] < 0) {
+            return;
+        }
+
+        addr.can_family = AF_CAN;
+
+        memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
+        strncpy(ifr.ifr_name, CANNAME[i].data(), 5);
+
+        if (ioctl(s[i], SIOCGIFINDEX, &ifr) < 0) {
+            return;
+        }
+        addr.can_ifindex = ifr.ifr_ifindex;
+
+        if (bind(s[i], (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+            return;
+        }
+    }
+
+    std::cout<<"threadsend open can success."<<std::endl;
+
+    mps = &s[0];
+
+ //   int currmax = 1;
+ //   int i;
     while(mbCANOpen == false)
     {
         std::this_thread::sleep_for(std::chrono::milliseconds(1));
@@ -257,6 +459,10 @@ void nvcan::threadsend()
     qint64 nLastSecond = 0;
     int nsecondsend = 0;
     int nretry = 0;
+#ifdef SEND_STAT
+    std::vector<qint64> xvectorlat;
+#endif
+    int secondretrycount = 0;
     while(mbSendRun)
     {
         mWaitMutex.lock();
@@ -264,16 +470,21 @@ void nvcan::threadsend()
         mWaitMutex.unlock();
 
 #ifdef TEST_PROG
-//        qDebug("send time : %lld",QDateTime::currentMSecsSinceEpoch());
+ //       qDebug("send time : %lld",QDateTime::currentMSecsSinceEpoch());
 #endif
 
         struct canfd_frame framesend[2500];
+#ifdef SEND_STAT
+        qint64 sendsettime[2500];
+#endif
 
         for(int nch =0;nch<currmax;nch++)
         {
             int nsend = 0;
             mMutex.lock();
-            for(i=0;i<mMsgSendBuf[nch].size();i++)
+            int nbufsize = mMsgSendBuf[nch].size();
+            if(nbufsize>2500)nbufsize = 2500;
+            for(i=0;i<nbufsize;i++)
             {
                 if(i>=2500)break;
                 memcpy(framesend[i].data,mMsgSendBuf[nch].at(i).data,8);
@@ -292,6 +503,9 @@ void nvcan::threadsend()
                 }
 
                 framesend[i].len = mMsgSendBuf[nch].at(i).nLen;
+#ifdef SEND_STAT
+                sendsettime[i] = mMsgSendBuf[nch].at(i).mSetTime;
+#endif
 
                 nsend++;
             }
@@ -302,13 +516,18 @@ void nvcan::threadsend()
             {
                 for(i=0;i<nsend;i++)
                 {
+                    mMutexRW.lock();
+
                     if (write(mps[nch], &framesend[i],16) != 16) {
+                        mMutexRW.unlock();
                         mivlog->error("write error 1");
  //                       perror("write error 1.");
+
                         nretry++;
+                        secondretrycount++;
                         if(nretry > 30)
                         {
-                            std::cout<<"retry fail,retry:"<<nretry<<std::endl;
+ //                           std::cout<<"retry fail,retry:"<<nretry<<std::endl;
                         }
                         else
                         {
@@ -321,7 +540,8 @@ void nvcan::threadsend()
                         }
                         else
                         {
-                            std::cout<<"retry more than 100. drop this message."<<std::endl;
+                            nretry = 0;
+//                            std::cout<<"retry more than 100. drop this message."<<std::endl;
                         }
                          std::this_thread::sleep_for(std::chrono::microseconds(100));
  //                       std::cout<<"retry send."<<std::endl;
@@ -329,19 +549,47 @@ void nvcan::threadsend()
                     }
                     else
                     {
+                        mMutexRW.unlock();
+#ifdef SEND_STAT
+                        qint64 nnowms = QDateTime::currentMSecsSinceEpoch();
+                        qint64 nlat = nnowms - sendsettime[i];
+                        xvectorlat.push_back(nlat);
                         nretry = 0;
                         nsecondsend++;
+#endif
+                    }
+                }
+            }
+
                         qint64 nnowsecond = QDateTime::currentSecsSinceEpoch();
                         if( nnowsecond != nLastSecond)
                         {
                             nLastSecond = nnowsecond;
                             std::cout<<" second send count: "<<nsecondsend<<std::endl;
                             nsecondsend = 0;
+#ifdef SEND_STAT
+                            int j;
+                            int nsendcount = xvectorlat.size();
+                            if(nsendcount > 0)
+                            {
+                                qint64 xlatmax = 0;
+                                qint64 xlatavg = 0;
+                                for(j=0;j<nsendcount;j++)
+                                {
+                                    if(xvectorlat[j]> xlatmax)xlatmax = xvectorlat[j];
+                                    xlatavg = xlatavg + xvectorlat[j];
+                                }
+                                xlatavg = xlatavg/nsendcount;
+                                std::cout<<" max latency: "<<xlatmax<<" avg latency: "<<xlatavg
+                                        <<" second retry count:"<<secondretrycount<<std::endl;
+
+
+                                xvectorlat.clear();
+                            }
+#endif
+                            secondretrycount = 0;
                         }
 
-                    }
-                }
-            }
 
         }
     }

+ 5 - 0
src/driver/driver_can_socket/nvcan.h

@@ -50,6 +50,11 @@ private:
     QMutex mWaitMutex;
 
     std::thread * mpsendthread;
+
+    QMutex mMutexRW;
+
+private:
+    void ExecRecv(int s);
 };
 
 #endif // NVCAN_H

+ 3 - 0
src/include/base/driver/can/basecan.h

@@ -15,6 +15,9 @@ class basecan_msg
     bool isRemote;
     unsigned char nLen;
     unsigned char data[8];
+#ifdef SEND_STAT
+    qint64 mSetTime;  //Used for calucate send latency
+#endif
 };
 
 class basecan : public QThread