您的位置:首页 > 运维架构 > Linux

Linux 驱动中工作队列的使用

2017-05-18 17:10 531 查看
工作队列

struct work_struct my_wq;//定义一个处理函数

void my_wq_func(unsigned long);//定义一个处理函数

通过INIT_WORK()可以初始化这个工作队列并将工作队列与处理函数绑定,

INIT_WORK(&my_wq,(void(*)(void*)) my_wq_func, NULL);

shedule_work(&my_wq);//调度工作队列执行。

10.3 工作队列使用模板

//定义工作队列和关联函数

struct work_struct xxx_wq;

void xxx_do_work(unsigned long);

//中断处理底半部

void xxx_do_work(unsigned long)

{
....

}

//中断顶半部

irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)

{
...
schedule_work(&xxx_wq);
...

}

//设备驱动模块加载函数

int xxx_init(void)

{
....
//申请中断
result = request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, "XXX", NULL);
//初始化工作队列
INIT_WORK(&xxx_wq, (void(*)(void *)) xxx_do_work,NULL);
...

}

void xxx_exit(void)

{
free_irq(xxx_irq, xxx_interrupt);

}

工作队列相关:

struct work_struct pen_event_work;

struct workqueue_struct *ts_workqueue;

flush_workqueue

cancel_work_sync(&pen_event_work);

destroy_workqueue(ts_workqueue);

work_pending(work_struct)//找出work_struct是否在pending状态

如:在中断处理上下文里的用法

static irqreturn_t gsl_ts_irq(int irq, void *dev_id)

{
struct gsl_ts *ts = dev_id;

if (ts->is_suspended == true) 
return IRQ_HANDLED;

print_info("==========GSLX680 Interrupt============\n");
 

disable_irq_nosync(ts->irq); //关中断

if (!work_pending(&ts->work)) //判断中断下文处理函数是否在pending
{
queue_work(ts->wq, &ts->work);
}

return IRQ_HANDLED;

}

==============================================================

struct work_struct stk_acc_work;

struct workqueue_struct *stk_acc_wq; //

static void stk_acc_poll_work_func(struct work_struct *work)

{
struct stk831x_data *stk = container_of(work, struct stk831x_data, stk_acc_work);

STK831x_ReadSensorData(stk);
STK831x_ReportValue(stk);
return;

}

stk_acc_wq = create_singlethread_workqueue("stk_acc_wq");//创建单线程。create_workqueue:为每一个CPU都创建一个内核线程。

INIT_WORK(&stk->stk_acc_work, stk_acc_poll_work_func);

queue_work(stk->stk_acc_wq, &stk->stk_acc_work);

destroy_workqueue(stk->stk_acc_wq);//销毁工作队列。

================================================================================

================================================================================

#include <linux/workqueue.h>

struct workqueue_struct;

struct work_struct;

struct delayed_work

struct workqueue_struct *create_workqueue(const char *name);

void destroy_workqueue(struct workqueue_struct *queue);

INIT_WORK(_work, _func);

INIT_DELAYED_WORK(_work, _func);

int queue_work(struct workqueue_struct *wq, struct work_struct *work);

int queue_delayed_work(struct workqueue_struct *wq,struct delayed_work *dwork, unsigned long delay);

int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,

            struct delayed_work *dwork, unsigned long delay);

int cancel_work_sync(struct work_struct *work);

int cancel_delayed_work_sync(struct delayed_work *dwork);

void flush_workqueue(struct workqueue_struct *wq);

 struct work_struct  ps_work; //work 工作

 struct workqueue_struct *ps_wq; //queue 队列

 

 INIT_WORK(work_struct, do_func);

 

序号    接口函数                           说明

 1      create_workqueue     用于创建一个workqueue队列,为系统中的每个CPU都创建一个内核线程。输入参数:
    @name:workqueue的名称

   

 2      create_singlethread_workqueue      用于创建workqueue,只创建一个内核线程。输入参数:@name:workqueue名称

 3      destroy_workqueue   释放workqueue队列。输入参数:@ workqueue_struct:需要释放的workqueue队列指针

 4      schedule_work 调度执行一个具体的任务,执行的任务将会被挂入Linux系统提供的workqueue——keventd_wq输入参数:

  @ work_struct:具体任务对象指针
 

 

 5      schedule_delayed_work              延迟一定时间去执行一个具体的任务,功能与schedule_work类似,多了一个延迟时间,输入参数: 
@delayed_work:具体任务对象指针
@delay:延迟时间
 

queue_work(struct workqueue_struct *wq,struct work_struct *work)
 

:调度执行一个指定中的wq任务。输入参数:@ workqueue_struct:指定的wq指针
@work_struct:具体任务对象指针

 7      queue_delayed_work 延迟调度执行一个指定workqueue中的任务,功能与queue_work类似,输入参数多了一个delay。

//delay work的用法

定义全局变量:

     #ifdef TPD_ESD_PROTECT

     #define TPD_ESD_CHECK_CIRCLE        2000

     static struct delayed_work gsl_esd_check_work;

     static struct workqueue_struct *gsl_esd_check_workqueue = NULL;

     #endif

 

初始化:

    #ifdef TPD_ESD_PROTECT

    INIT_DELAYED_WORK(&gsl_esd_check_work, gsl_esd_check_func);

    gsl_esd_check_workqueue = create_workqueue("gsl_esd_check");

    #endif

 

开启定时:

    queue_delayed_work(gsl_esd_check_workqueue, &gsl_esd_check_work, TPD_ESD_CHECK_CIRCLE);

 

关闭定时:

    cancel_delayed_work_sync(&gsl_esd_check_work);

    

中断函数:

    static void gsl_esd_check_func(struct work_struct *work) //函数的参数一定要为(struct work_struct *)结构指针类型。

    {

        **************************

    }

================================================================================

//android  early_suspend  

===================
4000
=============================================================

#if defined(CONFIG_HAS_EARLYSUSPEND)
struct early_suspend early_suspend;

#endif

#ifdef CONFIG_HAS_EARLYSUSPEND

static void gsl_ts_early_suspend(struct early_suspend *h)

{
struct gsl_ts *ts = container_of(h, struct gsl_ts, early_suspend);
print_info("gsl1680 call func start%s\n", __func__);

}

static void gsl_ts_late_resume(struct early_suspend *h)

{
struct gsl_ts *ts = container_of(h, struct gsl_ts, early_suspend);
print_info("gsl1680 call func end %s\n", __func__);

}

#endif

int xxx_init(void)

{
#ifdef CONFIG_HAS_EARLYSUSPEND
early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; //级别 也就是先后顺序
early_suspend.suspend = gsl_ts_early_suspend;
early_suspend.resume = gsl_ts_late_resume;
register_early_suspend(&early_suspend);
#endif

}

void xxx_exit(void)

{
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&early_suspend);
#endif

}

======================================================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: