jshxcn 发表于 2023-9-2 22:07:11

【米尔瑞萨RZ/G2L开发板-创新应用】在Qt中使用socket编程

本帖最后由 jshxcn 于 2023-9-2 22:24 编辑

使用Qt的socket实现can收发数据,目前可以正常发送数据,接收数据会一直接收,目前还不知道问题在哪里,先把程序发上来,请大家帮忙查找一下问题原因。





/*************
mainwindos.cpp
*************/

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    layoutInit();
    startcan();
    QTimer *time1 = new QTimer();
    time1->start(1000);
    connect(time1, &QTimer::timeout, this, &MainWindow::sendmsg);
}

MainWindow::~MainWindow()
{
    delete ui;
    stopcan();
}

void MainWindow::layoutInit()
{
    QList <QScreen *>list_screen = QGuiApplication::screens();
    this->resize(list_screen.at(0)->geometry().width(),
               list_screen.at(0)->geometry().height());

    textBrowser = new QTextBrowser();
    pushButton = new QPushButton("清除");
    mainWidget = new QWidget();
    vboxLayout = new QVBoxLayout();

    pushButton->setMinimumSize(120,30);
    pushButton->setMaximumHeight(50);
    pushButton->setSizePolicy(QSizePolicy::Expanding,
                              QSizePolicy::Expanding);
    vboxLayout->addWidget(textBrowser);
    vboxLayout->addWidget(pushButton);
    mainWidget->setLayout(vboxLayout);
    this->setCentralWidget(mainWidget);

    connect(pushButton, SIGNAL(clicked()),this, SLOT(textClear()));
}

void MainWindow::startcan()
{
    int ret;
    struct can_filter rfilter;
    ret = system("ifconfig can0 down");
    qDebug("can down ret:%d",ret);
    ret = system("ip link set can0 up type can bitrate 250000 sample-point 0.75 dbitrate 4000000 dsample-point 0.8 fd on restart-ms 100");
    qDebug("can setup ret:%d",ret);
    ret = system("ifconfig can0 up");
    qDebug("can up ret:%d",ret);

    fdcan = ::socket(PF_CAN, SOCK_RAW, CAN_RAW); // 创建套接字
    qDebug("can socket id:%d",fdcan);
    struct ifreq ifr; // 接口请求结构体
    strcpy(ifr.ifr_name, "can0");
    fcntl(fdcan, F_SETFL, 0); // 回到正常模式
    ioctl(fdcan, SIOCGIFINDEX, &ifr); // 指定CAN0设备
    addr.can_family = AF_CAN; // 协议类型
    addr.can_ifindex = ifr.ifr_ifindex; // CAN总线外设具体索引
    bind(fdcan, (struct sockaddr*)&addr, sizeof(addr)); // 绑定套接字和canbus外设

    // 禁用过滤规则,不接收报文,需接收注释掉
    rfilter.can_id = 0x18010101;
    rfilter.can_mask = 0x1FFFFFFF;
    rfilter.can_id = 0x0cf00400;
    rfilter.can_mask = 0x1FFFFFFF;
    setsockopt(fdcan, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

    int lookback = 0;
    setsockopt(fdcan, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &lookback, sizeof(lookback));

    t = NULL;
    t = new Thread(fdcan); // 开启单独线程接收监听
    qRegisterMetaType<can_frame>("can_frame");
    connect(t, SIGNAL(message0(can_frame)), this, SLOT(msg0(can_frame)));
    t->start();
}

void MainWindow::stopcan()
{
    int ret;
    if(t)
    {
      t->stop();
      t->deleteLater();
    }
    ::close(fdcan);
    ret = system("ifconfig can0 down"); // 关闭CAN
}

void MainWindow::sendmsg()
{
    struct can_frame frame;
    int nbytes;
    memset(&frame, 0, sizeof(struct can_frame));

    frame.can_id = (0x18010101 & CAN_EFF_MASK) | CAN_EFF_FLAG; // 扩展帧
    frame.can_dlc = 8;
    frame.data = 0x11;
    frame.data = 0x22;
    frame.data = 0x33;
    frame.data = 0x44;
    frame.data = 0x55;
    frame.data = 0x66;
    frame.data = 0x77;
    frame.data = 0x88;
    nbytes = write(fdcan, &frame, sizeof(frame));
    if(nbytes>0)
    {
      qDebug("send bytes: %d",nbytes);
    }
    return;
}

void MainWindow::msg0(can_frame frame)
{
    QString view;
    view = QString::number(frame.can_id & 0x1fffffff,16) + " --";
    for(int i=0;i<frame.can_dlc;i++)
    {
      view = view + " " + QString::number(frame.data,16);
    }
    textBrowser->insertPlainText(view+'\n');
    textBrowser->moveCursor(QTextCursor::End);
}

void MainWindow::textClear()
{
    textBrowser->setText("");
}





/************
mainwindow.h
************/

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QProcess>
#include <QThread>
#include <QTimer>
#include <QVBoxLayout>
#include <QWidget>
#include <QScreen>
#include <QDebug>
#include "thread.h"

#include <QTextBrowser>
#include <QPushButton>

extern "C"{
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
}

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void sendmsg();
    //void msg(sockaddr addr,socklen_t num);
    void msg0(can_frame frame);
    void stopcan();
    void startcan();
    void textClear();
private:
    Ui::MainWindow *ui;
    void layoutInit();

    int fdcan;
    struct sockaddr_can addr;
    Thread *t;

    QTextBrowser *textBrowser;
    QPushButton *pushButton;
    QWidget *mainWidget;
    QVBoxLayout *vboxLayout;
};
#endif // MAINWINDOW_H



/************
thread.cpp
************/

#include "thread.h"
#include "mainwindow.h"

Thread::Thread(int s,QObject *parent)
    : QThread{parent}
{
    fdcan = s;
    running = true;
}

void Thread::run()
{
    int nbytes;
    struct can_frame frame;

    while(running)
    {
      nbytes = read(fdcan, &frame, sizeof(frame));
      if(nbytes>0)
      {
            qDebug("rec bytes:%d", nbytes);
            emit message0(frame);
      }
    }
}

void Thread::stop()
{
    running = false;
}




/************
thread.h
************/

#ifndef THREAD_H
#define THREAD_H

#include <QThread>
extern "C"{
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <linux/can.h>
#include <linux/can/raw.h>
}

/*
#ifndef PF_CAN
#define PF_CAN29
#endif

#ifndef AF_CAN
#define AF_CANPF_CAN
#endif
*/
class Thread : public QThread
{
    Q_OBJECT
public:
    explicit Thread(int s,QObject *parent = nullptr);

signals:
    void message0(can_frame frame);
public slots:
    void run();
    void stop();
private:
    int fdcan;
    bool running;
};

#endif // THREAD_H



jshxcn 发表于 2023-9-3 16:09:37

程序没有问题,换了一个CAN分析仪就好了

lugl 发表于 2024-4-12 11:48:15

jshxcn 发表于 2023-9-3 16:09
程序没有问题,换了一个CAN分析仪就好了

大佬的QT环境是怎么安装的呀?

ILoveTec 发表于 2024-4-24 10:24:11

lugl 发表于 2024-4-12 11:48
大佬的QT环境是怎么安装的呀?

同问大佬,qt环境怎么安装?
页: [1]
查看完整版本: 【米尔瑞萨RZ/G2L开发板-创新应用】在Qt中使用socket编程