一。中断部分
1.中断申请函数 request_irq
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
输入参数:中断号 中断处理函数 中断类型 设备名字 返回给中断处理函数的设备号
成功返回0 失败返回错误代码
2.释放中断
void free_irq(unsigned int irq, void *dev_id)
参数:中断号 中断设备号
3.中断处理函数
static irqreturn_t xxx(int irq, void *dev_id)
二。工作队列部分
中断处理紧急部分,非紧急不涉及到硬件部分的交给工作队列处理,
以便及时响应其他中断。
工作结构:
struct work_struct {
atomic_long_t data;
struct list_head entry;
work_func_t func;
};
方式一:利用系统共享的工作队列添加工作
1. 编写工作处理函数
void my_func();
2.创建工作结构体变量并关联工作处理函数
struct work_struct my_work;
INIT_WORK(&my_work,my_func);
3.将工作结构变量添加入系统的共享工作队列 (通常放在open中)
schedule_work(&my_work); //添加入队列的工作完成后会自动从队列中删除
方式二:创建自己的工作队列来添加工作
1.声明工作处理函数和一个指向工作队列的指针
void my_func();
struct workqueue_struct *p_queue;
2.创建自己的工作队列和工作结构体变量 (通常放在open中)
p_queue = create_workqueue("my_queue"); //创建一个名为my_queue的工作队列
并把工作队列入口地址赋给声明的指针
struct work_struct my_work;
INIT_WORK(&my_work,my_func);
3.将工作添加入自己创建的工作队列中等待执行
queue_work(p_queue,&my_work);
4.删除自己的工作队列 (一般在exit中做)
destroy_workqueue(p_queue);
三。等待队列部分
等待队列头结构:
struct __wait_queue_head {
spinlock_t lock;
//自旋锁变量,用于在对等待队列头
struct list_head task_list;
// 指向等待队列的list_head
};
typedef struct __wait_queue_head wait_queue_head_t;
1.定义等待队列头
声明
wait_queue_head_t wait_que;
初始化
init_waitqueue_head( &wait_que);
/*可以不用
2.等待队列中存放的是在执行设备操作时不能获得资源而挂起的进程
struct __wait_queue {
unsigned int flags;
void *private;
wait_queue_func_t func;
//唤醒阻塞任务的函数 ,决定了唤醒的方式
struct list_head task_list;
// 阻塞任务链表
};
typedef struct __wait_queue wait_queue_t;
//声明一个等待队列并初始化为name
DECLARE_WAITQUEUE(name, tsk)
*/
3.等待
wait_event(wq, condition)
这是一个宏,让当前任务处于等待事件状态。输入参数如下:
@wq:等待队列
@conditions:等待条件
wait_event_timeout(wq, condition, timeout)
功能与wait_event类似,多了一个超时机制。参数中多了一项超时时间。
wait_event_interruptible(wq, condition)
这是一个宏,与前两个宏相比,该宏定义的等待能够被消息唤醒。如果被消息唤醒,那么返回- ERESTARTSYS。输入参数如下:
@wq:等待队列
@condition:等待条件
@rt:返回值
wait_event_interruptible_timeout(wq, condition, timeout)
与上一个相比,多了超时机制
4.唤醒
wake_up(x)
唤醒等待队列中的一个任务
wake_up_interruptible(x)
用于唤醒wake_event_interruptible()睡眠的进程
wake_up_all(x)
唤醒等待队列中的所有任务
补充:
Linux将进程状态描述为如下五种:
TASK_RUNNING:可运行状态。处于该状态的进程可以被调度执行而成为当前进程。
TASK_INTERRUPTIBLE:可中断的睡眠状态。处于该状态的进程在所需资源有效时被唤醒,也可以通过
信号
或
定时中断
唤醒(因为有signal_pending()函数)。
TASK_UNINTERRUPTIBLE:不可中断的睡眠状态。处于该状态的进程仅当所需资源有效时被唤醒。
TASK_ZOMBIE:僵尸状态。表示进程结束且已释放资源,但其task_struct仍未释放。
TASK_STOPPED:暂停状态。处于该状态的进程通过其他进程的信号才能被唤醒。