博客
关于我
17-18_静态和动态申请字符类设备号
阅读量:320 次
发布时间:2019-03-04

本文共 4071 字,大约阅读时间需要 13 分钟。

字符设备驱动开发

1. 相关头文件与函数

1.1 fs.h

在文件 include/linux/fs.h 中,内核提供了三个函数来注册一组字符设备编号:

  • register_chrdev_region()
  • alloc_chrdev_region()
  • register_chrdev()

(1)register_chrdev_region

int register_chrdev_region(dev_t from, unsigned count, const char *name)
  • from:要分配的设备编号范围的初始值,这组连续设备号的起始设备号。
  • count:连续编号范围,是这组设备号的大小(也是次设备号的个数)。
  • name:编号相关联的设备名称(/proc/devices),本组设备的驱动名称。

(2)alloc_chrdev_region

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
  • dev:alloc_chrdev_region函数向内核申请下来的设备号。
  • baseminor:次设备号的起始。
  • count:申请次设备号的个数。
  • name:执行 cat /proc/devices 显示的名称。

(3)register_chrdev(老版本的字符设备申请函数)

int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
  • major:主设备号,当用户设置为0时,内核会动态分配一个设备号。
  • name:设备名称。
  • fops:文件系统的接口指针。

1.2 kdev_t.h

头文件位置 include/linux/kdev_t.h,定义了以下宏:

#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))#define MKDEV(ma, mi) (((ma) << MINORBITS) | (mi))
  • MKDEV:将主设备号和次设备号组合成一个 dev_t 类型的设备编号。
  • dev_t 类型是 unsigned int,高12位为主设备号,低20位为次设备号。

1.3 cdev.h

头文件位置 include/linux/cdev.h,定义了 cdev 结构体:

struct cdev {    struct kobject kobj;    struct module *owner;    const struct file_operations *ops;    struct list_head list;    dev_t dev;    unsigned int count;}
  • cdev.dev:设备号,高12位为主设备号,低20位为次设备号。

2. 静态申请字符类设备号

2.1 代码示例

#include 
#include
#include
#include
#include
#include
#define DEVICE_NAME "scdev"#define DEVICE_MINOR_NUM 2#define DEV_MAJOR 0#define DEV_MINOR 0MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("iTOPEET_dz");int numdev_major = DEV_MAJOR;int numdev_minor = DEV_MINOR;module_param(numdev_major, int, S_IRUSR);module_param(numdev_minor, int, S_IRUSR);static int scdev_init(void) { int ret = 0; dev_t num_dev; printk(KERN_EMERG "numdev_major is %d!\n", numdev_major); printk(KERN_EMERG "numdev_minor is %d!\n", numdev_minor); if (numdev_major) { num_dev = MKDEV(numdev_major, numdev_minor); ret = register_chrdev_region(num_dev, DEVICE_MINOR_NUM, DEVICE_NAME); } else { printk(KERN_EMERG "numdev_major %d is failed!\n", numdev_major); } if (ret < 0) { printk(KERN_EMERG "register_chrdev_region req %d is failed!\n", numdev_major); } printk(KERN_EMERG "scdev_init!\n"); return 0;}static void scdev_exit(void) { printk(KERN_EMERG "scdev_exit!\n"); unregister_chrdev_region(MKDEV(numdev_major, numdev_minor), DEVICE_MINOR_NUM);}module_init(scdev_init);module_exit(scdev_exit);

2.2 Makefile

#!/bin/bashobj-m += request_cdev_num.oKDIR := /home/topeet/iTop4412_Kernel_3.0PWD := $(shell pwd)all:    make -C $(KDIR) M=$(PWD) modulesclean:    rm -rf *.mod.c *.o *.order *.ko *.mod.o *.symvers

3. 动态申请字符类设备号

3.1 驱动代码

#include 
#include
#include
#include
#include
#include
#define DEVICE_NAME "acdev"#define DEVICE_MINOR_NUM 2#define DEV_MAJOR 0#define DEV_MINOR 0MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("iTOPEET_dz");int numdev_major = DEV_MAJOR;int numdev_minor = DEV_MINOR;module_param(numdev_major, int, S_IRUSR);module_param(numdev_minor, int, S_IRUSR);static int acdev_init(void) { int ret = 0; dev_t num_dev; printk(KERN_EMERG "numdev_major is %d!\n", numdev_major); printk(KERN_EMERG "numdev_minor is %d!\n", numdev_minor); if (numdev_major) { num_dev = MKDEV(numdev_major, numdev_minor); ret = register_chrdev_region(num_dev, DEVICE_MINOR_NUM, DEVICE_NAME); } else { ret = alloc_chrdev_region(&num_dev, numdev_minor, DEVICE_MINOR_NUM, DEVICE_NAME); numdev_major = MAJOR(num_dev); printk(KERN_EMERG "adev_region req %d !\n", numdev_major); } if (ret < 0) { printk(KERN_EMERG "register_chrdev_region req %d is failed!\n", numdev_major); } printk(KERN_EMERG "acdev_init!\n"); return 0;}static void acdev_exit(void) { printk(KERN_EMERG "acdev_exit!\n"); unregister_chrdev_region(MKDEV(numdev_major, numdev_minor), DEVICE_MINOR_NUM);}module_init(acdev_init);module_exit(acdev_exit);

3.2 代码调试

[root@iTOP-4412]# insmod request_acdev_num.ko[root@iTOP-4412]# rmmod request_acdev_num

转载地址:http://idwh.baihongyu.com/

你可能感兴趣的文章
Objective-C实现三次样条曲线(附完整源码)
查看>>
Objective-C实现三维空间点到直线的距离(附完整源码)
查看>>
Objective-C实现三维空间点到直线的距离(附完整源码)
查看>>
Objective-C实现三重缓冲区(附完整源码)
查看>>
Objective-C实现上传文件到FTP服务器(附完整源码)
查看>>
Objective-C实现下载文件(附完整源码)
查看>>
Objective-C实现不重复字符的最长子串算法(附完整源码)
查看>>
Objective-C实现两个字符串由相同的字母组成但排列方式不同(字符串字谜)算法(附完整源码)
查看>>
Objective-C实现两个日期之间的天数(附完整源码)
查看>>
Objective-C实现两个栈实现队列算法(附完整源码)
查看>>
Objective-C实现两个队列实现栈算法(附完整源码)
查看>>
Objective-C实现两数之和问题(附完整源码)
查看>>
Objective-C实现中介者模式(附完整源码)
查看>>
Objective-C实现中值滤波(附完整源码)
查看>>
Objective-C实现中国剩余定理(附完整源码)
查看>>
Objective-C实现中国剩余定理(附完整源码)
查看>>
Objective-C实现中文模糊查询(附完整源码)
查看>>
Objective-C实现串口通讯(附完整源码)
查看>>
Objective-C实现串逐位和(附完整源码)
查看>>
Objective-C实现串链式存储简单匹配(附完整源码)
查看>>