Sorry! The testing module is unloading now!
二、向testmodule模块中添加新函数open()、release()、write()和read()
1、函数open( )
int open(struct inode *inode,struct file *filp) {
MOD_INC_USE_COUNT; // 增加该模块的用户数目
printk(“This module is in open!\\n”);
return 0;
}
2、函数release( ) void release(struct inode *inode,struct file *filp)
{
MOD_DEC_USE_COUNT; //该模块的用户数目减1
printk(“This module is in release!\\n”);
return 0;
#ifdef DEBUG
printk(“release(%p,%p)\\n”,inode,filp);
#endif
}
3、函数 read() int read(struct inode *inode,struct file *filp,char *buf,int count) {
int leave;
if(verify_area(VERIFY_WRITE,buf,count) == DEFAULT)
return DEFAULT; for(leave=count;leave>0;leave --)
{
__put_user(1,buf,1);
buf ++; }
return count;
}
4、函数write()
int write(struct inode *inode,struct file *filp,const char *buf,int
count) {
return count;
}
三、模块的测试
在该模块程序编译加载后,再在/dev目录下创建模块设备文件moduledev,使用命令: #mknod /dev/moduledev c major minor ,其中“c”表示moduledev是字符设备,“major”是moduledev的主设备号。 (该字符设备驱动程序编译加载后,可在/proc/modules文件中获得主设备号,或者使用命令: [root@linux /]#cat
/proc/modules | awk ”\\\\$2==\\” moduledev\\”{ print\\\\$1}” 获得主设备号)
#include
#include
#include
#include
main( ) {
int i,testmoduledev;
char buf[10];
testmoduledev=open(“/dev/moduledev”,O_RDWR);
if(testmoduledev == -1) {
printf(“Can’t open the file! \\n”);
exit(0);
}
read(testmoduledev,buf,10);
for(i=0;i<10;i++)
printf(“%d\\n”,buf[i]);
close(testmoduledev);
return 0;
}
实验三、定时器实验
【实验目的】
1、掌握 Linux 下的定时器编程方法; 2、掌握 Linux 下的常用时间函数编程方法。
【实验内容】
1、编写定时器程序 timer; 2、编写 Makefile 文件; 3、下载并调试 timer。
【预备知识】
1、C 语言的基础知识; 2、程序调试的基础知识和方法; 3、Linux 的基本操作;
4、掌握 Linux 下的程序编译与交叉编译过程; 5、掌握 Linux 下基本的应用程序编写方法。
【基础知识】
操作系统应该能够在将来某个时刻准时调度某个任务。所以需要一种能保证任务较准 时调度运行的机制。希望支持每种操作系统的微处理器必须包含一个可周期性中断它的可 编程间隔定时器。这个周期性中断被称为系统时钟滴答,它象节拍器一样来组织系统任务。 Linux 的时钟观念很简单:它表示系统启动后的以时钟滴答记数的时间。所有的系统时钟都基于这种量度,在系统中的名称和一个全局变量相同-jiffies。
Linux 包含两种类型的系统定时器,它们都可以在某个系统时间上被队列例程使用, 但是它们的实现稍有区别。
第一个是老的定时器机制,它包含指向 timer_struct 结构的 32 位指针的静态数组以当 前活动定时器的屏蔽码:time_active。
此定时器表中的位置是静态定义的(类似底层部分处理表 bh_base)。其入口在系统初 始化时被加入到表中。第二种是相对较新的定时器,它使用一个到期时间以升序排列的 timer_list 结构链表。
这两种方法都使用 jiffies 作为终结时间,这样希望运行 5 秒的定时器将不得不将 5 秒 时间转换成 jiffies 的单位并且将它和以 jiffies 记数的当前系统时间相加从而得到定时器的 终结时间。在每个系统时钟滴答时,定时器的底层部分处理过程被标记成活动状态以便调 度管理器下次运行时能进行定时器队列的处理。定时器底层部分处理过程包含两种类型的 系统定时器。老的系统定时器将检查 timer_active 位是否置位。如果活动定时器已经到期则其定时器例程将被调用同时
它的活动位也被清除。新定时 器位于 timer_list 结构链表中的入口也将受到检查。每个过期定时器将从链表中清除,同时 它的例程将被调用。新定时器机制的优点之一是能传递一个参数给定时器例程。
【实验说明】
在本实验应用程序中,需要进行时间相关的编程动作,如获取当前时间,对某一段工 作进行计时处理以及定时执行某一动作等。本实验将介绍如何在 Linux 调用时间相关函数 完成上述功能。
1、获取当前时间 在程序当中,可以使用下面两个函数输出系统当前的时间: time_t time(time_t*tloc); char*ctime(const time_t *clock);
time 函数返回从 1970 年 1 月 1 日 0 点以来的秒数.存储在 time_t 结构之中.这个函 数的返回值由于不够直观,以人类的理解方式,这组抽象的数字似乎缺乏实际意义。所以 我们可以另一个函数 ctime(const time_t *clock)将抽象的时间记录转化为直观的字符串, 以便显示。
2、计时处理
有时候我们要计算程序执行的时间。比如我们要对算法进行时间分析。这个时候可以使用下面这个函数,加在需要计算时间的程序的两端:
int gettimeofday(struct timeval*tv,struct timezone*tz) 第一个参数为 timeval 类型的结构,该结构声明如下: Strut timeval{ Long tv_sec; //秒数 Long tv_usec; }
gettimeofday 将时间保存在结构 tv 之中。 3、定时器
Linux 操作系统为每一个进程提供了 3 个内部间隔计时器。 ITIMER_REAL:减少实际时间。到时的时候发出 SIGALRM 信号。 TIMER_VIRTUAL:减少有效时间(进程执行的时间)。到时的时候产生 SIGVTALRM信号。
ITIME_PROF:减少进程的有效时间和系统时间(为进程调度用的时间)。到时的时候产生 SIGPROF 信号。
具体的操作函数是:
int getitimer(int which,struct itimerval*value); int setitimer(int which,struct itimerval*newvalitimerval*oldval)
,
struct
//微秒数