想来都有点恨自己,前几个月遇到的"难题".还是没有解决.一直卡死,又找不出原因.
吐个槽,那些只贴代码不附上运行结果的toturial, 我表示...我就不明白,既然有些bloger代码都给出来了
让我这种渣渣看一下肿么用的会怎么样?看一下你运行结果会怎么样?
说明:额...这个问题"贴"没有附上运行结果,是因为直接会卡死我的Linux主机,然后我压根没办法截屏给大家看,也没办法debug. 希望谅解
------------------------------------------------
问题代码一:
/***********************************************************
code writer : EOF
code date : 2014.09.02
code file : proc_time_delay.c
e-mail : jasonleaster@gmail.com
code purpose:
This code is programmed for how to delay 1 second by
jiffies and HZ.
If there is something wrong with my code, please touch
me by e-mail. Thank you.
************************************************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/proc_fs.h> /* for procfs */
#include <linux/seq_file.h> /* for 'struct seq_file' */
#include <linux/types.h>
#include <linux/jiffies.h> /* for jiffies */
#define PROC_NAME "delay_one_second"
MODULE_AUTHOR("Jason Leaster");
MODULE_LICENSE("Dual BSD/GPL");
static int proc_demo_seq_show(struct seq_file* sfile,void* v)
{
int tmp = 0;
unsigned long jif = jiffies;
unsigned long one_second_later = jiffies + HZ;
for(tmp = 0; tmp < 10;tmp++)
{
while(time_after(one_second_later,jif))
{
jif = jiffies;
}
one_second_later = jif + HZ;
seq_printf(sfile,"Hello world! jiffies:%lu\n",jif);
}
return 0;
}
static void* proc_demo_seq_start(struct seq_file* sfile,loff_t *pos)
{
return NULL;
}
static void proc_demo_seq_stop(struct seq_file* sfile,void* v)
{
/* Nothing to be done. */
}
static void* proc_demo_seq_next(struct seq_file* sfile,void* v,loff_t* pos)
{
return NULL;
}
static struct seq_operations proc_demo_ops =
{
.start = proc_demo_seq_start,
.next = proc_demo_seq_next,
.stop = proc_demo_seq_stop,
.show = proc_demo_seq_show,
};
static int proc_demo_open(struct inode* inode, struct file* filp)
{
return single_open(filp,&proc_demo_seq_show,NULL);
}
struct file_operations proc_demo_fops =
{
.owner = THIS_MODULE,
.open = proc_demo_open,
.read = seq_read,
.release= seq_release,
};
int proc_demo_init(void)
{
struct proc_dir_entry * entry = NULL;
entry = proc_create(PROC_NAME,0,NULL,&proc_demo_fops);
if(!entry)
{
printk(KERN_ALERT "line:%d proc_create failed!",__LINE__);
}
return 0;
}
void proc_demo_exit(void)
{
/*
** The second parameter of 'remove_proc_entry()' is
** a pointer which point to parent directory.We create our
** proc-entry-point in /proc/, so we pass NULL into it.
*/
remove_proc_entry(PROC_NAME,NULL);
}
module_init(proc_demo_init);
module_exit(proc_demo_exit);
/***********************************************************
code writer : EOF
code date : 2014.09.02
code file : proc_time_delay.c
e-mail : jasonleaster@gmail.com
code purpose:
This code is programmed for how to delay by kernel
timer.
If there is something wrong with my code, please touch
me by e-mail. Thank you.
************************************************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/proc_fs.h> /* for procfs */
#include <linux/seq_file.h> /* for 'struct seq_file' */
#include <linux/types.h>
#include <linux/jiffies.h> /* for jiffies */
#include <linux/timer.h> /* for timer*/
#include <linux/sched.h>
#include <linux/slab.h>
#define PROC_NAME "delay_kernel_timer"
MODULE_AUTHOR("Jason Leaster");
MODULE_LICENSE("Dual BSD/GPL");
#define LOOP 5
/*
** First of all, you should make abstract a model
** for our device driver and include the timer.
*/
struct timer_delay_model
{
struct timer_list timer;
wait_queue_head_t wait;
unsigned long prevjiffies;
struct seq_file * output;
int loops ;
/* ... */
};
void jif_timer_fn(unsigned long arg)
{
struct timer_delay_model* p_model = (struct timer_delay_model*)arg;
unsigned long jif = jiffies;
seq_printf(p_model->output,"Hello world! jiffies:%lu\n",jif);
printk(KERN_ALERT "in jif_timer_fc %d\n",p_model->loops);
/*
if(--(p_model->loops))
{
p_model->timer.expires += HZ;
p_model->prevjiffies = jif;
add_timer(&p_model->timer);
}
else
{
wake_up_interruptible(&p_model->wait);
}
*/
p_model->loops = 0;
}
static int proc_demo_seq_show(struct seq_file* sfile,void* v)
{
unsigned long jif = jiffies;
struct timer_delay_model* p_model;
p_model = kmalloc(sizeof(struct timer_delay_model),GFP_KERNEL);
if(!p_model)
{
printk(KERN_ALERT "kmalloc error in %d %s\n",__LINE__,__FUNCTION__);
return -ENOMEM;
}
else
{
printk(KERN_ALERT "start to initialization %lu\n",jiffies);
init_timer(&p_model->timer);
init_waitqueue_head(&p_model->wait);
p_model->prevjiffies = jif;
p_model->output = sfile;
p_model->loops = LOOP;
p_model->timer.data = (unsigned long) sfile;
p_model->timer.function = jif_timer_fn;
p_model->timer.expires = jif + HZ;// delay 1 second
printk(KERN_ALERT "add_timer ing %lu\n",jiffies);
add_timer(&p_model->timer);
}
printk(KERN_ALERT "add_timer finished %lu\n",jiffies);
// wait_event_interruptible(p_model->wait,!(p_model->loops));
while(time_after(p_model->prevjiffies + HZ,jif))
{
jif = jiffies;
}
printk(KERN_ALERT "wait finished\n");
kfree(p_model);
if (signal_pending(current))
return -ERESTARTSYS;
return 0;
}
static void* proc_demo_seq_start(struct seq_file* sfile,loff_t *pos)
{
return NULL;
}
static void proc_demo_seq_stop(struct seq_file* sfile,void* v)
{
/* Nothing to be done. */
}
static void* proc_demo_seq_next(struct seq_file* sfile,void* v,loff_t* pos)
{
return NULL;
}
static struct seq_operations proc_demo_ops =
{
.start = proc_demo_seq_start,
.next = proc_demo_seq_next,
.stop = proc_demo_seq_stop,
.show = proc_demo_seq_show,
};
static int proc_demo_open(struct inode* inode, struct file* filp)
{
return single_open(filp,&proc_demo_seq_show,NULL);
}
struct file_operations proc_demo_fops =
{
.owner = THIS_MODULE,
.open = proc_demo_open,
.read = seq_read,
.release= single_release,
};
int proc_demo_init(void)
{
struct proc_dir_entry * entry = NULL;
entry = proc_create(PROC_NAME,0,NULL,&proc_demo_fops);
if(!entry)
{
printk(KERN_ALERT "line:%d proc_create failed!",__LINE__);
}
return 0;
}
void proc_demo_exit(void)
{
/*
** The second parameter of 'remove_proc_entry()' is
** a pointer which point to parent directory.We create our
** proc-entry-point in /proc/, so we pass NULL into it.
*/
remove_proc_entry(PROC_NAME,NULL);
}
module_init(proc_demo_init);
module_exit(proc_demo_exit);
读过LDD3或者ELDD的读者能够一起交流讨论 : )