繁体   English   中英

在Linux设备驱动程序中写入计时器

[英]Write timer in Linux device driver

我是linux模块的新手。 我尝试创建一个计数器模块,其中计数器在计时器回调中递增。 计数器的结果必须发送到另一个模块(内存模块)。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> 
#include <linux/slab.h> 
#include <linux/fs.h> 
#include <linux/errno.h> 
#include <linux/types.h> 
#include <linux/proc_fs.h>
#include <linux/fcntl.h> 
#include <asm/system.h> 
#include <asm/uaccess.h> 

MODULE_AUTHOR("Helene");
MODULE_DESCRIPTION("Module memory");
MODULE_SUPPORTED_DEVICE("none");
MODULE_LICENSE("Dual BSD/GPL");

/* Global variables of the driver */
/* Buffer to store data */
char *memory_buffer;
int result;

struct file_operations memory_fops;


int memory_open(struct inode *inode, struct file *filp) {
//   printk(KERN_DEBUG "Opening memory module\n");
  return 0;
}

int memory_release(struct inode *inode, struct file *filp) {
//   printk(KERN_DEBUG "Releasing of memory module\n");
  return 0;
}

ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos){
//   printk(KERN_DEBUG "Reading memory module : %s\n", buf);
  if (*f_pos > 0)
      return 0;
  if (count > strlen(memory_buffer))
      count = strlen(memory_buffer);
  copy_to_user(buf,memory_buffer,count);
    *f_pos = *f_pos + count;
  return count; 
  }

ssize_t memory_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
//   printk(KERN_DEBUG "Writing memory module : %s\n", buf);
  copy_from_user(memory_buffer, buf, count);
  return count;
}

static int __init memory_init(void) {
  /* Registering device */
  result = register_chrdev(0, "memory", &memory_fops);
  if (result < 0) {
    printk(KERN_DEBUG "memory: cannot obtain major number \n");
    return result;
  }
  /* Allocating memory for the buffer */
  memory_buffer = kmalloc(1, GFP_KERNEL); 
  if (!memory_buffer) { 
    result = -ENOMEM;
    goto fail; 
  } 
  memset(memory_buffer, 0, 1);
  printk(KERN_ALERT "Inserting memory module : %d\n", result); 
  return 0;
  fail: 
    //memory_exit(); 
    return result;
}

static void __exit memory_exit(void) {
  /* Freeing the major number */
  unregister_chrdev(result, "memory");
  /* Freeing buffer memory */
  if (memory_buffer) {
    kfree(memory_buffer);
  }
  printk(KERN_DEBUG "Removing memory module\n");
}

struct file_operations memory_fops = {
  owner: THIS_MODULE,
  read: memory_read,
  write: memory_write,
  open: memory_open,
  release: memory_release
};


module_init(memory_init);
module_exit(memory_exit);

内存模块正常工作。 我的问题是当我在函数计时器回调上调用函数:filp_open / fp-> f_op-> write / filp_close时。 我已经在计时器回调中测试了这些功能,并且可以正常工作。

为什么filp_open函数(&co)在计时器回调函数上不起作用?

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */

MODULE_LICENSE("GPL");

static struct timer_list my_timer;
int cptNbClic ;
int result;

struct file_operations timer_fops;

int write_file_system(struct file *fp, char * buf){
  int nb;
  mm_segment_t old_fs=get_fs();
  set_fs(get_ds());
  nb = fp->f_op->write(fp,buf ,10, &fp->f_pos);
  set_fs(old_fs);
  return nb;
}

void writeInMemory(void){
//   printk(KERN_DEBUG "busy %d\n", busy);
    int nbwrite;
    char buf[3];
    int fmemory;
     fmemory=filp_open ("/dev/memory", O_WRONLY | O_APPEND | O_CREAT,0);    //don't work on this function
     if (fmemory==NULL){//verification de l'ouverture 
    printk(KERN_ALERT "filp_open error input memory!!.\n");
    return -1;
     } 
    sprintf(buf, "%d", cptNbClic); 
    printk(KERN_DEBUG "%d\n", cptNbClic);
      nbwrite = write_file_system(fmemory, buf);
      filp_close(fmemory, 0);
}

void my_timer_callback( unsigned long data )
{
  cptNbClic++;
    printk(KERN_DEBUG "cptNbClic %d\n", cptNbClic);
    writeInMemory();
    setup_timer(&my_timer, my_timer_callback, 0);
    mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000));
}


static int timer_open(struct inode *inode, struct file *filp) {
 /* setup your timer to call my_timer_callback */
  cptNbClic = 0;
  setup_timer(&my_timer, my_timer_callback, 0);
  /* setup timer interval to 200 msecs */
  mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000));
  return 0;
}

static int timer_release(struct inode *inode, struct file *filp) {
  /* Success */
    printk(KERN_DEBUG "Releasing of cpt module\n");
  del_timer(&my_timer);
  return 0;
}

static int __init timer_init(void) {
  /* Registering device */
  result = register_chrdev(0, "timer", &timer_fops);
  if (result < 0) {
    printk(KERN_DEBUG "timer: cannot obtain major number \n");
    return result;
  }
  printk(KERN_ALERT "Inserting timer module : %d\n", result); 
  return 0;     
}

static void __exit timer_exit(void) {
  unregister_chrdev(result, "timer");
  printk(KERN_DEBUG "Removing timer module\n");     
}

struct file_operations timer_fops = {
  owner: THIS_MODULE,
  open: timer_open,
  release: timer_release
};

/* Declaration of the init and exit functions */
module_init(timer_init);
module_exit(timer_exit);

对不起,我的英语不好

无需在my_timer_callback()中调用setup_timer函数。已经设置了计时器。 如果您想要一个循环计时器,则只需在处理程序中再次调用mod_timer()即可更新您的计时器到期值,并且您的计时器会愉快地一次又一次地运行直到del_timer()调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM