专栏首页科技分享zynq linux驱动之PL-PS中断【转】

zynq linux驱动之PL-PS中断【转】

转自: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 版权声明:本文为博主原创文章,转载请附上博文链接!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux中断管理 (1)Linux中断管理机制【转】

    转自:https://www.cnblogs.com/arnoldlu/p/8659981.html

    用户3033338
  • GIC , SPI , PPI (窝窝科技的文章题目改了下)【转】

    转自:https://www.cnblogs.com/tureno/articles/6403408.html

    用户3033338
  • GIC , SPI , PPI (窝窝科技的文章题目改了下)

    转载于: http://www.wowotech.net/irq_subsystem/gic-irq-chip-driver.html

    用户3033338
  • AI 公司面临隐私问题 不少仍坚持原则拒绝商业机会

    TechWeb报道,7月8日消息,据国外媒体报道,当一家由美国中央情报局支持的风险投资基金表示对拉纳·埃尔·卡利乌比(Rana el Kaliouby)的面部扫...

    周俊辉
  • Ubuntu 18.04 LTS将默认采用X.Org图形堆栈

    Canonical公司的Ubuntu桌面总监Will Cooke今天宣布,即将推出的Ubuntu 18.04 LTS(仿生海狸)操作系统将默认采用X.Org图形...

    企鹅号小编
  • 使用叮当声控智米电风扇

    HaHack
  • 2017,那些出现在日记中的人:简单的文本挖掘

    终于做出这张图时,我突然有点感慨,这就是2017年我的日记中提到过或记录过的一个个人名,当然为避免引起不必要的麻烦,隐去了许多亲人朋友的名字。想到一辈子说长也长...

    古柳_DesertsX
  • 强化学习基础概念ppt视频讲解

    用户1908973
  • 补习系列(18)-springboot H2 迷你数据库

    H2 数据库是一个纯 Java 实现的开源的嵌入式数据库,笔者第一次使用时还是在多年前的一个客户端项目中。 当时就觉得这个数据库很方便,如果你希望你的应用程序能...

    美码师
  • 微服务的架构适合你吗?微服务为何而来?

    最近拾起了基本英文的讲微服务的书,一方面是学习英文,一方面也是想原汁原味的了解一下外国人口中的微服务是怎么样的。所以这篇文章是想聊聊微服务,聊聊我眼中的微服务,...

    黑光技术

扫码关注云+社区

领取腾讯云代金券