day1

 

在linux内核中,当用户打开设备文件时,内核中的VFS层会调用设备驱动中的sys_open()函数,在sys_open()函数中,内核会根据文件的inode号判断文件是否存在于文件系统中,如果存在,内核会找到这个文件的文件信息结构体,并通过字符设备驱动对象结构体指针找到操作方法结构体中的open()函数。
 

字符设备驱动注册流程:
1.为字符设备驱动对象申请空间
    struct cdev *cdev=cdev_alloc();
2.字符设备驱动对象的初始化
    (1)实现字符设备驱动对象的部分初始化
        void cdev_init(struct cdev *cdev, const struct file_operations *fops);
    (2)申请设备号
        静态:int register_chrdev_region(dev_t from, unsigned count, const char *name)
        动态:int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
              const char *name)     
3.将字符设备驱动对象注册进内核
    int cdev_add(struct cdev *cdev, dev_t dev, unsigned count);
    
字符设备驱动注销流程:
1.字符设备驱动对象的注销
    void cdev_del(struct cdev *);
2.释放申请的设备号
    void unregister_chrdev_region(dev_t from, unsigned count)
3.释放对象空间  
    void kfree(void *p)

代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include "led.h"
 
struct cdev *cdev;
struct class *cls;
struct device * dev;
unsigned int major=500;
unsigned int minor=0;
dev_t devno;
 
 
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
 
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    return 0;
}
 
int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
 
//定义操作方法结构体变量并赋值
struct file_operations fops={
 
    .open=mycdev_open,
   .unlocked_ioctl=mycdev_ioctl,
    .release=mycdev_close,
};
 
static int __init mycdev_init(void)
{
    int ret,i;
 
    //1.分配对象空间
    cdev=cdev_alloc();
    if(cdev==NULL)
    {
        printk("分配字符设备驱动对象失败\n");
        ret=-EFAULT;
        goto OUT1;
    }
    printk("分配对象空间成功\n");
 
    //2.初始化对象
    cdev_init(cdev,&fops);
 
    //3.申请设备号
    if(major>0)//静态指定设备号
    {
        ret= register_chrdev_region(MKDEV(major,minor),3,"myled");
        if(ret)
        {
            printk("静态指定设备号失败\n");
            goto OUT2;
        }
    }
    else if(major==0)//动态申请设备号
    {
        ret=alloc_chrdev_region(&devno,minor,3,"myled");
        if(ret)
        {
            printk("动态申请设备号失败\n");
            goto OUT2;
        }
        //获取主设备号和次设备号
        major=MAJOR(devno);
        minor=MINOR(devno);
    }
    printk("申请设备号成功\n");
 
    //4.注册字符设备驱动对象
    ret=cdev_add(cdev,MKDEV(major,minor),3);
    if(ret)
    {
        printk("注册字符设备驱动对象失败\n");
        goto OUT3;
    }
    printk("注册字符设备驱动对象成功\n");
 
    //向上提交目录
    cls=class_create(THIS_MODULE,"myled");
    if(IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        ret=-PTR_ERR(cls);
        goto OUT4;
    }
    printk("向上提交目录成功\n");
 
    //向上提交设备节点信息
    for(i=0;i<3;i++)
    {
         dev=device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
         if(IS_ERR(dev))
         {
            ret=-PTR_ERR(dev);
            goto OUT5;
         }
    }
    printk("向上提交设备节点成功\n");
    //完成硬件寄存器地址的映射以及初始化
    return 0;
 
OUT5:
    //释放已经申请的设备节点信息
    for(--i;i>=0;i--)
    {
        device_destroy(cls,MKDEV(major,i));
    }
    //释放目录空间
    class_destroy(cls);
OUT4:
    //注销字符设备驱动对象
    cdev_del(cdev);
OUT3:
    //释放设备号
    unregister_chrdev_region(MKDEV(major,minor),3);
OUT2:
    //释放对象空间
    kfree(cdev);
OUT1:
    return ret;
}
 
