转自:https://blog.csdn.net/h244259402/article/details/83993524

PC:Windows 10

虚拟机:ubuntu 16.04

vivado:2017.04

的的PetaLinux:2017.04

开发板:黑金AX7010

根文件系统:debian8

-------------------------------------------------- --------------------传说中的分割线------------------------- -------------------------------------------------- ----

将  zynq linux驱动之传统开发  里的vivado工程另存为interrupt7010

接下来配置一下中断

这里会出现中断的接口

接下来添加一个引脚

连起来

重新生成一下顶层文件

打开顶层文件,加一个非门(因为PS这边貌似只支持上升沿中断和高电平中断)

在约束文件里面添加触发IRQ的引脚(这里用的是KEY4,HDMI座子旁边的那个按键)

执行生成位文件

结束之后将原来的SDK目录删掉

重新导入硬件和位文件之后打开SDK

将该文件夹拷贝到Ubuntu的里

使用的PetaLinux编译fsbl,u-boot的,内核,设备树文件:

过程略.....

用的PetaLinux制作BOOT.BIN文件,将BOOT.BIN,image.ub,system.dtb文件拷贝到SD卡的胖分区里(这里没有用的PetaLinux生成的根文件系统,用的是debian8)

接下来打开数据表

找到中断号是61

然后先到开板上看一下

cat /proc/interrupts

再看看数据表上

没有问题中断号都对得上

然后再来看看设备树

vim components/plnx_workspace/device-tree/device-tree-generation/zynq-7000.dtsi

发现这里的中断号跟数据表和/ PROC /中断里面的对不上

仔细观察发现设备树里面的中断号是数据表上的中断号减去32得到的值

接下来仿照这个写一个自己的

vim project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
/include/ "system-conf.dtsi"
/ {
amba_pl: amba_pl{
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
irq: irq@0{
compatible = "hello,irq";
interrupt-parent = <&intc>;
interrupts = <0 29 2>;
};
};
};

执行的PetaLinux建造编译

编译完成之后

到开发板上,挂接NFS文件系统,然后把编译好的设备树文件(system.dts)拷贝到开发板SD卡的脂肪分区里,重启开发板

ls /proc/device-tree/amba_pl/
可以看到设备树节点增加了IRQ @ 0

编写驱动:

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/of.h>
#include <linux/delay.h>

#include <linux/dma-mapping.h>

#include <linux/pm.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/dma-buf.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/dmaengine.h>
#include <linux/completion.h>
#include <linux/wait.h>
#include <linux/init.h>

#include <linux/sched.h>
#include <linux/pagemap.h>
#include <linux/errno.h> /* error codes */
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>

#include <linux/moduleparam.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
#include <linux/notifier.h>
#include <linux/init.h>
#include <linux/pci.h>

#include <linux/time.h>
#include <linux/timer.h>

//
static char devname[16];
static int major;
static int mijor;
static struct class* cls;
static void __iomem* base_address;
static resource_size_t remap_size;
static int irq;
static struct device* dev;

//

#define DEVICE_NAME "irq_drv"

static volatile int irq_is_open = 0;

static struct fasync_struct *irq_async;

static int irq_drv_open(struct inode *Inode, struct file *File)
{
irq_is_open = 1;
return 0;
}

int irq_drv_release (struct inode *inode, struct file *file)
{
irq_is_open = 0;
return 0;
}

static ssize_t irq_drv_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
return 0;
}

static ssize_t irq_drv_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
return 0;
}

static int irq_drv_fasync (int fd, struct file *filp, int on)
{
return fasync_helper (fd, filp, on, &irq_async);
}

static struct file_operations irq_fops = {
.owner = THIS_MODULE,
.open = irq_drv_open,
.read = irq_drv_read,
.write = irq_drv_write,
.fasync = irq_drv_fasync,
.release = irq_drv_release,
};

static irqreturn_t irq_interrupt(int irq, void *dev_id)
{
printk("irq = %d\n", irq);
if(irq_is_open)
{
kill_fasync (&irq_async, SIGIO, POLL_IN);
}
return IRQ_HANDLED;
}

static int irq_probe(struct platform_device *pdev)
{
int err;
struct device *tmp_dev;
memset(devname,0,16);
strcpy(devname, DEVICE_NAME);

major = register_chrdev(0, devname, &irq_fops);

cls = class_create(THIS_MODULE, devname);
mijor = 1;
tmp_dev = device_create(cls, &pdev->dev, MKDEV(major, mijor), NULL, devname);
if (IS_ERR(tmp_dev)) {
class_destroy(cls);
unregister_chrdev(major, devname);
return 0;
}

irq = platform_get_irq(pdev,0);
if (irq <= 0)
return -ENXIO;

dev = &pdev->dev;

err = request_threaded_irq(irq, NULL,
irq_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
devname, NULL);
if (err) {
printk(KERN_ALERT "irq_probe irq error=%d\n", err);

goto fail;
}
else
{
printk("irq = %d\n", irq);
printk("devname = %s\n", devname);
}

//保存dev
//platform_set_drvdata(pdev, &xxx);

return 0;

fail:

free_irq(irq, NULL);

device_destroy(cls, MKDEV(major, mijor));
class_destroy(cls);
unregister_chrdev(major, devname);

return -ENOMEM;

}

static int irq_remove(struct platform_device *pdev)
{
device_destroy(cls, MKDEV(major, mijor));
class_destroy(cls);
unregister_chrdev(major, devname);

free_irq(irq, NULL);
printk("irq = %d\n", irq);

return 0;
}

static int irq_suspend(struct device *dev)
{

return 0;
}

static int irq_resume(struct device *dev)
{

return 0;
}

static const struct dev_pm_ops irq_pm_ops = {
.suspend = irq_suspend,
.resume = irq_resume,
};

//MODULE_DEVICE_TABLE(platform, irq_driver_ids);

static const struct of_device_id irq_of_match[] = {
{.compatible = "hello,irq" },
{ }
};
MODULE_DEVICE_TABLE(of, irq_of_match);

static struct platform_driver irq_driver = {
.probe = irq_probe,
.remove = irq_remove,
.driver = {
.owner = THIS_MODULE,
.name = "irq@0",
.pm = &irq_pm_ops,
.of_match_table = irq_of_match,
},
};

module_platform_driver(irq_driver);

MODULE_LICENSE("GPL v2");

Makefile文件:

export ARCH=arm

KERN_DIR = /home/zynq/work/kernel/linux-4.9

all:
make -C $(KERN_DIR) M=`pwd` modules

clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order

obj-m += irq_drv.o

编译驱动

开发板挂接NFS文件系统,加载驱动

然后按一下按键,内核就能打印出IRQ

编写测试程序:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

int fd;

void my_signal_fun(int signum)
{
printf("irq app printf!\n");
}

int main(int argc, char **argv)
{
unsigned char key_val;
int ret;
int Oflags;

signal(SIGIO, my_signal_fun);

fd = open("/dev/irq_drv", O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}

fcntl(fd, F_SETOWN, getpid());

Oflags = fcntl(fd, F_GETFL);

fcntl(fd, F_SETFL, Oflags | FASYNC);

while (1)
{
sleep(1000);
}

return 0;
}
编译

arm-linux-gnueabihf-gcc -o irq irq.c
回到开发板运行测试程序

按下按键之后能够看到内核和测试程序的打印信息
---------------------
作者:h244259402
来源:CSDN
原文:https://blog.csdn.net/h244259402/article/details/83993524
版权声明:本文为博主原创文章,转载请附上博文链接!

zynq linux驱动之PL-PS中断【转】的更多相关文章

  1. linux驱动学习笔记---实现中断下半部以及驱动编写规范(七)【转】

    转自:https://blog.csdn.net/weixin_42471952/article/details/81609141 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协 ...

  2. ZYNQ笔记(4):PL触发中断

    一.ZYNQ中断框图 PL到PS部分的中断经过ICD控制器分发器后同时进入CPU1 和CPU0.从下面的表格中可以看到中断向量的具体值.PL到PS部分一共有20个中断可以使用.其中4个是快速中断.剩余 ...

  3. Linux驱动设计—— 中断与时钟

    中断和时钟技术可以提升驱动程序的效率 中断 中断在Linux中的实现 通常情况下,一个驱动程序只需要申请中断,并添加中断处理函数就可以了,中断的到达和中断函数的调用都是内核实现框架完成的.所以程序员只 ...

  4. Linux驱动之按键驱动编写(中断方式)

    在Linux驱动之按键驱动编写(查询方式)已经写了一个查询方式的按键驱动,但是查询方式太占用CPU,接下来利用中断方式编写一个驱动程序,使得CPU占有率降低,在按键空闲时调用read系统调用的进程可以 ...

  5. linux驱动之中断方式获取键值

    linux驱动之中断方式获取键值 ----------------------------------------------------------------------------------- ...

  6. Linux 驱动框架---驱动中的中断

    在单片机开发中中断就是执行过程中发生了一些事件需要及时处理,所以需要停止当前正在运行的处理的事情转而去执行中断服务函数,已完成必要的事件的处理.在Linux中断一样是如此使用但是基于常见的中断控制器的 ...

  7. Linux驱动实践:一起来梳理中断的前世今生(附代码)

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  8. Linux驱动技术(六) _内核中断

    在硬件上,中断源可以通过中断控制器向CPU提交中断,进而引发中断处理程序的执行,不过这种硬件中断体系每一种CPU都不一样,而Linux作为操作系统,需要同时支持这些中断体系,如此一来,Linux中就提 ...

  9. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

随机推荐

  1. script weixin app / weixin xiao chen xu

    s 开发人员: 1.设置权限程序员管理人员-管理体验者-配置测试人员的真实微信号2.微信小程序的后台-上传体验版代码-生成体验码二维码测试人员: 1.你的台式机/笔记本申请内外网.有usb权限2.有W ...

  2. SpringBoot笔记十四:消息队列

    目录 什么是消息队列 消息队列的作用 异步通信 应用解耦 流量削峰 RabbitMQ RabbitMQ流程简介 RabbitMQ的三种模式 安装RabbitMQ RabbitMQ交换器路由和队列的创建 ...

  3. Kafka权威指南 读书笔记之(三)Kafka 生产者一一向 Kafka 写入数据

    不管是把 Kafka 作为消息队列.消息总线还是数据存储平台来使用 ,总是需要有一个可以往 Kafka 写入数据的生产者和一个从 Kafka 读取数据的消费者,或者一个兼具两种角色的应用程序. 开发者 ...

  4. spring中整合memcached,以及创建memcache的put和get方法

    spring中整合memcached,以及创建memcache的put和get方法: 1:在项目中导入memcache相关的jar包 2:memcache在spring.xml的配置: 代码: < ...

  5. verilog仿真文件编写

    verilog仿真文件大概框架: ·timescale 1ns/1ps //但需要时间 module xxx_tb(); //仿真文件不需要输入和输出, intput clk; ] xx; //根据需 ...

  6. tarjan强连通算法

    #include <iostream> #include <string.h> using namespace std; ; ; struct edge{ int v,next ...

  7. pyqt5-定时器

    定时器的操作方法有两种: 方法一:利用每个对象包含的timerEvent函数 方法二:利用定时器模块    需要  from PyQt5.QtCore import QTimer 方法一:利用每个对象 ...

  8. matplotlib的安装和允许中文及几种字体

    安装  python -m pip install matplotlib  允许中文: 使用matplotlib的字体管理器指定字体文件 plt.rcParams['font.sans-serif'] ...

  9. [C++]Linux之C编程异常[true未定义解决方案]

    C语言里面是没有bool(布尔)类型的,C++里面才有,这就是说,在C++里面使用bool类型是没有问题的.bool类型有只有两个值:true =1 .false=0. 但是,C99标准里面,又定义了 ...

  10. 快速做ssh免密钥登陆

    1.本地生成密钥并发送目标主机 >&1 #采用数字签名RSA或DSA生成密钥文件和私钥文件 id_rsa,id_rsa.pub或id_dsa,id_dsa.pub ssh-copy-id ...