linux驱动开发之一个真正的设备驱动需要一些什么元素(设备号,操作方法)
2018-01-27 17:52
471 查看
1,需要一个设备号(重点看下面的代码)
因为内核中有很多的设备驱动,所以需要一个设备号id来进行区分
设备号分成两个部分:
主设备号:某一类设备
次设备号: 某类设备中某个设备设备
比如:前置和后置摄像头都是camera这类设备
前置 : 0
后置 : 1
在内核中: dev_t来表示设备号,
32bit的整数
高12bit: 主设备号
低20bit:次设备号
(1)申请设备号函数
//参数1—指定一个号码也可以由系统分配,填0表示由系统分配
//参数2–字符串–描述设备驱动信息–自定义
//参数3—文件操作对象
// 返回值—如果是系统分配,返回分配之后的号码,否则返回负数为错误
int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)
(2)卸载设备号函数
//参数1—已经申请到的设备号
//参数2–字符串–描述设备驱动信息–自定义
void unregister_chrdev(unsigned int major, const char *name)
备注:怎样在开发板查看驱动模块是否装载成功 用cat /proc/devices
2,需要一个设备文件
linux中将所有的设备都看成是文件,操作设备其实就是操作文件
设备文件称为设备节点
(c表示字符设备,b表示块设备)
驱动可以操作底层硬件,并且为应用服务的,例如驱动可以操控led亮或者灭,但是怎样亮灭,亮灭多久,是应用程序决定的。即如果只有驱动程序,没有应用程序,驱动程序就没有任何作用
3,需要一个设备的操作方法
编译工具:source insight 4.0
驱动程序:hello_drv.c
应用程序:hello_app.c
Makefile
执行应用程序./hello.app
查看设备节点:
cat /proc/devices
可知设备号为254,设备节点时hello_drv
因为内核中有很多的设备驱动,所以需要一个设备号id来进行区分
设备号分成两个部分:
主设备号:某一类设备
次设备号: 某类设备中某个设备设备
比如:前置和后置摄像头都是camera这类设备
前置 : 0
后置 : 1
在内核中: dev_t来表示设备号,
32bit的整数
高12bit: 主设备号
低20bit:次设备号
(1)申请设备号函数
//参数1—指定一个号码也可以由系统分配,填0表示由系统分配
//参数2–字符串–描述设备驱动信息–自定义
//参数3—文件操作对象
// 返回值—如果是系统分配,返回分配之后的号码,否则返回负数为错误
int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)
(2)卸载设备号函数
//参数1—已经申请到的设备号
//参数2–字符串–描述设备驱动信息–自定义
void unregister_chrdev(unsigned int major, const char *name)
备注:怎样在开发板查看驱动模块是否装载成功 用cat /proc/devices
2,需要一个设备文件
linux中将所有的设备都看成是文件,操作设备其实就是操作文件
设备文件称为设备节点
系统中所有的设备节点都在 ls -l /dev/ crw--w---- 1 root tty 4, 10 Nov 23 00:41 tty10 crw--w---- 1 root tty 4, 11 Nov 23 00:41 tty11 crw--w---- 1 root tty 4, 12 Nov 23 00:41 tty12
(c表示字符设备,b表示块设备)
创建: 手动和自动创建 手动:每次都要创建, /dev中所有的文件都是在内存中 mknod 文件名 类型 主设备号 次设备号 mknod /dev/hello c 254 0 [root@ubuntu /drv_module]# ls /dev/hello -l crw-r--r-- 1 0 0 254, 0 Jan 1 00:52 /dev/hello
驱动可以操作底层硬件,并且为应用服务的,例如驱动可以操控led亮或者灭,但是怎样亮灭,亮灭多久,是应用程序决定的。即如果只有驱动程序,没有应用程序,驱动程序就没有任何作用
3,需要一个设备的操作方法
int hello_drv_open(struct inode *inode, struct file *filp) { printk("-------^_^ %s-------\n", __FUNCTION__); return 0; } const struct file_operations hello_fops = { .open = hello_drv_open, };
编译工具:source insight 4.0
驱动程序:hello_drv.c
#include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> static int dev_major;//申请的设备号 int hello_drv_open(struct inode *inode, struct file *filp) { printk("-------^_^ %s-------\n", __FUNCTION__); return 0; } //文件操作对象int (*open) (struct inode *, struct file *); const struct file_operations hello_fops = { .open = hello_drv_open,//当应用程序调用open,实际是调用驱动程序中(该程序)的xxx_open() }; //实现驱动模块的装载函数-----insmod // 模块加载函数中主要完成系统资源的申请 static int __init hello_init(void) { printk("-------^_^ %s-------\n", __FUNCTION__); // 需要有一个设备号----申请/注册 //参数1---指定一个号码也可以由系统分配,填0表示由系统分配 //参数2--字符串--描述设备驱动信息--自定义--/proc/devices //参数3---文件操作对象 // 返回值---如果是系统分配,返回分配之后的号码,否则返回负数为错误 dev_major = register_chrdev(0, "hello_drv", &hello_fops); if(dev_major < 0) { printk("register_chrdev error\n"); return -EINVAL;//注意有负号 } return 0; } //实现驱动模块的卸载函数 // 模块卸载函数中主要完成系统资源的释放 static void __exit hello_exit(void) { printk("-------^_^ %s-------\n", __FUNCTION__); //参数1---已经申请到的设备号 //参数2--字符串--描述设备驱动信息--自定义 //卸载这类型的函数一般没有返回值 unregister_chrdev(dev_major, "hello_drv"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");
应用程序:hello_app.c
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char *argv[]) { int fd = open("/dev/hello", O_RDWR); return 0; }
Makefile
CROSS_COMPILE = arm-none-linux-gnueabi- CC = $(CROSS_COMPILE)gcc APP_NAME = hello_app MODULE_NAME = hello_drv #内核源码路径 KERNEL_DIR = /home/ubuntu/s5pv210/kernel/linux-3.0.8 CUR_DIR = $(shell pwd) all : #表示进入到内核目录,并且告诉内核要将当前的源码编译成模块 make -C $(KERNEL_DIR) M=$(CUR_DIR) modules $(CC) $(APP_NAME).c -o $(APP_NAME) clean : make -C $(KERNEL_DIR) M=$(CUR_DIR) clean rm -rf $(APP_NAME) install: cp -raf *.ko $(APP_NAME) /opt/rootfs/drv_module/ #指定编译哪个源文件 obj-m = $(MODULE_NAME).o
执行应用程序./hello.app
查看设备节点:
cat /proc/devices
可知设备号为254,设备节点时hello_drv
相关文章推荐
- 一些经久不衰的linux 视频教程列表,看看嵌入式开发需要什么
- Linux 驱动开发-字符设备驱动一些函数用法
- linux驱动开发--一个驱动管理多个设备
- Linux驱动开发学习的一些必要步骤
- 【转帖】驱动开发之一 --- 创建一个简单的设备驱动 【译文】
- Windows CE下USB设备驱动开发的一些基础知识
- [转]Linux驱动开发学习的一些必要步骤
- linux设备驱动开发工具光盘第一版推出
- Linux驱动程序开发(4) - 字符设备驱动(3)-LED设备驱动和应用程序
- [转帖]Linux驱动开发学习的一些必要步骤
- 浅谈 Linux 内核开发之 PCI 设备驱动
- Linux下的硬件驱动——USB设备(下)(驱动开发部分)
- Linux下PCI设备驱动程序开发 --- linux 驱动框架(二)
- Linux驱动程序开发 - 设备驱动模型初探
- Linux系统下的C语言开发都需要学些什么
- Linux下的硬件驱动——USB设备(下)(驱动开发部分)
- Linux系统下的C语言开发都需要学些什么
- Linux驱动开发学习的一些必要步骤
- Linux下的硬件驱动——USB设备(下)&& Linux下PCI设备驱动程序开发
- Linux驱动开发学习的一些必要步骤