static void __exit mycdev_exit(void)
{
    //销毁设备节点
    int i;
    for(i=0;i<3;i++)
    {
        device_destroy(cls,MKDEV(major,i));
    }
    //释放目录空间
    class_destroy(cls);
    //1.注销字符设备驱动对象
     cdev_del(cdev);
    //2.释放设备号
     unregister_chrdev_region(MKDEV(major,minor),3);
    //3.释放对象空间
     kfree(cdev);
}
 
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/31080.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

翻筋斗觅食策略改进灰狼算法(IGWO)

目录 一、动态扰动因子策略 二、翻筋斗觅食策略 三、改进灰狼算法收敛曲线图 灰狼优化算法存在收敛的不合理性等缺陷&#xff0c;目前对GWO算法的收敛性改进方式较少&#xff0c;除此之外&#xff0c;当GWO迭代至后期&#xff0c;所有灰狼个体都逼近狼、狼、狼&#xff0c;…

A Neural Conversational Model 读后感

目录 摘要 1、介绍 2、相关工作 3、模型 4、数据&#xff08;后面都是具体的东西&#xff0c;不赘述&#xff09; 5、总结 使用微软翻译得到的中文原文&#xff1a; 摘要 会话建模是自然语言理解和机器智能中的一项重要任务。尽管存在以前的方法&#xff0c;但它们通常仅…

React中的HOC高阶组件处理

先了解函数柯里化 柯里化函数&#xff08;Currying Function&#xff09;是指将一个接受多个参数的函数转化成一系列只接受单个参数的函数&#xff0c;并且返回接受单个参数的函数&#xff0c;达到简化函数调用和提高可读性的目的。 简单来说&#xff0c;柯里化即将接收多个参…

Pytorch数据类型Tensor张量操作(操作比较全)

文章目录 Pytorch数据类型Tensor张量操作一.创建张量的方式1.创建无初始化张量2.创建随机张量3.创建初值为指定数值的张量4.从数据创建张量5.生成等差数列张量 二.改变张量形状三.索引四.维度变换1.维度增加unsqueeze2.维度扩展expand3.维度减少squeeze4.维度扩展repeat 五.维度…

Jenkins-pipeline自动化构建Java应用

本实验操作需要&#xff1a;Jenkins&#xff0c;git代码仓库&#xff08;如gitlab&#xff0c;gitee等都可以&#xff09;&#xff0c;maven&#xff0c;docker&#xff0c;docker镜像仓库&#xff08;habor&#xff0c;nexus或者阿里云ACR等&#xff09;以及k8s环境。 前期准…

Python网络爬虫基础进阶到实战教程

文章目录 认识网络爬虫HTML页面组成Requests模块get请求与实战效果图代码解析 Post请求与实战代码解析 发送JSON格式的POST请求使用代理服务器发送POST请求发送带文件的POST请求 Xpath解析XPath语法的规则集&#xff1a;XPath解析的代码案例及其详细讲解&#xff1a;使用XPath解…

k8s使用ceph存储

文章目录 初始化操作k8s使用ceph rbdvolumePV静态pv动态pv k8s使用cephfsvolume静态pv 初始化操作 ceph创建rbd存储池 ceph osd pool create k8s-data 32 32 replicated ceph osd pool application enable k8s-data rbd rbd pool init -p k8s-dataceph添加授权&#xff0c;需…

吴恩达ChatGPT《Building Systems with the ChatGPT API》笔记

1. 课程介绍 使用ChatGPT搭建端到端的LLM系统 本课程将演示使用ChatGPT API搭建一个端到端的客户服务辅助系统&#xff0c;其将多个调用链接到语言模型&#xff0c;根据前一个调用的输出来决定使用不同的指令&#xff0c;有时也可以从外部来源查找信息。 课程链接&#xff1a…

client-go的Indexer三部曲之三:源码阅读

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 《client-go的Indexer三部曲》全部链接 基本功能性能测试源码阅读 本篇概览 本文是《client-go的Indexer三部曲》系列的终篇&#xff0c;主要任务是阅读和…

