代码如下

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h> int demo_major = ;
int demo_minor = ;
int demo_count = ; struct cdev cdev; static struct class *demo_class;
static struct device *demo_device; int demo_open(struct inode *inodep, struct file * filep) // 打开设备
{
printk("%s,%d\n", __func__, __LINE__);
return ;
} int demo_release(struct inode * inodep, struct file * filep) // 关闭设备
{
printk("%s,%d\n", __func__, __LINE__);
return ;
} struct file_operations fops =
{
.owner = THIS_MODULE,
.open = demo_open,
.release = demo_release,
}; static int __init demo_init(void)
{
int ret = ;
dev_t devno; printk("%s,%d\n", __func__, __LINE__); //使用下列宏则可以通过主设备号和次设备号生成 dev_t
devno = MKDEV(demo_major, demo_minor); printk("devno:%d\n", devno);
printk("demo_major:%d\n", demo_major); /**在调用 cdev_add()函数向系统注册字符设备之前,
*应首先调用 register_chrdev_region()或alloc_chrdev_region()函数向系统申请设备号
**/
if (demo_major)
{
     //使用cat /proc/devices | grep demo 来查询
ret = register_chrdev_region(devno, , "demo");
}
else
{
ret = alloc_chrdev_region(&devno, demo_minor, , "demo");
} if(ret)
{
printk("Failed to register_chrdev_region.\n");
return ret;
} //cdev_init()函数用于初始化 cdev 的成员,并建立 cdev 和 file_operations 之间的连接
cdev_init(&cdev, &fops);
cdev.owner = THIS_MODULE; //系统添加一个 cdev,完成字符设备的注册。
ret = cdev_add(&cdev, devno, demo_count);
if(ret)
{
printk(KERN_NOTICE " Failed to cdev_add [Error] %d adding demo%d", ret, demo_minor); goto failure_cdev_add; } /*自动创建设备节点文件*/ //1.注册设备类 /sys/class/demo的文件夹
  //使用 ls /sys/class/demo
demo_class = class_create(THIS_MODULE, "demo");
if( IS_ERR(demo_class))
{
printk("class_create failed!\n");
ret = PTR_ERR("demo_class");
goto failure_class_create;
} //2.注册设备 /sys/class/demo/demo0 /dev/demo0
demo_device = device_create(demo_class, NULL, MKDEV(demo_major, demo_minor), NULL, "demo%d", demo_minor);
if(IS_ERR(demo_device)){
printk("device_create failed!\n");
ret = PTR_ERR("demo_device");
goto failure_device_create;
}
return ; failure_device_create:
class_destroy(demo_class);
failure_class_create:
cdev_del(&cdev);
failure_cdev_add:
unregister_chrdev_region(devno, demo_count);
failure_register_chrdev:
return ret;
} static void __exit demo_exit(void)
{
printk("%s,%d\n", __func__, __LINE__); /*逆序消除*/
//从内核中删除设备
device_destroy(demo_class,MKDEV(demo_major, demo_minor));
//从内核中删除设备类
class_destroy(demo_class);
//删除一个 cdev,完成字符设备的注销。
cdev_del(&cdev);
//在调用cdev_del()函数从系统注销字符设备之后,unregister_chrdev_region()应该被调用以释放原先申请的设备号
unregister_chrdev_region( MKDEV(demo_major, demo_minor), demo_count );
} module_init(demo_init);
module_exit(demo_exit); MODULE_AUTHOR(" libra13179 ");
MODULE_LICENSE("GPL v2");
KVERS = $(shell uname -r)

# Kernel modules
obj-m += demo.o # Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0 build: kernel_modules kernel_modules:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
# @echo $(KVERS) clean:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

int main(int argc, const char *argv[])

{

    int fd;

    int val = ;

    fd = open("/dev/demo0", O_RDWR);

    if (fd < )

    {

        printf("can't open!\n");

        return -;

    }

    else

    {

        printf("open success.\n");

    }

    getchar();

    close(fd);

    return ;

}

主要使用到函数

class_create
device_create
device_destroy

class_destroy

小技巧:
类似
http://lxr.free-electrons.com/
http://lxr.oss.org.cn/
这样的网站提供了Linux内核源代码的交叉索引,
在其中输入Linux内核中的函数、数据结构或变量的名称就可以直接得到以超链接形式给出的定义和引用它的所有位置。
还有一些网站也提供了Linux内核中函数、变量和数据结构的搜索功能,
在google中搜索“linux identifier search”可得。
 

linux驱动开发(四) 字符设备驱动框架(自动创建设备节点)的更多相关文章

  1. class_create(),device_create自动创建设备文件结点

    class_create(),device_create自动创建设备文件结点 从linux 内核2.6的某个版本之后,devfs不复存在,udev成为devfs的替代.相比devfs,udev有很多优 ...

  2. GPIO硬件资源的申请,内核空间和用户空间的数据交换,ioctl(.....),设备文件的自动创建

    1.通过GPIO库函数控制LED   open("/dev/myleds",...)       close(fd)   ----------------------------- ...

  3. platform型设备在/dev目录下自动创建设备节点的分析【转】

    转自:http://blog.csdn.net/rockrockwu/article/details/7357648 系统启动过程中platform设备.驱动注册完毕,为什么在/dev目录下就自动创建 ...

  4. Linux驱动开发2——字符设备驱动

    1.申请设备号 #include <linux/fs.h> int register_chrdev_region(dev_t first, unsigned int count, char ...

  5. 初入android驱动开发之字符设备(四-中断)

    上一篇讲到android驱动开发中,应用是怎样去操作底层硬件的整个流程,实现了按键控制led的亮灭.当然,这是一个非常easy的实例,只是略微演变一下,就能够得到广泛的应用. 如开发扫描头,应用透过监 ...

  6. 初入android驱动开发之字符设备(一)

    大学毕业,初入公司,招进去的是android驱动开发工程师的岗位,那时候刚进去,首先学到的就是如何搭建kernel.android的编译环境,然后就是了解如何刷设备以及一些最基本的工具.如adb.fa ...

  7. 驱动开发--【字符设备、块设备简介】【sky原创】

    驱动开发   字符设备,块设备,网络设备   字符设备 以字节流的方式访问, 不能随机访问 有例外,显卡.EEPROM可以随机访问   EEPROM可以擦写1亿次,是一种字符设备,可以随机访问 读写是 ...

  8. linux设备驱动第四篇:驱动调试方法

    http://www.cnblogs.com/donghuizaixian/archive/2015/04/02/4387083.html 上一篇我们大概聊了如何写一个简单的字符设备驱动,我们不是神, ...

  9. linux设备驱动----利用mdev(udev)自动创建设备文件节点

    1.mdev的使用方法和原理: mdev是busybox 自带的一个简化版的udev,适合于嵌入式的应用埸合.其具有使用简单的特点.它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程 ...

随机推荐

  1. Qt布局管理: 停靠窗口QDockWidget类(纯代码实现)

    转载:好儿郎~志在四方 详细描述: QDockWidget类提供了一个窗体部件,其可以停靠在QMainWindow,或其本身作为一个在桌面上的顶级窗口(也就是父窗体). QDockWidget类提供了 ...

  2. Kubernetes1.8以后kubelet连接api-server问题

    Kubernetes1.8以后版本,kubelet命令去掉--api-servers选项,参考官方kubelet 1.8 --kubeconfig string Path to a kubeconfi ...

  3. 阿里云ECS专有网络下安装flannel注意事项

    参照文章http://www.cnblogs.com/lyzw/p/6016789.html在两台阿里云ECS主机安装与配置flannel,在专有网络下两台主机只能通过公网ip连通,所以flannel ...

  4. C与C++的部分区别

    1.函数无形参情况 void test() { } int main() { test(,); ; } 在C语言中形参括号没有参数时代表接受任意多的参数,而在C++语言中代表void(无参数) 所以上 ...

  5. NIO框架之MINA源码解析(四):粘包与断包处理及编码与解码

    1.粘包与段包 粘包:指TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.造成的可能原因: 发送端需要等缓冲区满才发送出去,造成粘包 接收 ...

  6. [VS2013]发布网站时修改配置文件

    本文来自:https://msdn.microsoft.com/en-us/library/ee942158.aspx#encrypt_webconfig Web Deployment FAQ for ...

  7. HDOJ 2007 平方和与立方和

    #include<iostream> #include<algorithm> using namespace std; int main() { int m, n; while ...

  8. windows server 2008 R2 安装

    微软服务器操作系统大致有: server 2000(简称2K),还有server 2003(2K3),server 2008(2K8),server 2000和2003是基于NT内核的,而2008是基 ...

  9. Jmeter(十九)Logic Controllers 之 Module Controller and Include Controller

    Module Controller ---模块控制器 测试计划设置“独立运行没每个线程组” 线程组2中使用Module Controller执行线程组1中的Sampler: 紧接着,将线程组1disa ...

  10. .net core批量注入实现类

    1.获取实现类程序集方法 public class RuntimeHelper { //通过程序集的名称加载程序集 public static Assembly GetAssemblyByName(s ...