linux申请字符设备号函数及头文件
头文件:
/*包含初始化宏定义的头文件,代码中的module_init和module_exit在此文件中*/
#include
/*包含初始化加载模块的头文件,代码中的MODULE_LICENSE在此头文件中*/
#include
/*定义module_param module_param_array的头文件*/
#include
/*定义module_param module_param_array中perm的头文件*/
#include
/*三个字符设备函数*/
#include
/*MKDEV转换设备号数据类型的宏定义*/
#include
/*定义字符设备的结构体*/
【linux申请字符设备号函数及头文件】#include
/*分配内存空间函数头文件*/
#include
/*包含函数device_create 结构体class等头文件*/
#include
Linux内核中:
a -- 使用cdev结构体来描述字符设备;
b -- 通过其成员dev_t来定义设备号(分为主、次设备号)以确定字符设备的唯一性;
c -- 通过其成员file_operations来定义字符设备驱动提供给VFS的接口函数,如常见的open()、read()、write()等;
在Linux字符设备驱动中:
a -- 模块加载函数通过 register_chrdev_region( ) 或 alloc_chrdev_region( )来静态或者动态获取设备号;
b -- 通过 cdev_init( ) 建立cdev与 file_operations之间的连接,通过 cdev_add( ) 向系统添加一个cdev以完成注册;
c -- 模块卸载函数通过cdev_del( )来注销cdev,通过 unregister_chrdev_region( )来释放设备号;
用户空间访问该设备的程序:
a -- 通过Linux系统调用,如open( )、read( )、write( ),来“调用”file_operations来定义字符设备驱动提供给VFS的接口函数;
示例如下:
#include
#include
#include
#include
static int major = 99;
//主设备号(用于区分设备类)
static int minor = 0;
//次设备号(用于区分哪个设备)
static dev_t devno;
static struct cdev cdev1;
struct class *hello_class;
static int hello_open(struct inode *inodep, struct file *filep)
{
printk(KERN_ALERT "hello are opened \r\n");
return 0;
}
static struct file_operations hello_ops = {
.open = hello_open,
};
static int hello_init(void)
{
int ret;
printk(KERN_ALERT "hello_init\r\n");
//第一步:将主设备号、次设备号转化成dev_t类型
devno = MKDEV(major, minor);
ret = register_chrdev_region(devno, 1, "hello");
if (ret < 0)
{
printk(KERN_ERR "my register_chrdev_region fail \r\n");
return ret;
}
printk(KERN_INFO "register_chrdev_region success\n");
//第二步:注册字符设备驱动
cdev_init(&cdev1, &hello_ops);
ret = cdev_add(&cdev1, devno, 1);
if (ret < 0)
{
printk(KERN_ERR "Uable to add dev\n");
return ret;
}
printk(KERN_INFO "cdev_add success\n");
//第三步:2.6内核之后要向sys文件系统中添加设备
hello_class = class_create(THIS_MODULE, "hello");
device_create(hello_class, NULL, devno, NULL, "hello");
printk(KERN_INFO "device created success\n");
return 0;
}
static void hello_exit(void)
{
cdev_del(&cdev1);
unregister_chrdev_region(devno, 1);
printk(KERN_ALERT "hell_exit\r\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
推荐阅读
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- Linux下面如何查看tomcat已经使用多少线程
- Beego打包部署到Linux
- 字符串拼接成段落,换行符(\n)如何只执行n-1次
- 爬虫数据处理HTML转义字符
- C语言的版本比较
- Linux|109 个实用 shell 脚本
- linux定时任务contab
- 芯灵思SinlinxA33开发板Linux内核定时器编程