跳转至

10.工作队列

实验说明

在中断实验后面修改。工作队列就是通过一个函数触发一个任务,感觉和异步通知有点像。

修改

这部分程序在定时器后面

先在结构体中定义struct work_struct work;

struct key_dev{ 
    struct class *class;        
    struct device *device;
    struct device_node  *nd;
    struct gpio_desc *gpiod;
    struct timer_list timer;
    struct tasklet_struct tasklet;
    struct work_struct work;
    int gpio;
    int irq;
    int major;              
    int minor;              
};

然后在初始化程序中初始化work。需要先定义好处理函数。

//work处理函数
static void key_work_func(struct work_struct *work)
{
    struct key_dev *gpio_key = container_of(work, struct key_dev, work);
    int val;

    val = gpiod_get_value(gpio_key->gpiod);

    printk("key_work_func: the process is %s pid %d\n",current->comm, current->pid);    
    printk("key_work_func key %d %d\n", gpio_key->gpio, val);
}

static int gpio_key_probe(struct platform_device *pdev)
{
    /*注册按键中断及定时器*/

    INIT_WORK(&key.work, key_work_func);

    /*注册设备*/

    return 0;
}

在中断服务函数中使用schedule_work触发这个队列任务

static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{
    struct key_dev *gpio_key = dev_id;
    tasklet_schedule(&gpio_key->tasklet);
    mod_timer(&gpio_key->timer, jiffies + HZ/5);
    schedule_work(&gpio_key->work);
    return IRQ_HANDLED;
}