4174|6

78

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

《边干边学-Linux内核指导》这本书上的那个“设计自己的驱动程序”的例子拿来编译不知道为什么错??? [复制链接]


书上说:采用下面的命令对vfifo.c进行编译:
#gcc -c vfifo.c -D_KERNEL__ -DMODULE -O2 -g -Wall
如果没有出错的话,将会在本目录下生成一个vfifo.o文件。

可是我在redhat 9上编译出错,错误如下:
In file included from /usr/include/linux/fs.h:23,
                 from vfifo.c:17:
/usr/include/linux/string.h:8:2: warning: #warning Using kernel header in userland!
In file included from vfifo.c:18:
/usr/include/linux/proc_fs.h:70: parse error before "atomic_t"
/usr/include/linux/proc_fs.h:73: parse error before '}' token
/usr/include/linux/proc_fs.h:203: parse error before "void"
In file included from /usr/include/linux/bitops.h:69,
                 from /usr/include/asm/system.h:7,
                 from vfifo.c:25:
/usr/include/asm/bitops.h:327:2: warning: #warning This includefile is not available on all architectures.
/usr/include/asm/bitops.h:328:2: warning: #warning Using kernel headers in userspace: atomicity not guaranteed
vfifo.c:27:25: asm/uaccess.h: 没有那个文件或目录
In file included from /usr/include/linux/sched.h:14,
                 from /usr/include/linux/mm.h:4,
                 from /usr/include/linux/locks.h:5,
                 from /usr/include/linux/devfs_fs_kernel.h:6,
                 from vfifo.c:41:
