#include "can_control.h"
Can_Control::Can_Control(QObject *parent)
: QThread(parent)
, stSocket(-1)
, m_bExit(false)
{
}
int Can_Control::can_send()
{
int stSocket_LO, stSend_LO;
struct sockaddr_can addr; //can总线的地址 同socket编程里面的 socketaddr结构体 用来设置can外设的信息
struct ifreq ifr;//接口请求结构体
struct can_frame frame[2] = {{0}}; //要发送的buffer
/* 创建socket套接字
PF_CAN 为域位 同网络编程中的AF_INET 即ipv4协议
SOCK_RAW使用的协议类型 SOCK_RAW表示原始套接字 报文头由自己创建
CAN_RAW为使用的具体协议 为can总线协议
*/
stSocket_LO = socket(PF_CAN, SOCK_RAW, CAN_RAW);//创建套接字
strcpy(ifr.ifr_name, "can0" );
ioctl(stSocket_LO, SIOCGIFINDEX, &ifr); //指定 can0 设备
addr.can_family = AF_CAN; //协议类型
addr.can_ifindex = ifr.ifr_ifindex; //can总线外设的具体索引 类似 ip地址
bind(stSocket_LO, (struct sockaddr *)&addr, sizeof(addr));//将套接字和canbus外设进行绑定,即套接字与 can0 绑定
//禁用过滤规则,本进程不接收报文,只负责发送
setsockopt(stSocket_LO, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
//生成两个报文
frame[0].can_id = 0x11;
frame[0]. can_dlc = 1;
frame[0].data[0] = '1';
frame[1].can_id = 0x22;
frame[1]. can_dlc = 1;
frame[1].data[0] = '2';
//循环发送两个报文
while(1)
{
stSend_LO = write(stSocket_LO, &frame[0], sizeof(frame[0])); //发送 frame[0]
if(stSend_LO != sizeof(frame[0]))
{
printf("Send Error frame[0]\n!");
break; //发送错误,退出
}
sleep(1);
stSend_LO = write(stSocket_LO, &frame[1], sizeof(frame[1])); //发送 frame[1]
if(stSend_LO != sizeof(frame[0]))
{
printf("Send Error frame[1]\n!");
break;
}
sleep(1);
}
close(stSocket_LO);//关闭套接字
return 0;
}
int Can_Control::can_recv()
{
int stSocket_LO, stRecv_LO;
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
struct can_filter rfilter[1];
stSocket_LO = socket(PF_CAN, SOCK_RAW, CAN_RAW); //创建套接字
strcpy(ifr.ifr_name, "can0" );
ioctl(stSocket_LO, SIOCGIFINDEX, &ifr); //指定 can0 设备
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(stSocket_LO, (struct sockaddr *)&addr, sizeof(addr)); //将套接字与 can0 绑定
//定义接收规则,只接收表示符等于 0x11 的报文
rfilter[0].can_id = 0x11;
rfilter[0].can_mask = CAN_SFF_MASK;
//设置过滤规则
setsockopt(stSocket_LO, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
while(1)
{
stRecv_LO = read(stSocket_LO, &frame, sizeof(frame)); //接收报文
//显示报文
if(stRecv_LO > 0)
{
printf("Idata[0]=0x%x\n",frame.data[0]);
}
}
close(stSocket_LO);
return 0;
}
int Can_Control::socket_connect(const char*m_port)
{
int ret = 0;
struct sockaddr_can canbus_addr_LO; //can总线的地址 同socket编程里面的 socketaddr结构体 用来设置can外设的信息
struct ifreq ifreq_LO; //接口请求结构体
QMutexLocker locker(&m_mutex);
stSocket = socket(PF_CAN, SOCK_RAW, CAN_RAW);//创建套接字
if(stSocket<0)
{
QMessageBox::information(NULL, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("打开CAN设备失败"));
return -1;
}
strcpy(ifreq_LO.ifr_name, m_port);//对CAN接口进行初始化,如设置CAN接口名,即当我们用ifconfig命令时显示的名字
ret=ioctl(stSocket, SIOCGIFINDEX, &ifreq_LO); //指定 can设备
if(ret<0)
{
QMessageBox::information(NULL, QString::fromUtf8("错误"), QString::fromUtf8("匹配CAN设备错误"));
return -1;
}
/* 设置CAN协议 */
canbus_addr_LO.can_family = AF_CAN; //协议类型
canbus_addr_LO.can_ifindex = ifreq_LO.ifr_ifindex; //can总线外设的具体索引 类似 ip地址
ret=bind(stSocket, (struct sockaddr *)&canbus_addr_LO, sizeof(canbus_addr_LO));//将套接字和canbus外设进行绑定,即套接字与 can0 绑定
if(ret<0)
{
::close(stSocket);//关闭套接字
QMessageBox::information(NULL, QString::fromUtf8("错误"), QString::fromUtf8("绑定套接字错误"));
return -1;
}
return stSocket;
}
void Can_Control::set_can_filter()//设置滤波
{
const int n = 1;
struct can_filter rfilter[n];
// 过滤规则:当<received_can_id> & mask == can_id & mask时,接收报文,否则过滤掉.
// 可以同时添加多条过滤规则
// 在用来发送CAN帧的CAN_RAW套接字上不接收任何CAN帧
rfilter[0].can_id = 0x00000000;
rfilter[0].can_mask = CAN_EFF_MASK;
(void)setsockopt(send_socket_fd, SOL_CAN_RAW, CAN_RAW_FILTER, rfilter, n * sizeof(struct can_filter));
// 在用来接收CAN帧的CAN_RAW套接字上禁用接收过滤规则
(void)setsockopt(recv_socket_fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
}
int Can_Control::send_frame(struct can_frame* data)
{
m_mutex.lock();
int ret = write(stSocket, data, sizeof(can_frame));
m_mutex.unlock();
if (ret != sizeof(can_frame))
{
QMessageBox::information(NULL, QString::fromUtf8("错误"), QString::fromUtf8("发送错误"));
return 1;
}
return ret;
}
int Can_Control::recv_frame( int sockfd, struct can_frame* buf, const int timeout_ms)
{
struct timeval tv_timeout;
tv_timeout.tv_sec = timeout_ms /1000;
tv_timeout.tv_usec = (timeout_ms % 1000) * 1000;
fd_set fs_read;
FD_ZERO(&fs_read);
FD_SET(sockfd, &fs_read); //如果fd == -1, FD_SET将在此阻塞
int ret = select((int)sockfd + 1, &fs_read, NULL, NULL, &tv_timeout);
if (ret == 0) // recv 超市
{
return 0;
}
if (ret < 0) // select 错误
{
return ret;
}
ret = read(sockfd, buf, sizeof(struct can_frame));
//ret = recv(sockfd, (char*)buf, count, 0);
if (ret <= 0)
{
return -1;
}
return ret;
}
void Can_Control::SetThreadStatus(bool status)
{
m_bExit = status;
}
void Can_Control::run()
{
while (!m_bExit) {
memset(&m_frame, 0, sizeof(m_frame));
m_mutex.lock();
m_dataLength = recv_frame(stSocket, &m_frame, 200);
m_mutex.unlock();
if(m_dataLength > 0)
{
emit SigSendData(&m_frame);
}
msleep(100);
}
QMutexLocker locker(&m_mutex);
::close(stSocket);
}
没有合适的资源?快使用搜索试试~ 我知道了~
Can调试工具源码,可以直接使用,也可以作为学习使用
0 下载量 80 浏览量
2024-02-04
16:39:28
上传
评论
收藏 50KB TGZ 举报
温馨提示
共8个文件
cpp:3个
h:2个
pro:1个
Can调试工具源码,欢迎下载
资源推荐
资源详情
资源评论
收起资源包目录
CanTool1.0.tgz (8个子文件)
test3
mainwindow.h 585B
can_control.cpp 7KB
mainwindow.cpp 3KB
main.cpp 172B
mainwindow.ui 3KB
test3.pro 1KB
test3.pro.user 23KB
can_control.h 1KB
共 8 条
- 1
资源评论
qq_39851127
- 粉丝: 535
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- JSP-JTBC-CMS(SQLITE).rar
- MC3362和MC145151调频无线接收器的设计.pdf
- MiniRenamer-v100.0一款简单易用的批量文件重命名工具(已注册PRO版本).rar
- 小狐狸Ai系统 小狐狸ai付费创作系统V2.8.0 ChatGPT智能机器人
- 公孙离-内衣-肚兜.zipgsl
- 快慢指针判断链表是否有环-go 语言实现
- 学生成绩管理系统的设计与实现-收藏备用.pdf
- JSP+SQL网站流量统计管理系统(源代码+论文).rar
- IBM-PC-XT微机过程...道中模拟量数据的采集和处理.pdf
- JSP+SQL网上选课系统(源代码+论文+答辩PPT).rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功