0
点赞
收藏
分享

微信扫一扫

微服务Gateway服务⽹关

郝春妮 2024-08-29 阅读 34
  • 内核poll的实现

在文件操作结构体中有一个poll函数,我们实现这个函数,并在这个函数中实现阻塞,那么上层调用这个函数就会调用上册函数阻塞。

那么poll阻塞是怎么实现的呢。

  • poll阻塞的实现
  1. 在poll函数里调用 poll_wait()函数。
  2. 在合适的情况下返回合适的值。

当然内核poll阻塞是靠等待队列实现的,所以,要在需要地方唤醒。

  • API函数
 void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
  • 整体实现

在其他地方调用,并设置cond=1;当然也得在别的地方把cond变为0,不然就只在开头阻塞一次

  • 读取按键整体代码
#include "linux/cdev.h"
#include "linux/device.h"
#include "linux/device/class.h"
#include "linux/poll.h"
#include "linux/export.h"
#include "linux/fs.h"
#include "linux/gpio.h"
#include "linux/interrupt.h"
#include "linux/irq.h"
#include "linux/module.h"
#include "linux/of_device.h"
#include "linux/of_gpio.h"
#include "linux/platform_device.h"
#include "linux/poll.h"
#include "linux/printk.h"
#include "linux/timer.h"
#include "linux/types.h"
#include "linux/uaccess.h"
#include "linux/wait.h"
#include "linux/zconf.h"
uint32_t pin;
dev_t dev_num;
struct cdev *cdev;
struct class *cls;
struct device * dev;
uint8_t cond;
struct timer_list timer;

DECLARE_WAIT_QUEUE_HEAD(queue);
uint8_t val;
irqreturn_t fun(int i, void * a)
{

    val=gpio_get_value(pin);
   printk("%d\r\n",val);
    
    mod_timer(&timer, jiffies+msecs_to_jiffies(10));
    return 0;
}
static ssize_t read(struct file *f, char __user *b, size_t s, loff_t *offt)
{
    cond=0;
   // wait_event_interruptible(queue,cond);
    int a=copy_to_user(b,&val,1);
    
    if(a)
    {
        
    }
    return 0;
}
static int open(struct inode *i, struct file *f)
{
    int ret=devm_request_irq(dev, gpio_to_irq(pin),fun,IRQ_TYPE_EDGE_FALLING,"key", NULL);
   printk("%d\r\n",ret);
    return ret;
}
static int close(struct inode *i, struct file *f)
{
  devm_free_irq(dev,gpio_to_irq(pin),NULL);
    return 0;
}
__poll_t poll (struct file *f, struct poll_table_struct *p)
{
    poll_wait(f, &queue, p);
    if(cond==1)
    {
        return EPOLLIN;
    }
    return 0;
}
struct file_operations fops={
   .owner=THIS_MODULE,
   .read=read,
   .open=open,
   .release=close,
   .poll=poll,
};
void func(struct timer_list *tl)
{
    wake_up_interruptible(&queue);
    cond=1;
}
int probe(struct platform_device *d)
{
    timer_setup(&timer, func, 0);
   dev=&d->dev;
    pin=of_get_named_gpio(d->dev.of_node,"key_pin",0);
    printk("%d\r\n",pin);
   printk("%d\r\n", platform_get_irq(d,0));
    printk("irq_num=%d", gpio_to_irq(pin));
    gpio_request(pin,"key");
    gpio_direction_input(pin);
   // devm_request_irq(&d->dev, gpio_to_irq(pin),fun,IRQ_TYPE_EDGE_FALLING,"key", NULL);
    alloc_chrdev_region(&dev_num, 0, 1,"key");
    cdev=cdev_alloc();
    cdev->ops=&fops;
    cdev_add(cdev,dev_num,1);
    cls=class_create(THIS_MODULE, "key");
    device_create(cls, NULL,dev_num,NULL,"key");
    return 0;
}
int remove(struct platform_device *d)
{
    return 0;
}
static struct of_device_id match={
    .compatible="key",
};

static struct platform_driver driver={
    .probe=probe,
    .remove=remove,
    .driver={
        .name="key",
        .of_match_table=&match,
    },
};
static int __init start(void)
{
    platform_driver_register(&driver);
    printk(KERN_INFO "Hello, world!\n");
    return 0;
}
static void __exit stop(void)
{
    platform_driver_unregister(&driver);
    printk(KERN_INFO "Goodbye, world!\n");
}
module_init(start);
module_exit(stop);
MODULE_LICENSE("GPL");
举报

相关推荐

0 条评论