您的位置:首页 > 运维架构 > Linux

zynq+linux+ramdisk can调试

2018-02-13 11:35 316 查看
由于采用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 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP  MTU:16  Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
Interrupt:22

eth0      Link encap:Ethernet  HWaddr 00:0A:35:00:01:22
inet addr:192.168.0.120  Bcast:192.168.0.255  Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:397 errors:0 dropped:0 overruns:0 frame:0
TX packets:242 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:476490 (465.3 KiB)  TX bytes:18536 (18.1 KiB)
Interrupt:148 Base address:0xb000

lo        Link encap:Local Loopback
LOOPBACK  MTU:65536  Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B)  TX bytes:0 (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 100000
xilinx_can e0008000.can can0: bitrate error 0.0%
Z-turn#./ip link set can0 up
Z-turn#./ip -d -s link show can0
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
link/can  promiscuity 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
bitrate 99999 sample-point 0.750
tq 2500 prop-seg 1 phase-seg1 1 phase-seg2 1 sjw 1
xilinx_can: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..256 brp-inc 1
clock 99999999
re-started bus-errors arbit-lost error-warn error-pass bus-off
0          0          0          0          0          0         numtxqueues 1 numrxqueues 1
RX: bytes  packets  errors  dropped overrun mcast
0          0        0       0       0       0
TX: bytes  packets  errors  dropped carrier collsns
0          0        0       0       0       0


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[32] = "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 < 0) {
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 != 0) {
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 = 0;
ret = setsockopt(fd, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &flag, sizeof(flag));
if (ret != 0) {
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 = 0;
ret = setsockopt(fd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
&flag, sizeof(flag));
if (ret != 0) {
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 != 0) {
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 (1) {
strncpy((char *)frame.data, senddata, len);
frame.can_dlc = len;
ret = sendto(fd, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr));
if (ret > 0) {
DBG_MSG("Send success: [%s], ret=%d\n", senddata, ret);
ret = recvfrom(fd, &frame, sizeof(struct can_frame), 0, (struct sockaddr *)&addr, &socket_len);
if (ret > 0) {
DBG_MSG("Recv message: [%s], ret=%d\n", frame.data, ret);
}
}
usleep(500000);
}

return 0;
}


参考文献:

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

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

3.https://wenku.baidu.com/view/65baea51bb68a98271fefaa7.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: