работа с can

Расскажите, как работать с CAN шиной?

вот тут http://www.armadeus.com/wiki/index.php?title=CAN_bus_Linux_driver неплохо написано. Понадобится собрать или скачать can-utils

спасибо, скомлирировал can-tools - candump & cansend прекрасно работают
так же скомпилировать socketcand
пускается, если подключаться и подписываться, либо просто мониторить в raw режиме - работает
но как только пытаюсь что то отправить (add) - весь девайс напрочь виснет…

походу толи can модуль кривой, толи модули ядра, то работает дико нестабильно…
написал простенькую прогу на чистом С, которая каждые 100 мсек шлёт can посылку…
хватает меньше чем на сотню посылок, потом ничего не отправляется… т.е. сокет то радостно говорит что мол всё ок, но из интерфейса уже ничего не вылетает… ip -details -statistics link show can0 говорит что счётчики не меняются… да и candump перестаёт что то показывать…
помогает ребут, а дальше всё по новой… воспроизводилось 100%…
не могли бы разработчики поправить ситуацию с каном? а то функциональность заявлена, а работает дико нестабильно…

собственно чтобы другие могли проверить, вот тестовая прога:

инициализируем интерфейс:
modprobe can
modprobe can-raw
modprobe can-bcm
ifconfig can0 down
ip link set can0 type can bitrate 250000
ifconfig can0 up

и компилируем такой код

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include <linux/can.h>
#include <linux/can/raw.h>

int main(int argc, char *argv)
{
int s; /
can raw socket */
struct ifreq ifr;
struct sockaddr_can addr;
struct canfd_frame frame;
unsigned short send_frame = 0;

/* open socket */
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) &lt; 0) {
	perror("socket");
	return 1;
}

addr.can_family = AF_CAN;

strcpy(ifr.ifr_name, "can0");
if (ioctl(s, SIOCGIFINDEX, &amp;ifr) &lt; 0) {
	perror("SIOCGIFINDEX");
	return 1;
}
addr.can_ifindex = ifr.ifr_ifindex;

/* disable default receive filter on this RAW socket */
/* This is obsolete as we do not read from the socket at all, but for */
/* this reason we can remove the receive list in the Kernel to save a */
/* little (really a very little!) CPU usage.                          */
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);

if (bind(s, (struct sockaddr *)&amp;addr, sizeof(addr)) &lt; 0) {
	perror("bind");
	return 1;
}

frame.can_id = 0x18FEEE00 | CAN_EFF_FLAG;
frame.len = 8;
frame.data[0] = 0x4C;
frame.data[1] = 0x34;
frame.data[2] = 0x69;
frame.data[3] = 0xCF;
frame.data[4] = 0xFF;
frame.data[5] = 0xFF;
	
while ( 1 ) {
	/* to control from candump packet number we stuck on */
	frame.data[6] = send_frame / 256;
	frame.data[7] = send_frame % 256;

	/* send frame */
	if (write(s, &amp;frame, CAN_MTU) != CAN_MTU)
		perror("write");
	else
		fprintf(stdout,"frame %d ok\n", send_frame);
	send_frame++;
	usleep(250*1000);
}			

close(s);

return 0;

}

потом смотрим candump -c -c -ta can0
у меня стабильно пропадает всё напрочь…

да, режим BCM (BroadCastManager) в принципе не работает…
так что похоже ядерные модули кривые…

  • нет поддержки vcan…

комментарии какие нибудь будут? или и не ждать?

Добрый день,

попробуем посмотреть, проблема видимо в драйвере. У нас там стандартное mainline ядро, соответственно все вопросы про это не к нам.

Самое лучшее, что сейчас можно сделать - это поискать в интернете по спискам рассылок linux kernel эти проблемы, и посмотреть по коммитам в драйвер, не появилось ли за последние пару месяцев каких-нибудь фиксов.
Если не поможет - то чинить самим или оформлять багрепорт в ядро. С последним точно поможем.

Проверьте у себя, код я привёл…
после cold boot у меня умирает в районе 845 посылки, точнее ни разу не видел больше (последние два байта в посылке это её номер для тестов)
я с линуксом не особо, поэтому подожду от вас, как от разработчиков продукта, решения…

Чувствую не дождетесь, похоже всем проектом занимается один Evgeny Boger и то левой ногой.
Не взлетела железняка похоже, у меня вот лежит на полке. Знаний что бы писать что то самому не хватает, а готовых решений для существующего железа просто нет, как и заинтересованного сообщества.

Jager, комьюнити у нас конечно не очень большое и это печально, но проектом занимаюсь далеко не я один - я просто на форуме один за всех пишу :slight_smile: Буду признателен, если вы напишите из-за чего конкретно пришлось отправить железку на полку - возможно всё-таки чем-то мы сможем помочь. Лучше в отдельную ветку на форуме или мне на почту (boger@contactless.ru).

HighTower, судя по всему подобные проблемы с CAN (этот же контроллер) наблюдал народ на raspberry pi.
Вот подробнее:
http://elinux.org/RPi_CANBus
http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=7027&start=500

Недавно появился альтернативный драйвер (https://github.com/msperl/mcp2515a), который похоже работает сильно лучше. Можете попробовать собрать ядро с ним.

Как я писал выше - с линуксом не очень, к сборке ядер пока не готов… и как я понял тут не само ядро нужно собирать, а только один модуль… не могли бы вы его скомпилировать и выложить, а я бы протестировал…

собрал
https://github.com/contactless/wirenboard/tree/master/contrib/kernel/test_can_mcp2515a - тут ядро, dtbs + отдельно модуль.
Скриптик для копирования ядра есть на уровень выше.

ещё потом модуль надо в правильное место положить, потом выгрузить старый и загрузить новый (см README там же).

Работоспособность не проверял.

хех… сдуру взял 3.13.0-imxv5-x0.1-modules.tar.gz и заменил его содержимым исходные модули… оказалось сильно зря, очень сильно…
в итоге система перестала грузиться…
через дебаг вижу
Synthesizing the initial hot plug events…
[ 8.430000] cn: disagrees about version of symbol __nlmsg_put
[ 8.440000] cn: Unknown symbol __nlmsg_put (err -22)
[ 8.490000] cn: disagrees about version of symbol __netlink_kernel_create
и далее по списку, в итоге ни один модуль не подгружается… lsmod выдаёт пустой список…
я в печали…

Заменить надо всё, не только модули но и ядро. Там несколько архивов должно лежать, нужны все.

Евгений,
просто все из архивов накатить и перезагрузить?

У меня устройство на удаленном подключении, страшшновато :slight_smile:

да, так, главное в правильные места.
Ethernet в любом случае не отпадёт, так что проблем быть не должно.

помог ли другой модуль?

итак, после долгого перерыва продолжил…
не грузится новый модуль…
ситуация сразу после старта

root@wirenboard:~# lsmod
Module                  Size  Used by
sc16is7x2              10782  0 
rtl8192cu              96271  0 
rtl_usb                14208  1 rtl8192cu
rtlwifi                88715  2 rtl_usb,rtl8192cu
rtl8192c_common        65331  1 rtl8192cu
smsc95xx               19171  0 
mcp251x                10745  0 
can_dev                10091  1 mcp251x
w1_gpio                 2946  0 
wire                   25336  1 w1_gpio
cn                      4802  1 wire

делаю

root@wirenboard:~# modprobe -r mcp251x
[  234.870000] waiting module removal not supported: please upgrade
[  234.960000] waiting module removal not supported: please upgrade

ок, разбиваю на шаги

root@wirenboard:~# modprobe -r can_dev
root@wirenboard:~# 
root@wirenboard:~# modprobe -r mcp251x
root@wirenboard:~# 
root@wirenboard:~# lsmod
Module                  Size  Used by
sc16is7x2              10782  0 
rtl8192cu              96271  0 
rtl_usb                14208  1 rtl8192cu
rtlwifi                88715  2 rtl_usb,rtl8192cu
rtl8192c_common        65331  1 rtl8192cu
smsc95xx               19171  0 
w1_gpio                 2946  0 
wire                   25336  1 w1_gpio
cn                      4802  1 wire

гружу новый - облом

root@wirenboard:~# modprobe  mcp2515a
FATAL: Module mcp2515a not found.

враньё…

root@wirenboard:# cd root@wirenboard:~# cd /lib/modules/3.13.0-imxv5-x0.1/kernel/drivers/net/can/
root@wirenboard:/lib/modules/3.13.0-imxv5-x0.1/kernel/drivers/net/can# 
root@wirenboard:/lib/modules/3.13.0-imxv5-x0.1/kernel/drivers/net/can# ls -lA
total 64
-rw-rw-r-- 1 1000 1000 18184 Sep  7  2014 can-dev.ko
-rw-r--r-- 1 root root 20260 Nov 13  2014 mcp2515a.ko
-rw-rw-r-- 1 1000 1000 21842 Sep  7  2014 mcp251x.ko
root@wirenboard:/lib/modules/3.13.0-imxv5-x0.1/kernel/drivers/net/can# modprobe mcp2515a.ko
FATAL: Module mcp2515a.ko not found.

при этом ВСЕ файлы по ссылке выше…

да, а если сделать не modprob, a insmod, то тоже ошибка, но более содержательная…

root@wirenboard:/lib/modules/3.13.0-imxv5-x0.1/kernel/drivers/net/can# insmod ./mcp2515a.ko
[13312.500000] mcp2515a: Unknown symbol open_candev (err 0)
[13312.500000] mcp2515a: Unknown symbol alloc_can_skb (err 0)
[13312.510000] mcp2515a: Unknown symbol unregister_candev (err 0)
[13312.520000] mcp2515a: Unknown symbol free_candev (err 0)
[13312.520000] mcp2515a: Unknown symbol close_candev (err 0)
[13312.530000] mcp2515a: Unknown symbol can_bus_off (err 0)
[13312.530000] mcp2515a: Unknown symbol alloc_candev (err 0)
[13312.540000] mcp2515a: Unknown symbol alloc_can_err_skb (err 0)
[13312.540000] mcp2515a: Unknown symbol register_candev (err 0)
Error: could not insert module ./mcp2515a.ko: Unknown symbol in module