由于采用ramdisk文件系统,自带的ip工具版本太旧无法配置can,需要自行编译ip,具体参见参考文献2

1.vivado配置ps

2.设备树增加can0,一般开发板均已提供此配置

can@e0008000 {
compatible = "xlnx,zynq-can-1.0";
status = "okay";
clocks = <0x1 0x13 0x1 0x24>;
clock-names = "can_clk", "pclk";
reg = <0xe0008000 0x1000>;
interrupts = <0x0 0x1c 0x4>;
interrupt-parent = <0x3>;
tx-fifo-depth = <0x40>;
rx-fifo-depth = <0x40>;
};

3.kernel配置,一般已配好,具体参见参考文献1

4.测试

# ifconfig -a
can0 Link encap:UNSPEC HWaddr ---------------
NOARP MTU: Metric:
RX packets: errors: dropped: overruns: frame:
TX packets: errors: dropped: overruns: carrier:
collisions: txqueuelen:
RX bytes: (0.0 B) TX bytes: (0.0 B)
Interrupt: eth0 Link encap:Ethernet HWaddr :0A::::
inet addr:192.168.0.120 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU: Metric:
RX packets: errors: dropped: overruns: frame:
TX packets: errors: dropped: overruns: carrier:
collisions: txqueuelen:
RX bytes: (465.3 KiB) TX bytes: (18.1 KiB)
Interrupt: Base address:0xb000 lo Link encap:Local Loopback
LOOPBACK MTU: Metric:
RX packets: errors: dropped: overruns: frame:
TX packets: errors: dropped: overruns: carrier:
collisions: txqueuelen:
RX bytes: (0.0 B) TX bytes: (0.0 B)

设置can0的波特率,这里设置的是100k, ip程序一般需要自己编译生成,参见2
#./ip link set can0 up type can bitrate 100000
显示can0状态信息
#./ip -d -s link show can0

Z-turn# ./ip link set can0 type can bitrate
xilinx_can e0008000.can can0: bitrate error 0.0%
Z-turn#./ip link set can0 up
Z-turn#./ip -d -s link show can0
: can0: <NOARP,UP,LOWER_UP,ECHO> mtu qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen
link/can promiscuity
can state ERROR-ACTIVE (berr-counter tx rx ) restart-ms
bitrate sample-point 0.750
tq prop-seg phase-seg1 phase-seg2 sjw
xilinx_can: tseg1 .. tseg2 .. sjw .. brp .. brp-inc
clock
re-started bus-errors arbit-lost error-warn error-pass bus-off
numtxqueues numrxqueues
RX: bytes packets errors dropped overrun mcast TX: bytes packets errors dropped carrier collsns

5.下面程序为收发测试,也可参见参考文献3

/*****************************************************************************
* Copyright (c) 2014-2017 MYIR Tech Ltd.
* File: can-test.c
* Date: 2014/11/3
* Author: Kevin Su
* Description: A demo program to show how to transmit/receive data with
* socket can interface on CAN bus.
* Please note that, this demo needs two boards to run as
* transmitter and receiver.
* Before run "can-test", we need to config the bitrate with
* "ip" command:
* # ip link set can0 up type can bitrate 100000
*/ #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
#include <linux/can/raw.h> #define DEBUG 1 #define ERR_MSG(fmt, args...) fprintf(stderr, fmt, ##args)
#ifdef DEBUG
#define DBG_MSG(fmt, args...) fprintf(stdout, fmt, ##args)
#else
#define DBG_MSG(fmt, args...)
#endif #ifndef PF_CAN
#define PF_CAN 29
#endif #ifndef AF_CAN
#define AF_CAN PF_CAN
#endif int main(int argc, char *argv[])
{
int fd, ret, flag, len;
char senddata[] = "test";
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
socklen_t socket_len = sizeof(struct sockaddr_can); /* Create a socket with PF_CAN family, SOCK_RAW and CAN_RAW protocol */
fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (fd < ) {
ERR_MSG("Open socket failed!\n");
return fd;
} /* Use can0 */
strcpy((char *)(ifr.ifr_name), "can0"); /* Get information */
ret = ioctl(fd, SIOCGIFINDEX, &ifr);
if (ret != ) {
ERR_MSG("SIOCGIFINDEX failed! ret:%d\n", ret);
close(fd);
return ret;
}
DBG_MSG("can0 can_ifindex = %x\n",ifr.ifr_ifindex); /* Disable loopback */
flag = ;
ret = setsockopt(fd, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &flag, sizeof(flag));
if (ret != ) {
ERR_MSG("Set loopback disable failed! ret:%d\n", ret);
close(fd);
return ret;
}
DBG_MSG("Set can0 loopback disable\n"); /* Disable receiving own message */
flag = ;
ret = setsockopt(fd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
&flag, sizeof(flag));
if (ret != ) {
ERR_MSG("Disable receiving own message failed! ret:%d\n", ret);
close(fd);
return ret;
}
DBG_MSG("Disable receiving own message\n"); /* Use AF_CAN protocol family */
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex; /* Binding socket */
ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
if (ret != ) {
ERR_MSG("Bind socket failed! ret:%d\n", ret);
close(fd);
return ret;
}
DBG_MSG("Bind can0 socket\n"); frame.can_id = 0x123;
len = strlen(senddata); while () {
strncpy((char *)frame.data, senddata, len);
frame.can_dlc = len;
ret = sendto(fd, &frame, sizeof(struct can_frame), , (struct sockaddr*)&addr, sizeof(addr));
if (ret > ) {
DBG_MSG("Send success: [%s], ret=%d\n", senddata, ret);
ret = recvfrom(fd, &frame, sizeof(struct can_frame), , (struct sockaddr *)&addr, &socket_len);
if (ret > ) {
DBG_MSG("Recv message: [%s], ret=%d\n", frame.data, ret);
}
}
usleep();
} return ;
}

超时设置(参考文献4):

struct timeval timeout = {,}; //1.0s
//设置发送超时
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
//设置接收超时
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));

对于offline节点处理:

如果该控制器没有连接到can网络上,调用send会返回成功,但只是发送至kernel的缓冲区,并非发送至can网络。kernel会一直尝试重发,即使关闭socket或结束进程都不会取消重  发操作,此时如果将控制器连接到can网络上则会一次性将缓冲区内所有内容发出,有时这并非所要结果。如果想要清空发送和接收缓冲区,只能重启can接口

ifconfig can0 down
ifconfig can0 up

在程序中可使用system调用。

有两点注意就是:
1)recv ()的第四个参数需为MSG_WAITALL,在阻塞模式下不等到指定数目的数据不会返回,除非超时时间到。

2)即使等待超时时间值未到,但对方已经关闭了socket, 则此时recv()会立即返回,并收到多少数据返回多少数据。

参考文献:

1.http://xilinx.eetrend.com/blog/12062

2.http://www.cnblogs.com/hujianhua/p/8446291.html

3.https://wenku.baidu.com/view/65baea51bb68a98271fefaa7.html

4.https://blog.csdn.net/newger/article/details/2459113

最新文章

  1. Docker create image
  2. 关于Depth Bounds Test (DBT)和在CE3的运用
  3. 看看JavaScript中void(0)的含义
  4. Android(java)学习笔记106-2:反射机制
  5. stream_iterator、ostream_iterator 使用初探
  6. TCP/IP笔记 应用层(3)——HTTP
  7. 别动我的奶酪:CSV文件数据丢零现象及对策
  8. [CSS3] 学习笔记--CSS盒子模型
  9. echarts中视觉映射器(visualMap)与时间轴(timeline)混用的实现方法
  10. 第六篇Scrum冲刺博客
  11. 使用MUI/html5plus集成微信支付需要注意的几点问题
  12. C语言进阶之路(二)----字符串操作常见模型
  13. 2018.11.01 NOIP训练 cost数(搜索+容斥原理)
  14. 【HTML】input标签中alt属性和title属性的比较
  15. nginx Server names
  16. idea集成项目管理工具 --- Maven 并且【配置tomcat】
  17. C# 动态调取 soap 接口
  18. Linux主从同步监测和利用sendMail来发邮件
  19. css滤镜模糊效果filter和backdrop-filter
  20. js运算符、关键字、保留字、转义字符

热门文章

  1. html ---- a 标签 在新窗口打开的问题
  2. 转 C#:使用MD5对用户密码加密与解密
  3. spark读写mysql
  4. C语言-常量指针与指针常量
  5. ubuntu 进入临时客户会话页面 转入用户自己页面
  6. 初识Django框架——环境搭建前你需要了解的几点
  7. 使用Ant 和 Maven打包发布命令行程序(转载)
  8. 【技能】Ext.Viewport 实现左三右一排列方式。
  9. 将NSTimer加入至RunLoop中的两种方法差别
  10. 保留的 IPv4 地址