VR全景智慧园区,沉浸式数字化体验,720度全视角展示

导语&#xff1a; 随着科技的迅猛发展&#xff0c;虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;全景技术已经成为了人们趋之若鹜的新兴领域。 而城市园区作为现代社会的重要组成部分&#xff0c;也正在积极寻求创新的方式来吸引更多的人流和投资。 一&…

C++基础

C基础入门 1 C初识 1.1 第一个C程序 编写一个C程序总共分为4个步骤 创建项目创建文件编写代码运行程序 1.1.1 创建项目 ​ Visual Studio是我们用来编写C程序的主要工具&#xff0c;我们先将它打开 1.1.2 创建文件 右键源文件&#xff0c;选择添加->新建项 1.1.3 编…

SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

SignalR快速入门 ~ 仿QQ即时聊天&#xff0c;消息推送&#xff0c;单聊&#xff0c;群聊&#xff0c;多群公聊&#xff08;基础》提升&#xff0c;5个Demo贯彻全篇&#xff0c;感兴趣的玩才是真的学&#xff09; 官方demo:http://www.asp.net/signalr/overview/getting-started…

【面试】标准库相关题型(二)

文章目录 1. deque底层实现原理1.1 概述1.2 原理图1.3 类结构1.4 操作函数 2. 什么时候使用vector、list、deque2.1 vector2.2 list2.3 deque 3. priority_queue的底层实现原理3.1 一句话概括&#xff1a;用堆来实现优先级队列3.2 堆结构3.3 底层容器3.4 STL对堆结构提供的接口…

Java-API简析_java.lang.SecurityManager类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131346082 出自【进步*于辰的博客】 其实我的【Java-API】专栏内的博文对大家来说意义是不大的。…

Python入门(二十七)测试(二)

测试&#xff08;二&#xff09; 1.测试类2.各种断言方法3.一个要测试的类4.测试AnonymousSurvey类5.方法setUp() 1.测试类 前面我们编写了针对单个函数的测试&#xff0c;下面来编写针对类的测试。很多程序中都会用到类&#xff0c;因此证明我们的类能够正确工作大有裨益。如…

学了那么长时间的编程,C语言的各种操作符都搞不懂?点开这里有详细的介绍—>

目录 前言 一、原码、反码、补码的基础概念 1.原码 2.反码 3.补码 二、原码、反码、补码的计算方法 1.原码 2.反码 3.补码 三、算术操作符 四、移位操作符 1. 左移操作符 移位规则&#xff1a; 2. 右移操作符 移位规则&#xff1a; &#xff08;1&#xff09; …

电脑怎么录屏?推荐2款录制电脑屏幕的软件!

案例&#xff1a;我经常需要把电脑上的内容分享给别人&#xff0c;一般通过手机拍摄的方式。这就导致视频十分模糊&#xff0c;给人的观感不太好&#xff0c;有没有什么方法可以实现在电脑上直接录屏&#xff1f; 【我想录制我的电脑屏幕上的内容分享给别人&#xff0c;但是我…

几个SQL的高级写法

一、ORDER BY FLELD() 自定义排序逻辑 MySql 中的排序 ORDER BY 除了可以用 ASC 和 DESC&#xff0c;还可以通过 ORDER BY FIELD(str,str1,...) 自定义字符串/数字来实现排序。这里用 order_diy 表举例&#xff0c;结构以及表数据展示&#xff1a; ORDER BY FIELD(str,str1,..…

【Neo4j教程之CQL函数基本使用】

&#x1f680; Neo4j &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;C…

3d重建+神经渲染

3d重建 基于深度相机(结构光、TOF、双目摄像头)的三维重建基于图像的三维重建&#xff1a;深度学习基于视觉几何的传统三维重建&#xff1a;这种三维重建方法研究时间比较久远&#xff0c;技术相对成熟。主要通过多视角图像对采集数据的相机位置进行估计&#xff0c;再通过图像…