娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

IMX257 linux設備驅動之Cdev結構

發布者:Meilin8888最新更新時間:2024-08-15 來源: cnblogs關鍵字:linux設備驅動 手機看文章 掃描二維碼
隨時隨地手機看文章

一、CDEV結構

  1. /*  

  2. *內核源碼位置  

  3. *linux2.6.38/include/linux/cdev.h  

  4. */  

  5.     

  6. struct cdev {  

  7.     struct kobject kobj;  

  8.     struct module *owner;   //一般初始化為:THIS_MODULE  

  9.     const struct file_operations *ops;   

  10. //字符設備用到的例外一個重要的結構體file_operations,cdev初始化時與之綁定  

  11.     struct list_head list;  

  12.     dev_t dev;  //主設備號24位 與次設備號8位,dev_t為32位整形  

  13.     unsigned int count;  

  14. };

 

二、file_operation 結構

  1. /* 

  2. ~/include/linux/fs.h 

  3. */  

  4.     

  5. struct file_operations {  

  6.     struct module *owner;  

  7.     loff_t (*llseek) (struct file *, loff_t, int);  

  8.     ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);  

  9.     ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);  

  10.     ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);  

  11.     ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);  

  12.     int (*readdir) (struct file *, void *, filldir_t);  

  13.     unsigned int (*poll) (struct file *, struct poll_table_struct *);  

  14.     long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);  

  15.     long (*compat_ioctl) (struct file *, unsigned int, unsigned long);  

  16.     int (*mmap) (struct file *, struct vm_area_struct *);  

  17.     int (*open) (struct inode *, struct file *);  

  18.     int (*flush) (struct file *, fl_owner_t id);  

  19.     int (*release) (struct inode *, struct file *);  

  20.     int (*fsync) (struct file *, int datasync);  

  21.     int (*aio_fsync) (struct kiocb *, int datasync);  

  22.     int (*fasync) (int, struct file *, int);  

  23.     int (*lock) (struct file *, int, struct file_lock *);  

  24.     ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);  

  25.     unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);  

  26.     int (*check_flags)(int);  

  27.     int (*flock) (struct file *, int, struct file_lock *);  

  28.     ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);  

  29.     ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);  

  30.     int (*setlease)(struct file *, long, struct file_lock **);  

  31.     long (*fallocate)(struct file *file, int mode, loff_t offset,  

  32.               loff_t len);  

  33. };  

 

三、為cdev申請內存

接下來,我們就需要為cdev申請內存,然后再通過cdev_init 函數將cdev與file_operation結構體聯系起來,

  1. void cdev_init(struct cdev *cdev, const struct file_operations *fops)  

  2. {  

  3.     memset(cdev, 0, sizeof *cdev);  

  4.     INIT_LIST_HEAD(&cdev->list);  

  5.     kobject_init(&cdev->kobj, &ktype_cdev_default);  

  6.     cdev->ops = fops;  

  7. }  

 

最后通過cdev_add函數,將cdev添加到內核中

  1. int cdev_add(struct cdev *p, dev_t dev, unsigned count)  

  2. {  

  3.     p->dev = dev;  

  4.     p->count = count;  

  5.     return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);  

  6. }  

 

四、實例解析

1.自定義一個cdev結構體

如圖所示,上述代碼中,先自定義一個簡單的cdev結構體key_dev,然后再實例化key_device, 接下來就定義一個我們接下來要操作的數組key_buff[MEM_SIZE],MEM_SIZE為自定義的內存的大小。

 

2.在init函數中初始化cdev結構體

當我們的應用程序調用open函數打開設備時,

在init函數中初始化cdev結構體,為cdev結構體開辟內存,連接cdev與fops結構體,注冊cdev進入內核

 

3.一旦注冊入內核,我們就可以開始使用了

當我們的應用程序打開設備時,在open函數中將filp的private_data賦值為我們所分配的key_device的結構體

 

4.釋放cdev內存

當我們不用驅動時自然就要釋放我們剛剛開辟的內存。

如圖所示,首先刪除cdev結構體,然后再使用kfree來釋放cdev釋放申請的內存

 

5.編譯與測試

 

 

如圖所示,我們在應用程序中先使用write函數往數組中寫入'hello,Lover雪兒'的字符串,然后再使用read函數讀取內容,但是,必須注意一點,在每次read后者write前,必須先使用lseek函數中重定位指針。

