CAN-200  1.3.1
test-write.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 <getopt.h>
#include "can200_api.h"
#define EOK 0
int main(int argc, char *argv[])
{
//Пример асинхронной записи данных для платы CAN200
int device = -1; /* Номер платы */
int speed = -1; /* Скорость */
int type = -1; /* Тип выдаваемых кадров */
CAN_data frame; /* Принятый кадр */
int hCan; /* Хэндл платы */
int result; /* Статус завершения операции */
int i; /* Счетчик цикла */
char name[256]; /* Имя платы */
struct CAN_info_t conf; /* Информация о плате CAN200 */
fd_set wfd; /* Для select */
struct timeval tv; /* Тайм-аут */
int status; /* Статус окончания выдачи */
int len; /* Оставшаяся длина выдаваемых данных */
while (-1 != (result = getopt(argc, argv, "d:s:t:")))
{
switch (result)
{
case 'd':
{
/* Номер платы CAN200 */
device = atoi(optarg);
break;
}
case 's':
{
/* Скорость обмена */
speed = atoi(optarg);
}
case 't':
{
/* Тип выдаваемых кадров */
if (0 == strcmp(optarg, "BasicCAN"))
{
type = BasicCAN;
}
if (0 == strcmp(optarg, "PeliCAN"))
{
type = PeliCAN;
}
}
default:
{
break;
}
}
}
if ((device < 0) || (speed < 0) || (type < 0))
{
printf("Use test_write -d <number_device> -s <speed (10, 20, 50, 125, 250, 500, 8000, 1000)> -t <type (BasicCAN, PeliCAN)>\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_SetCANSpeed(hCan, (unsigned int)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;
}
frame.type = (unsigned char)type;
frame.dlc = 0;
frame.rtr = 0;
frame.id = 0;
for (i = 0; i < 8; i++)
{
frame.data[i] = 0;
}
// Имитация kbhit, цикл до ввода любого символа
while (1)
{
FD_ZERO(&wfd);
FD_SET(hCan, &wfd);
tv.tv_sec = 0;
tv.tv_usec = 100000; /* 100 ms */
result = select(1 + hCan, NULL, &wfd, 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, &wfd))
{
/* Вызов CAN200_GetTransmitStatus приведен для примера */
/* В данной точке программы очередь выдачи пуста */
result = CAN200_GetTransmitStatus(hCan, &status, &len);
if (EOK != result)
{
printf("Error SetDriverMode (%d, %s).\n", result, strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
if ((CAN_TRANSMIT_COMPLETE != status) && (CAN_TRANSMIT_WAIT != status))
{
printf("Error transmit, status = %d\n", status);
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
// Выдача
if (-1 == write(hCan, &frame, sizeof(CAN_data)))
{
printf("Error write (%s)\n", strerror(errno));
// Закрываем плату
close(hCan);
return EXIT_FAILURE;
}
frame.dlc = (unsigned char)((frame.dlc + 1) % 9);
if (PeliCAN == type)
{
frame.id = (frame.id + 1) % 0x20000000;
}
else
{
frame.id = (frame.id + 1) % 0x800;
}
for (i = 0; i < 8; i++)
{
frame.data[i] = (unsigned char)((frame.data[i] + 1) % 0x100);
}
sleep(1);
}
}
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.