驱动模型
来源:互联网 发布:工业3.0是什么知乎 编辑:程序博客网 时间:2024/06/16 00:03
#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/uaccess.h>//设备结构体 struct xxx_dev_t{ struct cdev cdev; ...}xxx_dev;/*打开*/int xxx_open(struct inode *inode, struct file *filp){ /****************************************************************************************** struct inode被内核用来代表一个文件,注意和struct file的 区别,struct inode代表文件, struct file代表打开的文件;同一个文件可以被打开好多次,所以可以对应很多struct file, 但是只对应一个struct inode。 ******************************************************************************************/ ... } int xxx_release(struct inode *inode, struct file *filp){ //release释放相当于close ...}/* 读设备*/ ssize_t xxx_read(struct file *filp, char __user *buf, size_t count, loff_t*f_pos) { ... copy_to_user(buf, ..., ...); /*******************************************************************************************************1、设备驱动的读写函数中,filp是文件结构体指针,buf是用户空间内存的地址,该地址在内核空间不能直接读写, count是要读写的字节数,f_pos是读写的位置相对于文件 开头的偏移。 2、由于内核空间与用户空间的内存不能直接互访,因此借助函数 copy_from_user()完成用户空间到内核空间的复制,函数 copy_to_user()完成内核空间到用户空间的复制。 copy_from_user()和copy_to_user()的原型如下所示: unsigned long copy_from_user(void *to, const void _ _user *from, unsigned long count); unsigned long copy_to_user(void _ _user *to, const void *from, unsigned long count);**********************************************************************************************************/ ... }/* 写设备*/ssize_t xxx_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { /**************************************************************************************************//filp:与字符设备文件关联的file结构指针, 由内核创建。//buff : 从设备读取到的数据,需要保存到的位置。由read系统调用提供该参数。//count: 请求传输的数据量,由read系统调用提供该参数。//offp: 文件的读写位置,由内核从file结构中取出后,传递进来。/*buff参数是来源于用户空间的指针,这类指针都不能被内核代码直接引用,必须使用专门的函数: int copy_from_user(void *to, const void __user *from, int n) int copy_to_user(void __user *to, const void *from, int n)*/************************************************************************************/ ... copy_from_user(..., buf, ...); ... } /* ioctl函数 */int xxx_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { ... switch (cmd) { case XXX_CMD1: ... break; case XXX_CMD2: ... break; default: /* 不能支持的命令 */ return - ENOTTY; } return 0; }struct file_operations xxx_fops = { .owner = THIS_MODULE, .open = xxx_open, .release = xxx_release, .read = xxx_read, .write = xxx_write, .ioctl = xxx_ioctl, ... }; //设备驱动模块加载函数 static int __init xxx_init(void) { /**********************************************************************分配cdev:cdev变量的定义可以采用静态和动态两种办法静态分配:struct cdev mdev;动态分配: struct cdev *pdev = cdev_alloc();初始化cdev:struct cdev的初始化使用cdev_init函数来完成。cdev_init(struct cdev *cdev, const struct file_operations *fops)参数:cdev: 待初始化的cdev结构fops: 设备对应的操作函数集注册cdev:字符设备的注册使用cdev_add函数来完成。cdev_add(struct cdev *p, dev_t dev, unsigned count)参数:p: 待添加到内核的字符设备结构dev: 设备号count: 该类设备的设备个数***********************************************************************/ ... cdev_init(&xxx_dev.cdev, &xxx_fops); //初始化cdev xxx_dev.cdev.owner = THIS_MODULE; if (xxx_major) //获取字符设备号 { register_chrdev_region(xxx_dev_no, 1, DEV_NAME); } else { alloc_chrdev_region(&xxx_dev_no, 0, 1, DEV_NAME); } ret = cdev_add(&xxx_dev.cdev, xxx_dev_no, 1); //注册设备 ... } /*设备驱动模块卸载函数*/ static void __exit xxx_exit(void) { unregister_chrdev_region(xxx_dev_no, 1); //释放占用的设备号 cdev_del(&xxx_dev.cdev); //注销设备 ... }module_init(xxx_init);module_exit(xxx_exit);MODULE_AUTHOR("XXXX");MODULE_LICENSE("GPL");//许可证
阅读全文
0 0
- 驱动模型
- 驱动模型
- 模型驱动
- 模型驱动
- 驱动模型
- 驱动框架,驱动模型
- Linux驱动设备驱动模型
- 模型驱动和属性驱动
- linux驱动子系统--驱动模型
- Linux驱动设备驱动模型
- 数据驱动与模型驱动
- 属性驱动和模型驱动
- struts2属性驱动,模型驱动
- 模型驱动开发
- 模型驱动开发(二)
- “MDD”--模型驱动开发
- MDA模型驱动架构
- 模型驱动架构
- 前端工程师是怎样一种职业
- python xpath介绍和新闻内容爬虫
- python包——好玩的wordcloud
- 一头坑进Redis之持久化 Snapshot和AOF说明
- 父类中访问子类成员
- 驱动模型
- 生产者与消费者模型(互斥锁)
- python 分页爬取
- CRC的3种方法
- 2017-8-17
- [PAT乙级]自测2
- html自定义搜索框(与selector2不同)
- 欢迎使用CSDN-markdown编辑器
- python mysql-connector的安装和使用