使用seq_file构建Linux / proc文件驱动程序

时间:2016-09-15 06:59:09

标签: c linux linux-device-driver

为什么在使用/proc构建Linux seq_file文件驱动程序时会收到以下错误消息?

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

#define PROC_NAME "iter"

MODULE_AUTHOR("MS Chaudhari");
MODULE_LICENSE("GPL");

/*  
   This function is called at the beginning of a sequence.
    ie, when:
    - the /proc file is read (first time)
    - after the function stop (end of sequence)
*/
static void *my_seq_start(struct seq_file *s, loff_t *pos)
{
    static unsigned long counter = 0;

    // beginning a new sequence
    if (*pos == 0)
    {
        return &counter;
    }
    else
    {
        *pos = 0;
        return NULL;
    }
}

/*
     This function is called after the beginning of a sequence.
     It's called untill the return is NULL (this ends the sequence).
*/
static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
    unsigned long *tmp_v = (unsigned long *)v;
    (*tmp_v)++; 
    (*pos)++;
    return NULL;
}

/*
     This function is called for each "step" of a sequence
*/

static int my_seq_show(struct seq_file *s, void *v)
{
    loff_t *spos = (loff_t *)v;

    seq_printf(s, "%Ld\n", *spos);
    return 0;
}

/*
        This structure gather "function" to manage the sequnce
*/

static struct seq_operation my_seq_ops = 
{
    .start = my_seq_start,
    .next = my_seq_next,
    .stop = my_seq_stop,
    .show = my_seq_show
};

/*
     This function is called when the /proc file is open.
*/
static int my_open(struct inode *inode, struct file *file)
{
    return seq_open(file, &my_seq_ops);
}

/*
    This structure gather "function" that manage the /proc file
*/
static struct file_operations fops =
{
    .owner   = THIS_MODULE,
    .open    = my_open,
    .read    = seq_read,
    .llseek  = seq_lseek,
    .release = seq_release
};


/*
    This function is called when the module is loaded
*/
int init_module(void)
{
    struct proc_dir_entry *entry;

    entry = proc_create(PROC_NAME, 0, NULL, &fops);

//  entry = create_entry(PROC_NAME, 0, NULL);
    if (entry) 
    {
        entry->proc_fops = &my_file_ops;
    }

    return 0;
}

/*
     This function is called when the module is unloaded.
*/
void cleanup_module(void)
{
    remove_proc_entry(PROC_NAME, NULL);
}

当我使用make命令编译时,我遇到了以下错误。

/home/radix/programing/DD/procSeq.c:61:15: error: variable ‘my_seq_ops’ has initializer but incomplete type
 static struct seq_operation my_seq_ops = 
               ^
/home/radix/programing/DD/procSeq.c:63:2: error: unknown field ‘start’ specified in initializer
  .start = my_seq_start,
  ^
/home/radix/programing/DD/procSeq.c:63:2: warning: excess elements in struct initializer [enabled by default]
/home/radix/programing/DD/procSeq.c:63:2: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c:64:2: error: unknown field ‘next’ specified in initializer
  .next = my_seq_next,
  ^
/home/radix/programing/DD/procSeq.c:64:2: warning: excess elements in struct initializer [enabled by default]
/home/radix/programing/DD/procSeq.c:64:2: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c:65:2: error: unknown field ‘stop’ specified in initializer
  .stop = my_seq_stop,
  ^
/home/radix/programing/DD/procSeq.c:65:10: error: ‘my_seq_stop’ undeclared here (not in a function)
  .stop = my_seq_stop,
          ^
/home/radix/programing/DD/procSeq.c:65:2: warning: excess elements in struct initializer [enabled by default]
  .stop = my_seq_stop,
  ^
/home/radix/programing/DD/procSeq.c:65:2: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c:66:2: error: unknown field ‘show’ specified in initializer
  .show = my_seq_show
  ^
/home/radix/programing/DD/procSeq.c:67:1: warning: excess elements in struct initializer [enabled by default]
 };
 ^
/home/radix/programing/DD/procSeq.c:67:1: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c: In function ‘my_open’:
/home/radix/programing/DD/procSeq.c:74:2: warning: passing argument 2 of ‘seq_open’ from incompatible pointer type [enabled by default]
  return seq_open(file, &my_seq_ops);
  ^
In file included from /home/radix/programing/DD/procSeq.c:4:0:
include/linux/seq_file.h:98:5: note: expected ‘const struct seq_operations *’ but argument is of type ‘struct seq_operation *’
 int seq_open(struct file *, const struct seq_operations *);
     ^
/home/radix/programing/DD/procSeq.c: In function ‘init_module’:
/home/radix/programing/DD/procSeq.c:102:8: error: dereferencing pointer to incomplete type
   entry->proc_fops = &my_file_ops;
        ^
/home/radix/programing/DD/procSeq.c:102:23: error: ‘my_file_ops’ undeclared (first use in this function)
   entry->proc_fops = &my_file_ops;
                       ^
/home/radix/programing/DD/procSeq.c:102:23: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [/home/radix/programing/DD/procSeq.o] Error 1
make[1]: *** [_module_/home/radix/programing/DD] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.13.0-24-generic'
make: *** [all] Error 2

很抱歉我的代码很长。

1 个答案:

答案 0 :(得分:4)

这是因为没有struct seq_operationstruct seq_operations