Linux 中断编程分为中断顶半部,中断底半部

中断顶半部: 做紧急,耗时短的事情,同时还启动中断底半部。

中断底半部: 做耗时的事件,这个事件在执行过程可以被中断。

中断底半部实现方法: tasklet,工作队列,软中断等机制实现。实际上是把耗时事件推后执行,不在中断程序执行。

什么是tasklet?

Tasklet 一词的原意是“小片任务”的意思,这里是指一小段可执行的代码,且通常以函数的形式出现。这个 tasklet 绑定的函数在一个时刻只能在一个 CPU 上运行 ,tasklet(小任务)机制是中断处理下半部分最常用的一种方法,其使用也是非常简单的。一个使用 tasklet 的中断程序首先会通过执行中断处理程序来快速完成上半部分的工作,接着通过调用 tasklet 使得下半部分的工作得以完成。可以看到,下半部分被上半部分所调用,至于下半部分何时执行则属于内核的工作。

tasklet 机制核心数据结构

Interrupt.h linux-3.5\include\Linux
struct tasklet_struct
{
struct tasklet_struct *next; // tasklet_struct 结构链表
unsigned long state; //当前这个 tasklet 是否已经被调度
atomic_t count;
void (*func)(unsigned long); //指向 tasklet 绑定的函数的指针
unsigned long data; //传递给tasklet 绑定的函数的参数
};

tasklet 相关 API

  • 初始化相关

    • 1) 静态初始化 DECLARE_TASKLET(name, func, data)

      作用:定义一个名字为 name 的 tasklet_struct 结构变量,并且初始化这个结构。 所定义的这个 tasklet 是可以被调度,默认是处于被使能状态。

    • 2 ) 静态初始化 DECLARE_TASKLET_DISABLED(name, func, data)

      作用:定义一个名字为 name 的 tasklet_struct 结构变量,并且初始化这个结构。所定义的这个 tasklet 是不能被调度,默认是处于被禁能状态。 要调度这个 tasklet 需要先使能。

    • 3 )动态初始化

      void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data)

      作用:初始化一个 tasklet_struct 结构变量,初始化的结构默认是处于激活状态,可以被调度。

tasklet_disable使能函数

1. void tasklet_disable(struct tasklet_struct *t)

作用:函数激活给定的 tasklet被 tasklet_schedule 调度

2. void tasklet_enable (struct tasklet_struct *t)

作用:函数禁止给定的 tasklet被 tasklet_schedule 调度

tasklet 调度函数

void tasklet_schedule (struct tasklet_struct *t)

作用:调用 tasklet_schedule 函数去通知内核帮我们调度所绑定的函数

void tasklet_kill(struct tasklet_struct *t);

作用:取消调度函数

编程步骤

Step1 定义并静态初始化tasklet_struct 结构变量

Step2 编写tasklet服务函数

Step3 在适当的地地方进行调度

Step4 在适当的地地方取消调度

开发平台

芯灵思SinlinxA33开发板

淘宝店铺: https://sinlinx.taobao.com/

嵌入式linux 开发板交流 QQ:641395230

驱动代码:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h> void tasklet_fun(unsigned long data);
//Step1 定义并静态初始化tasklet_struct 结构变量
DECLARE_TASKLET(mytasklet, tasklet_fun, 651);
//Step2 tasklet服务函数
void tasklet_fun(unsigned long data)
{
static unsigned long count = 0;
printk("count:%lu,%s is call! data:%lu\r\n",count++,__FUNCTION__,data);
tasklet_schedule(&mytasklet); //在工作函数中重新调度自己,这样会循环调用tasklet_fun
}
static int __init mytasklet_init(void)
{
//Step3 开始调度 mytasklet
tasklet_schedule(&mytasklet);
printk("%s is call!\r\n",__FUNCTION__);
return 0;
}
static void __exit mytasklet_exit(void) //Module exit function specified by module_exit()
{
//Step4 删除 tasklet
tasklet_kill(&mytasklet);
}
module_init(mytasklet_init);
module_exit(mytasklet_exit);
MODULE_LICENSE("GPL");

Makefile 代码

KERN_DIR = /work/lichee/linux-3.4
all:
make -C $(KERN_DIR) M=`pwd` modules
arm-none-linux-gnueabi-gcc btntest.c -o btntest
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += tasklet_drv.o

实验现象

循环调用tasklet_fun函数

嵌入式Linux内核tasklet机制(附实测代码)的更多相关文章

  1. 全志A33 linux led驱动编程(附实测参考代码)

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 开发平台 * 芯灵思Sinl ...

  2. Linux内核同步机制--转发自蜗窝科技

    Linux内核同步机制之(一):原子操作 http://www.wowotech.net/linux_kenrel/atomic.html 一.源由 我们的程序逻辑经常遇到这样的操作序列: 1.读一个 ...

  3. Linux内核同步机制

    http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环 ...

  4. Linux内核同步机制之(四):spin lock【转】

    转自:http://www.wowotech.net/kernel_synchronization/spinlock.html 一.前言 在linux kernel的实现中,经常会遇到这样的场景:共享 ...

  5. [内核同步]浅析Linux内核同步机制

    转自:http://blog.csdn.net/fzubbsc/article/details/37736683?utm_source=tuicool&utm_medium=referral ...

  6. Linux内核OOM机制的详细分析(转)

    Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...

  7. Linux内核同步机制之(五):Read Write spin lock【转】

    一.为何会有rw spin lock? 在有了强大的spin lock之后,为何还会有rw spin lock呢?无他,仅仅是为了增加内核的并发,从而增加性能而已.spin lock严格的限制只有一个 ...

  8. Linux内核同步机制之completion【转】

    Linux内核同步机制之completion 内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束.这个活动可能是,创建一个新的内核线程或者新的用户空间进程.对一个已有进程的 ...

  9. 浅析Linux内核同步机制

    非常早之前就接触过同步这个概念了,可是一直都非常模糊.没有深入地学习了解过,最近有时间了,就花时间研习了一下<linux内核标准教程>和<深入linux设备驱动程序内核机制>这 ...

随机推荐

  1. Mac OS X 清除DNS缓存

    参考: Flushing your DNS cache in Mac OS X and Linux Mac OS X 清除DNS缓存 根据Mac OS X操作系统的版本选择以下命令: Mac OS X ...

  2. Linux系统初始配置标准化

    Inux系统标准化 配置环境:4台Centos7.6版本的虚拟机,刚刚最小化安装完成,未作任何操作,分别是node1.node2.node3.node4 本文打算利用ansible工具对这四台虚拟机进 ...

  3. SAP PI

    PI功能很是强大,且系统很稳定. 1.什么是PI PI = Process IntegrationSAP PI是一项集成的技术和平台    1.为sap和non-sap之间提供集成    2.为A2A ...

  4. 从实验室走向世界:HSP90抑制剂,一种新的癌症药物

    热休克蛋白90(HSP90)是细胞内一种普遍存在的.十分保守的以及有高度活性的蛋白质,它在肿瘤细胞内的含量要比正常细胞多.作为一种分子伴侣,HSP90协助不同种类的癌蛋白(即HSP90的服务蛋白)进行 ...

  5. 运行Python出错,提示“丢失api-ms-win-crt-runtime-l1-1-0.dll”

    运行python时出错,提示“丢失api-ms-win-crt-runtime-l1-1-0.dll”, 上网搜了一下说是本地api-ms-win-crt-runtime-l1-1-0.dll 版本过 ...

  6. Node.js的缺陷

    Node.js最大的优点是事件机制,一切皆在回调中触发(不阻塞).我想缺点或许有正在于此,方法没有返回值,而只能在回调中使用返回结果,会导致事件回调嵌套,代码结构很差. 在jQuery中有一套很好的机 ...

  7. pandas中的空值处理

    1.空值 1.1 有两种丢失数据: None: Python自带的数据类型 不能参与到任何计算中 np.nan: float类型 能参与计算,但结果总是nan # None+2 # 报错 # np.n ...

  8. php 添加环境变量

    1.php添加环境变量主要为了能在 cmd和软件的客户端用php来运行 首先我们要做的第一步: 添加环境变量(记住php.exe的路径,然后再环境变量中编辑path 多个用逗号分隔开,保存重启电脑) ...

  9. LSTM如何解决梯度消失或爆炸的?

    from:https://zhuanlan.zhihu.com/p/44163528 哪些问题? 梯度消失会导致我们的神经网络中前面层的网络权重无法得到更新,也就停止了学习. 梯度爆炸会使得学习不稳定 ...

  10. 基于FastJson的通用泛型解决方案

    由于项目使用的是fastjson,也无法换成其他的序列化框架,所以研究了一下他对泛型序列化和反序列化的支持能力,最终解决了这个问题. 要达成的目标 我的封装方式属于通用封装,我要达到的目标是如下的使用 ...