远程
帧
远程帧由6个场组成:帧起始、仲裁场、控制场、CRC场、应答场和帧结束。远程帧不存在数据场。
远程帧的RTR位必须是
隐位。
DLC的数据值是独立的,它可以是0~8中的任何数值,为对应数据帧的数据长度。
pp
头文件
#ifndef __CANPROTO_DEF_H
#define __CANPROTO_DEF_H
#include "printdef.h"
#include "UI.h"
#define CAN_EFF_FLAG 0x80000000U //扩展帧的标识
#define CAN_RTR_FLAG 0x40000000U //远程帧的标识
#define CAN_ERR_FLAG 0x20000000U //错误帧的标识用于检查错误
typedef struct tagCANFRAME {
unsigned int canID;
unsigned char len;
unsigned char flag;
unsigned char rev[2];
unsigned char data[8];
}CanFrame, *CanFrmPtr;
#define MAX_BUFLEN (512)
class CanProto {
public:
CanProto();
~CanProto();
public:
UI *m_pUI; // send to UI handle
void SetUI(UI *ui) { m_pUI = ui;}
int Start(void);
// 将串口接收到的数据写加到分析缓冲区中
int AddData(unsigned char *ibuf, int len);
// 分析接收到的数据
int Parse(unsigned char *ibuf = NULL, int len = 0);
static void *Receive_Pthread(void *p);
int Hex_Int(unsigned int inc);
void status_id_10(int i,unsigned char *data);
void status_id_11(int i,unsigned char *data);
void status_id_01(int i,unsigned char *data);
//打印接受到的数据
void printf_frame(unsigned int frame_id,unsigned char *data,unsigned char len);
CanFrmPtr GetRFrame() { return (CanFrmPtr)&m_RecvFrame; }
private:
unsigned short m_buflen; // m_anaBuf data len
unsigned char m_anaBuf[MAX_BUFLEN]; // 接收到等待分析的数据命令
CanFrame m_RecvFrame, m_SendFrame; // 最后一次接收或发送的数据包
};
extern CanProto gCanProto;
#endif// __CANPROTO_DEF_H
int m_fd;//socket打开句柄
void * Send_Pthread(void *p) //线程发送函数
{
CanFrame cf[2]= {{0}};
// CanFrame cf;
cf[0].canID = 0x00000010 | CAN_RTR_FLAG;
cf[1].canID = 0x00000011 | CAN_RTR_FLAG;
cf[0].len = 8;
cf[1].len = 8;
//cf[0].data = 0x10;
while(1){
int ret = write(m_fd,&cf[0],sizeof(cf[0]));
if(ret!=sizeof(cf[0])){
printf("write Error cf[0]\n");
}
usleep(50000);
int ret1 = write(m_fd,&cf[1],sizeof(cf[1]));
if(ret1!=sizeof(cf[1])){
printf("write Error cf[1]\n");
}
usleep(50000);
}
return NULL;
}
void CanProto::printf_frame(unsigned int frame_id,unsigned char *data,unsigned char lea)//处理打印函数
{
char buf[128] = {0};
int i=0,j=0;
int check;
check = Hex_Int(frame_id);
if(check == 16){
for(i == 0 ;data && i<lea && i<8;i++){
j += sprintf(buf+j,"%02X",data[i]);
//status_id_10(i,data);
}
}
else if(check == 17){
for(i == 0 ;data && i<lea && i<8;i++){
j += sprintf(buf+j,"%02X",data[i]);
// status_id_11(i,data);
}
}
else if(check == 2){
for(i == 0 ;data && i<lea && i<8;i++){
j += sprintf(buf+j,"%02X",data[i]);
// status_id_01(i,data);
}
}
else if(check == 1){
printf("-----\n");
for(i == 0 ;data && i<lea && i<8;i++){
printf("-----%d,,,\n",i);
j += sprintf(buf+j,"%02X",data[i]);
// status_id_01(i,data);
}
}
// m_pUI->OnHostStatus(byte_data,leg);
printf("ID=0x%X DLE=%d data=%s ,check=%d\n",frame_id,lea,buf,check);
leg=0;
len=0;
}
void * CanProto::Receive_Pthread(void *p)//线程接收
{
CanFrame frame;
unsigned char *precvframe = (unsigned char *)&frame;
const int can_frame_len = sizeof(CanFrame);
int maxfd,ret;
fd_set rfds;
struct timeval timeout;
timeout.tv_sec = 0;
memset(&frame,0x00,sizeof(frame));
while(1) {
FD_ZERO(&rfds);
FD_SET(m_fd,&rfds);
timeout.tv_usec = 8000;
memset(precvframe,0x00 ,can_frame_len);
maxfd = m_fd +1;
if((ret = select(maxfd,&rfds,NULL,NULL,&timeout)) < 0 ){
PERROR("select");
}
if(ret > 0){
int ret = read(m_fd,(char*)precvframe,can_frame_len);
printf("ret = %d\n",ret);
((CanProto *)p)->printf_frame(frame.canID,frame.data,frame.len);
}
}
}
int CanProto::Start(void)
{
int rdlen;
CanDev can;
CmdProcess m_canProc;
m_fd = can.Open();
if(m_fd < 0)
return 0;
pthread_t pid;
int pidbyte = pthread_create(&pid,NULL,Send_Pthread,NULL);
pthread_t pidt;
int resepidt = pthread_create(&pidt,NULL,CanProto::Receive_Pthread,this);
return 0;
}
<pre name="code" class="cpp">int CanDev::Open(const char *dev)
{
int fd;
struct ifreq ifr;
struct sockaddr_can addr;
if((fd = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
return -1;
addr.can_family = AF_CAN;
memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
strcpy(ifr.ifr_name, dev);
if (strcmp(ANYDEV, ifr.ifr_name)) {
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
close(fd);
return -2;
}
addr.can_ifindex = ifr.ifr_ifindex;
}
else
addr.can_ifindex = 0; /* any can interface */
PFUNC("canifindex=%d %s \n", addr.can_ifindex, ANYDEV);
if (!addr.can_ifindex) {
PERROR("Get can interface\n");
close(fd);
return -3;
}
// setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
PERROR("can bind ERROR\n");
close(fd);
return -4;
}
m_fd = fd;
return fd;
}
上面的程序不可以运行,仅供参考发送和接收,完整的程序可以运行的