1、驱动代码:
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/poll.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/proc_fs.h>
#define QUEUE_COUNT 256
int ReadQCount = 0;
int ReadQHead = 0;
int ReadQTail = 0;
char ReadQ[QUEUE_COUNT][2]={0x00,0x00,};
DECLARE_WAIT_QUEUE_HEAD(WaitQueue_Read);
static irqreturn_t xxx_interrupt(int irq, void* dev_id,struct pt_regs* regs)
{
ReadQ[ReadQHead][0]= value1;
ReadQ[ReadQHead][1]= value2;
ReadQHead = (ReadQHead+1)%QUEUE_COUNT;
ReadQCount++;
wake_up_interruptible(&WaitQueue_Read);
return IRQ_HANDLED;
}
unsigned int xxx_poll(struct file *filp, struct poll_table_struct *wait)
{
unsigned int mask = 0;
poll_wait(filp,&WaitQueue_Read,wait);
if(ReadQCount > 0)
{
mask |= POLLIN | POLLRDNORM;
}
return mask;
}
ssize_t xxx_read(struct file *filp,char *buf,size_t count,loff_t *f_pos)
{
int ret = 0;
if((ReadQCount == 0) && (filp->f_flags & O_NONBLOCK))
{
return -1;
}
ret = wait_event_interruptible(WaitQueue_Read,ReadQCount);
if(ret != 0)
{
return ret;
}
if(ReadQCount>0)
{
copy_to_user(buf,ReadQ[ReadQTail],2);
ReadQTail =(ReadQTail+1)%QUEUE_COUNT;
ReadQCount--;
}
return 0;
}
2、应用层示例代码:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<sys/poll.h>
#define XXX_DEV "/dev/xxx_dev"
int main()
{
int Fd = -1;
int Ret = -1;
struct pollfd Events[1];
char Buff[2];
Fd = open(XXX_DEV,O_RDWR);
if(Fd < 0)
{
printf("open %s failed!\n",XXX_DEV);
}
else
{
printf("open %s success\n",XXX_DEV);
while(1)
{
memset(Events,0,sizeof(Events));
Events[0].fd = Fd;
Events[0].events = POLLIN;
Ret = poll((struct pollfd *)&Events,1,200);
if(Events[0].revents & POLLERR)
{
printf("Device Error\n");
exit(EXIT_FAILURE);
}
if(Events[0].revents & POLLIN)
{
read(Fd,&Buff,2);
printf("value1 : %x, value2 : %x\n",Buff[0],Buff[1]);
}
}
}
return 0;
}