#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/poll.h>
int main()
{
int dev;
struct pollfd events [1];
int retval;
char buff [128];
int readcnt;
int loop;
int flashing;
printf ("poll Program Start\n");
dev = open ("/dev/polldev", O_RDWR); /*可阻塞打开设备*/
if (dev < 0) {
printf ("[/dev/polldev] Open fail\n");
exit (-1);
}
flashing = 0;
printf ("wait poll \n");
buff [0] = 0xff;
write (dev, buff, 1);
while (1) {
memset (events, 0, sizeof (events));
events[0].fd = dev;
events[0].events = POLLIN; /*对有数据读入感兴趣*/
retval = poll ((struct pollfd *) &events, 1, 1000);
if (retval < 0) { /*出错*/
perror ("poll error: ");
exit (EXIT_FAILURE);
}
if (retval == 0) { /*1s 内 poll 不到数据*/
flashing = !flashing;
if (flashing)
buff[0] = 0x00;
else
buff[0] = 0xff;
write (dev, buff, 1);
continue;
}
if (events[0].revents & POLLERR) {
printf ("Device Error\n");
exit (EXIT_FAILURE);
}
if (events[0].revents & POLLIN) { /*有数据可读*/
readcnt = read (dev, buff, sizeof (buff));
printf ("READ DATA COUNT [%d]\n", readcnt);
for (loop = 0; loop < readcnt; loop++) {
printf ("READ DATA [%02X]\n", buff [loop]);
}
}
}
buff [0] = 0x00;
write (dev, buff, 1);
close (dev);
return (0);
}
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/poll.h>
#define POLL_DEV_NAME "polldev"
#define POLL_DEV_MAJOR 240
#define POLL_WRITE_ADDR 0x378
#define POLL_READ_ADDR 0X379
#define POLL_CTRL_ADDR 0x37A
#define POLL_IRQ 3
#define POLL_IRQ_ENABLE_MASK 0x10
#define POLL_BUFF_MAX 64
DECLARE_WAIT_QUEUE_HEAD(WaitQueue_Read);
#define MAX_QUEUE_CNT 128
static unsigned char ReadQ [MAX_QUEUE_CNT];
static unsigned long ReadQCount = 0;
static unsigned long ReadQHead = 0;
static unsigned long ReadQTail = 0;
irqreturn_t poll_interrupt (int irq, void *dev_id)
{
unsigned long flags;
local_save_flags(flags);
local_irq_disable();
if (ReadQCount < MAX_QUEUE_CNT) {
ReadQ [ReadQHead] = (unsigned long) inb (POLL_READ_ADDR); /*读数据并保存*/
ReadQHead = (ReadQHead + 1) % MAX_QUEUE_CNT;
ReadQCount++;
}
local_irq_restore(flags);
wake_up_interruptible(&WaitQueue_Read);
return (IRQ_HANDLED);
}
int poll_open (struct inode *inode, struct file *filp)
{
if (!request_irq (POLL_IRQ, poll_interrupt, IRQF_DISABLED, POLL_DEV_NAME, NULL));
outb (POLL_IRQ_ENABLE_MASK, POLL_CTRL_ADDR);
return (0);
}
ssize_t poll_read (struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
unsigned long flags;
int realmax;
int loop;
int retstate;
if ((!ReadQCount) && (filp->f_flags & O_NONBLOCK)) /*无可读数据且应用程序不阻塞调用*/
return (-EAGAIN);
retstate = wait_event_interruptible(WaitQueue_Read, ReadQCount); /*等待,直到 ReadQCount > 0*/
if (retstate) return (retstate); /*被信号打断返回-ERESTARTSYS,条件满足时返回0*/
local_save_flags(flags);
local_irq_disable(); /*处理可以被中断改变的全局变量时要先禁止中断*/
realmax = 0;
if (ReadQCount > 0) {
if (ReadQCount <= count)
realmax = ReadQCount;
else
realmax = count; /*传递所有可读数据,应用程序read要求读取的数据可能会比实际可读的还要多*/
for (loop = 0; loop < realmax; loop++) {
put_user (ReadQ[ReadQTail], (char *) &buf[loop]);
ReadQTail = (ReadQTail + 1) % MAX_QUEUE_CNT;
ReadQCount--;
}
}
local_irq_restore(flags);
return (realmax);
}
ssize_t poll_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
unsigned char status;
int loop;
for (loop = 0; loop < count; loop++) {
get_user (status, (char *)buf);
outb (status, POLL_WRITE_ADDR);
}
return (count);
}
unsigned int poll_poll (struct file *filp, poll_table *wait)
{
unsigned int mask = 0;
poll_wait (filp, &WaitQueue_Read, wait);
if (ReadQCount > 0)
mask |= (POLLIN | POLLRDNORM);
return mask;
}
int poll_release (struct inode *inode, struct file *filp)
{
outb (0x00, POLL_CTRL_ADDR);
free_irq (POLL_IRQ, NULL);
return (0);
}
struct file_operations poll_fops = {
.owner = THIS_MODULE,
.read = poll_read,
.write = poll_write,
.poll = poll_poll,
.open = poll_open,
.release = poll_release,
};
int poll_init (void)
{
int result;
result = register_chrdev (POLL_DEV_MAJOR, POLL_DEV_NAME, &poll_fops);
if (result < 0)
return (result);
return (0);
}
void poll_exit (void)
{
unregister_chrdev (POLL_DEV_MAJOR, POLL_DEV_NAME);
}
module_init(poll_init);
module_exit(poll_exit);
MODULE_LICENSE ("Dual BSD/GPL");
poll Program Start
wait poll
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [3F]
READ DATA COUNT [1]
READ DATA [7F]
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |