linux设备驱动之时间,延迟及延缓操作(实践)

2024-02-21 09:48

本文主要是介绍linux设备驱动之时间,延迟及延缓操作(实践),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 jit.函数源码

/** jit.c -- the just-in-time module** Copyright (C) 2001,2003 Alessandro Rubini and Jonathan Corbet* Copyright (C) 2001,2003 O'Reilly & Associates** The source code in this file can be freely used, adapted,* and redistributed in source or binary form, so long as an* acknowledgment appears in derived source files.  The citation* should list that the code comes from the book "Linux Device* Drivers" by Alessandro Rubini and Jonathan Corbet, published* by O'Reilly & Associates.   No warranty is attached;* we cannot take responsibility for errors or fitness for use.** $Id: jit.c,v 1.16 2004/09/26 07:02:43 gregkh Exp $*/#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>#include <linux/time.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>#include <linux/param.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/sched.h>#include <asm/hardirq.h>
/** This module is a silly one: it only embeds short code fragments* that show how time delays can be handled in the kernel.*/int delay = HZ; /* the default delay, expressed in jiffies */module_param(delay, int, 0);MODULE_AUTHOR("Alessandro Rubini");
MODULE_LICENSE("Dual BSD/GPL");/* use these as data pointers, to implement four files in one function */
enum jit_files {JIT_BUSY,JIT_SCHED,JIT_QUEUE,JIT_SCHEDTO
};/** This function prints one line of data, after sleeping one second.* It can sleep in different ways, according to the data pointer*/
int jit_fn(char *buf, char **start, off_t offset,int len, int *eof, void *data)
{unsigned long j0, j1; /* jiffies */wait_queue_head_t wait;init_waitqueue_head (&wait);j0 = jiffies;j1 = j0 + delay;switch((long)data) {case JIT_BUSY:while (time_before(jiffies, j1))cpu_relax();break;case JIT_SCHED:while (time_before(jiffies, j1)) {schedule();}break;case JIT_QUEUE:wait_event_interruptible_timeout(wait, 0, delay); break;case JIT_SCHEDTO:set_current_state(TASK_INTERRUPTIBLE);schedule_timeout (delay);break;}j1 = jiffies; /* actual value after we delayed */len = sprintf(buf, "%9li %9li\n", j0, j1);*start = buf;return len;
}/** This file, on the other hand, returns the current time forever*/
int jit_currentime(char *buf, char **start, off_t offset,int len, int *eof, void *data)
{struct timeval tv1;struct timespec tv2;unsigned long j1;u64 j2;/* get them four */j1 = jiffies;j2 = get_jiffies_64();do_gettimeofday(&tv1);tv2 = current_kernel_time();/* print */len=0;len += sprintf(buf,"0x%08lx 0x%016Lx %10i.%06i\n""%40i.%09i\n",j1, j2,(int) tv1.tv_sec, (int) tv1.tv_usec,(int) tv2.tv_sec, (int) tv2.tv_nsec);*start = buf;return len;
}/** The timer example follows*/int tdelay = 10;
module_param(tdelay, int, 0);/* This data structure used as "data" for the timer and tasklet functions */
struct jit_data {struct timer_list timer;struct tasklet_struct tlet;int hi; /* tasklet or tasklet_hi */wait_queue_head_t wait;unsigned long prevjiffies;unsigned char *buf;int loops;
};
#define JIT_ASYNC_LOOPS 5void jit_timer_fn(unsigned long arg)
{struct jit_data *data = (struct jit_data *)arg;unsigned long j = jiffies;data->buf += sprintf(data->buf, "%9li  %3li     %i    %6i   %i   %s\n",j, j - data->prevjiffies, in_interrupt() ? 1 : 0,current->pid, smp_processor_id(), current->comm);if (--data->loops) {data->timer.expires += tdelay;data->prevjiffies = j;add_timer(&data->timer);} else {wake_up_interruptible(&data->wait);}
}/* the /proc function: allocate everything to allow concurrency */
int jit_timer(char *buf, char **start, off_t offset,int len, int *eof, void *unused_data)
{struct jit_data *data;char *buf2 = buf;unsigned long j = jiffies;data = kmalloc(sizeof(*data), GFP_KERNEL);if (!data)return -ENOMEM;init_timer(&data->timer);init_waitqueue_head (&data->wait);/* write the first lines in the buffer */buf2 += sprintf(buf2, "   time   delta  inirq    pid   cpu command\n");buf2 += sprintf(buf2, "%9li  %3li     %i    %6i   %i   %s\n",j, 0L, in_interrupt() ? 1 : 0,current->pid, smp_processor_id(), current->comm);/* fill the data for our timer function */data->prevjiffies = j;data->buf = buf2;data->loops = JIT_ASYNC_LOOPS;/* register the timer */data->timer.data = (unsigned long)data;data->timer.function = jit_timer_fn;data->timer.expires = j + tdelay; /* parameter */add_timer(&data->timer);/* wait for the buffer to fill */wait_event_interruptible(data->wait, !data->loops);if (signal_pending(current))return -ERESTARTSYS;buf2 = data->buf;kfree(data);*eof = 1;return buf2 - buf;
}void jit_tasklet_fn(unsigned long arg)
{struct jit_data *data = (struct jit_data *)arg;unsigned long j = jiffies;data->buf += sprintf(data->buf, "%9li  %3li     %i    %6i   %i   %s\n",j, j - data->prevjiffies, in_interrupt() ? 1 : 0,current->pid, smp_processor_id(), current->comm);if (--data->loops) {data->prevjiffies = j;if (data->hi)tasklet_hi_schedule(&data->tlet);elsetasklet_schedule(&data->tlet);} else {wake_up_interruptible(&data->wait);}
}/* the /proc function: allocate everything to allow concurrency */
int jit_tasklet(char *buf, char **start, off_t offset,int len, int *eof, void *arg)
{struct jit_data *data;char *buf2 = buf;unsigned long j = jiffies;long hi = (long)arg;data = kmalloc(sizeof(*data), GFP_KERNEL);if (!data)return -ENOMEM;init_waitqueue_head (&data->wait);/* write the first lines in the buffer */buf2 += sprintf(buf2, "   time   delta  inirq    pid   cpu command\n");buf2 += sprintf(buf2, "%9li  %3li     %i    %6i   %i   %s\n",j, 0L, in_interrupt() ? 1 : 0,current->pid, smp_processor_id(), current->comm);/* fill the data for our tasklet function */data->prevjiffies = j;data->buf = buf2;data->loops = JIT_ASYNC_LOOPS;/* register the tasklet */tasklet_init(&data->tlet, jit_tasklet_fn, (unsigned long)data);data->hi = hi;if (hi)tasklet_hi_schedule(&data->tlet);elsetasklet_schedule(&data->tlet);/* wait for the buffer to fill */wait_event_interruptible(data->wait, !data->loops);if (signal_pending(current))return -ERESTARTSYS;buf2 = data->buf;kfree(data);*eof = 1;return buf2 - buf;
}int __init jit_init(void)
{create_proc_read_entry("currentime", 0, NULL, jit_currentime, NULL);create_proc_read_entry("jitbusy", 0, NULL, jit_fn, (void *)JIT_BUSY);create_proc_read_entry("jitsched",0, NULL, jit_fn, (void *)JIT_SCHED);create_proc_read_entry("jitqueue",0, NULL, jit_fn, (void *)JIT_QUEUE);create_proc_read_entry("jitschedto", 0, NULL, jit_fn, (void *)JIT_SCHEDTO);create_proc_read_entry("jitimer", 0, NULL, jit_timer, NULL);create_proc_read_entry("jitasklet", 0, NULL, jit_tasklet, NULL);create_proc_read_entry("jitasklethi", 0, NULL, jit_tasklet, (void *)1);return 0; /* success */
}void __exit jit_cleanup(void)
{remove_proc_entry("currentime", NULL);remove_proc_entry("jitbusy", NULL);remove_proc_entry("jitsched", NULL);remove_proc_entry("jitqueue", NULL);remove_proc_entry("jitschedto", NULL);remove_proc_entry("jitimer", NULL);remove_proc_entry("jitasklet", NULL);remove_proc_entry("jitasklethi", NULL);
}module_init(jit_init);
module_exit(jit_cleanup);

二 Makefilewenjian源码

KERNELDIR = /usr/src/linux-headers-2.6.38-8-generic
PWD := $(shell pwd)obj-m := jit.o modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

三 编译及安装驱动

1  caoyin@caoyin:~/jit$ make

2 root@caoyin:/home/caoyin/jit# insmod ./jit.ko

四 测试例子

a 获取当前时间

root@caoyin:/home/caoyin/jit# head -8 /proc/currentime

b 忙等待

root@caoyin:/home/caoyin/jit# dd bs=20 count=5 < /proc/jitbusy

c 让出处理器

root@caoyin:/home/caoyin/jit# dd bs=20 count=5 < /proc/jitshed

d 超时

root@caoyin:/home/caoyin/jit# dd bs=20 count=5 < /proc/jitqueue

e tasklet的实现

root@caoyin:/home/caoyin/jit# cat /proc/jitasklet



这篇关于linux设备驱动之时间,延迟及延缓操作(实践)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/731364

相关文章

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n