现有一个fpga设备挂载lpc端口下,想要主设备这里收到来自FPGA的中断后,做清除中断的操作,以此写一个完整的lpc_master的驱动
时间: 2024-05-07 15:22:46 浏览: 194
Linux下中断方式的设备驱动程序设计
5星 · 资源好评率100%
首先,需要在主设备上搭建一个LPC总线,然后将FPGA设备连接到LPC总线的LPC端口下。接下来,需要在主设备上编写LPC Master驱动程序。
以下是一个简单的LPC Master驱动程序示例,用于演示如何处理FPGA设备发送的中断:
```c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#define FPGA_LPC_IRQ 11 /* 中断号 */
static void __iomem *lpc_io_base; /* LPC IO 基址 */
/* LPC I/O 空间偏移 */
#define LPC_IO_OFFSET_ISR 0x00 /* 中断状态寄存器 */
#define LPC_IO_OFFSET_ICR 0x04 /* 中断清除寄存器 */
/* 中断状态寄存器位定义 */
#define LPC_ISR_IRQ1 (1 << 0) /* IRQ1 中断 */
#define LPC_ISR_IRQ2 (1 << 1) /* IRQ2 中断 */
#define LPC_ISR_IRQ3 (1 << 2) /* IRQ3 中断 */
#define LPC_ISR_IRQ4 (1 << 3) /* IRQ4 中断 */
#define LPC_ISR_IRQ5 (1 << 4) /* IRQ5 中断 */
#define LPC_ISR_IRQ6 (1 << 5) /* IRQ6 中断 */
#define LPC_ISR_IRQ7 (1 << 6) /* IRQ7 中断 */
#define LPC_ISR_IRQ8 (1 << 7) /* IRQ8 中断 */
/* 中断清除寄存器位定义 */
#define LPC_ICR_IRQ1 (1 << 0) /* IRQ1 中断清除 */
#define LPC_ICR_IRQ2 (1 << 1) /* IRQ2 中断清除 */
#define LPC_ICR_IRQ3 (1 << 2) /* IRQ3 中断清除 */
#define LPC_ICR_IRQ4 (1 << 3) /* IRQ4 中断清除 */
#define LPC_ICR_IRQ5 (1 << 4) /* IRQ5 中断清除 */
#define LPC_ICR_IRQ6 (1 << 5) /* IRQ6 中断清除 */
#define LPC_ICR_IRQ7 (1 << 6) /* IRQ7 中断清除 */
#define LPC_ICR_IRQ8 (1 << 7) /* IRQ8 中断清除 */
/* 中断处理函数 */
static irqreturn_t lpc_irq_handler(int irq, void *dev_id)
{
u8 isr = readb(lpc_io_base + LPC_IO_OFFSET_ISR); /* 读取中断状态寄存器 */
if (isr & LPC_ISR_IRQ1) /* 判断是否是 IRQ1 中断 */
{
pr_info("LPC Master: received FPGA interrupt IRQ1.\n");
writeb(LPC_ICR_IRQ1, lpc_io_base + LPC_IO_OFFSET_ICR); /* 清除 IRQ1 中断 */
}
/* 处理其他的中断 */
return IRQ_HANDLED;
}
static int __init lpc_master_init(void)
{
int ret;
/* 映射 LPC I/O 空间 */
lpc_io_base = ioremap(0x0cf8, 8);
/* 注册中断处理函数 */
ret = request_irq(FPGA_LPC_IRQ, lpc_irq_handler, IRQF_SHARED, "lpc_master", NULL);
if (ret)
{
pr_err("LPC Master: failed to request FPGA interrupt.\n");
return ret;
}
return 0;
}
static void __exit lpc_master_exit(void)
{
/* 释放中断 */
free_irq(FPGA_LPC_IRQ, NULL);
/* 解除 LPC I/O 空间映射 */
iounmap(lpc_io_base);
}
module_init(lpc_master_init);
module_exit(lpc_master_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("LPC Master Driver");
```
在此示例中,我们使用 `ioremap` 函数将LPC IO空间映射到内核地址空间中。然后,我们使用 `request_irq` 函数注册一个中断处理函数,并在中断处理函数中检查并清除FPGA设备发送的中断。
请注意,此示例仅包含了处理IRQ1中断的代码,您需要根据实际情况添加其他中断的处理代码。
阅读全文