|
本帖最后由 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[2];
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[0].can_id = 0x18010101;
rfilter[0].can_mask = 0x1FFFFFFF;
rfilter[1].can_id = 0x0cf00400;
rfilter[1].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[0] = 0x11;
frame.data[1] = 0x22;
frame.data[2] = 0x33;
frame.data[3] = 0x44;
frame.data[4] = 0x55;
frame.data[5] = 0x66;
frame.data[6] = 0x77;
frame.data[7] = 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_CAN 29
#endif
#ifndef AF_CAN
#define AF_CAN PF_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
|
|