Linux Kernel 学习笔记3:设备编号
2017-04-14 15:55
381 查看
(本章基于:linux-4.4.0-37)
Linux中设备编号分为主、次两种。主设备编号表示设备相连的驱动。次设备号决定引用哪个设备,这个由驱动自行定义。
在内核中,设备编号类型为dev_t,本质就是一个32位无符号整型的量,在linux/types.h中定义。其中主编号占12位,次编号占20位。通过下面的宏可以获取主次编号:
MAJOR(dev_t dev);
MINOR(dev_t dev);
相反,通过主次编号获取设备编号使用:
MKDEV(int major, int minor);
以上宏在linux/kdev_t.h中定义
静态注册设备编号:
int register_chrdev_region(dev_t, unsigned, const char *);
1)需要注册的设备编号
2)连续编号个数
3)设备名,会出现在/proc/devices中
注册成功返回0,失败返回一个错误码
静态注册需要实现准备好一个设备号,但必须去其他的驱动模块区分开来,不能重复,因此静态注册并不常用,更通用的方法是让内核动态为你分配一个设备编号。
动态注册设备编号:
int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
1)设备编号
2)第一个次设备号,常用0
3)连续编号个数
4)设备名
成功注册返回0,失败返回一个错误码
无论用哪种方式注册设备编号,当不再使用的时候需要注销此设备号,以防止不必要的资源占用。
注销设备编号:
void unregister_chrdev_region(dev_t, unsigned);
1)待注销的设备号
2)连续的设备号个数
以上函数均在linux/fs.h中定义
例:
hello.c
成功加载模块后可在/proc/devices中查看
Linux中设备编号分为主、次两种。主设备编号表示设备相连的驱动。次设备号决定引用哪个设备,这个由驱动自行定义。
在内核中,设备编号类型为dev_t,本质就是一个32位无符号整型的量,在linux/types.h中定义。其中主编号占12位,次编号占20位。通过下面的宏可以获取主次编号:
MAJOR(dev_t dev);
MINOR(dev_t dev);
相反,通过主次编号获取设备编号使用:
MKDEV(int major, int minor);
以上宏在linux/kdev_t.h中定义
静态注册设备编号:
int register_chrdev_region(dev_t, unsigned, const char *);
1)需要注册的设备编号
2)连续编号个数
3)设备名,会出现在/proc/devices中
注册成功返回0,失败返回一个错误码
静态注册需要实现准备好一个设备号,但必须去其他的驱动模块区分开来,不能重复,因此静态注册并不常用,更通用的方法是让内核动态为你分配一个设备编号。
动态注册设备编号:
int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
1)设备编号
2)第一个次设备号,常用0
3)连续编号个数
4)设备名
成功注册返回0,失败返回一个错误码
无论用哪种方式注册设备编号,当不再使用的时候需要注销此设备号,以防止不必要的资源占用。
注销设备编号:
void unregister_chrdev_region(dev_t, unsigned);
1)待注销的设备号
2)连续的设备号个数
以上函数均在linux/fs.h中定义
例:
hello.c
#include <linux/init.h> #include <linux/module.h> #include <linux/stat.h> #include <linux/kdev_t.h> #include <linux/fs.h> dev_t devId; static __init int hello_init(void) { int result; #if 0 //静态 if(( result = register_chrdev_region(MKDEV(888, 0), 10, "stone-dev") ) != 0) { printk(KERN_WARNING "register dev id error:%d\n", result); } else { printk(KERN_WARNING "register dev id success!\n"); } #else //动态 if(( result = alloc_chrdev_region(&devId, 0, 1, "stone-alloc-dev") ) != 0) { printk(KERN_WARNING "register dev id error:%d\n", result); } else { printk(KERN_WARNING "register dev id success!\n"); } #endif printk(KERN_ALERT "hello init success!\n"); return 0; } static __exit void hello_exit(void) { //unregister_chrdev_region(MKDEV(888, 0), 10); unregister_chrdev_region(devId, 1); printk(KERN_WARNING "helloworld exit!\n"); } module_init(hello_init); module_exit(hello_exit);
成功加载模块后可在/proc/devices中查看
# cat /proc/devices | grep stone 247 stone-alloc-dev
相关文章推荐
- linux网络设备应用与驱动编程学习笔记(1)——应用编程(套接字)
- linux设备模型学习笔记——理论篇
- 【Linux学习笔记②】Linux系统内核Kernel和GNU计划
- 嵌入式linux学习笔记4之字符设备驱动
- Linux设备驱动模型学习笔记(kobject,kset,subsystem子系统)
- Linux设备模型学习笔记——结构体描述
- linux学习笔记-读《Linux编程技术详解》(6-1)-设备文件
- 《Linux 设备驱动 Edition 3》学习笔记
- linux 下块设备驱动开发学习笔记 2(sbull驱动分析)
- 学习笔记 --- LINUX MTD设备之NANDFLASH驱动分析
- linux内存学习笔记(二)——设备地址到用户空间
- Linux 学习笔记1 --- kernel初始化以及module_init(x)解析
- linux字符设备驱动学习笔记1
- linux字符设备驱动-重新学习-笔记-1
- Linux网络设备驱动学习笔记(-)
- linux网络设备应用与驱动编程学习笔记(2)——网络驱动基础
- linux字符设备驱动学习笔记3
- Linux 驱动学习笔记3 -- 字符设备驱动实例(driver+client)
- linux内存学习笔记(二)——设备地址到用户空间
- linux字符设备驱动学习笔记(一):简单的字符设备驱动