qt下socketcan发送和接收数据问题

JackYoung168 2016-08-13 12:24:31
qt中socketcan发送和接收数据放在一个线程下还是两个线程 目前用周立功max287操作屏开发板提供的例程,创建一个线程用select阻塞然后read读数据,然后发送数据不知道怎么处理了。是去掉select函数直接把read和write放到同一个线程下循环,还是为发送数据再创建一个线程?如果创建一个线程的话write(fd,sendbuf,&sizeof(sendbuf))怎么调用读线程里面绑定过的套接字描述字符fd?求高人指点方向!!!
...全文
1074 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
JackYoung168 2016-08-13
  • 打赏
  • 举报
回复 1
下面是测试程序 #include <stdio.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <net/if.h> #include <linux/socket.h> #include <linux/can.h> #include <linux/can/error.h> #include <linux/can/raw.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <time.h> #ifndef AF_CAN #define AF_CAN 29 #endif #ifndef PF_CAN #define PF_CAN AF_CAN #endif static void print_frame(struct can_frame *fr) { int i; printf("%08x\n", fr->can_id & CAN_EFF_MASK); //printf("%08x\n", fr->can_id); printf("dlc = %d\n", fr->can_dlc); printf("data = "); for (i = 0; i < fr->can_dlc; i++) printf("%02x ", fr->data[i]); printf("\n"); } #define errout(_s) fprintf(stderr, "error class: %s\n", (_s)) #define errcode(_d) fprintf(stderr, "error code: %02x\n", (_d)) static void handle_err_frame(const struct can_frame *fr) { if (fr->can_id & CAN_ERR_TX_TIMEOUT) { errout("CAN_ERR_TX_TIMEOUT"); } if (fr->can_id & CAN_ERR_LOSTARB) { errout("CAN_ERR_LOSTARB"); errcode(fr->data[0]); } if (fr->can_id & CAN_ERR_CRTL) { errout("CAN_ERR_CRTL"); errcode(fr->data[1]); } if (fr->can_id & CAN_ERR_PROT) { errout("CAN_ERR_PROT"); errcode(fr->data[2]); errcode(fr->data[3]); } if (fr->can_id & CAN_ERR_TRX) { errout("CAN_ERR_TRX"); errcode(fr->data[4]); } if (fr->can_id & CAN_ERR_ACK) { errout("CAN_ERR_ACK"); } if (fr->can_id & CAN_ERR_BUSOFF) { errout("CAN_ERR_BUSOFF"); } if (fr->can_id & CAN_ERR_BUSERROR) { errout("CAN_ERR_BUSERROR"); } if (fr->can_id & CAN_ERR_RESTARTED) { errout("CAN_ERR_RESTARTED"); } } #define myerr(str) fprintf(stderr, "%s, %s, %d: %s\n", __FILE__, __func__, __LINE__, str) static int test_can_rw(int fd, int master) { int ret, i; struct can_frame fr, frdup; struct timeval tv; fd_set rset; while (1) { tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&rset); FD_SET(fd, &rset); ret = select(fd+1, &rset, NULL, NULL, NULL); //阻塞 if (ret == 0) { myerr("select time out"); return -1; } ret = read(fd, &frdup, sizeof(frdup)); //读数据 if (ret < sizeof(frdup)) { myerr("read failed"); return -1; } if (frdup.can_id & CAN_ERR_FLAG) { /* 出错设备错误 */ handle_err_frame(&frdup); myerr("CAN device error"); continue; } print_frame(&frdup); ret = write(fd, &frdup, sizeof(frdup));//发送读到的数据 if (ret < 0) { myerr("write failed"); return -1; } } return 0; } /*************************************************************************************** **函数名称: main() **函数说明: **创建时间: ***************************************************************************************/ int main(int argc, char *argv[]) { int s; int ret; struct sockaddr_can addr; struct ifreq ifr; int master; /* * 创建socket can套接字 */ srand(time(NULL)); s = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (s < 0) { perror("socket PF_CAN failed"); return 1; } strcpy(ifr.ifr_name, "can0"); ret = ioctl(s, SIOCGIFINDEX, &ifr); if (ret < 0) { perror("ioctl failed"); return 1; } addr.can_family = PF_CAN; addr.can_ifindex = ifr.ifr_ifindex; ret = bind(s, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { perror("bind failed"); return 1; } if (0) { struct can_filter filter[2]; filter[0].can_id = 0x200 | CAN_EFF_FLAG; filter[0].can_mask = 0xFFF; filter[1].can_id = 0x20F | CAN_EFF_FLAG; filter[1].can_mask = 0xFFF; ret = setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)); if (ret < 0) { perror("setsockopt failed"); return 1; } } test_can_rw(s, master); close(s); return 0; }
Linux下面QT写Can通信程序,网络上有很多例子都是互相抄的;本人因为项目原因,通过源代码Socket函数,写了完整的程序,含有2个案例;分享给大家; 这里主要是包含几个步骤,1:绑定Socket;2:cna/can1的设置,3:波特率的设置(如果发送和接收波特率不一致肯定不行的);4:发送;5:接收处理; 下面就贴出部分代码: void MyWindow::startcan(int number) { int ret = 0; //can先关闭 设置好波特率后 再开启can if(number == 0) //can0 { system("ifconfig can0 down");//先关闭 system("ip link set can0 up type can bitrate 50000 triple-sampling on");//设置波特率 system("ifconfig can0 up");//再开启 } else //can1 { system("ifconfig can1 down");//先关闭 system("ip link set can1 up type can bitrate 50000 triple-sampling on");//设置波特率 system("ifconfig can1 up");//再开启 } socket = ::socket(PF_CAN,SOCK_RAW,CAN_RAW); struct ifreq ifr; strcpy((char *)(ifr.ifr_name),number == 0 ? "can0" : "can1"); ioctl(socket,SIOCGIFINDEX,&ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; ret = bind(socket,(struct sockaddr*)&addr,sizeof(addr)); if (ret OpenCan(50000); ArmCan = new Thread(zyhapi,socket,port); ArmCan->start(); } void MyWindow::stopcan(int number) { if(ArmCan) { ArmCan->stop(); ArmCan->terminate(); ArmCan->wait(); } zyhapi->CloseCan(number); } //发送 void MyWindow::on_sendbtn_clicked() { /* struct can_frame frame; memset(&frame,0,sizeof(struct can_frame)); std::string str=ui->edit->text().toStdString(); if(str.length() > 8) { QMessageBox::about(this,"error","length of send string must less than 8 bytes"); return; } */ struct can_frame frame; memset(&frame,0,sizeof(struct can_frame)); char buf[8]={0X20,0XFF,0X01,0X02,0X03,0X04,0XFF,0XFF}; frame.can_id = 0x00000020;//发出去的帧ID即:0X00000020 frame.can_dlc = 8;//帧数据长度 for(int i=0;isocket,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr,sizeof(addr)); /* struct can_frame frame; char buf[8]={0X20,0XFF,0X01,0X02,0X03,0X04,0XFF,0XFF}; frame.can_id = 0x00000020;//发出去的帧ID即:0X00000020 frame.can_dlc = 8;//帧数据长度 for(int i=0;iWriteCan(frame.can_id,frame.data,frame.can_dlc);//发数据,通过can端口-- 暂时默认 CAN0 端口 */ }

27,373

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