附上驅動程序源代碼:

  1 #include

  2 #include

  3 #include

  4 #include

  5 #include

  6 #include

  7 #include

  8 #include

  9 #include

 10 #include

 11 #include

 12 #include

 13 

 14 #define DEVICE_NAME    'cdev'

 15 #define Driver_NAME 'key_cdev'

 16 

 17 #define KEY_MAJOR 220

 18 #define KEY_MINOR 0

 19 #define COMMAND1 1

 20 #define COMMAND2 2

 21 #define MEM_SIZE 256

 22 

 23 struct key_dev {

 24         struct cdev cdev;

 25 };

 26 struct key_dev *key_device;

 27 static unsigned char key_buff[MEM_SIZE];

 28 

 29 //auto to create device node

 30 static struct class *drv_class = NULL;

 31 static struct class_device *drv_class_dev = NULL;

 32 

 33 static int key_open(struct inode *inode,struct file *filp){

 34     filp->private_data = key_device;

 35     return 0;

 36 }

 37 

 38 static int key_release(struct inode* inode,struct file *filp){

 39     return 0;

 40 }

 41 

 42 static ssize_t key_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos){

 43     ssize_t ret = 0;

 44     loff_t pos = *f_pos;

 45     if(pos > MEM_SIZE)    //如果文件指針偏移超出文件大小

 46         return ret = 0;

 47     if(count > (MEM_SIZE - pos))

 48         count = 256 - pos;    //若內存不足,則寫到內存滿的位置

 49     pos += count;

 50     //讀出數據

 51     if(copy_to_user(buf,key_buff + *f_pos,count)){

 52         return ret = -EFAULT;

 53     }

 54     *f_pos = pos;

 55     return count;

 56 }

 57 

 58 static ssize_t key_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){

 59     ssize_t ret = -ENOMEM;

 60     loff_t pos = *f_pos;        //獲取當前文件指針偏移

 61     if(pos > MEM_SIZE)    //如果文件指針偏移超出文件大小

 62         return ret;

 63     if(count > (MEM_SIZE - pos))

 64         count = 256 - pos;    //若內存不足,則寫到內存滿的位置

 65     pos += count;

 66     //從fops處開始寫入數據

 67     if(copy_from_user(key_buff + *f_pos,buf,count)){

 68         ret = -EFAULT;

 69         return ret;

 70     }

 71     *f_pos = pos;

 72     return count;

 73 }

 74 

 75 static int key_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){

 76     switch(cmd){

 77         case COMMAND1: printk('<0>ncommand 1 n'); break;

 78         case COMMAND2: printk('<0>ncommand 2 n'); break;

 79         default: printk('<0>command default n'); break;

 80     }

 81     return 0;

 82 }

 83 

 84 static loff_t key_llseek(struct file *filp, loff_t off, int whence){

 85     loff_t pos;

 86     pos = filp->f_pos;    //獲取文件指針當前位置

 87     switch(whence){

 88         case 0: pos = off;    break;    //重定位到文件開頭

[1] [2]
關鍵字:linux設備驅動 引用地址:IMX257 linux設備驅動之Cdev結構

上一篇:IMX257 Linux內存空間內存分配
下一篇:【改進定時器】IMX257實現GPIO-IRQ定時器消抖驅動程序

推薦閱讀最新更新時間:2025-06-08 23:01

XScale PXA270在Linux下的FPGA設備驅動
引言   Intel公司推出的XScale采用ARM V5TE結構,是Strong ARM的升級換代產品。XScale PXA270處理器最高主頻可達624 MHz,加入了Wireless MMX、Intel SpeedStep等新技術,以其高性能、低功耗、多功能等特點在信息家電、工業控制等領域得到了廣泛的應用。在嵌入式控制中,“微處理器+FPGA”是一種常用的解決方案。FPGA(現場可編程門陣列)有編程方便、集成度高、速度快等特點,電子設計人員可以通過硬件編程的方法來實現FPGA芯片各種功能的開發。在我們的一個數控平臺的研究項目中,采用XScale PXA270作為主CPU,并對其進行FPGA擴展,使其具有插補、電機驅動、信
[嵌入式]
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 皮山县| 雷州市| 桂林市| 新源县| 德钦县| 嘉荫县| 偏关县| 海口市| 融水| 安溪县| 金川县| 读书| 平舆县| 景泰县| 丽水市| 四川省| 区。| 新和县| 乌苏市| 堆龙德庆县| 武威市| 台湾省| 丰原市| 奎屯市| 安多县| 枣庄市| 西平县| 方城县| 华容县| 通江县| 鹤庆县| 玉溪市| 彝良县| 凤凰县| 平邑县| 章丘市| 罗源县| 龙井市| 霍州市| 尼玛县| 焦作市|