[ADD] can driver

This commit is contained in:
xudx 2024-11-13 15:16:23 +08:00
parent 6332f6b17d
commit d92ffe2966
2 changed files with 334 additions and 0 deletions

View File

@ -0,0 +1,301 @@
#include "drv_can.h"
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <termios.h> /*PPSIX 终端控制定义*/
#include "drv_can.h"
/*
* @description :
* @param - *destpoint :
* @param - *fmt :
* @return :
*/
char func_dprintf(char *destpoint, char *fmt, ...)
{
va_list arg_ptr;
char ulen, *tmpBuf;
tmpBuf = destpoint;
va_start(arg_ptr, fmt);
ulen = vsprintf(tmpBuf, fmt, arg_ptr);
va_end(arg_ptr);
return ulen;
}
/*
* @description : can外设
* @param - *device :
* @param - para : can应用参数
* @return : -1
*/
int func_open_can(char *device, struct_can_param para)
{
FILE *fstream = NULL;
char buff[300] = {0}, command[50] = {0};
int fd = -1;
struct sockaddr_can addr;
struct ifreq ifr;
/*关闭can设备 ifconfig can0 down*/
memset(buff, 0, sizeof(buff));
memset(command, 0, sizeof(command));
func_dprintf(command, "ifconfig %s down", device);
printf("%s \n", command);
if (NULL == (fstream = popen(command, "w")))
{
fprintf(stderr, "execute command failed: %s", strerror(errno));
}
while (NULL != fgets(buff, sizeof(buff), fstream))
{
printf("%s\n", buff);
if (strstr(buff, "No such device") || strstr(buff, "Cannot find device"))
return -1;
}
pclose(fstream);
sleep(1);
/*设置can波特率 ip link set can0 up type can bitrate 250000 triple-sampling on*/
memset(buff, 0, sizeof(buff));
memset(command, 0, sizeof(command));
if (para.loopback_mode == 1)
{
func_dprintf(command, "ip link set %s up type can bitrate %d triple-sampling on loopback on", device, para.baudrate);
}
else
{
func_dprintf(command, "ip link set %s up type can bitrate %d triple-sampling on loopback off", device, para.baudrate);
}
printf("%s \n", command);
if (NULL == (fstream = popen(command, "w")))
{
fprintf(stderr, "execute command failed: %s", strerror(errno));
}
while (NULL != fgets(buff, sizeof(buff), fstream))
{
printf("%s\n", buff);
if (strstr(buff, "No such device") || strstr(buff, "Cannot find device"))
return -1;
}
pclose(fstream);
sleep(1);
/*打开can设备 ifconfig can0 up*/
memset(buff, 0, sizeof(buff));
memset(command, 0, sizeof(command));
func_dprintf(command, "ifconfig %s up", device);
printf("%s \n", command);
if (NULL == (fstream = popen(command, "w")))
{
fprintf(stderr, "execute command failed: %s", strerror(errno));
}
while (NULL != fgets(buff, sizeof(buff), fstream))
{
printf("%s\n", buff);
if (strstr(buff, "No such device") || strstr(buff, "Cannot find device"))
return -1;
}
pclose(fstream);
sleep(3);
/* 创建 socket */
fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (fd < 0)
{
printf("socket:%s", strerror(errno));
return -1;
}
/* 设置接口设备名称 */
strcpy(ifr.ifr_name, device);
/* 确定接口 index */
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
{
printf("SIOCGIFINDEX:%s\n", strerror(errno));
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
/* 绑定 socket到 CAN 接口 */
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
printf("bind:%s\n", strerror(errno));
return -1;
}
return fd;
}
/*
* @description : can回环模式和过滤规则
* @param - fd :
* @param - para: can应用参数
* @return : 1-1
*/
int func_set_can(int fd, struct_can_param para)
{
int loopback = 1;
int reciveown = 1;
if (para.loopback_mode == 1)
{
//回环设置 0 关闭回环 1 打开回环
setsockopt(fd, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));
//接收自己的帧 0 不接收自己帧 1 接收自己帧
setsockopt(fd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &reciveown, sizeof(reciveown));
}
/* 设置过滤规则 */
if (setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &para.filter, sizeof(para.filter)) < 0)
{
printf("error when set filter\n");
return -1;
}
return 1;
}
/*
* @description : can接收一个can帧
* @param - fd :
* @param - *pframe: can帧结构体指针
* @return :
*/
int func_receive_can_frame(int fd, struct can_frame *pframe)
{
int rx_count = 0;
rx_count = recv(fd, pframe, sizeof(*pframe), 0);
if (rx_count <= 0)
{
return rx_count;
}
else
{
if (pframe->can_id & CAN_EFF_FLAG) /*如果是扩展帧,清除扩展帧标识*/
{
pframe->can_id &= (~CAN_EFF_FLAG);
}
else
{
pframe->can_id &= (~CAN_SFF_MASK);
}
}
return pframe->can_dlc;
}
/*
* @description : can接收一组数据包
* @param - fd :
* @param - *buff: can一组数据的缓冲区首指针
* @param - len :
* @return :
*/
int func_receive_can_buff(int fd, unsigned char *buff, int len)
{
int receive_len = 0, total_receive_len = 0;
struct can_frame frame;
int i = 0;
while (1)
{
receive_len = func_receive_can_frame(fd, &frame);
for (i = 0; i < receive_len; i++)
{
*(buff + total_receive_len) = frame.data[i];
total_receive_len++;
}
if ((receive_len < 8) || (total_receive_len > (len - 8)))
{
return total_receive_len;
}
}
return total_receive_len;
}
/*
* @description : can发送一个can帧
* @param - fd :
* @param - *pframe: can帧结构体指针
* @param - param : can应用参数
* @return : -1
*/
int func_send_can_frame(int fd, struct can_frame *pframe, struct_can_param param)
{
int result = 0;
if (param.extend == 1) /*扩展帧增加扩展帧标志*/
{
pframe->can_id &= CAN_EFF_MASK;
pframe->can_id |= CAN_EFF_FLAG;
}
else
{
pframe->can_id &= CAN_SFF_MASK;
}
result = send(fd, pframe, sizeof(struct can_frame), 0);
if (result == -1)
{
printf("send:%s\n", strerror(errno));
return -1;
}
return result;
}
/*
* @description : can发送一组数据包
* @param - fd :
* @param - *buff: can一组数据的缓冲区首指针
* @param - len :
* @param - param: can应用参数
* @return :
*/
int func_send_can_buff(int fd, unsigned char *buff, int len, struct_can_param param)
{
int remain_frame_len = 0, frame_numb = 0;
struct can_frame frame;
int i = 0;
remain_frame_len = len;
while (1)
{
if (remain_frame_len >= 8)
{
frame.can_dlc = 8; /*填充发送长度*/
remain_frame_len -= 8; /*剩余数据长度*/
}
else
{
frame.can_dlc = remain_frame_len; /*填充发送长度*/
remain_frame_len = 0; //
}
frame.can_id = param.id; /*填充发送id*/
for (i = 0; i < frame.can_dlc; i++)
{
frame.data[i] = buff[frame_numb * 8 + i]; /*填充发送数据*/
}
func_send_can_frame(fd, &frame, param);
frame_numb++;
if (remain_frame_len == 0)
{
return len;
}
}
return len;
}

