LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 820|回复: 3

[求助]有關linux-device-driver的問題

[复制链接]
发表于 2006-12-25 00:48:19 | 显示全部楼层 |阅读模式
各位大大好,我是linux新手,
最近跟著書上的範例(linux device driver, 3rd)
第3章的character driver實作,

driver name: scull

int scull_init_module(void){

        int result, i;
        dev_t dev=0;
        if(scull_major!=0){
                dev = MKDEV(scull_major,scull_minor);
                result = register_chrdev_region(dev,scull_nr_devs,"scull");
        }
        else{
                result = alloc_chrdev_region(&dev,scull_minor,scull_nr_devs,"scull");
                scull_major=MAJOR(dev);
        }
       
        if (result < 0){
                printk(KERN_WARNING "scull cannot get major %d\n", scull_major);
                return result;
        }
        scull_devices=kmalloc(scull_nr_devs*sizeof(struct scull_dev),GFP_KERNEL);
       
        if(scull_devices==NULL){
                result =-ENOMEM;
                goto fail;
        }
        memset(scull_devices,0,scull_nr_devs*sizeof(struct scull_dev));

        for(i=0;i<scull_nr_devs;++i){
                scull_devices.quantum=scull_quantum;
                scull_devices.qset=scull_qset;
                init_MUTEX(&scull_devices.sem);
                scull_setup_cdev(&scull_devices,i);
        }
       
        dev=MKDEV(scull_major,scull_minor+scull_nr_devs);
        //dev += scull_p_init(dev);
        //dev += scull_access_init(dev);
        #ifdef SCULL_DEBUG
        scull_create_proc();
        #endif
        printk("<0> Scull Module has been registered\n");
        return 0;
        fail:
                scull_cleanup_module();
                return result;
}

module_init(scull_init_module);
module_exit(scull_cleanup_module);

struct file_operations scull_fops={
        .owner=THIS_MODULE,
        .llseek=scull_llseek,
        .read=scull_read,
        .write=scull_write,
        .ioctl=scull_ioctl,
        .open=scull_open,
        .release=scull_release
};

function: scull_open

int scull_open(struct inode* inode, struct file* filp)
{
        struct scull_dev *dev;
       
        #ifdef FUNCDEBUG
        printk("<0> scull_open begin\n");
        #endif//FUNCDEBUG

        dev=container_of(inode->i_cdev,struct scull_dev, cdev);
        filp->private_data=dev;

        if((filp->f_flags & O_ACCMODE) == O_WRONLY){
                scull_trim(dev);
        }

        #ifdef FUNCDEBUG
        printk("<0> scull_open end\n");
        #endif//FUNCDEBUG
        return 0;
}

function: scull_read

ssize_t scull_read(struct file* flip, char __user *buf, size_t count, loff_t* f_pos)
{
        struct scull_dev* dev=flip->private_data;
        struct scull_qset* dptr;
        int quantum=dev->quantum,qset=dev->qset;
        int itemsize=quantum*qset;
        int item,s_pos,q_pos,rest;
        ssize_t retval=0;
        read_function_count+=1;
       
        #ifdef FUNCDEBUG
        printk("<0> scull_read begin\n");
        #endif//FUNCDEBUG

        if (down_interruptible(&dev->sem))
                return -ERESTARTSYS;
        if (*f_pos > dev->size)
                goto out;
        if(*f_pos+count>dev->size)
                count=dev->size-*f_pos;

        item=(long)*f_pos / itemsize;
        rest=(long)*f_pos % itemsize;
        s_pos=rest / quantum;q_pos=rest % quantum;

        dptr = scull_follow(dev,item);
       
        if(dptr==NULL || !dptr->data || !dptr->data[s_pos])
                goto out;

        if(count > quantum-q_pos)
                count=quantum-q_pos;
        if(copy_to_user(buf,dptr->data[s_pos]+q_pos,count)){
                retval=-EFAULT;
                goto out;
        }
        *f_pos+=count;
        retval=count;
       
        out:
                up(&dev->sem);

        #ifdef FUNCDEBUG
        printk("<0> scull_read end\n");
        #endif//FUNCDEBUG

        return retval;
}

scull_write

driver本身是OK了但是我不知道怎樣寫一個user-application去call driver
也就是說我不知道怎們去call driver裡的function

我的目的是
寫一個driver會receive1個producer傳來的data並send data給1個consumer

請各位大大告訴我謝謝。
发表于 2006-12-25 08:53:25 | 显示全部楼层
建一个设备节点,然后对这个节点操作就是了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-12-25 12:31:19 | 显示全部楼层
請問如何建一個設備節點?

//開啟
int rc = open("my_device",major);

之後我要如何call function?

是要宣告

ssize_t scull_read(struct file* flip, char __user *buf, size_t count, loff_t* f_pos);

struct file_operations fps = {
   .read = scull_read,
   .write = scull_write,
}

  fps.read(77,buf,0,f_pos);
這樣好像不行= =
回复 支持 反对

使用道具 举报

发表于 2006-12-25 18:12:07 | 显示全部楼层
mknod 设备结点名 设备类型 主设备号 次设备号
然后用普通读写函数操作就是了。
回复 支持 反对

使用道具 举报

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

本版积分规则

快速回复 返回顶部 返回列表