在该驱动中,我们假设对键盘的获取是以0.2s为周期执行。源代码如下
static struct timer_list timer///////我们定义的定时器,也许你会问timer_list是什么来的,其实一看名称就应该就知道了,而为什么要用到list那么多定时器呢?其实在linux中还有很多相同的定义,比如说信号,我们定义的也是信号集,你可以定义该list是一个元素的,也可以是多个的。所以对于 timer_list就可以这样描述:在未来某一个特定时刻执行某一系列特定任务的功能。下面我们还会给出内核中timer_list的具体描述,^_^ 好像我的话又说多了
static int Keypad_starttimer(void)
{
init_timer(&timer)//初始化定时器结构
timer.function=Keypad_timer//超时服务程序
timer.expires=jiffies+20//当前时刻加0.2s
add_timer(&timer)
return 0
}
///超时服务程序
static void Keypad_timer(unsigned long data)
{
read_xy()
}
/////////接下来说下timer-list这个数据结构,如果你不感兴趣的话可以跳过,该结构在include\linux\timer.h中定义
struct timer_list
{
struct list_head entry
unsigned long expries
spinlock_t lock
unsigned long magic
void (*function)(unsigned long)
unsigner long data
struct tvec_t_base_s *base
}
在用户程序执行读 *** 作的时候有可能尚且没有数据可以读取,为此需要让read *** 作等待,直到有数据可以读取,这就是阻塞型i\o,阻塞型io可以通过使用进程休眠方法实现。在无数据可以读取的时候,采用等待队列让进程休眠,直到有数据到达的时候才唤醒进程完成数据的读 *** 作。
在本驱动中的read,若循环队列缓冲区中没有数据,则进程进入休眠态,定时器函数每隔0.2s读取键值一次,将按键状态放入缓冲并且适时唤醒进程读取数据。
等待队列的使用流程如下:
1.声明一个等待队列
2.把当前进程加入到等待队列中
3.把进程的状态设置为TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE
4.调用schedule,以让出cpu
5.检测所需要的资源是否可用,若是,把当前进程从等待队列中删除,否则转3循环
接下来我们在对read中有关等待队列阻塞实现做具体的解释
static ssize_t Keypad_read(struct file *filp,char *buf,ssize_t count,loff_t *l)
{
DECLEARE_WAITQUEUE(wait,current)//声明等待队列,将当前进程加入到等待队列中
KEY_EVENT t
ulong out_buf[2]
if(head==tail)//当前循环队列中没有数据可以读取
{
if(filp->f_flags &O_NONBLOCK)//假如用户采用的是非堵塞方式读取
return _EAGAIN
add_wait_queue(&queue,&wait)//将当前进程加入等待队列
current->state=TASK_INTERRUPTIBLE//设置当前进程的状态
while((head==tail)&&!signal_pending(current))//假若还没有数据到循环队列并且当前进程没有受到信号(该类信号具体来说是未决的休眠)
{
shedule()//进程调度
current->state=TASK_INTERRUPTIBLE
}
current->state=TASK_RUNNING//该进程恢复执行
remove_wait_queue(&queue,&wait)//移出等待队列
if(head==tail)
return count
t=get_data()//调用get_data()函数,得到缓冲区中的数据,下面将给予详细的 介绍
out_buf[0]=t.status
out_buf[1]=t.click
copy_to_user(buf,&out_buf,sizeof(out_buf))//将得到的键值拷贝到用户数据区
return count
}
}
以装载和卸载模块为例:
1、首先输入代码
#include <linux/init.h>
#include <linux/module.h>
2、然后输入下方的代码:
static int my_init(void)
{
return 0
}
static void my_exit(void)
3、然后在输入下方的代码:
{
return
}
module_init(my_init)
module_exit(my_exit)这样就完成了。
LINUX服务器定时重启的具体命令如下:
crontab -e
0 1 * * * /sbin/reboot ( 0 1 * * *表示每天凌晨一点重启.)
0 1 * * 1/sbin/reboot (0 1 * * 1表示每周一凌晨一点重启
30 2 * * * /home/bin/oraclebackup.sh (备份数据库和站点目录)
30 3 * * * /home/bin/cmsbackup.sh (备份数据库和站点目录)
[root@localhost ~]# /etc/init.d/crond restart
[root@localhost ~]# chkconfig --levels 35 crond on(重启crond服务)
扩展资料:
在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:
minute hour day month week command
其中:
1.minute: 表示分钟,可以是从0到59之间的任何整数。
2.hour:表示小时,可以是从0到23之间的任何整数。
3.day:表示日期,可以是从1到31之间的任何整数。
4.month:表示月份,可以是从1到12之间的任何整数。
5.week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
6.command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)