设为首页 加入收藏

TOP

简单字符设备驱动程序(一)
2014-11-24 07:17:47 来源: 作者: 【 】 浏览:5
Tags:简单 字符 设备 驱动程序

理论知识参考Linux Device Driver, 3rd Edition。实验中使用主动分配主设备号,按照LDD3中说的最好是自动分配设备号,这里只是为了理解。


实验步骤如下:


(1)使用cat/proc/device查看字符设备主设备号,这里假设50主设备号没有使用而在本设备中使用。


创建字符设备文件节点:mknod/dev/mycdev c 50 0


修改设备文件权限:chmod 777/dev/mycdev


其中的mycdev为步骤(2)中要安装的模块名。


(2)编写驱动程序:注意代码中 #define MYCDEV_MAJOR (50)


/* =====================================================================


* Filename: mycdev.c


*


* Description:


*


* Version: 1.0 (02/26/2013)


* Created: xhzuoxin(xiahouzuoxin@163.com)


* Compiler: gcc


*======================================================================


*/


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include



MODULE_LICENSE("GPL");



#defineMYCDEV_MAJOR (50)


#defineMYCDEV_SIZE 0x1000



staticdev_t mycdev_major = MYCDEV_MAJOR;



structmycdev {


struct cdev cdev;


unsigned charmem[255];


};


//struct mycdev dev;


structmycdev *devp;




static int mycdev_open(structinode *inode,struct file *fp)


{


fp->private_data= devp;



return 0;


}



static int mycdev_release(structinode *inode,struct file *fp)


{


return 0;


}



staticssize_t mycdev_read(struct file *fp,char __user *buf, size_t size, loff_t *pos)


{


unsigned long p =*pos;


unsigned int count =size;


struct mycdev *tmp_dev = fp->private_data;



if (p >= MYCDEV_SIZE) {


return -1;


}


if (count > MYCDEV_SIZE - p) {


count =MYCDEV_SIZE - p;


}


if (copy_to_user(buf, (void*)(tmp_dev->mem + p), count) != 0) {


printk("read error!\n");


return -1;


} else {


*pos +=count;


printk(KERN_INFO"read %d bytes from %ld\n", count, p);


}



return count;


}



staticssize_t mycdev_write(struct file *fp,const char __user*buf, size_t size, loff_t *pos)


{


unsigned long p =*pos;


unsigned int count =size;


struct mycdev *tmp_dev = fp->private_data;



if (p > MYCDEV_SIZE) {


return -1;


}


if (p > MYCDEV_SIZE - count) {


count =MYCDEV_SIZE - p;


}


if (copy_from_user((void*)(tmp_dev->mem + p), buf, count) != 0) {


return -1;


} else {


*pos +=count;


printk(KERN_INFO"write %d bytes from %ld\n", count, p);


}



return count;


}



staticloff_t mycdev_llseek(struct file *fp, loff_toff,int whence)


{


// structmycdev *dev = fp->private_data;


loff_tnew_pos = 0;



switch(whence) {


case SEEK_SET:


new_pos= off;


break;


case SEEK_CUR:


new_pos= fp->f_pos + off;


break;


case SEEK_END:


new_pos= MYCDEV_SIZE + off;


}



if (new_pos < 0) {


return -EINVAL;


} else {


fp->f_pos= new_pos;


return new_pos;


}


}



/* paddingg struct file operation */


static const structfile_operations mycdev_fops = {


.owner =THIS_MODULE,


.read =mycdev_read,


.write =mycdev_write,


.open =mycdev_open,


.release =mycdev_release,


.llseek =mycdev_llseek,


};



static void setup_mycdev(structmycdev *dev,int index)


{


int ret;


int devno = MKDEV(mycdev_major, index);



cdev_init(&dev->cdev,&mycdev_fops);


dev->cdev.owner= THIS_MODULE;


dev->cdev.ops= &mycdev_fops;


ret =cdev_add(&dev->cdev, devno, 1);



if (ret) {


printk("adding mycdev error!\n");


}


}



static int __init mycdev_init(void)


{


int ret;


dev_tdevno = 0;



if (mycdev_major) { /* 静态分配*/


devno =MKDEV(mycdev_major, 0);


ret =register_chrdev_region(devno, 1, "mycdev");


} else { /* 动态分配 */


ret =alloc_chrdev_region(&devno, 0, 1, "mycdev");


mycdev_major= MAJOR(devno);


}


devp =kmalloc(sizeof(structmycdev), GFP_KERNEL);


if (!devp) {


ret =-ENOMEM;


unregister_chrdev_region(devno,1);


return ret;


}


memset(devp,0, sizeof(structmycdev));



setup_mycdev(devp,0);



return 0;


}



static void __exit mycdev_exit(void)


{


printk("mycdev module is leavi

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇二叉堆例程 下一篇Linux/Unix shell 脚本监控磁盘可..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Java 学习线路图是怎 (2025-12-25 15:19:15)
·关于 Java 学习,有 (2025-12-25 15:19:12)
·有没有Java swing教 (2025-12-25 15:19:09)
·Start, Stop, and Di (2025-12-25 14:50:57)
·C语言入门教程:零基 (2025-12-25 14:50:54)