全志A33 Linux内核tasklet机制(附实测代码)

简介: Linux 中断编程分为中断顶半部,中断底半部 中断顶半部: 做紧急,耗时短的事情,同时还启动中断底半部。 中断底半部: 做耗时的事件,这个事件在执行过程可以被中断。中断底半部实现方法: tasklet,工作队列,软中断等机制实现。

开发平台

*  芯灵思SinlinxA33开发板

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

image

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

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/]()

image

嵌入式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函数

相关文章
|
8天前
|
API
linux---线程互斥锁总结及代码实现
linux---线程互斥锁总结及代码实现
|
6天前
|
Linux
Linux异步io机制 io_uring
Linux异步io机制 io_uring
13 1
|
8天前
|
API
Linux---线程读写锁详解及代码实现
Linux---线程读写锁详解及代码实现
|
19天前
|
Unix Linux 开发工具
Linux 命令 `ctags`:代码导航的利器
`ctags` 是一款Unix工具,用于生成代码标签,方便在Vim、Emacs等编辑器中快速跳转到函数、变量定义。在Linux上,可通过包管理器安装。使用`ctags -R`生成`tags`文件,然后在Vim中用`Ctrl+]`跳转,`Ctrl+T`返回。Emacs则使用`M-.`和`M-,`。`ctags`可自定义语言映射和排除规则,是提升编程效率的利器。
|
19天前
|
Linux C语言
探索Linux命令c2ph:将C代码转换为PostScript或PDF的奇妙工具
`c2ph`是Linux下的工具,能将C代码转换为PostScript或PDF,便于阅读和分享。通过pretty-print技术美化源代码。安装需从源码编译,使用`c2ph -o &lt;output&gt; &lt;source.c&gt;`生成PostScript文件,再用`ps2pdf`转为PDF。注意它可能不支持复杂格式设置,大型文件处理可能慢,且兼容性有限。适合偶尔需要打印代码副本的情况。
|
弹性计算 运维 NoSQL
Aliyun Linux 实测,效果竟然这么好?
本次性能测试主要使用了公司当前做性能测试使用的几个开源benchmark,分别测试了综合性能、CPU、内存、以及一些典型应用场景,本文中的每项测试指标都是以多次有效测试的平均值作为最终数据,并排除了波动干扰等因素,确保数据真实可靠。
Aliyun Linux 实测,效果竟然这么好?
|
1天前
|
Linux
Linux如何快速执行历史命令
Linux如何快速执行历史命令
14 8
|
1天前
|
存储 安全 Linux
Linux passwd命令:守护账户安全的密钥
`passwd`命令是Linux中管理用户密码的关键工具,确保数据安全。它用于更改密码,采用加密存储,并有锁定/解锁账号、设置密码策略等功能。参数如`-d`删除密码,`-l`锁定账号,`-u`解锁。最佳实践包括定期更改复杂密码,保护root密码,谨慎使用无密码选项。了解和正确使用passwd是保障系统安全的重要步骤。
|
1天前
|
SQL 关系型数据库 数据库
深入探索Linux中的pgawk命令
`pgawk`是`awk`的扩展,带有对PostgreSQL的支持,允许在`awk`脚本中执行SQL查询,简化文本与数据库交互。它保持了`awk`的全部功能,且高效传输数据。使用时,可以通过参数如`-d`、`-h`、`-p`、`-U`和`-W`指定数据库连接详情。示例中展示了如何结合`pgawk`和`psql`从文本文件获取销售数据并联查数据库获取客户名称。在使用时要注意安全连接、优化SQL、测试验证和版本兼容性,以实现有效且安全的数据处理。
|
1天前
|
安全 Linux 数据处理
深入探究Linux的pathchk命令
`pathchk`是Linux命令,用于检查文件名和路径的可移植性,遵循POSIX规范。它检测不可移植字符,确保文件在不同系统间的兼容性。选项如 `-p`, `-P` 和 `--portability` 提供不同级别的检查。基本用法是 `pathchk [选项] [文件名/路径名] [后缀]`。例如,`pathchk /etc/httpd/conf/httpd.conf` 检查路径的可移植性。使用时要注意目标系统的特性,谨慎处理警告,并结合其他命令如`find`使用。在操作前备份数据以防止损失。