c_cpp CAN设备远程通信
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp CAN设备远程通信相关的知识,希望对你有一定的参考价值。
/* 定义通信报文类型 */
struct car_frame{
short int head; //报文头
short int identification; //报文标识
/* 手机APP */
short int Left; //左转
short int Right; //右转
short int Brake; //刹车
short int Accelerator; //油门
short int Gear; //档位
short int EmergencyBrake; //紧急制动
short int Lock; //车门锁定
int Window; //车窗调节
short int Flag; //遥控标志位
unsigned int AccAim; //车辆加速度
/* 模拟驾驶舱 */
short int CarID; //车辆ID
int Speed; //控制速度
int Angle; //方向盘转角
// short int Flag; //遥控标志位
unsigned short CheckBit; //校验位
};
#include <can_config.h>
#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <linux/can.h>
#include <linux/can/raw.h>
/* 通信相关协议 */
#include <can_socket.h>
extern int optind, opterr, optopt;
static int s = -1;
static int running = 1;
enum {
VERSION_OPTION = CHAR_MAX + 1,
FILTER_OPTION,
};
static void sigterm(int signo)
{
running = 0;
}
static struct can_filter *filter = NULL;
static int filter_count = 0;
/* 定义全局报文 */
struct car_frame send_frame ;
struct car_frame recv_frame;
int add_filter(u_int32_t id, u_int32_t mask);
#define BUF_SIZ (255)
int main(int argc, char **argv)
{
//修改部分
struct sockaddr_in server_addr_in;
int cfd; //创建Socket描述符
int port = 1234;
struct ifreq ifr;
struct sockaddr_can addr;
FILE *out = stdout; //文件输出
char *interface = "can0";
char *optout = NULL;
char *ptr;
char buf[BUF_SIZ];
int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW;
int n = 0, err;
int nbytes, i, j;
int opt, optdaemon = 0;
int canID_flag; //不同类型帧标志位
struct can_frame frame = {
.can_id = 1,
};
struct can_frame Final_CAN = {
.can_id = 1,
}; //最终发送CAN报文
int flag = 1;
__u8 temp_buf[15] = {0};
int s, ret,dlc = 0, rtr = 0, extended = 0;
__u8* r_temp;
__u8 temp[7] = {0}; //存储待转换的数值和转换后的数值
__u8 bin_frame[64];
uint32_t id, mask;
signal(SIGPIPE, SIG_IGN);
/* 网络Socket建立连接 */
cfd = socket( AF_INET, SOCK_STREAM, 0 ); //创建Socket连接
bzero( &server_addr_in, sizeof(server_addr_in) );
server_addr_in.sin_family = AF_INET;
server_addr_in.sin_port = htons(port);
inet_pton( AF_INET, "118.25.187.160", &server_addr_in.sin_addr );
if (optind != argc)
interface = argv[optind];
printf("interface = %s, family = %d, type = %d, proto = %d\n",
interface, family, type, proto);
/* 本地CAN设备的Socket连接 */
if ((s = socket(family, type, proto)) < 0) {
perror("socket");
return 1;
}
addr.can_family = family;
strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFINDEX, &ifr)) {
perror("ioctl");
return 1;
}
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
return 1;
}
if (filter) {
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, filter,
filter_count * sizeof(struct can_filter)) != 0) {
perror("setsockopt");
exit(1);
}
}
if (optdaemon)
daemon(1, 0);
else {
signal(SIGTERM, sigterm);
signal(SIGHUP, sigterm);
}
if (optout) {
out = fopen(optout, "a");
if (!out) {
perror("fopen");
exit (EXIT_FAILURE);
}
}
//修改部分,实现网络Socket连接
if(connect( cfd, (struct sockaddr *)&server_addr_in, sizeof(server_addr_in) ) < 0){
printf("can't connect to server!\n");
exit(1);
}
printf("Connecting success!\n");
while (1) {
if(flag){ //进行时间片轮转
//-------------------------------------------------------------------
//开发板-->服务器
//-------------------------------------------------------------------
if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) {
perror("read");
return 1;
}
if (frame.can_id & CAN_EFF_FLAG)
n = snprintf(buf, BUF_SIZ, "<0x%08x> ", frame.can_id & CAN_EFF_MASK);
else {
n = snprintf(buf, BUF_SIZ, "<0x%03x> ", frame.can_id & CAN_SFF_MASK);
}
n += snprintf(buf + n, BUF_SIZ - n, "[%d] ", frame.can_dlc);
//----------------------------------------------
//报文修改
//----------------------------------------------
//汽车方向盘转角
send_frame.Angle = (frame.data[7] + (frame.data[6]<<8) )*0.01;
//汽车加速度
send_frame.AccAim = frame.data[5]*0.05-7;
printf("send_frame.Angle = %d\n",send_frame.Angle);
printf("send_frame.AccAim = %d\n",send_frame.AccAim);
send(cfd,&send_frame,sizeof(send_frame),0);
n = 0;flag = 0;
}
else {
//-------------------------------------------------------------------
//服务器-->开发板
//-------------------------------------------------------------------
if((recv(cfd,&recv_frame,sizeof(recv_frame),0)) < 0){
printf("Error comes when receive data\n");
exit(1);
}
//----------------------------------------------
//报文修改
//----------------------------------------------
printf("recv_frame.Angle = %d\n",recv_frame.Angle);
printf("recv_frame.AccAim = %d\n",recv_frame.AccAim);
//汽车方向盘转角
temp[7] = (recv_frame.Angle)*100 & 0xff;
temp[6] = ((recv_frame.Angle)*100)>>8 & 0xf;
//汽车加速度
temp[5] = (recv_frame.AccAim)*20 +7;
dlc = 0;
for(i = 0;i < 8 ; i ++){
Final_CAN.data[dlc++] = temp[i];
if(dlc == 8)
break;
}
memset(temp,0,sizeof(temp));
memset(&recv_frame,0,sizeof(recv_frame));
Final_CAN.can_dlc = dlc;
Final_CAN.can_id &= CAN_SFF_MASK;
//往CAN设备写数据
ret = write(s,&Final_CAN,sizeof(Final_CAN));
if(ret == -1){
perror("write");
break;
}
flag = 1;
}
}
close(cfd);
exit (EXIT_SUCCESS);
}
int add_filter(u_int32_t id, u_int32_t mask)
{
filter = realloc(filter, sizeof(struct can_filter) * (filter_count + 1));
if(!filter)
return -1;
filter[filter_count].can_id = id;
filter[filter_count].can_mask = mask;
filter_count++;
printf("id: 0x%08x mask: 0x%08x\n",id,mask);
return 0;
}
以上是关于c_cpp CAN设备远程通信的主要内容,如果未能解决你的问题,请参考以下文章