Qt 通过插座访问CAN总线端口;需要非阻塞解决方案
我有一个应用程序,我将使用一个独立的C编程来读取带有套接字的CAN总线端口。此上的用户界面是Qt/QML代码。我想使用非阻塞方法调用bin程序,要么不返回任何内容,要么返回CAN数据包的字符串 应用程序将是低速的(仅监视按键等),因此速度不是问题。当前的方法涉及将数据从套接字程序写入文件,然后让另一个C程序获取该文件并将字符串回显到QML。啊!看起来很乱。一个简单的去/不去电话会更容易。这是我到目前为止得到的代码 谢谢你的评论Qt 通过插座访问CAN总线端口;需要非阻塞解决方案,qt,sockets,qml,can-bus,Qt,Sockets,Qml,Can Bus,我有一个应用程序,我将使用一个独立的C编程来读取带有套接字的CAN总线端口。此上的用户界面是Qt/QML代码。我想使用非阻塞方法调用bin程序,要么不返回任何内容,要么返回CAN数据包的字符串 应用程序将是低速的(仅监视按键等),因此速度不是问题。当前的方法涉及将数据从套接字程序写入文件,然后让另一个C程序获取该文件并将字符串回显到QML。啊!看起来很乱。一个简单的去/不去电话会更容易。这是我到目前为止得到的代码 谢谢你的评论 #include <stdio.h> #include
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
// Returns 0 if no errors, > 0 if errors found
int main(void) {
struct ifreq ifr;
struct can_frame frame;
struct sockaddr_can addr;
int s; // CAN socket descriptor
int nbytes; // Number of bytes read from CAN socket
char run_daemon = 0; // Set to 1 to run as a daemon process
char show_errors = 0; // Set to 1 to print errors
char *ifname = "can0"; // Define the CAN driver for use
if (run_daemon) // Skip the daemon call if not enabled
daemon(1,1);
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
if (show_errors)
perror("Error while opening RAW socket");
return 1;
}
strcpy (ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
if (show_errors)
perror("Error in socket bind");
return 2;
}
// Loop here for daemon process
while (1) {
// Read CAN frame data
nbytes = read(s, &frame, sizeof(struct can_frame));
// If data is ready, process it
if (nbytes > 0) {
// Print all relevent frame data to QML
printf("%d ",frame.can_id);
printf("%d ",frame.can_dlc);
if(frame.can_dlc>0) printf("%d ",frame.data[0]);
if(frame.can_dlc>1) printf("%d ",frame.data[1]);
if(frame.can_dlc>2) printf("%d ",frame.data[2]);
if(frame.can_dlc>3) printf("%d ",frame.data[3]);
if(frame.can_dlc>4) printf("%d ",frame.data[4]);
if(frame.can_dlc>5) printf("%d ",frame.data[5]);
if(frame.can_dlc>6) printf("%d ",frame.data[6]);
if(frame.can_dlc>7) printf("%d ",frame.data[7]);
printf("\n");
}
if (!run_daemon) { // Exit if daemon is not running
close(s); // Close the CAN socket
return 0;
}
}
return 0; // Should never get here !!!
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//如果没有错误,则返回0;如果发现错误,则返回>0
内部主(空){
结构ifreq-ifr;
结构can_框架;
结构sockaddr\u can addr;
int s;//CAN套接字描述符
int nbytes;//从CAN套接字读取的字节数
char run_daemon=0;//设置为1以作为守护进程运行
char show_errors=0;//设置为1可打印错误
char*ifname=“can0”//定义要使用的CAN驱动程序
if(run_daemon)//如果未启用,则跳过daemon调用
守护进程(1,1);
如果((s=插座(PF_CAN、SOCK_RAW、CAN_RAW))<0){
如果(显示错误)
perror(“打开原始套接字时出错”);
返回1;
}
strcpy(ifr.ifr\u name,ifname);
ioctl(s、SIOCGIFINDEX和ifr);
addr.can_family=AF_can;
addr.can_iIndex=ifr.ifr_iIndex;
if(绑定(结构sockaddr*)&addr,sizeof(addr))<0{
如果(显示错误)
perror(“套接字绑定错误”);
返回2;
}
//在这里为守护进程循环
而(1){
//读取CAN帧数据
nbytes=读取(s,&frame,sizeof(struct can_frame));
//如果数据已准备就绪,请对其进行处理
如果(n字节>0){
//将所有相关帧数据打印到QML
printf(“%d”,帧can\u id);
printf(“%d”,帧can\u dlc);
如果(frame.can_dlc>0)printf(“%d”,frame.data[0]);
如果(frame.can_dlc>1)printf(“%d”,frame.data[1]);
如果(frame.can_dlc>2)printf(“%d”,frame.data[2]);
如果(frame.can_dlc>3)printf(“%d”,frame.data[3]);
如果(frame.can_dlc>4)printf(“%d”,frame.data[4]);
如果(frame.can_dlc>5)printf(“%d”,frame.data[5]);
如果(frame.can_dlc>6)printf(“%d”,frame.data[6]);
如果(frame.can_dlc>7)printf(“%d”,frame.data[7]);
printf(“\n”);
}
如果(!run_daemon){//如果daemon未运行,则退出
关闭;//关闭CAN插座
返回0;
}
}
返回0;//不应该到这里!!!
}
是什么阻止您使用QProcess
及其异步接口在CAN二进制输出某些数据时收到通知?这段代码以前就在这里,我还有很多其他章节要写。我想对这个做一些小的改变,而不是从新开始写,然后让它工作。我想在正确的地方写几行就可以了。我不太确定我是否理解你的要求。与@KubaOber相同,我的建议是通过QProcess
运行程序。程序将按原样继续,在一个紧循环中读取,当数据到达时,进程对象将异步发出信号。我最初的想法是,来自QML的CAN read调用将立即以字符串形式返回读取数据包,或者不返回任何内容。无论哪种方式,它都将允许QML继续。我还将研究在这方面使用QProcess。我将此理解为将套接字设置为非阻塞?我来测试一下。int标志fcntl(套接字,F_GETFL,0);fcntl(插座、F|U设置FL、标志| U非块);是什么阻止您使用QProcess
及其异步接口在CAN二进制输出某些数据时获得通知?这段代码以前就在这里,我还有很多其他章节要写。我想对这个做一些小的改变,而不是从新开始写,然后让它工作。我想在正确的地方写几行就可以了。我不太确定我是否理解你的要求。与@KubaOber相同,我的建议是通过QProcess
运行程序。程序将按原样继续,在一个紧循环中读取,当数据到达时,进程对象将异步发出信号。我最初的想法是,来自QML的CAN read调用将立即以字符串形式返回读取数据包,或者不返回任何内容。无论哪种方式,它都将允许QML继续。我还将研究在这方面使用QProcess。我将此理解为将套接字设置为非阻塞?我来测试一下。int标志fcntl(套接字,F_GETFL,0);fcntl(插座、F|U设置FL、标志| U非块);