Hello,
I've tried to insmod the module which I attached to this file.
On insmod'ing, the module gets stuck on the
wake_up_interruptible(&timer_queue);
line. If I'm uncommenting this line, everything goes smooth...the timer
runs.
Does somebody know, why the wake_up_interruptible call blocks? What
do I have to do to prevent this? Because I've to wake up processes on every
interrupt.
Best regards,
Juergen
--
Neu bei GMX: Preissenkung für MMS-Versand und FreeMMS!
Ideal für alle, die gerne MMS verschicken:
25 FreeMMS/Monat mit GMX TopMail.
http://www.gmx.net/de/cgi/produktemail
+++ GMX - die erste Adresse für Mail, Message, More! +++
/*
* amu_module.c is based on procfs_example.c by Erik Mouw.
* For more information, please see The Linux Kernel Procfs Guide,
* http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html
*
* J.J. Boor, AimSys bv
* http://www.aimsys.nl
* jjboor@aimsys.nl
*/
/*
${CROSS_COMPILE}gcc -O2 -D__KERNEL__ -DMODULE amu_timer.c -o amu_timer.o
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#define TICK_MAJOR 241
#define MODULE_VERSION "0.1"
#define MODULE_NAME "timer"
static struct proc_dir_entry *timer_file;
static struct timer_list timer;
static unsigned long tick_count = 0;
static int timer_delay = 1;
DECLARE_WAIT_QUEUE_HEAD(timer_queue);
int timer_open(struct inode* inode, struct file* filp);
ssize_t timer_read (struct file *filp, char *buf, size_t count, loff_t *f_pos);
int timer_release(struct inode* inode, struct file* filp);
static struct file_operations timer_fops = {
open: timer_open,
read: timer_read,
release: timer_release
};
static int proc_read_timer(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = sprintf(page, "nr of timer ticks: %lu\n", tick_count);
return len;
}
static int proc_write_timer(struct file *file, const char *buffer,
unsigned long count, void *data)
{
return 0;
}
void timerEvent(unsigned long arg)
{
tick_count++;
wake_up_interruptible(&timer_queue);
timer.expires= jiffies + timer_delay;
add_timer(&timer);
}
int __init init_timer_module(void)
{
/* Create the proc entry and make it readable and writeable by all - 0666 */
timer_file = create_proc_entry("timer", 0666, NULL);
if (timer_file == NULL) {
return -ENOMEM;
}
/* Set timer_file fields */
timer_file->read_proc = &proc_read_timer;
timer_file->write_proc = &proc_write_timer;
timer_file->owner = THIS_MODULE;
SET_MODULE_OWNER(&timer_fops);
/* register /dev/tick */
register_chrdev(TICK_MAJOR, "tick", &timer_fops);
init_timer(&timer);
timer.expires= jiffies + timer_delay;
timer.function=timerEvent;
timer.data=42;
add_timer(&timer);
/* everything initialized */
printk(KERN_INFO "%s %s initialized\n", MODULE_NAME, MODULE_VERSION);
return 0;
}
static void __exit cleanup_timer_module(void)
{
del_timer(&timer);
remove_proc_entry("timer", NULL);
unregister_chrdev(TICK_MAJOR, "tick");
printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERSION);
}
int timer_open(struct inode* inode, struct file* filp)
{
return 0;
}
int timer_release(struct inode* inode, struct file* filp)
{
return 0;
}
ssize_t timer_read (struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
/* dummy read to wait on kernel timer */
while (1) {
interruptible_sleep_on(&timer_queue);
if (signal_pending (current)) /* a signal arrived */
return -ERESTARTSYS; /* tell the fs layer to handle it */
else break;
}
return 0;
}
#ifdef MODULE
/* here are the compiler macros for module operation */
module_init(init_timer_module);
module_exit(cleanup_timer_module);
#endif
MODULE_AUTHOR("J.J. Boor, AimSys bv");
MODULE_DESCRIPTION("timer module");
MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;