linux驱动-poll使用笔记
2024-01-02 20:51:36
前言
一个项目中使用了赛灵思的FPGA,需要fpga这边和arm这边进行数据通讯,通讯方式使用的是一段fpga和arm共享的ddr内存,把这块内存做了一个fifo,并通过中断出发,我在arm这边实现一个驱动来接收处理中断,然后读取fifo.
驱动的结构体
struct ddr_fifo_dev {
int index;
dev_t devid;
struct cdev cdev;
struct miscdevice miscdev;
struct device * device;
struct device_node * nd;
char name[64];
struct fasync_struct * async_queue;
wait_queue_head_t r_wait;
struct file * file;
int openflag;
int irq_id;
void __iomem * regbase;
phys_addr_t physreg;
size_t physreglen;
phys_addr_t rxfifostart;
size_t rxfifolen;
phys_addr_t txfifostart;
size_t txfifolen;
atomic_t irq_flag;
};
poll处理函数
static unsigned int ddr_fifo_poll(struct file * file, struct poll_table_struct * poll_table)
{
unsigned int mask = 0;
struct ddr_fifo_dev * df_devdata =
container_of(file->private_data, struct ddr_fifo_dev, miscdev);
//添加这个文件结构到等待队列
poll_wait(file, &df_devdata->r_wait, poll_table);
if (atomic_read(&df_devdata->irq_flag)==0) {
//没有数据,这个接口返回0,等待内核的下次调用
mask = 0;
}else{
//有数据,返回POLLIN | POLLRDNORM后,调用poll的进程会被内核唤醒
atomic_dec(&df_devdata->irq_flag);
mask = POLLIN | POLLRDNORM;
dev_dbg(df_devdata->device, "POLLIN irq_flag=%d\n",atomic_read(&df_devdata->irq_flag));
}
return mask;
}
中断处理函数
- 每次进入中断后,操作寄存器清除中断标记
- 唤醒等待队列上的进程
- 原子计数加一
static irqreturn_t irq_interrupt(int irq, void * dev_id)
{
struct ddr_fifo_dev * df_devdata = (struct ddr_fifo_dev *)dev_id;
ddr_rxfifo_irq_clear(df_devdata->regbase);
wake_up_interruptible(&df_devdata->r_wait);
atomic_inc(&df_devdata->irq_flag);
return IRQ_HANDLED;
}
文章来源:https://blog.csdn.net/qq_24276421/article/details/135348342
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!