一.目标
在米尔科技zynq的开发平台上,通过zynq的按键开关,实现pl中断。
二.分析
原理图
挂在pl端,需要在vivado上进行引脚锁定。配置如下
当然可以通过中断函数操作三色灯,也可以不用管三色灯了,在中断中打印信息也可证明进入中断了。
三.代码实现
引脚限制文件
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}]
中断驱动程序
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
*按键中断驱动
*
*
*
*
*
*
*
*
* **/
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;
}
//驱动框架
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 结构数据,沟通内核与操作系统桥梁
*建立起 read 与led_read write与led_write 对应关系
* */
static struct file_operations led_lops=
{
.owner = THIS_MODULE,
.read = led_read,
.write = led_write,
};
/*
*LED 初始化,用于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 退出 用于 module exit
*
* */
static int led_exit(void)
{
unregister_chrdev(major,"led_IRQ");
device_destroy(led_class,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 接口函数
*
* */
static int led_open(struct inode *inode,struct file *file)
{
printk("LED open\r\n");
return 0;
}
/*
*LED write 接口函数
*
* */
static int led_write(struct file *file,const char __user *buf, size_t count,loff_t *ppos)
{
return 0;
}
/*
*LED read 接口函数
*
* */
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");
测试程序
#include
#include
#include
#include
#include
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文件
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