tasklet_schedule函数功能描述:此函数是一个内联函数,调用了函数__tasklet_schedule( )。函数首先进行软中断状态的检查,如果当前中断没有被加入中断等待队列中,即没有被调度,则函数tasklet_schedule( )更改中断的状态值,设置state字段的值为1,即说明此中断被调度,加入中断等待队列中,然后调用函数__tasklet_schedule( )将中断加入tasklet_vec中断向量链表的尾部,等待获得CPU资源并被调度执行。与tasklet_hi_vec相比,此中断向量链表是一个普通的中断向量链表,中断的优先级较低。
tasklet_schedule文件包含
#include<linux/interrupt.h>
tasklet_schedule函数定义
在内核源码中的位置:linux-3.19.3/include/linux/interrupt.h
函数定义格式:
static inline void tasklet_schedule(struct tasklet_struct *t)
{
if (! test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
__tasklet_schedule(t);
}
tasklet_schedule输入参数说明
此函数的输入参数是struct tasklet_struct结构体类型的指针变量,代表软中断的描述符信息,其定义及详细解释参考函数__tasklet_hi_schedule( )分析文档的输入参数说明部分。
tasklet_schedule返回参数说明
此函数的返回值是void类型的变量,即函数不返回任何值。
tasklet_schedule实例解析:
编写测试文件:tasklet_schedule.c
头文件引用及全局变量声明:
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static unsigned long data=0;
static struct tasklet_struct tasklet;
中断处理函数定义:
// 自定义软中断处理函数,在此只有显示功能
static void irq_tasklet_action(unsigned long data)
{
printk("in the irq_tasklet_action the state of the tasklet is :%ld\n",(&tasklet)->state); //显示中断状态
printk("tasklet running. by author\n");
return;
}
模块初始化函数,验证函数的调用:
static int __init tasklet_schedule_init(void)
{
printk("into tasklet_schedule\n");
tasklet_init(&tasklet, irq_tasklet_action, data);
//初始化一个struct tasklet_struct变量,对应一个软中断
printk("the state of the tasklet after tasklet_init is :%ld\n", (&tasklet)->state);
// 显示软中断状态
tasklet_schedule(&tasklet); //将中断变量放入软中断执行队列
printk("the state of the tasklet after tasklet_schedule is :%ld\n",
(&tasklet)->state); //显示中断状态
printk("out tasklet_schedule_init\n");
return 0;
}
模块退出函数:
static void __exit tasklet_schedule_exit(void)
{
printk("Goodbye tasklet_schedule\n");
return;
}
模块加载、退出函数的调用:
module_init(tasklet_schedule_init);
module_exit(tasklet_schedule_exit);
实例运行结果及分析:
编译模块,执行命令insmod tasklet_schedule.ko加载模块,然后输入命令dmesg -c查看内核输出信息,出现如图所示结果。
结果分析:
由图可以看出函数tasklet_schedule( )执行之后,中断的状态值变为1, state字段的bit[0]被设置为1,即当前中断处于被调度状态,已经被加入中断向量链表。模块加载函数执行之后,中断处理函数被调度执行了,如果注释掉函数tasklet_schedule( ),不会出现图所示的结果,中断处理函数不会被调度执行。