ZYNQ学习笔记-LINUX篇-字符设备驱动控制AXI-GPIO

2023-05-16

ZYNQ 学习笔记

硬件平台:zynq-7000 & xc7z100ffg900-2
linux开发平台:ubuntu16.04.4 LTS
zynq-linux内核:linux-xlnx-xilinx-v2017.4

LINUX篇

字符设备驱动控制AXI-GPIO

一、准备工作

  1. 确保已经安装好交叉编译器gcc-arm-linux-gnueabihf。
    sudo apt-get install gcc-arm-linux-gnueabihf
    sudo apt-get update
    sudo apt-get upgrade
    
  2. 准备好zynq-linux内核,这里使用linux-xlnx-xilinx-v2017.4,路径设置为/home/user/linux/kernel/linux-xlnx-xilinx-v2017.4(此路径仅作参考,和驱动的Makefile中路径一致即可)。进入内核目录,对顶层Makefile修改,将250行左右的编译指令重新设置:
    # ARCH			?= $(SUBARCH)
    # CROSS_COMPILE	?= $(CONFIG_CROSS_COMPILE:"%"=%)
    # user add: change the value, to avoid long command input 
    ARCH			?= arm
    CROSS_COMPILE	?= arm-linux-gnueabihf-
    
    为了确保编译过程顺利进行,将内核文件更改用户为自己:
    cd /home/user/linux/kernel/linux-xlnx-xilinx-v2017.4 	//进入内核目录
    sudo chown -R user:user * 								//更改对当前目录下所有文件生效
    
    随后可以开始编译内核:
    make clean 					//第一次编译前清理一下
    make xilinx_zynq_defconfig 	//配置linux内核
    make -j8 					//根据自己cpu核心数量进行多核编译
    
  3. 获取AXI-GPIO的内存地址,可在vivado-Address Editor或xilink SDK-system.mss中查看。
    axi_gpio_led_address

二、字符设备驱动编写

  1. 创建led_mod.c、ledApp.c文件,并编写程序。这里程序参考《正点原子ZYNQ-LED开发实验教程》,有所不同的是这里由于使用AXI-GPIO,控制设备时无需配置寄存器等,获取地址后直接写入、读取即可。
    /* led_mod.c */
    #include <linux/types.h>
    #include <linux/kernel.h>
    #include <linux/delay.h>
    #include <linux/ide.h>
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/errno.h>
    #include <linux/gpio.h>
    #include <asm/mach/map.h>
    #include <asm/uaccess.h>
    #include <asm/io.h>
    #define LED_MAJOR		200			/* 主设备号 */
    #define LED_NAME		"axi-led"		/* 设备名字 */
    
    #define ZYNQ_AXI_GPIO_0_BASE    0x41210000
    static void __iomem *data_addr; /* 映射后的寄存器虚拟地址指针 */
    
    static int led_open(struct inode *inode, struct file *filp)
    {
    	return 0;
    }
    static ssize_t led_read(struct file *filp, char __user *buf,
    			size_t cnt, loff_t *offt)
    {
    	return 0;
    }
    static ssize_t led_write(struct file *filp, const char __user *buf,
    			size_t cnt, loff_t *offt)
    {
    	int ret;
    	int val;
    	char kern_buf[1];
    	ret = copy_from_user(kern_buf, buf, cnt);	// 得到应用层传递过来的数据
    	if(0 > ret) {
    		printk(KERN_ERR "kernel write failed!\r\n");
    		return -EFAULT;
    	}
    	val = readl(data_addr);
    	printk("write-read:0x%x\r\n", val);
    	val = kern_buf[0];
    	printk("write 0x%x now\r\n", val);
    	writel(val, data_addr);
    	return 0;
    }
    static int led_release(struct inode *inode, struct file *filp)
    {
    	return 0;
    }
    static struct file_operations led_fops = {
    	.owner		= THIS_MODULE,
    	.open		= led_open,
    	.read		= led_read,
    	.write		= led_write,
    	.release	= led_release,
    };
    static int __init led_init(void)
    {
    	u32 val;
    	int ret;
    	/* 1.寄存器地址映射 */
    	data_addr = ioremap(ZYNQ_AXI_GPIO_0_BASE, 4);
    	/* 7.注册字符设备驱动 */
    	ret = register_chrdev(LED_MAJOR, LED_NAME, &led_fops);
    	if(0 > ret){
    		printk(KERN_ERR "Register LED driver failed!\r\n");
    		return ret;
    	}
    	printk("led-mod init now\r\n");
    	return 0;
    }
    static void __exit led_exit(void)
    {
    	/* 1.卸载设备 */
    	unregister_chrdev(LED_MAJOR, LED_NAME);
    	/* 2.取消内存映射 */
    	iounmap(data_addr);
    	printk("led-mod exit\r\n");
    }
    /* 驱动模块入口和出口函数注册 */
    module_init(led_init);
    module_exit(led_exit);
    MODULE_AUTHOR("mlia");
    MODULE_DESCRIPTION("ZYNQ AXI-GPIO LED Test Driver");
    MODULE_LICENSE("GPL");
    
    /* ledApp.c */
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
        int fd, ret;
        unsigned char buf[1];
        if(3 != argc) {
            printf("Usage:\n"
            "\t./ledApp /dev/led 1 @ close LED\n"
            "\t./ledApp /dev/led 0 @ open LED\n"
            );
            return -1;
        }
        /* 打开设备 */
        fd = open(argv[1], O_RDWR);
        if(0 > fd) {
            printf("file %s open failed!\r\n", argv[1]);
            return -1;
        }
        /* 将字符串转换为int型数据 */
        buf[0] = atoi(argv[2]);
        /* 向驱动写入数据 */
        ret = write(fd, buf, sizeof(buf));
        if(0 > ret){
            printf("LED Control Failed!\r\n");
            close(fd);
            return -1;
        }
        /* 关闭设备 */
        close(fd);
        return 0;
    }
    
  2. 编写Makefile1以进行模块编译:
    KERN_DIR := /home/user/linux/kernel/linux-xlnx-xilinx-v2017.4
    obj-m := led_mod.o
    all:
    	make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERN_DIR) M=`pwd` modules
    clean:
    	make -C $(KERN_DIR) M=`pwd` clean
    
  3. 编译输出.ko与执行文件:
    make 										//输出.ko文件
    arm-linux-gnueabihf-gcc ledApp.c -o ledApp 	//输出测试程序
    

