如何编写杂项设备驱动
1.函数说明
1.1、注册杂项设备
int misc_register(struct miscdevice * misc)
头文件:#include <linux/miscdevice.h>
功能:注册一个杂项设备
参数:misc- 杂项设备的核心结构指针,至少已经实现minor,name,fops三个成员。
返回值:0,表示注册成功;负数,注册失败。
说明:注册成功之后,会在/dev目录下生成一个设备节点文件。
2.2、注销函数
int misc_deregister(struct miscdevice *misc)
头文件:#include <linux/miscdevice.h>
功能:注销一个已经存在杂项设备
参数:misc,杂项设备的核心结构指针,已经注册的struct miscdevice结构。
返回值:0,表示注销成功;负数,注销失败
杂项设备的核心数据结构struct miscdevice:(头文件中已经定义好)
struct miscdevice {int minor;const char *name;const struct file_operations *fops;struct list_head list;struct device *parent;struct device *this_device;const char *nodename;umode_t mode;
};
结构体struct miscdevice结构中的函数结构液体struct file_operations(头文件中已经定义好)
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);
};
代码例子:
驱动代码
#include <linux/kernel.h>
#include <linux/module.h>
//包含必须的头文件
#include <linux/fs.h>
#include <linux/miscdevice.h>//以下是文件操作方法的具体实现代码
static int xxx_open (struct inode *pinode, struct file *pfile)
{printk("line:%d,%s is call\n",__LINE__,__FUNCTION__);return 0;
}static ssize_t xxx_read (struct file *pfile, char __user *buf, size_t count, loff_t *poff)
{printk("line:%d,%s is call\n",__LINE__,__FUNCTION__);return count;
}
static ssize_t xxx_write (struct file *pfile, const char __user *buf, size_t count, loff_t *poff)
{printk("line:%d,%s is call\n",__LINE__,__FUNCTION__);return count;
}static int xxx_release (struct inode *pinode, struct file *pfile)
{printk("line:%d,%s is call\n",__LINE__,__FUNCTION__);return 0;
}//文件操作方法集合指针
//文件操作方法:根据具体设备实现需要的功能
static const struct file_operations char_dev_fops={.open = xxx_open,.write = xxx_write,.read = xxx_read,.release = xxx_release,
};//定义核心数据结构
#define DEV_NAME "mymisc"static struct miscdevice misc_dev={.minor = 255,.name = DEV_NAME,.fops = &char_dev_fops,
};static int __init chrdev_test_init(void)
{int ret;//注册核心结构ret = misc_register(&misc_dev);if(ret < 0){printk("misc_register erron!\n");return ret;}printk("misc_register OK!\n");return 0;
}static void __exit chrdev_test_exit(void)
{int ret;//注销核心结构ret = misc_deregister(&misc_dev);if(ret < 0){printk("misc_deregister erron!\n");return ;}printk("misc_deregister OK!\n");
}module_init(chrdev_test_init);
module_exit(chrdev_test_exit);MODULE_LICENSE("GPL");
应用代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define DEV_NAME "/dev/mymisc"int main(void)
{int ret;char buf[] = {1, 0, 0, 0};//1,亮,0表示灭int fd; //打开文件设备O_RDWR, O_RDONLY, O_WRONLY,fd = open(DEV_NAME, O_RDWR);if(fd < 0){printf("open :%s failt!\r\n", DEV_NAME); return -1;} read(fd, buf, 4); //从内核空间中读取数据write(fd, buf, 4);//写数据到内核空间close(fd);//关闭设备 ,可以不调用,程序关闭时系统自动调用return 0;
}
编译代码:
# Makefile 2.6
#交叉编译器前缀
cc := arm-linux-#应用程序名
AN := app#应用程序源文件列表
ANSRC := app.c#模块列表
obj-m := mise_device_moudle.o#内核源码路径
#KDIR :=/lib/modules/$(shell uname -r)/build
KDIR := /home/jian/aaa/linux/linux-3.5/#模块最终存放
rootfs_dir := /home/jian/aaa/rootfs/home all:@make -C $(KDIR) M=$(PWD) modules @${cc}gcc ${ANSRC} -o ${AN}cp ${AN} *.ko ${rootfs_dir}@rm -rf .tmp_versions *.o *.mod.o *.mod.c *.bak *.symvers *.markers *.unsigned *.order *~ .*.*.cmd .*.*.*.cmd
clean:@rm -f ${AN} *.ko *.o *.mod.o *.mod.c *.bak *.symvers *.markers *.unsigned *.order *~
如何编写杂项设备驱动相关推荐
- Linux杂项设备驱动
一.Linux杂项设备驱动简介 Linux杂项驱动出现的意义在于:有很多简单的外围字符设备,它们功能相对简单,一个设备占用一个主设备号对于内核资源来说太浪费. 所以对于这些简单的字符设备它们共用一个主 ...
- Misc杂项设备驱动框架
Misc杂项设备驱动框架 由于设备号比较紧张,所以一些不相关的设备可以使用同一个主设备号,不同的次设备号.主设备号通常是10. 杂项设备结构体 struct miscdevice {int minor ...
- linux misc device字符杂项设备驱动
杂项设备也是在嵌入式系统中用得比较多的一种设备驱动.miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同.misc设备其实就是特殊的字符设备,主设备编号采用10,并且可自 ...
- linux块设备驱动编写,Linux内核学习笔记 -49 工程实践-编写块设备驱动的基础
块设备可以随机存储.字符设备,比如键盘,只能按照输入顺序存取,不可随机,打乱输入的字节流. 文件系统层,包括常见的文件系统,以及虚拟文件系统层VFS,字符设备可以直接用应用程序打开.块设备不会在应用程 ...
- 如何编写字符设备驱动
0.包含必须的头文件 #include <linux/fs.h> #include <linux/cdev.h> #include <linux/slab.h> / ...
- 杂项设备驱动框架_干货分享丨轻松玩转 Huawei LiteOS 传感框架
摘要:LiteOS传感框架将物联网终端设备上不同类型的传感器统一管理,通过抽象不同类型传感器接口,屏蔽其硬件细节,做到"硬件"无关性,非常方便于物联网设备的开发.维护和功能扩展. ...
- 迅为IMX6ULL开发板Linux I2C设备驱动编写流程-信息描述
1 .不使用设备树文件 当开始编写 I2C 设备驱动时,首先要添加设备信息.先来看一下在不使用设备树,使用平台文件时, 如何在平台文件中添加 I2C 设备信息. 在平台文件中通过 i2c_board_ ...
- (六)Linux之设备驱动模型(续)
前面我们学习了杂项设备驱动模型.早期经典字符设备驱动模型,这一小节来讲解Linux中的标准字符设备驱动. 目录 (一)为什么引入标准字符设备驱动模型 (二)相关接口 (三)注册流程 (四)程序示例 ( ...
- (五)Linux之设备驱动模型
目录 (一)Linux内核驱动简介 (二)杂项设备驱动模型 (1)相关接口 (2)杂项设备注册过程 (三)早期经典字符设备驱动模型 (1)相关接口 (2)杂项设备注册过程 (二)杂项和早期经典的区别 ...
最新文章
- 【Python初级】009-错误与异常
- python编程入门教学下载-Python编程从入门到实践的PDF教程免费下载
- deepin--解决屏幕撕裂问题
- 深化对KMP算法的理解
- 设置最小值_WELSIM中设置有限元计算结果的最大最小值
- boot2源码-事务
- 推荐游戏玩家使用金山密保保护帐号安全
- 一次外网打不开网站的故障总结
- java day19【File类、递归】
- Linux php.ini设置date.timezone=XXX为什么不生效?
- ListView中动态显示和隐藏HeaderFooter
- process 类 java_Process 执行命令行Java封装类详解
- .Net·使用ILSpy反编译exe或dll文件保存为项目结构
- 华为手机所有图标变黑_华为手机app图标变成黑色
- Win7 安装.Net 4.7.2 失败
- 2020年携程校招开发方向第一题
- java.io.FileNotFoundException: /opt/shan/es/logs/elasticsearch_index_indexing_slowlog.json (权限不够)
- UnicodeDecodeError: 'rawunicodeescape' codec can't decode bytes in position 80-81: truncated \UXXX
- BI是什么?应用BI工具能给企业带来哪些帮助?
- matlab四足仿真,基于MATLAB的四足机器人建模与仿真.docx
热门文章
- Android 开发 带图像的Toast提示
- 第五周课程总结试验报告三
- django准备 —环境配置,及其虚拟环境安装、django安装、数据库安装、新建项目...
- 即插即用!开源项目【云框架】发布“基于Spring cloud的微服务架构”
- c++ 求2-100内的素数问题
- 在一个工程(包)下面让activity和SensorEventListener监听分离,在不同类中完成
- 测试基础-03-用例设计方法:案例讲解
- 接口测试--apipost参数定位
- Selenium 编写第一个自动化脚本
- 03-25 内存统计