1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-30 00:00:11 +01:00
VILLASnode/lib/nodes/can-test/main.c
2020-07-09 07:25:33 +02:00

189 lines
4.3 KiB
C

#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 <linux/can.h>
#include <linux/can/raw.h>
#include <stdint.h>
#include <sys/time.h>
/** An accurate timestamp can be obtained with an ioctl(2) call after reading
* a message from the socket:
*
* struct timeval tv;
* ioctl(s, SIOCGSTAMP, &tv);
*
* The timestamp has a resolution of one microsecond and is set automatically
* at the reception of a CAN frame.
*/
void can_receive_timestamp(int socket)
{
struct timeval tv;
ioctl(socket, SIOCGSTAMP, &tv);
printf("%0d:%03d:%03d s:ms:us\n", tv.tv_sec, tv.tv_usec/1000, tv.tv_usec%1000);
}
int can_receive(char *ifn)
{
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
const char *ifname = ifn;
struct timeval start, end;
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, 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(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error in socket bind");
return -2;
}
int i,j;
printf("warmup...\n");
for (j=0; j < 10; ++j) {
for (i=0; i < 1000; ++i) {
nbytes = read(s, &frame, sizeof(struct can_frame));
if (nbytes != sizeof(struct can_frame)) {
printf("ERROR: can read() error. read() returned %d\n", nbytes);
}
//can_receive_timestamp(s);
//printf("id:%d, len:%d, data: 0x%x:0x%x\n", frame.can_id,
// frame.can_dlc,
// ((uint32_t*)&frame.data)[0],
// ((uint32_t*)&frame.data)[1]);
}
}
printf("measure...\n");
int sec=0, usec=0;
for (j=0; j < 10; ++j) {
gettimeofday(&start, NULL);
for (i=0; i < 1000; ++i) {
nbytes = read(s, &frame, sizeof(struct can_frame));
}
gettimeofday(&end, NULL);
sec += end.tv_sec-start.tv_sec;
usec += end.tv_usec-start.tv_usec;
printf("%d frames in %0d:%03d:%03d s:ms:us\n", i, end.tv_sec-start.tv_sec,
(end.tv_usec-start.tv_usec)/1000,
(end.tv_usec-start.tv_usec)%1000);
}
usec=((usec + sec*1000*1000)/j) % (1000*1000);
sec /= j;
printf("average: %0d:%03d:%03d s:ms:us\n", sec, usec/1000, usec%1000);
usec=((usec + sec*1000*1000)/i) % (1000*1000);
sec /= i;
printf("average per read: %0d:%03d:%03d s:ms:us\n", sec, usec/1000, usec%1000);
return 0;
}
int can_send(char *ifn)
{
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
const char *ifname = ifn;
uint32_t high = 0, low = 0;
struct timeval start, end;
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
printf("%d,%d\n", a.tv_sec, a.tv_usec);
strcpy(ifr.ifr_name, ifname);
ioctl(s, 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(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error in socket bind");
return -2;
}
frame.can_id = 0x1;
frame.can_dlc = 8;
int i,j;
printf("warmup...\n");
for (j=0; j < 10; ++j) {
for (i=0; i < 1000; ++i) {
((uint32_t*)frame.data)[0] = high++;
((uint32_t*)frame.data)[1] = low++;
nbytes = write(s, &frame, sizeof(struct can_frame));
usleep(250);
}
}
printf("measure...\n");
int sec=0, usec=0;
for (j=0; j < 10; ++j) {
gettimeofday(&start, NULL);
for (i=0; i < 1000; ++i) {
((uint32_t*)frame.data)[0] = high++;
((uint32_t*)frame.data)[1] = low++;
nbytes = write(s, &frame, sizeof(struct can_frame));
usleep(250);
}
gettimeofday(&end, NULL);
sec += end.tv_sec-start.tv_sec;
usec += end.tv_usec-start.tv_usec;
printf("%d frames in %0d:%03d:%03d s:ms:us\n", i, end.tv_sec-start.tv_sec,
(end.tv_usec-start.tv_usec)/1000,
(end.tv_usec-start.tv_usec)%1000);
}
usec=((usec + sec*1000*1000)/j) % (1000*1000);
sec /= j;
printf("average: %0d:%03d:%03d s:ms:us\n", sec, usec/1000, usec%1000);
usec=((usec + sec*1000*1000)/i) % (1000*1000);
sec /= i;
printf("average per write: %0d:%03d:%03d s:ms:us\n", sec, usec/1000, usec%1000);
return 0;
}
int main()
{
#ifdef SEND
printf("can_send\n");
return can_send("vcan0");
#else
printf("can_receive\n");
return can_receive("vcan0");
#endif
}