文档章节

基于zynq的CAN接口移植

sspg
 sspg
发布于 2017/07/14 17:33
字数 641
阅读 21
收藏 0

主机:Ubuntu 16.04

目标板:zynq + Linux内核4.4

一 硬件设计

    采用zynq的CAN接口,外面用物理芯片SN65HVD23x,挂载到CAN总线。开始感觉不用物理芯片也可以向串口一样进行回环测试,发现是不可能,查看CAN的协议可以发现原因。

    vivado生成相关文件,不在累述。

二 向内核中添加xilinx的can的驱动模块
[*] Networking support --->
    <*> CAN bus subsystem support --->
            CAN Device Drivers --->
                <*> Xilinx CAN
三 修改设备树文件
zynq-7000.dtsi文件中,已经包含CAN的设备树文件,只是status设置为了disabled
    can0: can@e0008000 {
        compatible = "xlnx,zynq-can-1.0";
        status = "disabled";
        clocks = <&clkc 19>, <&clkc 36>;
        clock-names = "can_clk", "pclk";
        reg = <0xe0008000 0x1000>;
        interrupts = <0 28 4>;
        interrupt-parent = <&intc>;
        tx-fifo-depth = <0x40>;
        rx-fifo-depth = <0x40>;
    };

    can1: can@e0009000 {
        compatible = "xlnx,zynq-can-1.0";
        status = "disabled";
        clocks = <&clkc 20>, <&clkc 37>;
        clock-names = "can_clk", "pclk";
        reg = <0xe0009000 0x1000>;
        interrupts = <0 51 4>;
        interrupt-parent = <&intc>;
        tx-fifo-depth = <0x40>;
        rx-fifo-depth = <0x40>;
    };
为了保持一致性,在system.dts文件中修改can的状态设置
    &can0 {
        status = "okay";
    };
    &can1 {
        status = "okay";
    };
三 通过cantest.c程序测试
可以通过ipconfig -a查看can接口状态
配置can0和can1

ip link set can0 down                                                           
ip link set can1 down                                                           
ip link set can0 type can bitrate 500000                                        
ip link set can1 type can bitrate 500000                                                           
ip link set can0 up                                                             
ip link set can1 up

can0和can1都挂载在can总线上
 

./cantest -r can0
./cantest -s can1

附cantest.c代码

#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, nbytes;
    int i;
	char *array[2] = {"-r", "-s"};
	struct sockaddr_can addr;
	struct ifreq ifr;
	struct can_frame frame;
	struct can_filter rfilter[1];


	/* handle (optional) flags first */
	if(argc != 3) {
		fprintf(stderr, "Usage:  %s <-r> <can interface name> for receiving\nor <-s> <can interface name> for sending\n", argv[0]);
		exit(1);
	}
    /* create socket */
	if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
	{
	    perror("Create socket failed");
	    exit(-1);
	}

	/* set up can interface */
	strcpy(ifr.ifr_name, argv[2]);
	printf("can port is %s\n",ifr.ifr_name);
	/* assign can device */
	ioctl(s, SIOCGIFINDEX, &ifr);
    addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;
    /* bind can device */
	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		perror("Bind can device failed\n");
		close(s);
		exit(-2);
	}

	/* configure receiving */
	if(!strcmp(argv[1],array[0]))
	{
	    /* set filter for only receiving packet with can id 0x1F */
	    rfilter[0].can_id = 0x1F;
	    rfilter[0].can_mask = CAN_SFF_MASK;
	    if(setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0)
	    {
	    	perror("set receiving filter error\n");
	    	close(s);
	    	exit(-3);
	    }
	    /* keep reading */
	    while(1){
	        nbytes = read(s, &frame, sizeof(frame));
	        if(nbytes > 0)
	        {
	        	printf("%s ID=%#x data length=%d\n", ifr.ifr_name, frame.can_id, frame.can_dlc);
	        	for (i=0; i < frame.can_dlc; i++)
	        		printf("%#x ", frame.data[i]);
	        	printf("\n");
	        }
	    }
	}
	/* configure sending */
	else if(!strcmp(argv[1],array[1]))
	{
        /* configure can_id and can data length */
		frame.can_id = 0x1F;
        frame.can_dlc = 8;
        printf("%s ID=%#x data length=%d\n", ifr.ifr_name, frame.can_id, frame.can_dlc);
        /* prepare data for sending: 0x11,0x22...0x88 */
        for (i=0; i<8; i++)
        {
        	frame.data[i] = ((i+1)<<4) | (i+1);
        	printf("%#x ", frame.data[i]);
        }
        printf("Sent out\n");
        /* Sending data */
        if(write(s, &frame, sizeof(frame)) < 0)
		{
            perror("Send failed");
            close(s);
            exit(-4);
		}
    }
	/* wrong parameter input situation */
	else
	{
	    printf("wrong parameter input\n");
	}

	close(s);
    return 0;
}

 

© 著作权归作者所有

共有 人打赏支持
sspg
粉丝 0
博文 1
码字总数 641
作品 0
南京
LEDE 17.01.0 发布,基于 OpenWrt 的嵌入式 Linux 发行

LEDE 17.01.0 发布了,LEDE (Linux Embedded Development Environment) 是在 OpenWrt 的开发者之间出现分歧后的一个分支。目前有关于合并 OpenWrt 和 LEDE 的传闻,但还未具体落实。 LEDE 1...

王练
2017/02/25
3.1K
4
RT-Thread 嵌入式操作系统 2.0.0 beta 发布

RT-Thread v2.0.0这个版本系列是RT-Thread嵌入式实时操作系统当前的开发分支,如果要上新项目,建议使用这个版本来进行,预计这个版本的正式版会在年底发布。欢迎对这个版本进行测试、并反馈...

午夜熊
2014/08/09
4.6K
8
基于Zynq的MIO与EMIO的区别和应用

MIO与EMIO的区别与应用 1 MIO与EMIO概念 MIO:多功能IO接口,属于Zynq的PS部分,在芯片外部有54个引脚。这些引脚可以用在GPIO、SPI、UART、TIMER、Ethernet、USB等功能上,每个引脚都同时具有...

feifansong
05/09
0
0
Zynq-Linux移植学习笔记之九-petalinux

在对zynq上进行linux操作系统移植时,除了使用传统的由用户编译u-boot,kernel,rootfs方法外,目前主流采用vivado+petalinux操作方式。该操作方式能够快速生成适配于zynq的linux镜像,下文中进...

jj12345jj198999
2017/02/26
0
0
RZJM/Miz702_VGA

基于ZYNQ的VGA驱动,显示静态彩色图像,像素640*480 开发平台:Miz702(兼容Zedboard) 软件开发环境:Vivado Design Suit 2015.2 VGA driver based on the ZYNQ, show static color image, 64...

RZJM
2016/03/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

gson1.7.1线程并发导致空指针问题

java.lang.NullPointerExceptionat com.google.gson.FieldAttributes.getAnnotationFromArray(FieldAttributes.java:231)at com.google.gson.FieldAttributes.getAnnotation(FieldAttribut......

东风125
34分钟前
1
0
以太坊RPC接口使用

以太坊RPC接口文档: https://github.com/ethereum/wiki/wiki/JSON-RPC#web3_clientversion 使用方式: 比如我要调用某个合约的balanceOf(address _owner)方法。 因为没有改变合约的状态,所以...

王坤charlie
今天
2
0
C#下的一个好用的日历库(sxtwl_cpp),支持农历转公历,和公历转农历等功能

sxtwl_cpp是寿星天文历的C++版本实现。支持多种语言的绑定 代码首页 懒人包 懒人包使用方法 1、右链工程中的引用-》添加引用-》浏览-》选中dotnet目录下的sxtwl.net.dll 2、生成解决方案-》找...

元谷
今天
1
0
C++基础知识

链接:https://zhuanlan.zhihu.com/p/38399566 本文主要提一下以下三个区别: 引用必须初始化,而指针可以不初始化。 我们在定义一个引用的时候必须为其指定一个初始值,但是指针却不需要。 ...

悲催的古灵武士
今天
1
0
Oracle备份脚本,保留10天数据

@echo off echo 删除10天前的备分文件和日志forfiles /p "D:\oracleback\backfile" /m *.dmp /d -10 /c "cmd /c del @path" forfiles /p "D:\oracleback\backfile" /m *.log /d -10......

lyle_luo
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部