linux时间类驱动程序
来源:互联网 发布:java完全自学视频 编辑:程序博客网 时间:2024/05/29 07:06
本文例程来自于 lddr3_examples/misc_modules/jit.c
代码经过修改,使用insmod加载模块后可以运行
先贴makefile
modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions.PHONY: modules modules_install cleanelse # called from kernel build system: just declare what our modules are obj-m := hello.o hellop.o seq.o jit.o jiq.o sleepy.o complete.o \ silly.o faulty.o kdatasize.o kdataalign.oendif
jit.c代码
#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/sched.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 <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;//1sswitch((long)data) {//忙等待 cpu会一直relax,不会有任务的调度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","HZ=\n"; j1, j2, (int) tv1.tv_sec, (int) tv1.tv_usec, (int) tv2.tv_sec, (int) tv2.tv_nsec,(int)HZ);*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);
jit.c里面。先定义处理函数,再使用create_proc_read_entry("name",0,NULL,fuc,传递的参数)
来给每个处理函数在/proc目录下创建一个动态的记录信息文件,函数里面需要使用sprintf来打印东西,打印的东西会再/proc/name文件里面有记录
使用cat就可以看到,或者 head -10 /proc/name
以currenttime为例
sudo insmod jit.ko后会在/proc下建立 /proc/currenttime这歌文件
使用head -10 /proc/currenttime 会读到如下数据
0x00161edc 0x0000000100161edc 1350636696.283261 1350636696.278695256HZ=2500x00161edc 0x0000000100161edc 1350636696.283268 1350636696.278695256HZ=2500x00161edc 0x0000000100161edc 1350636696.283272 1350636696.278695256HZ=250
是cpu的相关时间。本实验完成
- linux时间类驱动程序
- linux 设备驱动程序 时间流 总结
- linux设备驱动程序第二版 时间流
- 时间、延迟(Linux设备驱动程序)
- linux 设备驱动程序 时间流 之 延迟执行 --转载
- linux 设备驱动程序 时间流 之 延迟执行 -1
- linux 设备驱动程序 时间流 之 延迟执行 -2
- 转载:Linux设备驱动程序学习- 时间、延迟及延缓操作
- 【Linux设备驱动程序(第三版)】----获取当前时间
- linux设备驱动程序学习(7) 时间、延迟及延缓操作
- 《Linux设备驱动程序》——时间、延迟及延缓操作
- Linux驱动程序
- Linux驱动程序
- linux驱动程序
- linux驱动程序
- Linux驱动程序入门-----------------------------驱动程序框架
- linux设备驱动程序--类class的实现
- Linux设备驱动程序学习———时间、延迟及延缓操作
- ORACLE 创建表空间、创建用户 .
- 哲学中的推理规则 —— 《自然哲学之数学原理》
- 根据表名查找所在的数据库名(用游标)
- 用Python实现Windows上的气泡提醒
- Netstat命令详解 如何关闭TIME_WAIT连接 如何查看nginx的访问流量
- linux时间类驱动程序
- Android图片圆角
- http 1.1 协议错误代码解析
- Android重力感应 .
- BMP文件结构
- 利用PLSQL工具导入导出数据库 .
- Hough变换原理
- windows查找进程关闭进程
- 用Python找出文件中使用率最高的汉字