View File

@ -0,0 +1,33 @@
#ifndef __DRV_CAN_H_
#define __DRV_CAN_H_
#include <linux/can.h>
#define CAN_MODE 0
#define CAN_FD_MODE 1
#define _DEFAULT_SOURCE
/*CAN口参数结构体 */
typedef struct
{
unsigned long baudrate; /*波特率 5k~1000k*/
unsigned int id; /*设备ID*/
struct can_filter filter; /*接收设备过滤ID*/
unsigned char extend; /*扩展ID*/
unsigned char loopback_mode; /*回环模式*/
unsigned char canfd_mode; /*CANFD模式*/
unsigned long data_baudrate; /*CANFD模式下需要单独设置数据波特率*/
} struct_can_param;
int func_open_can(char *device, struct_can_param para);
int func_set_can(int fd, struct_can_param para);
int func_receive_can_buff(int fd, unsigned char *buff, int len);
int func_send_can_buff(int fd, unsigned char *buff, int len, struct_can_param param);
// int func_open_canfd(char *device, struct_can_param para);
// int func_set_canfd(int fd, struct_can_param para);
// int func_receive_canfd_buff(int fd, unsigned char *buff, int len);
// int func_send_canfd_buff(int fd, unsigned char *buff, int len, struct_can_param param);
#endif