#include "can-text.h"
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error message frame */
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
int can_parse();
int can_back(struct can_frame frame, char* can_mark);
static int s,nbytes_read,nbytes_write,i;
static char can_mark[16];
static struct sockaddr_can addr;
static struct ifreq ifr;
static struct can_frame frame;
static struct can_frame frame_write;
static pthread_t can_read_tid;
int (*pc)(struct can_frame, char*) = NULL;
callback_func_pf callback_func;
//pc = &can_back;
//发数据线程
void can_write(__u32 canid, unsigned char candlc, unsigned char data[8])
{
//赋予frame_write要发送的值
frame_write.can_id = canid;
frame_write.can_dlc = candlc;
//strcpy(data,frame_write.data);
int i;
for(i =0; i < candlc; i++)
{
frame_write.data[i] = data[i];
}
//发送
nbytes_write = write(s,&frame_write,sizeof(frame_write));
//通过判断成功发送的字符数与初值对比判定是否发送成功
if(nbytes_write != sizeof(frame_write))
{
printf("send error frame_write!\n");
//break;
}
//return NULL;
}
//收数据线程
void *can_read()
{
while(1)
{
//未读到数据时,读函数会阻塞进程
nbytes_read = read(s, &frame, sizeof(frame));
//如果成功接收到的字符数大于0,说明成功接收,将接收到的数据表示
if(nbytes_read > 0)
{
can_parse();
//get_Time();
(*pc)(frame, can_mark);
}
}
return NULL;
}
void get_Time()
{
struct timeval tv;
gettimeofday(&tv,NULL);
/*
char buf[128];
sprintf(buf,"%ld",tv.tv_usec/1000);
strncpy(can_mark,buf + (strlen(buf)-8),8);
*/
sprintf(can_mark,"%ld",tv.tv_usec/1000);
}
int can_parse()
{
__u8 func;
__u32 sid,eid,exide,rtr,err;
exide = (frame.can_id & CAN_EFF_FLAG) ? 1:0;
//取can_id的31位,判断是标准帧还是扩展帧
if(exide)
{
strcpy(can_mark,"extend");
return 0;
//若为扩展帧,can_id的0-28位为ID,其中高11位为标准ID
}
else
{
sid = (frame.can_id & CAN_SFF_MASK);
}
eid = (frame.can_id & CAN_EFF_MASK);
rtr = (frame.can_id & CAN_RTR_FLAG) ? 1:0;
//是否为远程帧
if(rtr)
{
strcpy(can_mark,"rtr");
return 0;
}
err = (frame.can_id & CAN_ERR_FLAG) ? 1:0;
//是否为错误消息
if(err)
{
strcpy(can_mark,"err");
return -1;
}
func = (frame.can_id & 0x7ff) >> 6;
switch(func)
{
case 0b00000:
strcpy(can_mark,"NMT");
break;
case 0b00001:
strcpy(can_mark,"EMCY");
break;
case 0b00100:
strcpy(can_mark,"SDO M->S");
break;
case 0b00101:
strcpy(can_mark,"SDO S->M");
break;
case 0b00110:
case 0b00111:
case 0b01000:
case 0b01001:
case 0b01010:
case 0b01011:
case 0b01100:
case 0b01101:
case 0b01110:
case 0b01111:
case 0b10000:
case 0b10001:
case 0b10010:
case 0b10011:
case 0b10100:
case 0b10101:
case 0b10110:
case 0b10111:
case 0b11000:
case 0b11001:
case 0b11010:
case 0b11011:
strcpy(can_mark,"PDO");
break;
case 0b11100:
strcpy(can_mark,"SDO M->S");
break;
case 0b11101:
strcpy(can_mark,"SDO S->M");
break;
default:
strcpy(can_mark,"ERROR!");
break;
}
}
//can模块初始化进程
void can_open(callback_func_pf func)
{
pc = func;
//创建can套接字
s = socket(PF_CAN,SOCK_RAW,CAN_RAW);
//指定can0设备
strcpy(ifr.ifr_name,"can0");
ioctl(s,SIOCGIFINDEX,&ifr);
//配置相关参数
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
//将套接字与can0绑定
bind(s,(struct sockaddr *)&addr,sizeof(addr));
//创建读线程
if(pthread_create(&can_read_tid,NULL,can_read,NULL)!=0)
{
perror("cannot create");
//return 0;
}
//return NULL;
}
void can_close()
{
pthread_join(can_read_tid,NULL);
close(s);
}
int can_back(struct can_frame frame, char* can_mark)
{
int i = 0;
printf("id = %02x dlc = %02x data = ",frame.can_id,frame.can_dlc);
while(frame.can_dlc)
{
printf("%02x ",frame.data[i]);
frame.can_dlc--;
}
printf("mark = %s\n",can_mark);
}
评论0