//g++ can.cpp -lrt -o can
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <error.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/time.h>
#define CAN_ID 0x1
int socket_fd = -1;
struct can_frame frame_send, frame_recv;
//事件1
void timeout1(int sig)
{
struct timespec mytime;
int nbytes;
if(socket_fd == -1) return;
clock_gettime(CLOCK_REALTIME, &mytime);
printf("write time:%lds %ldns\n",mytime.tv_sec,mytime.tv_nsec);
nbytes = write(socket_fd, &frame_send, sizeof(struct can_frame));//发送
if(nbytes > 0)
{
printf("Send:ID=0x%X DLC=%d Data ", frame_send.can_id,frame_send.can_dlc);
for(int i=0;i<sizeof(frame_send.data)/sizeof(frame_send.data[0]);i++){
printf("%X ",frame_send.data[i]);
}
printf("\n");
}
}
void create_timer_by_signal(void)
{
static timer_t times;
struct itimerspec ts; //用于配置定时器时间
struct timespec now; //获取linux系统时间
struct sigevent evp;
evp.sigev_notify = SIGEV_SIGNAL;
evp.sigev_signo = SIGUSR1;
evp.sigev_value.sival_ptr = ×
evp.sigev_notify_attributes = NULL;
timer_create(CLOCK_REALTIME, &evp, ×);
//第一次调用时间
ts.it_value.tv_sec = 1;
ts.it_value.tv_nsec = 0;
//第一次调用后,每次调用间隔时间
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 100000000;//100ms
signal(SIGUSR1, &timeout1);
timer_settime(times, 0, &ts, NULL);
}
void settime_alarm(void)
{
static struct itimerval tick;
signal(SIGALRM, &timeout1);
memset(&tick, 0, sizeof(tick));
//第一次调用时间
tick.it_value.tv_sec = 1;
tick.it_value.tv_usec = 0;
//第一次调用后,每次调用间隔时间
tick.it_interval.tv_sec = 0;
tick.it_interval.tv_usec = 100000;//100ms
if(setitimer(ITIMER_REAL, &tick, NULL) < 0)
{
printf("Set timer failed!\n");
}
}
int main(void)
{
frame_send.can_id = 0x123;
frame_send.can_dlc = 8;
frame_send.data[0] = 0x11;
frame_send.data[1] = 0x11;
frame_send.data[2] = 0x22;
frame_send.data[3] = 0x33;
frame_send.data[4] = 0x44;
frame_send.data[5] = 0x55;
frame_send.data[6] = 0x66;
frame_send.data[7] = 0x77;
int nbytes;
struct sockaddr_can addr;
struct ifreq ifr;
struct timespec mytime;
if((socket_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
//create_timer_by_signal();
settime_alarm();
const char *ifname = "can0";
strcpy(ifr.ifr_name, ifname);
ioctl(socket_fd, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
printf("%s at index %d\n", ifname, ifr.ifr_ifindex);
if(bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error in socket bind");
return -2;
}
while(1)
{
nbytes = read(socket_fd, &frame_recv, sizeof(struct can_frame)); //接收报文
if(CAN_ID != frame_recv.can_id) continue;
//显示报文
if(nbytes > 0)
{
clock_gettime(CLOCK_REALTIME, &mytime);
printf("read time:%lds---%ldns\n",mytime.tv_sec,mytime.tv_nsec);
printf("Recv:ID=0x%X DLC=%d Data ", frame_recv.can_id, frame_recv.can_dlc);
for(int i=0;i<sizeof(frame_recv.data)/sizeof(frame_recv.data[0]);i++){
printf("%X ",frame_recv.data[i]);
}
printf("\n");
}
}
return 0;
}
带有定时器发送的Linux CAN收发
于 2022-10-10 09:54:40 首次发布