久久精品国产清自在天天线_日韩国产欧美系列_亚洲天堂影视在线观看_91在线艹亚洲无码午夜_日本写真高清视频免费网站网_亚州无码大尺度另类_高跟翘臀老师后进式视频午夜_久久精品国产亚洲AV热黑人_国产另ts另类人妖_丁香五月 开心五月 激情五月

當(dāng)前位置: > 華清遠(yuǎn)見教育科技集團(tuán) > 嵌入式學(xué)習(xí) > 講師博文 > 驅(qū)動之cdev
驅(qū)動之cdev
時間:2016-12-12作者:華清遠(yuǎn)見

前面寫到如何向系統(tǒng)申請一個設(shè)備號,設(shè)備號就像我們的身份證號一樣,號本身并沒有什么特殊的意義,只有把這個號和人對應(yīng)才有意義,通用設(shè)備號也需要和一個特殊的東西對于,這就是cdev, cdev是linux下抽象出來的一個用來描述一個字符設(shè)備的結(jié)構(gòu)體,在linux下定義如下:

struct cdev {
                struct kobject kobj;
                struct module *owner;
                const struct file_operations *ops;
                struct list_head list;
                dev_t dev;
                unsigned int count;
        };

結(jié)構(gòu)體中有幾個成員事我們寫驅(qū)動的時候必須關(guān)心的:

dev 類型是dev_t,也就是我們的設(shè)備號

ops是一個同樣也是一個結(jié)構(gòu)體并且是一個字符驅(qū)動實(shí)現(xiàn)的主體,字符驅(qū)動通常需要和應(yīng)用程序交互,在學(xué)linux系統(tǒng)編程的時候,都會講到linux 應(yīng)用程序通過系統(tǒng)調(diào)用陷入到內(nèi)核空間,從而執(zhí)行內(nèi)核代碼,而驅(qū)動作為內(nèi)核的一部分同樣也是需要在內(nèi)核空間執(zhí)行的,ops也就是file_operations這個結(jié)構(gòu)體就是我們的驅(qū)動為應(yīng)用程序調(diào)用驅(qū)動而實(shí)現(xiàn)的一個操作的集合,它的定義如下:

struct file_operations {
                struct module *owner;
                loff_t (*llseek) (struct file *, loff_t, int);
                ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
                ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
                ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
                ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
                int (*readdir) (struct file *, void *, filldir_t);
                unsigned int (*poll) (struct file *, struct poll_table_struct *);
                long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
                long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
                int (*mmap) (struct file *, struct vm_area_struct *);
                int (*open) (struct inode *, struct file *);
                int (*flush) (struct file *, fl_owner_t id);
                int (*release) (struct inode *, struct file *);
                int (*fsync) (struct file *, loff_t, loff_t, int datasync);
                int (*aio_fsync) (struct kiocb *, int datasync);
                int (*fasync) (int, struct file *, int);
                int (*lock) (struct file *, int, struct file_lock *);
                ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
                unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
                int (*check_flags)(int);
                int (*flock) (struct file *, int, struct file_lock *);
                ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
                ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
                int (*setlease)(struct file *, long, struct file_lock **);
                long (*fallocate)(struct file *file, int mode, loff_t offset,loff_t len);
        };

我們在驅(qū)動中要做的事情就是申請一個cdev并把cdev注冊到系統(tǒng)中去,操作cdev的函數(shù)有:

void cdev_init(struct cdev *, const struct file_operations *);
        struct cdev *cdev_alloc(void);
        int cdev_add(struct cdev *, dev_t, unsigned);
        void cdev_del(struct cdev *);

1、cdev的定義

cdev的定義有兩種方式一種是:struct cdev cdev;另外一種是:strcut cdev cdev;cdev = cdev_alloc();

2、cdev的初始化

cdev_init實(shí)現(xiàn)cdev的初始化,主要的工作是將我們定義好的file_operaionts與cdev關(guān)聯(lián)起來,file_operations的實(shí)現(xiàn)根據(jù)實(shí)際需求來實(shí)現(xiàn),后面詳細(xì)介紹。

3、cdev的注冊

cdev_add實(shí)現(xiàn)cdev的注冊,linux內(nèi)核里維護(hù)了一個cdev_map的表,所謂cdev的注冊就是把我們的cdev注冊到cdev_map表上,cdev_map表結(jié)構(gòu)如圖:

4、設(shè)備的刪除

cdev_del 將我們的cdev從cdev_map中移除。

發(fā)表評論
評論列表(網(wǎng)友評論僅供網(wǎng)友表達(dá)個人看法,并不表明本站同意其觀點(diǎn)或證實(shí)其描述)