linux Driver for Zyqn pl Interruption in Mill Technology

Zyqn pl interrupt
I. objectives
On the development platform of Miller Technology zynq, pl interruption is realized by zynq's key switch.
Two. Analysis.
Schematic diagram

Hang on the pl side, need to be on vivado pin locking. The configuration is as follows


Of course, the interruption function can be used to operate the tricolor lamp, or you can leave the tricolor lamp alone. Printing information in the interruption can also prove that the interruption has entered.
3. Code Implementation
Pin limit file

set_property PACKAGE_PIN R14 [get_ports {gpio_rtl_tri_o[0]}]
set_property PACKAGE_PIN Y16 [get_ports {gpio_rtl_tri_o[1]}]
set_property PACKAGE_PIN Y17 [get_ports {gpio_rtl_tri_o[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_rtl_tri_o[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_rtl_tri_o[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_rtl_tri_o[0]}]
set_property PACKAGE_PIN R19 [get_ports {button1}]
set_property IOSTANDARD LVCMOS33 [get_ports {button1}]
set_property PACKAGE_PIN T19 [get_ports {button2}]
set_property IOSTANDARD LVCMOS33 [get_ports {button2}]
set_property PACKAGE_PIN G14 [get_ports {button3}]
set_property IOSTANDARD LVCMOS33 [get_ports {button3}]
set_property PACKAGE_PIN J15 [get_ports {button4}]
set_property IOSTANDARD LVCMOS33 [get_ports {button4}]

Interrupt Driver

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
/**
 *Key interrupt drive  
 *
 *
 *
 *
 *
 *
 *
 *
 * **/
static irqreturn_t k1_irq(int irq,void *dev_id)
{
    printk("irq=%d\n",irq);
    return IRQ_HANDLED;
}
static irqreturn_t k2_irq(int irq,void *dev_id)
{
    printk("irq=%d\n",irq);
    return IRQ_HANDLED;
}
static irqreturn_t k3_irq(int irq,void *dev_id)
{
    printk("irq=%d\n",irq);
    return IRQ_HANDLED;
}
static irqreturn_t k4_irq(int irq,void *dev_id)
{
    printk("irq=%d\n",irq);
    return IRQ_HANDLED;
}
//Driver Framework
int major;

static struct class *led_class   = NULL;
static struct device *led_device = NULL;
static int led_init(void);
static int led_exit(void);
static int led_open(struct inode *inode,struct file *file);
static int led_write(struct file *file,const char __user *buf, size_t count,loff_t *ppos);
static int led_read(struct file *file,char __user *buf,size_t size,loff_t *ppos);
/*
 *file_operations Structural Data, Bridge between Kernel and Operating System
 *Establish the corresponding relationship between read and led_read write and led_write
 * */
static struct file_operations led_lops=
{
.owner = THIS_MODULE,
.read  = led_read,
.write = led_write,
};
/*
 *LED Initialization for module init
 *
 * */
static int led_init(void)
{
    major=register_chrdev(0,"led_IRQ",&led_lops);
    led_class  = class_create(THIS_MODULE,"led_IRQ");
    led_device = device_create(led_class,NULL,MKDEV(major,0),NULL,"led_IRQ");

    request_irq(61,k1_irq,IRQF_TRIGGER_RISING,"led_IRQ",NULL);
    request_irq(62,k2_irq,IRQF_TRIGGER_RISING,"led_IRQ",NULL);
    request_irq(63,k3_irq,IRQF_TRIGGER_RISING,"led_IRQ",NULL);
    request_irq(64,k4_irq,IRQF_TRIGGER_RISING,"led_IRQ",NULL);



    printk("LED init");
    return 0;
}
/*
 *LED Exit for module exit
 *
 * */
static int led_exit(void)
{
    unregister_chrdev(major,"led_IRQ");
    
    device_destroy(led_device,MKDEV(major,0));
    class_destroy(led_class);
    free_irq(k1_irq,NULL);
    free_irq(k2_irq,NULL);
    free_irq(k3_irq,NULL);
    free_irq(k4_irq,NULL);
    printk("LED exit");
    return 0;
}
/*
 *LED open Application program interface
 *
 * */
static int led_open(struct inode *inode,struct file *file)
{
    printk("LED open\r\n");
    return 0;
}
/*
 *LED write Application program interface
 *
 * */
static int led_write(struct file *file,const char __user *buf, size_t count,loff_t *ppos)
{
    
    return 0;
}
/*
 *LED read Application program interface
 *
 * */
static int led_read(struct file *file,char __user *buf,size_t size,loff_t *ppos)
{
    printk("LED read\n");
    return 0;
}

module_init(led_init);
module_exit(led_exit);

MODULE_AUTHOR("TEST@LED");
MODULE_DESCRIPTION("LED driver");
MODULE_ALIAS("led linux driver");
MODULE_LICENSE("GPL");

Test program

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

void delay(void)
{
    int i,j;
    for(i=0;i<20000;i++)
        for(j=0;j<10000;j++);
}
int main(int argc , char ** argv)
{
    int fd;
    int i;
    int val=7;

    fd = open("/dev/led_IRQ",O_RDWR);
    if(fd<0) {printf("can not open file\n");while(1);}
    else printf("open file sucuss\n");
    while(1)
    {
/*        printf(" light off all led!\n");
        val = 0x00000007;
        write(fd,&val,4);
        delay();delay();

        printf("light on frist!\n");
        val = 0x00000006;
        write(fd,&val,4);
        delay();delay();delay();

        printf("light on second!\n");
        val = 0x00000005;
        write(fd,&val,4);
        delay();delay();delay();

        printf("light on third!\n");
        val = 0x00000003;
        write(fd,&val,4);
        delay();delay();delay();

        printf("light on all led!\n");
        val = 0;
        write(fd,&val,4);
        delay();delay();delay();
  */  }

    return 0;
}

Makefile file file

KDIR = /home/python/Hard_disk_21G/04-Linux_Source/Kernel/linux-xlnx
PWD := $(shell pwd)
CC   = $(CROSS_COMPILE)gcc
ARCH =arm
MAKE =make

obj-m:=button_interrupt.o

modules:
	$(MAKE) -C $(KDIR) ARCH=$(ARCH) CROSS_COMPLE=$(CROSS_COMPLE) M=$(PWD) modules
clean:
	make -C $(KDIR) ARCH=$(ARCH) CROSS_COMPLE=$(CROSS_COMPLE) M=$(PWD) clean

Tags: Linux Makefile Python shell

Posted on Fri, 11 Oct 2019 08:36:36 -0700 by cmanhatton