三、测试与实验

  1. 开启开发板,这里使用nfs共享文件。
    mount -t nfs -o nolock 192.168.0.116:/home/user/nfs /mnt
    
  2. 加载模块,这里使用动态加载驱动模块,进入.ko等文件路径:
    insmod led_mod.ko 					//加载模块
    mknod /dev/led c 200 0 				//创建设备节点
    ls /dev 							//查看节点是否创建成功
    ./ledApp /dev/led 1 				//写入值,此时led1应被点亮
    ./ledApp /dev/led 15 				//写入值,此时led1~4应被点亮
    ./ledApp /dev/led 16 				//写入值,此时led1~4均熄灭(axi-gpio虽有4byte宽度,但只关注width位的值)
    rmmod led_mod 						//测试完成,卸载驱动
    dmesg | tail 						//查看一下测试过程中的printk信息
    

四、总结

至此,测试完全结束。


  1. Makefile文件尤其要注意tab缩进。 ↩︎

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ZYNQ学习笔记-LINUX篇-字符设备驱动控制AXI-GPIO 的相关文章

  • Spring4+Hibernate4+SpringMVC整合配置

    这里是Spring4 3 9 43 Hibernate4 0 2的整合配置 配置web xml span class hljs pi lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 g
  • Android Keystore System介绍

    翻译 sdk docs training articles keystore html q 61 keystore q 61 keystore KeyStore KeyStore负责维护加密密钥及其所有者 可以通过修改JAVA HOME l
  • html5之div居中

    效果如图 xff1a 代码如下 xff1a navright display inline block vertical align middle width 100 height 100 min height 400px border 1
  • 服务器后台自动运行程序和停止

    后台运行命令 如何后台运行python程序 关键的命令 xff1a nohup 只需要输入下面的命令就可以在后台一直执行python程序啦 nohup python u test py gt test log 2 gt amp 1 amp
  • 谷歌浏览器(Chrome)插件安装失败的解决办法

    最新的谷歌浏览器下载完成以后进行安装插件时 xff0c 可能会提示 无法从该网站添加应用 扩展程序和用户脚本 的提示 这是因为谷歌比较重视用户信息安全性的 xff0c 所以不希望用户随便安装一些除官方商店之外的东西 xff0c 以免造成用户
  • Docker-CentOS开启防火墙firewalled映射Docker端口

    开启docker的Tomcat容器后 xff0c 启动 docker run d p 8080 8080 tomcat 访问不了Tomcat 查看防火墙所有开放的端口 firewall cmd zone 61 public list por
  • mysql 5.6 utf-8 编码设置

    mysql 5 5 utf 8编码 正确设置的方法 xff1a 在 etc my cnf mysqld utf 8 设置 character set server 61 utf8 collation server 61 utf8 gener
  • 文件内容查找方式

    第一种 xff0c 使用windows自带的查找工具 搜索工具里面有 高级选项 xff0c 选择 文件内容 然后进行搜索即可 第二种 xff0c 使用命令行 在需要进行搜索的文件夹下使用命令行 xff1a Get span class to
  • Image打包流程-Android10.0编译系统(四)

    摘要 xff1a 本节主要来进行Android10 0 Image打包流程 xff0c 理解system img是如何打包的 1 概述 前面我们讲完了Android10 0 编译的初始化和make的完整流程 xff0c 从make中我们看到
  • Ubuntu18.04安装踩坑与排错记录

    很早以前就想装Ubuntu玩玩了 xff0c 今天终于动手实现了这个想法 但过程并不顺利 xff0c 所以记录一下 对他人可能借鉴意义不大 xff0c 但对自己来说还是有记录价值的 机子是之前淘汰掉的华硕笔记本 xff08 14年买的 xf
  • Jupyter Notebook FileNotFoundError: [WinError 2] 系统找不到指定的文件

    问题描述 xff1a 通过Anaconda新创建环境 tfenv python 61 3 5 5 并依次安装tensorflow ipython xff0c jupyter xff0c matplotlib这三个包及其依赖包 然后在该环境下
  • 命令提示符(cmd)的一些简单用法

    命令提示符 xff08 cmd xff09 快捷键 xff1a win 43 r 切换位置 xff1a 盘名 xff1a 进入目录 xff1a cd 43 文件夹名 xff08 tab可以切换文件夹 xff09 只要路径写对cd可以访问多级
  • Java中,&&与&,||与|的区别

    1 1 逻辑运算符 amp amp xff08 短路与 xff09 xff0c amp 用法 xff1a amp amp 和 amp 都是表示与区别是 xff1a amp amp 若第一个条件不满足 xff0c 后面条件就不再判断 而 am
  • Java基础类(六):Collections工具类

    目录 1 Collections 1 1 排序操作 xff1a xff08 均为static方法 xff09 1 2 查找 替换 1 3 同步控制 1 4 返回不可变集合 1 Collections Collections 是一个操作 Se
  • Bash脚本:采用for循环重复执行某条指令100次

    1 新建一个脚本文件 直接vim for sh就可以 2 编辑脚本文件 bin bash for i 61 1 i lt 61 100 i 43 43 do test 想要重复执行的命令 xff09 done 3 将脚本文件变为可执行文件
  • Android.mk 和 CMakeLists.txt 的转换规则

    Android mk 和 CMakeLists txt 都是用来构建 Android 应用程序或库的工具 但是它们有不同的语法和规则 xff0c 所以将一个 Android mk 文件转换成一个 CMakeLists txt 文件需要一些注
  • EFI Shell 命令参考

    对于使用使用DOS的人来说 xff0c 会使用DOS命令是最基本的 xff0c 而在当今即将盛行的EFI BIOS来说 xff0c 就有了新的变化 xff0c 如何操作EFI Shell 呢 xff1f 至此我贴出了EFI Shell 的命
  • mysql出现提示错误10061的解决方法

    MySQL出现提示错误10061的解决方法 错误提示 xff1a 今天打开Navicat连接mysql突然提示 2003 Can t connect to MySQL server on localhost 10061 xff09 的错误提
  • 3分钟爬取全网10W+爆款,脚本无偿分享,零基础拿来直接就能用!

    市面上的新媒体资料都是过去时了 xff0c 只有最新的爆款文才是新媒体人的福音 xff01 三分钟爬取全网10W 43 爆款文 xff01 爬虫脚本无偿分享 xff0c 拿来就能直接用 xff0c 零基础也能用 xff01 需要的看图 xf
  • 使用Wake On Lan远程唤醒

    使用Wake On Lan远程唤醒 客厅里的那台htpc xff0c 在无下片任务的时候 xff0c 大部分时间里都在白白浪费电 主板是支持wake on lan的 xff0c 把它弄成可以远程控制会比较经济 首先要设置bios xff0c

随机推荐

  • .gitignore文件作用

    gitignore文件用于在将文件提交到git暂存区时 xff0c 指定将哪些文件排除 xff1b 1 gitignore文件基本用法 在 git文件所在的目录创建 gitignore 文件 文件内容如下 span class token
  • 《计算机应用基础》形考作业及答案

    国家开放大学 计算机应用基础 形考作业 及 答案 题目1 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 兔子bu蹬鹰 在Word 2010中编辑文本时 编辑
  • php操作redis代码

    lt php Redis缓存操作 64 author hxm 64 version 1 0 64 since 2015 05 04 class RCache extends Object implements CacheFace priva
  • C++实现归并排序

    C 43 43 实现归并排序 span class token comment span span class token comment main cpp span span class token comment MergeSort s
  • LinuxNote 第二章 新手必须掌握的Linux命令

    目录 第二章 新手必须掌握的Linux命令2 1 Shell2 2 命令格式及帮助命令 man2 2 1 命令格式2 2 2 帮助命令 man 2 3 常用的系统工作命令2 3 1 echo2 3 2 date2 3 3 reboot2 3
  • Linux PXE无盘工作站

    关于PXE无盘工作站系统的简介 PXE无盘工作站系统是指由一台或多台 系统服务器 和多台 PXE客户端 无盘工作站 通过 交换机 相连组成的局域网系统 xff08 图1 xff1a 无盘工作站系统部署拓扑图 xff09 系统服务器 xff1
  • 环形缓冲区的实现原理

    http blog chinaunix net uid 7491192 id 2051200 html 在通信程序中 xff0c 经常使用环形缓冲区作为数据结构来存放通信中发送和接收的数据 环形缓冲区是一个先进先出的循环缓冲区 xff0c
  • 计算任意二叉树T中其数据域大于等于x的结点个数并返回该值

    span class token macro property span class token directive keyword include span span class token string lt stdio h gt sp
  • 使用Mybatis这篇就够了

    第一章 框架概述 1 1 三层架构 界面层 xff1a 和用户打交道的 xff0c 接收用户的请求参数 xff0c 显示处理结果的 xff08 jsp xff0c html xff0c servlet xff09 业务逻辑层 xff1a 接
  • Web项目中访问路径问题

    访问路径问题 1 1访问路径的组成 URL xff0c 统一资源定位符 xff0c 用于定位资源的一种方式 通常的 URL 资源访问路径由两部分 构成 xff1a 资源路径与资源名称 资源名称指的是要访问资源的直接名称 xff0c 如 sh
  • 解决Navicat远程登录服务器的Mysql服务Password authentication failed

    常规用的是grant all privileges on to root 64 identified by zhaiwenhai 这里设置的密码 SSH用的是服务器的用户名和密码来进行验证
  • 一篇打通java路径问题

    访问路径问题 1 1访问路径的组成 URL xff0c 统一资源定位符 xff0c 用于定位资源的一种方式 通常的 URL 资源访问路径由两部分 构成 xff1a 资源路径与资源名称 资源名称指的是要访问资源的直接名称 xff0c 如 sh
  • ElasticSearch为索引库添加静态映射报:Failed to parse mapping [properties]: Root mapping definition has unsupport

    代码 span class token constant PUT span span class token operator span my index span class token punctuation span span cla
  • Adobe XD常见问题和解决方案

    1 Adobe XD软件是什么 xff1f Adobe XD是一种端到端解决方案 xff0c 用于设计网站和移动应用程序的用户体验 xff0c 并为其构建原型 使用功能强大的工具 xff0c 在线框 视觉设计 交互设计 原型构建 预览和共享
  • 2022最新JSON解析计费系统扶风视频解析计费系统V1.8详解

    我个人认为扶风的计费会比云海的比较相对操作好上手 xff0c 且 bug 也少 xff0c 而且之前的之前的版本加载速度实在慢 xff0c 真心感人 扶风计费程序介绍 后台可对接多个专用 json 接口解析 xff0c 可以 m3u8 资源
  • 五大适合STM32的嵌入式操作系统

    基于STM平台且满足实时控制要求操作系统 xff0c 有以下5种可供移植选择 分别为 Clinux C xff0f OS II eCos FreeRTOS和都江堰操作系统 djyos 下面分别介绍这五种嵌入式操作系统的特点及不足 1 Cli
  • 我的2013这一年 -- 唯一关键词 变化

    又一年 xff0c 又是一个年终总结 xff0c 2013的关键词就一个 变化 xff0c 貌似去年是三个 起初没怎么注意已到了2013年未 xff0c 圣诞前后 xff0c CSDN上开始扎堆出现年终总结的帖子或博客文章 xff0c 还有
  • 【Minecraft】在我的世界Minecraft服务端上开启第三方认证,并支持皮肤

    这篇文章也可以在我的博客中查看 前言 上篇文章我们讲到如何在客户端使用皮肤 但提到多人联机中需要服务端的支持 但其实对服务端而言 xff0c 这并不只是一个更换皮肤的问题 xff0c 而是一个认证系统的问题 xff0c 因此这篇文章我们谈谈
  • python3 执行pip3 install requests ,提示找不到ssl模块

    python3 执行pip3 install requests xff0c 提示找不到ssl模块 xff1a 解决方法 xff1a 复制自 xff1a http www cnblogs com yuechaotian archive 201
  • ZYNQ学习笔记-LINUX篇-字符设备驱动控制AXI-GPIO

    ZYNQ 学习笔记 硬件平台 xff1a zynq 7000 amp xc7z100ffg900 2 linux开发平台 xff1a ubuntu16 04 4 LTS zynq linux内核 xff1a linux xlnx xilin