CAN-200  1.4.0
test-read.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <termios.h>
#include "can200_api.h"
int main(int argc, char *argv[])
{
//Пример асинхронного чтения данных для платы CAN200
int device = -1; /* Номер платы */
int speed = -1; /* Скорость */
CAN_data frame; /* Принятый кадр */
int hCan; /* Хэндл платы */
int result; /* Статус завершения операции */
int i; /* Счетчик цикла */
char name[256]; /* Имя платы */
struct CAN_info_t conf; /* Информация о плате CAN200 */
fd_set rfd; /* Для select */
struct timeval tv; /* Тайм-аут */
while (-1 != (result = getopt(argc, argv, "d:s:")))
{
switch (result)
{
case 'd':
{
/* Номер платы CAN200 */
device = atoi(optarg);
break;
}
case 's':
{
/* Скорость обмена */
speed = atoi(optarg);
}
default:
{
break;
}
}
}
if ((device < 0) || (speed < 0))
{
printf("Use test_read -d <number_device> -s <speed (10, 20, 50, 125, 250, 500, 8000, 1000)>\n");
return EXIT_FAILURE;
}
// Скорость
if (CAN_SPEED_1000 != speed && CAN_SPEED_800 != speed &&
CAN_SPEED_500 != speed && CAN_SPEED_250 != speed &&
CAN_SPEED_125 != speed && CAN_SPEED_50 != speed &&
CAN_SPEED_20 != speed && CAN_SPEED_10 != speed)
{
printf("Unexpected speed #%d (expected %d or %d or %d or %d or %d or %d or %d or %d)\n", speed,
return -1;
}
/* Открываем плату */
sprintf(name, "/dev/can200_%d", device);
hCan = open(name, O_RDWR | O_NONBLOCK);
if (-1 == hCan)
{
printf("Error open /dev/can200_%d (%s)\n", device, strerror(errno));
return EXIT_FAILURE;
}
// Читаем конфигурацию платы
result = CAN200_GetConfig(hCan, &conf);
if (EOK != result)
{
printf("Error GetConfig (%d, %s).\n", result, strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
printf("Board: %s\n", conf.szName);
printf("Serial num.: %s\n", conf.szSN);
printf("Base port: %Xh\n", conf.wPorts);
printf("IRQ: %.2d\n\n", conf.wIRQ);
// Режим работы - PeliCAN
result = CAN200_SetWorkMode(hCan, PeliCAN);
if (EOK != result)
{
printf("Error CAN200_SetWorkMode (%d, %s).\n", result, strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
// Настройка входного фильтра на прием всех кадров
result = CAN200_P_SetFilter(hCan, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
if (EOK != result)
{
printf("Error P_SetInputFilter (%d, %s).\n", result, strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
// Настройка скорости
result = CAN200_SetCANSpeed(hCan, speed);
if (EOK != result)
{
printf("Error SetCANSpeed (%d, %s).\n", result, strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
// Переводим плату в рабочий режим
result = CAN200_SetDriverMode(hCan);
if (EOK != result)
{
printf("Error SetDriverMode (%d, %s).\n", result, strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
printf("Waiting....\n");
// Имитация kbhit, цикл до ввода любого символа
while (0 == tcischars(fileno(stdin)))
{
FD_ZERO(&rfd);
FD_SET(hCan, &rfd);
tv.tv_sec = 0;
tv.tv_usec = 100000; /* 100 ms */
result = select(1 + hCan, &rfd, NULL, NULL, &tv);
if (-1 == result)
{
printf("Error select (%s)\n", strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
if (0 == result)
{
/* Тайм-аут */
continue;
}
if (FD_ISSET(hCan, &rfd))
{
result = read(hCan, &frame, sizeof(CAN_data));
if (-1 == result)
{
printf("Error read (%s)\n", strerror(errno));
return EXIT_FAILURE;
}
if (0 == result)
{
continue;
}
if ((BasicCAN != frame.type) && (PeliCAN != frame.type))
{
/* Кадр ошибки */
printf("Error frame receive\n");
printf("mode = %Xh\n", frame.data[0]);
printf("status = %Xh\n", frame.data[1]);
printf("error code = %Xh\n", frame.data[2]);
printf("lost capture = %Xh\n", frame.data[3]);
continue;
}
// Приняли пакет
printf("Receive frame:\n");
if (BasicCAN == frame.type)
{
printf("\tStandart ID = %.3lXh\n", frame.id);
}
else
{
printf("\tExtended ID = %lXh\n", frame.id);
}
printf("\tRTR = %.1d\n", frame.rtr);
printf("\tDLC = %.1d\n", frame.dlc);
for (i = 0; i < frame.dlc; i++)
{
printf("\tDatabyte = %.2Xh\n", (int)frame.data[i]);
}
}
}
result = close(hCan);
if (-1 == result)
{
printf("Error close (%s)\n", strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

CAN-200 documentation. Copyright (c) 2012 - 2017 Elcus Corporation. All rights reserved.