Linux设备驱动程序 之 tasklet
多数情况下,为了控制一个寻常的硬件设备,tasklet机制都是实现自己下半部的最佳选择;tasklet可以动态创建,使用方便,执行起来还算快;
声明tasklet
tasklet既可以静态的创建,也可以动态的创建;如果准备静态的创建一个tasklet,可以使用下面的两个宏之一:
#define DECLARE_TASKLET(name, func, data) \
struct tasklet_struct name = { NULL, , ATOMIC_INIT(), func, data } #define DECLARE_TASKLET_DISABLED(name, func, data) \
struct tasklet_struct name = { NULL, , ATOMIC_INIT(), func, data }
两个宏都能根据给定的名称静态的创建一个tasklet_struct结构;当该tasklet被调度以后,给定函数func会被执行,它的参数是data;前面一个宏创建的tasklet的引用计数设置为0,该tasklet处于激活状态;另一个宏引用计数为1,该tasklet处于禁止状态;
tasklet处理程序
tasklet处理程序必须符合以下定义:
void tasklet_handler(ungigned long data)
因为靠软中断实现,所以tasklet不能睡眠;这意味着你不能再tasklet中使用信号量或者其他阻塞式的函数;由于tasklet运行时允许响应中断,所以必须做好预防工作,如果你的tasklet和中断处理程序之间共享了某些数据的话;两个相同的tasklet绝不会同时执行,这点和软中断不同,尽管两个不同的tasklet可以再两个处理器上同时执行;如果tasklet和其他的tasklet或者软中断共享了数据,就必须进行锁保护;
调度tasklet
通过调用tasklet_schedule()函数并传递给它们相应的tasklet_struct指针,该tasklet就会被调度以便执行;
void tasklet_schedule(struct tasklet_struct *t)
在tasklet被调度以后,只要有机会它就会尽可能早的运行。在它还没有得到运行机会之前,如果有一个相同的tasklet又被调度了,那么它只会运行一次;如果这时它已经开始运行了,比如说在另外一个处理器上,那么这个新的tasklet会被调度并再次运行;作为一种优化措施,一个tasklet总在调度它的处理器上执行–这是希望能更好的利用处理器的高速缓存;
禁用启用tasklet
tasklet_disable()用来禁止某个指定的tasklet,如果该tasklet当前正在执行,这个函数会等到它执行完毕再返回;还可以调用tasklet_disable_nosync(),它也用来禁止指定的tasklet,不过它无需等待tasklet执行完毕,这么做通常不安全,因为无法估计tasklet是否仍在执行;调用tasklet_enable()可以激活一个tasklet,如果希望激活DECLARE_TASKLET_DISABLED()宏创建的tasklet,也需要调用这个函数;
void tasklet_disable_nosync(struct tasklet_struct *t)
void tasklet_disable(struct tasklet_struct *t) void tasklet_enable(struct tasklet_struct *t)
删除挂起tasklet
可以通过调用tasklet_kill()从挂起的队列中去掉一个tasklet,该函数的参数一个指向某个tasklet的tasklet_struct指针;在处理一个经常重新调度它自身的tasklet的时候,从挂起的队列中移除已调度的tasklet很有用;这个函数首先等待tasklet执行完毕,然后再将它移除;当然,没什么方法可以阻止其他地方的代码重新调度该tasklet;由于该函数可能引起休眠,所以禁止在中断上下文中使用;
void tasklet_kill(struct tasklet_struct *t)
ksoftirq
每个处理器都有一组辅助处理软中断(和tasklet)的内核线程;当内核中出现大量的软中断的时候,这些内核线程就会辅助处理它们;
每个处理器都有一个处理线程,名字叫做ksoftirqd/n,区别在于n,它对应着处理器的编号;在一个双处理器上就有两个这样的线程,分别叫ksoftirq/0和ksoftirq/1;为了保证只要有空闲的处理器,就会处理软中断,所以每个处理器都会分配一个这样的线程;一旦初始化,就会执行死循环处理中断;只要有待处理的中断,ksoftirq就会调度do_softirq()去处理它们;当所有中断处理完成之后,内核线程将自己设置为TASK_INTERRUPTIBLE状态,以唤起调度程序选择其他可执行线程投入运行;
Linux设备驱动程序 之 tasklet的更多相关文章
- linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)
原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...
- 【转】linux设备驱动程序中的阻塞机制
原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...
- Linux设备驱动程序 第三版 读书笔记(一)
Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...
- Linux设备驱动程序学习之分配内存
内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...
- 教你写Linux设备驱动程序:一个简短的教程
教你写Linux设备驱动程序:一个简短的教程 http://blog.chinaunix.net/uid-20799298-id-99675.html
- linux设备驱动程序_hello word 模块编译各种问题集锦
在看楼经典书籍<linux设备驱动程序>后,第一个程序就是编写一个hello word 模块. 原以为非常easy,真正弄起来,发现问题不少啊.前两天编过一次,因为没有记录,今天看的时候又 ...
- Linux设备驱动程序学习----1.设备驱动程序简介
设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介 Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...
- Linux设备驱动程序学习----2.内核模块与应用程序的对比
内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...
- Linux设备驱动程序学习----3.模块的编译和装载
模块的编译和装载 更多内容请参考Linux设备驱动程序学习----目录 1. 设置测试系统 第1步,要先从kernel.org的镜像网站上获取一个主线内核,并安装到自己的系统中,因为学习驱动程序的编写 ...
随机推荐
- 前端:table、thead、th、tr、td
table:表格:thead:表头:tr:行:td:单元格:th:一行的首个单元格 tbody包含行的内容下载完优先显示,不必等待表格结束.另外,还需要注意一个地方.表格行本来是从上向下显示的.但是, ...
- JavaScript--常用对象的属性及方法(3)
String对象(字符串) 字符串在本质上也是数组 都可以通过str[i]访问内容 但是数组创建后可以修改 而字符串一旦创建内容不可更改 属性:length 作用与数组相同 获取字符串的长度 方法: ...
- 还在用ABAP进行SAP产品的二次开发?来了解下这种全新的二次开发理念吧
Jerry从2018年底至今,已经写了一系列关于SAP Kyma的文章,您可以移步到本文末尾获得这些文章的列表.Kyma是SAP开源的一个基于Kubernetes的云原生应用开发平台,能够允许SAP的 ...
- Metasploit Penetration (第一夜加班)
1.最近白天瞒着上班,晚自习看英语,还要瞒着写论文(现在是看,之前的部分章节被老师否定了,现在开始要从新进行整理)所以只有这晚上来开始看我的渗透测试了,发现渗透的很多知识,只要你平时不用很快就会生疏, ...
- golang的序列化与反序列化的几种方式
golang用来序列化的模块有很多,我们来介绍3个. json 首先登场的是json,这个几乎毋庸置疑. 序列化 package main import ( "encoding/json&q ...
- DNS zone file
zone file格式最初由Berkeley Internet Name Domain(BIND)软件包使用,但已被其他DNS server software广泛采用.它们中的一些(例如NSD,Pow ...
- Go语言—— Array,Slice,Map 和 Set
转自:https://se77en.cc/ Array(数组) 内部机制 在 Go 语言中数组是固定长度的数据类型,它包含相同类型的连续的元素,这些元素可以是内建类型,像数字和字符串,也可以是结构类型 ...
- Linux 02 Linux基本概念及操作
基本echo "hello word" 输出 hello wordtouch file 创建文件名为file 常用快捷键TAB:在忘记命令时,可以用来补全命令Ct ...
- idou老师教你学istio 21:基于角色的访问控制
istio的授权功能,也称为基于角色的访问控制(RBAC),它为istio服务网格中的服务提供命名空间级别.服务级别和方法级别的访问控制.基于角色的访问控制具有简单易用.灵活和高性能等特性.本文介绍如 ...
- gorm 更新数据时,0值会被忽略
原文: https://www.tizi365.com/archives/22.html ------------------------------------------------------- ...