内核态休眠与唤醒

休眠与唤醒

在中断的简介里面,介绍了四种模式:查询,休眠-唤醒,poll机制,异步通知机制。本节主要说休眠-唤醒机制。

举例:我们在等待按键被按下,可以使用“休眠-唤醒”机制。在应用程序中,等待按键事件发生。

1.APP使用read等操作函数尝试读取硬件底层数据。

2.APP调用read等函数,进入内核态,执行驱动中的对应的函数(file_operatons),发现有数据,复制数据到用户空间并返回。

3.如果在驱动程序中没有数据,进行休眠状态

4.按键按下,休眠的程序(内核态)被唤醒。

5.继续运行内核态代码,复制数据到用户空间并返回。

函数调用流程

 

 

 

驱动中如果没有程序,程序在执行drv_read函数时,在内核态进入会休眠,这样内核调度器不会调度执行它。当按下按键,

驱动程序被唤醒,记录按键数据。唤醒休眠的内核态程序,等待调度器调度执行它。等再次执行,执行drv_read剩下的代码,把数据复制到用户空间。

 

 

 

 

根据上图的历程,涉及两个app。由于休眠,导致其它app被执行。在按下被按下的中断中,唤醒被休眠的程序。

备注:中断程序不能被休眠,中断如果休眠,由哪些来唤醒呢?因此,在中断函数中不能使用会导致休眠的函数。

内核函数

休眠函数

 

Function

说明

wait_event (wq, condition)

休眠,直到condition为真;

休眠期间是可被打断的,可以被信号打断

wait_event_interruptible(wq, condition)

休眠,直到condition为真;

退出的唯一条件是condition为真,信号也不好使

wait_event_interruptible_timeout(wq, condition, timeout)

休眠,直到condition为真或超时;

休眠期间是可被打断的,可以被信号打断

wait_event_timeout(wq, condition, timeout)

休眠,直到condition为真;

退出的唯一条件是condition为真,信号也不好使

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Wq:是一个队列,等待队列。内核态的程序一旦休眠,将其进程放置在该队列,等待后续被唤醒。

如果没有该等待队列变量,无法定位休眠的程序。

Condition:条件变量为真之后,才唤醒休眠的程序。

 

唤醒函数

 

函数

说明

wake_up_interruptible(x)

唤醒x队列中状态为“TASK_INTERRUPTIBLE”的线程,只唤醒其中的一个线程

wake_up_interruptible_nr(x, nr)

唤醒x队列中状态为“TASK_INTERRUPTIBLE”的线程,只唤醒其中的nr个线程

wake_up_interruptible_all(x)

唤醒x队列中状态为“TASK_INTERRUPTIBLE”的线程,唤醒其中的所有线程

wake_up(x)

唤醒x队列中状态为“TASK_INTERRUPTIBLE”或“TASK_UNINTERRUPTIBLE”的线程,只唤醒其中的一个线程

wake_up_nr(x, nr)

唤醒x队列中状态为“TASK_INTERRUPTIBLE”或“TASK_UNINTERRUPTIBLE”的线程,只唤醒其中nr个线程

wake_up_all(x)

唤醒x队列中状态为“TASK_INTERRUPTIBLE”或“TASK_UNINTERRUPTIBLE”的线程,唤醒其中的所有线程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

驱动框架

 

posted @ 2022-07-28 21:44  JwChu  阅读(267)  评论(0编辑  收藏  举报