/usr/include/linux/timex.h:173: field `time' has incomplete type
/usr/include/linux/timex.h:188: confused by earlier errors, bailing out
在Fedora 6上试了也不行。
小弟经验不足,希望能得到大家的指点。

最新回复

估计是内核版本太低 redhat9太老了,换ubuntu 8或fedora 10  详情 回复 发表于 2009-3-5 00:59
点赞 关注

回复
举报

89

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

//主要是设计和实现一个虚拟命名管道(FIFO)的字符设备.
//源代码如下:
/*  vfifo.c  */
#ifndef        __KERNEL__
#define        __KERNEL__
#endif

#ifndef        MODULE
#define        MODULE
#endif

#define  __NO_VERSION__

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef        VFIFO_MAJOR
#define        VFIFO_MAJOR                241
#endif

#ifndef        VFIFO_NR_DEVS
#define        VFIFO_NR_DEVS        4
#endif

#ifndef        VFIFO_BUFFER
#define        VFIFO_BUFFER        4000
#endif

#include

devfs_handle_t        vfifo_devfs_dir;

int vfifo_major=VFIFO_MAJOR;
int vfifo_nr_devs=VFIFO_NR_DEVS;
int vfifo_buffer=VFIFO_BUFFER;

MODULE_PARM(vfifo_major,"i");
MODULE_PARM(vfifo_nr_devs,"i");
MODULE_PARM(vfifo_buffer,"i");
MODULE_AUTHOR("EBUDDY");

typedef         struct        Vfifo_Dev{
        wait_queue_head_t        rdq,wrq;
        char*        base;
        unsigned int        buffersize;
        unsigned int        len;
        unsigned int        start;
        unsigned int        readers,writers;
        struct semaphore        sem;
        devfs_handle_t        r_handle,w_handle;
        }Vfifo_Dev;
Vfifo_Dev *vfifo_devices;
char vfifoname[8];
static int vfifo_open(struct inode *inode,struct file *filp)
{
  Vfifo_Dev *dev;
  int        num=MINOR(inode->i_rdev/*获取次设备号*/);
printk("<1>Hi, vfifo open--KENEL\n");
/*检查读写权限是否合法 */
if((filp->f_mode&FMODE_READ)&&!(num%2)||(filp->f_mode&FMODE_WRITE)&&(num%2))
                  return        -EPERM;

  if(!filp->private_data){
                if(num>=vfifo_nr_devs*2)
                        return        -ENODEV;
                dev=&vfifo_devices[num/2];
                filp->private_data=dev; /*.将获得的dev保存到filp->private_data*/
  }else{
          dev=filp->private_data;
  }

        /*获得互斥访问的信号量 */
  if(down_interruptible(&dev->sem))
                  return        -ERESTARTSYS; /*如果返回0,表示获得信号量正常返回,如果被信号打断,返回-EINTR*/

        /*如果尚未分配缓冲区,则分配并初始化         */
  if(!dev->base){
                  dev->base=kmalloc(vfifo_buffer,GFP_KERNEL);
                if(!dev->base){
                        up(&dev->sem);
                        return        -ENOMEM;
                }
                dev->buffersize=vfifo_buffer;
                  dev->len=dev->start=0;
  }

  if(filp->f_mode&FMODE_READ)
          dev->readers++;
  if(filp->f_mode&FMODE_WRITE)
                dev->writers++;

  filp->private_data=dev;
  MOD_INC_USE_COUNT;
up(&dev->sem);
printk("<1> out of open\n");
  return 0;
}
static int vfifo_release(struct inode *inode,struct file *filp)
{
  Vfifo_Dev        *dev=filp->private_data;
printk("<1> IN RELEASE \n");
        /*获得互斥访问的信号量 */
  down(&dev->sem);
printk("<1> IN RELEASE:GOT SEM\n");
  if(filp->f_mode&FMODE_READ)
                  dev->readers--;
  if(filp->f_mode&FMODE_WRITE){
                  dev->writers--;
                wake_up_interruptible(&dev->sem.wait);
  }

  if((dev->readers+dev->writers==0)&&(dev->len==0)){
                  kfree(dev->base);
                dev->base=NULL;
  }
  up(&dev->sem);
  MOD_DEC_USE_COUNT;
  return 0;
}
static ssize_t vfifo_read(struct file *filp,char *buf,size_t count,loff_t *f_pos)
{
  Vfifo_Dev        *dev=filp->private_data;
  ssize_t        read=0;
printk("IN READING\n");
        /*不允许进行定位操作 */
  if(f_pos!=&filp->f_pos/*表示文件中的当前位置*/)
          return        -ESPIPE;
        /*获得互斥访问的信号量 */
  if(down_interruptible(&dev->sem))
          return        -ERESTARTSYS;
do_more_read:
        /*没有数据可读,则进入循环等待 */
        while(dev->len==0){
                if(!dev->writers){
                        up(&dev->sem);
                        return        -EAGAIN/*(Resource temporarily unavailable)*/;
                }
               
                up(&dev->sem);
                if(filp->f_flags&O_NONBLOCK/*O_NONBLOCK 表示采用非阻塞的文件IO方法。*/)
                        return        -EAGAIN;
                printk("%s reading:going to sleep\n",current->comm/*存于current->comm 的命令名称是由当前进程执行的程序文件的基本名称*/);
                if(wait_event_interruptible(dev->rdq,(dev->len>0)))
                        return        -ERESTARTSYS;
                printk("%s has been waken up\n",current->comm);
                if(down_interruptible(&dev->sem))
                        return        -ERESTARTSYS;
        }
        /*读数据 */
        while(count>0&&dev->len){
                char        *pipebuf=dev->base+dev->start;
                /*(buffersize – start)是可以一次性读取的最大数据量 */
                ssize_t        chars=dev->buffersize-dev->start;

                if(chars>count)        chars=count;
                if(chars>dev->len)        chars=dev->len;

                if(copy_to_user(buf,pipebuf,chars)){
                        up(&dev->sem);
                        return        -EFAULT;
                }
                read+=chars;
                dev->start+=chars;
                dev->start%=dev->buffersize;
                dev->len-=chars;
                count-=chars;
                buf+=chars;
        }
        /*Cache behavior optimizition*/
        if(!dev->len)        dev->start=0;
        if(count&&dev->writers&&!(filp->f_flags&O_NONBLOCK)){
                up(&dev->sem);
                wake_up_interruptible(&dev->wrq);
                if(down_interruptible(&dev->sem))
                        return -ERESTARTSYS;
                goto        do_more_read;
        }
        up(&dev->sem);
        wake_up_interruptible(&dev->wrq);
        printk("%s did read %li bytes\n",current->comm, (long)read);
printk("OUT of READING\n");
        return        read;
}

 
 

回复

80

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
static ssize_t vfifo_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos)
{

  Vfifo_Dev        *dev=filp->private_data;
  ssize_t        written=0;

printk("<1> in WRITE,want to write %d bytes \n",count);
  if(f_pos!=&filp->f_pos||count==0)
          return        -ESPIPE;
  if(down_interruptible(&dev->sem))
          return        -ERESTARTSYS;
do_more_write:
          while(dev->len==dev->buffersize){
printk("<1> in WRITE: full begin\n");
                up(&dev->sem);
                if(filp->f_flags&O_NONBLOCK)
                        return        -EAGAIN;
                printk("%s writting:going to sleep\n",current->comm);
                if(wait_event_interruptible(dev->wrq,(dev->lenbuffersize)))
                        return        -ERESTARTSYS;
                printk("%s has been waken up\n",current->comm);
                if(down_interruptible(&dev->sem))
                        return        -ERESTARTSYS;
        }
        while(count>0){
                char        *pipebuf=dev->base+(dev->len+dev->start)%dev->buffersize;
                ssize_t        chars=dev->buffersize-(dev->len+dev->start);
                if(chars<0)        chars+=dev->start;
                if(chars!=0){
                        if(chars>count)        chars=count;

                        if(copy_from_user((char *)pipebuf,buf,chars)){
                                up(&dev->sem);
                                return        -EFAULT;
                        }
                written+=chars;
                dev->len+=chars;
                count-=chars;
                buf+=chars;
                }
        }
        if(count&&!(filp->f_flags&O_NONBLOCK)){
                up(&dev->sem);
                wake_up_interruptible(&dev->rdq);
                if(down_interruptible(&dev->sem))
                        return -ERESTARTSYS;
                goto        do_more_write;
        }
up(&dev->sem);        
wake_up_interruptible(&dev->rdq);
printk("<1>write end: size is %d after this write\n", dev->buffersize);       
        printk("<1>%s did write %li bytes\n",current->comm, (long)written);
return        written;
}

unsigned int vfifo_poll(struct file *filp, poll_table *wait)
{
    Vfifo_Dev *dev = (filp->private_data);
    unsigned int mask = 0;

    poll_wait(filp, &dev->rdq, wait);
    poll_wait(filp, &dev->wrq, wait);
    if (dev->len > 0) mask |= POLLIN | POLLRDNORM;  
    if (dev->len != dev->buffersize)  mask |= POLLOUT | POLLWRNORM;
    return mask;
}

struct file_operations vfifo_fops=
{
open: vfifo_open,
release: vfifo_release,
read: vfifo_read,
write: vfifo_write,
poll: vfifo_poll,
};

static int __init vfifo_init_module(void)
{
  int result,i;

  SET_MODULE_OWNER(&vfifo_fops);
printk("<1>VFIFO INIT--\n");
#ifdef        CONFIG_DEVFS_FS
          vfifo_devfs_dir=devfs_mk_dir(NULL,"vfifo",NULL);
        if(!vfifo_devfs_dir)
                return        -EBUSY;
#endif
          result=devfs_register_chrdev(vfifo_major,"vfifo",&vfifo_fops);
        if(result<0){
                printk(KERN_WARNING "vfifo: can't get major %d\n",vfifo_major);
                return        result;
        }

        if(vfifo_major==0)
                vfifo_major=result;
               
        vfifo_devices = kmalloc(vfifo_nr_devs*sizeof(Vfifo_Dev),GFP_KERNEL);
        if(!vfifo_devices){
                return -ENOMEM;
        }

        memset(vfifo_devices,0,vfifo_nr_devs*sizeof(Vfifo_Dev));
        for(i=0;i                 init_waitqueue_head(&vfifo_devices.rdq);
                init_waitqueue_head(&vfifo_devices.wrq);
                sema_init(&vfifo_devices.sem,1);
#ifdef        CONFIG_DEVFS_FS
                sprintf(vfifoname,"vfifo%d",2*i);
                vfifo_devices.w_handle=
                        devfs_register(vfifo_devfs_dir,vfifoname,
                                        DEVFS_FL_NON,
                                        vfifo_major,2*i,S_IFCHR|S_IRUGO|S_IWUGO,
                                        &vfifo_fops,vfifo_device+i);
                sprintf(vfifoname,"vfifo%d",2*i+1);
                vfifo_devices.r_handle=
                        devfs_register(vfifo_devfs_dir,vfifoname,
                                        DEVFS_FL_NON,
                                        vfifo_major,2*i+1,S_IFCHR|S_IRUGO|S_IWUGO,
                                        &vfifo_fops,vfifo_device+i);
                if(!vfifo_devices.r_handle||!vfifo_devices.w_handle){
                        printk(KERN_WARNING "vfifo: can't register vfifo device nr %i\n",i);
                        }
        #endif
        }

        #ifdef        VFIFO_DEBUG
                create_proc_read_entry("vfifo",0,NULL,vfifo_read_mem,NULL);
        #endif

        return        0;
}

static void __exit vfifo_cleanup_module(void)
{
int i;

  devfs_unregister_chrdev(vfifo_major,"vfifo");

  #ifdef VFIFO_DEBUG
          remove_proc_entry("vfifo",NULL);
  #endif

  if(vfifo_devices){
                  for(i=0;i                         if(vfifo_devices.base)
                                kfree(vfifo_devices.base);
                        devfs_unregister(vfifo_devices.r_handle);
                        devfs_unregister(vfifo_devices.w_handle);
               
        }
       
                kfree(vfifo_devices);
                devfs_unregister(vfifo_devfs_dir);
  }
}
module_init(vfifo_init_module);
module_exit(vfifo_cleanup_module);
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

4
 
那个例子的源代码见上。
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

5
 
帮顶。
关注结果。
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

6
 
估计是内核版本太低
redhat9太老了,换ubuntu 8或fedora 10
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

7
 
估计是内核版本太低
redhat9太老了,换ubuntu 8或fedora 10
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表