精华内容
下载资源
问答
  • 一次设备进行控制,保护作用的设备叫做二次设备,如继电器,控制开关,指示灯,测量仪表等。 另解: 一次设备通常包含以下五类: (1)、能量转换设备(如发电机、变压器、电动机等) (2)、开关设备(断路器...
    完成发电-输电-配电功能的设备叫做一次设备,如发电机,断路器,电流电压互感器,变压器,避雷器等;
    对一次设备进行控制,保护作用的设备叫做二次设备,如继电器,控制开关,指示灯,测量仪表等。
    另解:
    一次设备通常包含以下五类:
    (1)、能量转换设备(如发电机、变压器、电动机等)
    (2)、开关设备(断路器、熔断器、负荷开关、隔离开关等)
    (3)、载流导体(母线、绝缘子和电缆等)
    (4)、互感器(电压、电流等互感器)
    (5)、电抗器和避雷器(电抗器主要用于限制电路中的短路电流;避雷器则用于限制电气设备的过电压)
    二次设备:对电气一次设备的工作状态进行监测、控制和保护的辅助性电气设备称为二次设备。例如各种电气仪表、继电器、自动控制设备、信号电缆和控制电缆等。
    
    展开全文
  • 在20世纪40年代和50年代,来自不同领域(数学,心理学,工程学,经济学和政治学)的批科学家开始探讨制造人工大脑的可能性。1956年,人工智能被确立为一门学科。 控制论与早期神经网络 最初的人工智能研究是30年...

    https://www.toutiao.com/a6654718358287548932/

     

    2019-02-06 11:05:58

    人工智能的诞生:1943 – 1956

    在20世纪40年代和50年代,来自不同领域(数学,心理学,工程学,经济学和政治学)的一批科学家开始探讨制造人工大脑的可能性。1956年,人工智能被确立为一门学科。

    控制论与早期神经网络

    最初的人工智能研究是30年代末到50年代初的一系列科学进展交汇的产物。神经学研究发现大脑是由神经元组成的电子网络,其激励电平只存在“有”和“无”两种状态,不存在中间状态。维纳的控制论描述了电子网络的控制和稳定性。克劳德•香农提出的信息论则描述了数字信号(即高低电平代表的二进制信号)。图灵的计算理论证明数字信号足以描述任何形式的计算。这些密切相关的想法暗示了构建电子大脑的可能性。

    人工智能史上的二次低谷——第一次低谷

    IBM 702:第一代AI研究者使用的电脑

    这一阶段的工作包括一些机器人的研发,例如W。Grey Walter的“乌龟(turtles)”,还有“约翰霍普金斯兽”(Johns Hopkins Beast)。这些机器并未使用计算机,数字电路和符号推理;控制它们的是纯粹的模拟电路。

    Walter Pitts和Warren McCulloch分析了理想化的人工神经元网络,并且指出了它们进行简单逻辑运算的机制。他们是最早描述所谓“神经网络”的学者。马文•闵斯基是他们的学生,当时是一名24岁的研究生。1951年他与Dean Edmonds一道建造了第一台神经网络机,称为SNARC。在接下来的五十年中,闵斯基是AI领域最重要的领导者和创新者之一。

    游戏AI

    1951年,Christopher Strachey使用曼彻斯特大学的Ferranti Mark 1机器写出了一个西洋跳棋(checkers)程序;Dietrich Prinz则写出了一个国际象棋程序。Arthur Samuel在五十年代中期和六十年代初开发的国际象棋程序的棋力已经可以挑战具有相当水平的业余爱好者。游戏AI一直被认为是评价AI进展的一种标准。

    图灵测试

    1950年,图灵发表了一篇划时代的论文,文中预言了创造出具有真正智能的机器的可能性。由于注意到“智能”这一概念难以确切定义,他提出了著名的图灵测试:如果一台机器能够与人类展开对话(通过电传设备)而不能被辨别出其机器身份,那么称这台机器具有智能。这一简化使得图灵能够令人信服地说明“思考的机器”是可能的。论文中还回答了对这一假说的各种常见质疑。图灵测试是人工智能哲学方面第一个严肃的提案。

    人工智能史上的二次低谷——第一次低谷

    图灵测试

    符号推理与“逻辑理论家”程序

    50年代中期,随着数字计算机的兴起,一些科学家直觉地感到可以进行数字操作的机器也应当可以进行符号操作,而符号操作可能是人类思维的本质。这是创造智能机器的一条新路。

    1955年,Newell和(后来荣获诺贝尔奖的)Simon在J. C. Shaw的协助下开发了“逻辑理论家(Logic Theorist)”。这个程序能够证明《数学原理》中前52个定理中的38个,其中某些证明比原著更加新颖和精巧。Simon认为他们已经“解决了神秘的心/身问题,解释了物质构成的系统如何获得心灵的性质。” (这一断言的哲学立场后来被John Searle称为“强人工智能”,即机器可以像人一样具有思想。)

    1956年达特茅斯会议:AI的诞生

    1956年达特矛斯会议的组织者是Marvin Minsky,约翰•麦卡锡和另两位资深科学家Claude Shannon以及Nathan Rochester,后者来自IBM。会议提出的断言之一是“学习或者智能的任何其他特性的每一个方面都应能被精确地加以描述,使得机器可以对其进行模拟。” 与会者包括Ray Solomonoff,Oliver Selfridge,Trenchard More,Arthur Samuel,Newell和Simon,他们中的每一位都将在AI研究的第一个十年中作出重要贡献。会上纽厄尔和西蒙讨论了“逻辑理论家”,而麦卡锡则说服与会者接受“人工智能”一词作为本领域的名称。1956年达特矛斯会议上AI的名称和任务得以确定,同时出现了最初的成就和最早的一批研究者,因此这一事件被广泛承认为AI诞生的标志。

    黄金年代:1956 – 1974

    达特茅斯会议之后的数年是大发现的时代。对许多人而言,这一阶段开发出的程序堪称神奇:计算机可以解决代数应用题,证明几何定理,学习和使用英语。当时大多数人几乎无法相信机器能够如此“智能”。研究者们在私下的交流和公开发表的论文中表达出相当乐观的情绪,认为具有完全智能的机器将在二十年内出现。 ARPA(国防高等研究计划署)等政府机构向这一新兴领域投入了大笔资金。从50年代后期到60年代涌现了大批成功的AI程序和新的研究方向。下面列举其中最具影响的几个。

    搜索式推理

    许多AI程序使用相同的基本算法。为实现一个目标(例如赢得游戏或证明定理),它们一步步地前进,就像在迷宫中寻找出路一般;如果遇到了死胡同则进行回溯。这就是“搜索式推理”。

    这一思想遇到的主要困难是,在很多问题中,“迷宫”里可能的线路总数是一个天文数字(所谓“指数爆炸”)。研究者使用启发式算法去掉那些不太可能导出正确答案的支路,从而缩小搜索范围。Newell和Simon试图通过其“通用解题器(General Problem Solver)”程序,将这一算法推广到一般情形。另一些基于搜索算法证明几何与代数问题的程序也给人们留下了深刻印象,例如Herbert Gelernter的几何定理证明机(1958)和Minsky的学生James Slagle开发的SAINT(1961)。还有一些程序通过搜索目标和子目标作出决策,如斯坦福大学为控制机器人Shakey而开发的STRIPS系统。

    自然语言

    AI研究的一个重要目标是使计算机能够通过自然语言(例如英语)进行交流。早期的一个成功范例是Daniel Bobrow的程序STUDENT,它能够解决高中程度的代数应用题。 如果用节点表示语义概念(例如“房子”,“门”),用节点间的连线表示语义关系(例如“有 — 一个”),就可以构造出“语义网(semantic net)”。第一个使用语义网的AI程序由Ross Quillian开发;[54] 而最为成功(也是最有争议)的一个则是Roger Schank的“概念关联(Conceptual Dependency)”。Joseph Weizenbaum的ELIZA是第一个聊天机器人,可能也是最有趣的会说英语的程序。与ELIZA“聊天”的用户有时会误以为自己是在和人类,而不是和一个程序,交谈。但是实际上ELIZA根本不知道自己在说什么。它只是按固定套路作答,或者用符合语法的方式将问题复述一遍。

    人工智能史上的二次低谷——第一次低谷

    自然语言

    微世界

    60年代后期,麻省理工大学AI实验室的Marvin Minsky和Seymour Papert建议AI研究者们专注于被称为“微世界”的简单场景。他们指出在成熟的学科中往往使用简化模型帮助基本原则的理解,例如物理学中的光滑平面和完美刚体。许多这类研究的场景是“积木世界”,其中包括一个平面,上面摆放着一些不同形状,尺寸和颜色的积木。在这一指导思想下,Gerald Sussman(研究组长),Adolfo Guzman,David Waltz(“约束传播(constraint propagation)”的提出者),特别是Patrick Winston等人在机器视觉领域作出了创造性贡献。同时,Minsky和Papert制作了一个会搭积木的机器臂,从而将“积木世界”变为现实。微世界程序的最高成就是Terry Winograd的SHRDLU,它能用普通的英语句子与人交流,还能作出决策并执行操作。

    乐观思潮

    第一代AI研究者们曾作出了如下预言:

    1958年,H. A. Simon,Allen Newell:“十年之内,数字计算机将成为国际象棋世界冠军。” “十年之内,数字计算机将发现并证明一个重要的数学定理。”

    1965年,H. A. Simon:“二十年内,机器将能完成人能做到的一切工作。”

    1967年,Marvin Minsky:“一代之内……创造‘人工智能’的问题将获得实质上的解决。”

    1970年,Marvin Minsky:“在三到八年的时间里我们将得到一台具有人类平均智能的机器。”

    经费

    1963年6月,MIT从新建立的ARPA(即后来的DARPA,国防高等研究计划局)获得了二百二十万美元经费,用于资助MAC工程,其中包括Minsky和McCarthy五年前建立的AI研究组。此后ARPA每年提供三百万美元,直到七十年代为止。ARPA还对Newell和Simon在卡内基梅隆大学的工作组以及斯坦福大学AI项目(由John McCarthy于1963年创建)进行类似的资助。另一个重要的AI实验室于1965年由Donald Michie在爱丁堡大学建立。[65]在接下来的许多年间,这四个研究机构一直是AI学术界的研究(和经费)中心。经费几乎是无条件地提供的:时任ARPA主任的J. C. R. Licklider相信他的组织应该“资助人,而不是项目”,并且允许研究者去做任何感兴趣的方向。这导致了MIT无约无束的研究氛围及其hacker文化的形成,但是好景不长。

    第一次AI低谷:1974 – 1980

    到了70年代,AI开始遭遇批评,随之而来的还有资金上的困难。AI研究者们对其课题的难度未能作出正确判断:此前的过于乐观使人们期望过高,当承诺无法兑现时,对AI的资助就缩减或取消了。同时,由于Marvin Minsky对感知器的激烈批评,联结主义(即神经网络)销声匿迹了十年。70年代后期,尽管遭遇了公众的误解,AI在逻辑编程,常识推理等一些领域还是有所进展。

    问题

    70年代初,AI遭遇了瓶颈。即使是最杰出的AI程序也只能解决它们尝试解决的问题中最简单的一部分,也就是说所有的AI程序都只是“玩具”。AI研究者们遭遇了无法克服的基础性障碍。尽管某些局限后来被成功突破,但许多至今仍无法满意地解决。

    计算机的运算能力

    当时的计算机有限的内存和处理速度不足以解决任何实际的AI问题。例如,Ross Quillian在自然语言方面的研究结果只能用一个含二十个单词的词汇表进行演示,因为内存只能容纳这么多。1976年Hans Moravec指出,计算机离智能的要求还差上百万倍。他做了个类比:人工智能需要强大的计算能力,就像飞机需要大功率动力一样,低于一个门限时是无法实现的;但是随着能力的提升,问题逐渐会变得简单。

    计算复杂性和指数爆炸

    1972年Richard Karp根据Stephen Cook于1971年提出的Cook-Levin理论证明,许多问题只可能在指数时间内获解(即,计算时间与输入规模的幂成正比)。除了那些最简单的情况,这些问题的解决需要近乎无限长的时间。这就意味着AI中的许多玩具程序恐怕永远也不会发展为实用的系统。

    常识与推理。许多重要的AI应用,例如机器视觉和自然语言,都需要大量对世界的认识信息。程序应该知道它在看什么,或者在说些什么。这要求程序对这个世界具有儿童水平的认识。研究者们很快发现这个要求太高了:1970年没人能够做出如此巨大的数据库,也没人知道一个程序怎样才能学到如此丰富的信息。

    莫拉维克悖论

    证明定理和解决几何问题对计算机而言相对容易,而一些看似简单的任务,如人脸识别或穿过屋子,实现起来却极端困难。这也是70年代中期机器视觉和机器人方面进展缓慢的原因。

    框架和资格问题

    采取逻辑观点的AI研究者们(例如John McCarthy)发现,如果不对逻辑的结构进行调整,他们就无法对常见的涉及自动规划(planning or default reasoning)的推理进行表达。为解决这一问题,他们发展了新逻辑学(如非单调逻辑(non-monotonic logics)和模态逻辑(modal logics))。

    停止拨款

    由于缺乏进展,对AI提供资助的机构(如英国政府,DARPA和NRC)对无方向的AI研究逐渐停止了资助。早在1966年ALPAC(Automatic Language Processing Advisory Committee,自动语言处理顾问委员会)的报告中就有批评机器翻译进展的意味,预示了这一局面的来临。NRC(National Research Council,美国国家科学委员会)在拨款二千万美元后停止资助。1973年Lighthill针对英国AI研究状况的报告批评了AI在实现其“宏伟目标”上的完全失败,并导致了英国AI研究的低潮(该报告特别提到了指数爆炸问题,以此作为AI失败的一个原因)。DARPA则对CMU的语音理解研究项目深感失望,从而取消了每年三百万美元的资助。到了1974年已经很难再找到对AI项目的资助。

    Hans Moravec将批评归咎于他的同行们不切实际的预言:“许多研究者落进了一张日益浮夸的网中”。还有一点,自从1969年Mansfield修正案通过后,DARPA被迫只资助“具有明确任务方向的研究,而不是无方向的基础研究”。60年代那种对自由探索的资助一去不复返;此后资金只提供给目标明确的特定项目,比如自动坦克,或者战役管理系统。

    来自大学的批评

    一些哲学家强烈反对AI研究者的主张。其中最早的一个是John Lucas,他认为哥德尔不完备定理已经证明形式系统(例如计算机程序)不可能判断某些陈述的真理性,但是人类可以。Hubert Dreyfus讽刺六十年代AI界那些未实现的预言,并且批评AI的基础假设,认为人类推理实际上仅涉及少量“符号处理”,而大多是具体的,直觉的,下意识的“窍门(know how)”。 John Searle于1980年提出“中文房间”实验,试图证明程序并不“理解”它所使用的符号,即所谓的“意向性(intentionality)”问题。Searle认为,如果符号对于机器而言没有意义,那么就不能认为机器是在“思考”。

    AI研究者们并不太把这些批评当回事,因为它们似乎有些离题,而计算复杂性和“让程序具有常识”等问题则显得更加紧迫和严重。对于实际的计算机程序而言,“常识”和“意向性”的区别并不明显。Minsky提到Dreyfus和Searle时说,“他们误解了,所以应该忽略”。在MIT任教的Dreyfus遭到了AI阵营的冷遇:他后来说,AI研究者们“生怕被人看到在和我一起吃中饭”。 ELIZA程序的作者Joseph Weizenbaum感到他的同事们对待Dreyfus的态度不太专业,而且有些孩子气。虽然他直言不讳地反对Dreyfus的论点,但他“清楚地表明了他们待人的方式不对”。

    Weizenbaum后来开始思考AI相关的伦理问题,起因是Kenneth Colby开发了一个模仿医师的聊天机器人DOCTOR,并用它当作真正的医疗工具。二人发生争执;虽然Colby认为Weizenbaum对他的程序没有贡献,但这于事无补。1976年Weizenbaum出版著作《计算机的力量与人类的推理》,书中表示人工智能的滥用可能损害人类生命的价值。

    展开全文
  • Linux设备驱动基本概念

    万次阅读 2017-03-21 14:35:54
    、Linux 系统的设备文件分为三类:块设备文件、字符设备文件和网络设备文件。 · 块设备文件通常指一些需要以块(如512 字节)的方式写入的设备,如IDE 硬盘、SCSI硬盘、光驱等。 · 字符型设备文件通常指可以直接...
    一、Linux 系统的设备文件分为三类:块设备文件、字符设备文件和网络设备文件
    

    · 块设备文件通常指一些需要以块(如512 字节)的方式写入的设备,如IDE 硬盘、SCSI硬盘、光驱等。

    · 字符型设备文件通常指可以直接读写,没有缓冲区的设备,如并口、虚拟控制台等。

    · 网络设备文件通常是指网络设备访问的BSD socket接口,如网卡等。


    二、设备号

    设备号包含主设备号和次设备号,主设备号表明某一类设备,一般对应着确定的驱动程序;次设备号一般是用于区分标明不同属性,例如不同的使用方法,不同的位置,不同的操作等,它标志着某个具体的物理设备。高字节为主设备号和底字节为次设备号。


    三、Linux输入/输出系统层次结构




    四、 驱动程序编译进内核的步骤

    1. 将编写的源代码复制到 Linux 内核源代码的相应目录;

    2. 在目录的 Kconfig 文件中增加新源代码对应项目的编译配置选项;

    3. 在目录的 Makefile 文件中增加对新源代码的编译条目。


    五、Kconfig和.config

    分布在各目录下的Kconfig构成了一个分布式的内核配置 数据库 ,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(或xconfig等)时,从Kconfig中读出配置菜单,用户配置完后保存到.config(在顶层目录下生成)中。 说简单点就是Kconfig生成配置菜单, 
    然后配置完的参数会在.config中生成。
    假如选择编译成内核模块,则会在.config中生成一个CONFIG_HELLO_MODULE=m的配置,假如选择内建,就是直接编译成内核映像,就会在.config中生成一个CONFIG_HELLO_MODULE=y的配置

    展开全文
  • 设备驱动的主要任务有两个: 1. 存取设备的内存 2. 处理设备产生的中断对于第个任务,UIO 核心实现了mmap()可以处理物理...第个任务,对于设备中断的应答必须在内核空间进行。所以在内核空间有小部分代码

    一个设备驱动的主要任务有两个:
    1. 存取设备的内存
    2. 处理设备产生的中断

    对于第一个任务,UIO 核心实现了mmap()可以处理物理内存(physical memory),逻辑内存(logical memory),
    虚拟内存(virtual memory)。UIO驱动的编写是就不需要再考虑这些繁琐的细节。

    第二个任务,对于设备中断的应答必须在内核空间进行。所以在内核空间有一小部分代码
    用来应答中断和禁止中断,但是其余的工作全部留给用户空间处理。

    如果用户空间要等待一个设备中断,它只需要简单的阻塞在对 /dev/uioX的read()操作上。
    当设备产生中断时,read()操作立即返回。UIO 也实现了poll()系统调用,你可以使用
    select()来等待中断的发生。select()有一个超时参数可以用来实现有限时间内等待中断。

    对设备的控制还可以通过/sys/class/uio下的各个文件的读写来完成。你注册的uio设备将会出现在该目录下。
    假如你的uio设备是uio0那么映射的设备内存文件出现在 /sys/class/uio/uio0/maps/mapX,对该文件的读写就是
    对设备内存的读写。
    如下的图描述了uio驱动的内核部分,用户空间部分,和uio 框架以及内核内部函数的关系。
    这里写图片描述

    这里写图片描述

     struct uio_portio {
        struct kobject kobj;
        struct uio_port *port;
    };
    
    /**
     * struct uio_port - description of a UIO port region
     * @name:       name of the port region for identification
     * @start:      start of port region
     * @size:       size of port region
     * @porttype:       type of port (see UIO_PORT_* below)
     * @portio:     for use by the UIO core only.
     */
    struct uio_port {
        const char      *name;
        unsigned long       start;
        unsigned long       size;
        int         porttype;
        struct uio_portio   *portio;
    };
    
    /* defines for uio_port->porttype */
    #define UIO_PORT_NONE   0
    #define UIO_PORT_X86    1
    #define UIO_PORT_GPIO   2
    #define UIO_PORT_OTHER  3
    
    
      /*
      * struct uio_mem - description of a UIO memory region
     * @name:       name of the memory region for identification
     * @addr:       address of the device's memory
     * @size:       size of IO
     * @memtype:        type of memory addr points to
     * @internal_addr:  ioremap-ped version of addr, for driver internal use
     * @map:        for use by the UIO core only.
     */
    struct uio_mem {
        const char      *name;// 内存映射的名字
        unsigned long       addr; // 内存块的地址
        unsigned long       size; //addr所指向的内存块的大小
        int         memtype; //UIO_MEM_PHYS,UIO_MEM_LOGICAL(kmalloc()),UIO_MEM_VIRTUAL( virtual memory)
        void __iomem        *internal_addr; // If you have to access this memory region from within your kernel module,
                                                                   // you will want to map it internally by using something like ioremap().
    
        struct uio_map      *map;
    };
    
     struct uio_map {
        struct kobject kobj;
        struct uio_mem *mem;
    };
    
    
     static const struct vm_operations_struct uio_vm_ops = {
        .open = uio_vma_open,
        .close = uio_vma_close,
        .fault = uio_vma_fault,
    };
     static struct device_attribute uio_class_attributes[] = {
        __ATTR(name, S_IRUGO, show_name, NULL),
        __ATTR(version, S_IRUGO, show_version, NULL),
        __ATTR(event, S_IRUGO, show_event, NULL),
        {}
    };
     /* UIO class infrastructure */
    static struct class uio_class = {
        .name = "uio",// /sys/class/uio
        .dev_attrs = uio_class_attributes,
    };
    
    static const struct file_operations uio_fops = {
        .owner      = THIS_MODULE,
        .open       = uio_open,
        .release    = uio_release,
        .read       = uio_read,
        .write      = uio_write,
        .mmap       = uio_mmap,
        .poll       = uio_poll,
        .fasync     = uio_fasync,
        .llseek     = noop_llseek,
    };
    
    /* Protect idr accesses */
    static DEFINE_MUTEX(minor_lock);
    static DEFINE_IDR(uio_idr);
    //关于idr机制,参见 http://blog.csdn.net/ganggexiongqi/article/details/6737389
    
    struct uio_device {
        struct module       *owner;
        struct device       *dev; //在__uio_register_device中初始化
        int         minor; // 次设备id号,uio_get_minor
        atomic_t        event; //中断事件计数
        struct fasync_struct    *async_queue;//该设备上的异步等待队列//
                                                                   // 关于 “异步通知“ //参见LDD3第六章
        wait_queue_head_t   wait; //该设备上的等待队列,在注册设备时(__uio_register_device)初始化
        int         vma_count;
        struct uio_info     *info;// 指向用户注册的uio_info,在__uio_register_device中被赋值的
        struct kobject      *map_dir;
        struct kobject      *portio_dir;
    };  
    /*
     * struct uio_info - UIO device capabilities
     * @uio_dev:        the UIO device this info belongs to
     * @name:       device name
     * @version:        device driver version
     * @mem:        list of mappable memory regions, size==0 for end of list
     * @port:       list of port regions, size==0 for end of list
     * @irq:        interrupt number or UIO_IRQ_CUSTOM
     * @irq_flags:      flags for request_irq()
     * @priv:       optional private data
     * @handler:        the device's irq handler
     * @mmap:       mmap operation for this uio device
     * @open:       open operation for this uio device
     * @release:        release operation for this uio device
     * @irqcontrol:     disable/enable irqs when 0/1 is written to /dev/uioX
     */     
    struct uio_info {
        struct uio_device   *uio_dev; // 在__uio_register_device中初始化
        const char      *name; // 调用__uio_register_device之前必须初始化
        const char      *version; //调用__uio_register_device之前必须初始化
        struct uio_mem      mem[MAX_UIO_MAPS];
        struct uio_port     port[MAX_UIO_PORT_REGIONS];
        long            irq; //分配给uio设备的中断号,调用__uio_register_device之前必须初始化
        unsigned long       irq_flags;// 调用__uio_register_device之前必须初始化
        void            *priv; //
        irqreturn_t (*handler)(int irq, struct uio_info *dev_info); //uio_interrupt中调用,用于中断处理
                                                                    // 调用__uio_register_device之前必须初始化
        int (*mmap)(struct uio_info *info, struct vm_area_struct *vma); //在uio_mmap中被调用,
                                                                        // 执行设备打开特定操作
        int (*open)(struct uio_info *info, struct inode *inode);//在uio_open中被调用,执行设备打开特定操作
        int (*release)(struct uio_info *info, struct inode *inode);//在uio_device中被调用,执行设备打开特定操作
        int (*irqcontrol)(struct uio_info *info, s32 irq_on);//在uio_write方法中被调用,执行用户驱动的
                                                                                           //特定操作。
    };
    • 1、 函数: static int __init uio_init(void)

      功能:申请字符设备号,设备,并注册到系统中,注册uio_class到系统中
      调用模块:init_uio_class()
      执行流程:
      申请字符设备号,设备,并注册到系统中,注册uio_class到系统中 //init_uio_class
      //创建”/sys/class/uio”

    • 2、函数:uio_exit
      功能:注销uio_class,注销字符设备编号,删除设备
      调用模块:release_uio_class
      执行流程:
      注销uio_class,注销字符设备编号,删除设备 //release_uio_class

    • 3、函数:static void release_uio_class(void)
      功能:注销uio_class,注销字符设备编号,删除设备
      执行流程:
      注销uio_class//class_unregister
      注销字符设备编号,删除设备 //uio_major_cleanup

    • 4、函数:static int init_uio_class(void)
      功能:申请字符设备号,设备,并注册到系统中,注册uio_class到系统中
      调用模块: uio_major_init()
      class_register()
      执行流程:
      申请字符设备编号,设备,并初始化//uio_major_init
      注册class 类型全局变量uio_class到系统//class_register
      //ls -l /sys/class 查看

    • 5、函数: static int uio_major_init(void)
      功能:申请字符设备编号,设备,并初始化
      调用模块:
      alloc_chrdev_region()
      cdev_alloc()
      kobject_set_name()
      cdev_add()
      执行流程:
      申请字符设备编号(多个)//alloc_chrdev_region
      //2^UIO_MAX_DEVICES个从设备
      //设备的名字为”uio”
      分配一个表示字符设备的cdev结构//cdev_alloc
      初始化cdev结构的file_operations类型字段//控制cdev设备的各种操作,
      // 如 open, close, read, write…
      设置cdev结构的kobj字段的name为uio //kobject_set_name
      添加字符设备到系统中 //cdev_add,调用成功后,我们的设备就“活了”
      // cat /proc/devices ,可以查看到分配到主设备号
      保存主设备号到全局变量uio_major
      保存设备指针到全局变量uio_cdev

      返回

    • 6、函数:static void uio_major_cleanup(void)
      功能:注销字符设备编号,删除设备
      调用模块:unregister_chrdev_region
      执行流程:
      注销字符设备编号//unregister_chrdev_region
      删除设备uio_cdev //cdev_del

      file_operations

    • 7、 函数:static int uio_open(struct inode *inode, struct file *filep)

      参数:inode:
      filep:
      功能:获得和次设备号关联的uio_device指针,创建一个辅助变量listener, 并调用info指向的uio_info结构中的open方法
      执行流程:
      获得保护uio_idr的锁 //mutex_lock
      从inode 结构中获取次编号 //iminor
      获得和次编号关联的uio_device指针 //idr_find 在那里进行地设置呢???
      // 在 uio_get_minor 中分配的次设备编号并设置的关联
      放弃锁 //mutex_unlock
      增加uio_device类型指针指向的模块的引用计数 //try_module_get
      分配一个uio_listener类型的listener //kmalloc
      关联listener和 uio_device 指针
      获得uio_device 指向设备的事件计数值,并存入listener //atomic_read
      把listener指针保存到filep->private_data字段
      调用uio_device的info字段指向的uio_info中的open方法//*

    • 8、函数:static int uio_release(struct inode *inode, struct file *filep)
      功能:从而调用uio_device的字段info指向的uio_info中的release方法
      释放辅助结构体listener
      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针。
      利用listener指针找到指向uio_device类型结构指针
      从而调用uio_device的字段info指向的uio_info中的release方法。
      减少uio_device类型指针指向的模块的引用计数//module_put
      释放listener结构体 //kfree

    • 9、 函数:static int uio_fasync(int fd, struct file *filep, int on)

      参数:
      fd
      filep
      on : 0, 删除;非零,添加
      功能: 管理uio_device的async_queue
      调用模块:fasync_helper()
      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针。
      利用listener指针找到指向uio_device类型结构指针
      设置uio_device的async_queue//fasync_helper

    • 10、函数:static unsigned int uio_poll(struct file *filep, poll_table *wait)
      功能: 使进程在传递到该系统调用的所有文件描述符对应的等待队列上等待,并返回一个是否可以立即无阻塞执行的位掩码
      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针。
      利用listener指针找到指向uio_device类型结构指针
      判断用uio_device类型指针的info字段(uio_info类型)的irq成员不为0,则继续,
      否则,返回IO错误
      向poll_table类型的wait表中添加uio_device类型指针指向结构的wait等待队列//poll_wait
      //!!!! 注意poll_wait并不阻塞
      如果listener中的事件计数值event_count和uio_device的
      事件计数值count不一致时// uio_interrupt调用了uio_event_notify对
      //中断事件计数器增一
      返回“通常”的数据可读的位掩码

    • 11、函数:static ssize_t uio_read(struct file *filep, char __user *buf,
      size_t count, loff_t *ppos)
      功能:复制uio设备中断事件计数器的值到用户空间

      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针
      利用listener指针找到指向uio_device类型结构指针
      创建一个等待队列的项 //DECLARE_WAITQUEUE
      检查确认uio设备的设备info的中断号(0)不为零
      添加本进程到uio设备的等待队列wait上 // add_wait_queue
      //由uio_interrupt调用uio_event_notify唤醒
      REP: 设置当前进程的 “可中断标志”
      检查是否有中断事件发生,
      如果有(listener中的中断事件计数值event_count)和uio设备中的中断事件
      计数器值不一致),则将设备中断计数器的值复制到用户空间
      并将listener中的中断事件计数值更新为设备的中断事件计数值
      把当前进程设置为TASK_RUNNING状态,
      并将当前进程从uio设备的等待队列wait上删除
      如果文件读时设置了O_NONBLOCK标志,
      那么,把当前进程设置为TASK_RUNNING状态,
      并将当前进程从uio设备的等待队列wait上删除
      返回 -EAGAIN
      检查当前进程是否有信号处理 //signal_pending
      //http://blog.chinaunix.net/space.php?uid=20746501&do=blog&cuid=1820175
      如有,把当前进程设置为TASK_RUNNING状态,
      并将当前进程从uio设备的等待队列wait上删除
      并返回 -ERESTARTSYS
      执行调度 //schedule
      JMP REP

    • 12、uio_register_device
      功能: 调用uio_info中注册的handler中断处理函数,对设备的中断事件计数器增一并通知各读进程,有数据可读
      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针
      调用 uio_device类型指针的info字段(uio_info类型)的handler
      如果属于本设备的中断,并且在handler中已经处理过
      那么对设备的中断事件计数器增一,
      并通知各读进程,有数据可读 //uio_event_notify

    • 13、函数:void uio_event_notify(struct uio_info *info)
      功能:“触发“ 一个中断事件,对设备的中断事件计数器增一,并通知各读进程,有数据可读
      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针
      对中断事件计数器增一
      唤醒阻塞在设备等待队列wait上的读进程 //wake_up_interruptible
      // 该队列上的进程在uio_read中添加
      向异步等待队列async_queue发出可读信号 //kill_fasync

    • 14、 函数:static ssize_t uio_write(struct file *filep, const char __user
      *buf,size_t count, loff_t *ppos)
      功能: 读取用户空间的值,并调用uio_device注册的irqcontrol函数
      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针
      调用 uio_device类型指针的info字段(uio_info类型)的handler
      检验info字段(uio_info类型)的中断号irq
      读取从用户空间传过来的32位的值//copy_from_user
      调用info字段(uio_info类型)的irqcontrol函数,将用户空间传递过来的32位值作为参数传入。

    • 15、函数:static int uio_mmap(struct file *filep, struct vm_area_struct

      *vma)

      执行流程:
      从filep->private_data中获得uio_open中保存的listener指针
      调用 uio_device类型指针的info字段(uio_info类型)的handler
      保存uio_device类型指针到 vma 的vm_private_data
      返回映射区域的索引(比如 mapX,的X) //uio_find_mem_index
      计算实际的页数和请求的页数
      如果实际的页数小于请求的页数那么,返回-EINVAL
      如果uio设备注册有mmap函数,那么就调用它
      当内存区域的类型为UIO_MEM_PHYS时,
      //uio_mmap_physical
      当内存区域的类型为UIO_MEM_LOGICAL、UIO_MEM_VIRTUAL时,
      为虚拟内存区域设置操作,和告诉内存不要将
      该区域交换出去,访问计数器增一//uio_mmap_logical

    展开全文
  • 一次路由多次转发正好在NF的代码中也有说到,为每一个转发创建一个flow,此后的包全部都由底层转发。 使用IP的设备A------------------------三层交换机------------------------使用IP的设备B ...
  • 设备树学习(设备树dts/dtsi格式)

    万次阅读 多人点赞 2019-02-14 22:17:00
    说明:后续的博文参考自韦东山老师的设备树视屏,老师用的是2440的开发板,我用的是s5pv210的开发板。原理一样 、前言 简单的说,如果要使用Device Tree,首先用户要了解自己的硬件配置和系统运行参数,并把...
  • 、Linux 设备模型 1、设备模型概述  从2.6版本开始,Linux开发团队便为内核建立起个统一的设备模型。在以前的内核中没有独立的数据结构用来让内核获得系统整体配合的信息。尽管缺乏这些信息,在多数情况下内核...
  • 、什么是Linux设备文件系统  首先我们不看定义,定义总是太抽象很难理解,我们先看现象。当我们往开发板上移植了个新的文件系统之后(假如各种设备驱动也移植好了),启动开发板,我们用串口工具进入开发板,...
  • 当在宿主机上插入个USB设备的时候,通过设置,可以在vmware的虚拟机系统里边能访问到这个USB设备, 而且访问这个USB设备,就跟真的把这个USB设备插入到这个虚拟系统中一样,跟真实的几乎没任何区别。 再看种情况...
  • 传输设备基础知识〖 篇就看懂〗

    千次阅读 2020-06-02 15:55:26
    传输网概念1.1 传输设备在通信网的位置1.2 演进过程1.2.1 PDH(准同步数字系列)特点1.2.2 SDH(同步数字传输体制)特点1.3 SDH设备实现的要点1.4 PDH与SDH的标准速率等级1.5 帧结构. 传输网特性2.1 SDH信号复用映射...
  • 篇介绍了云计算基本概念,本篇继续介绍个云计算中非常重要的概念:虚拟化。虚拟化定义虚拟化这个词并不像云计算那个难以令人捉摸,虚拟化是种资源管理技术,是将计算机的各种实体资源(CPU、内存、磁盘空间...
  • Linux块设备驱动

    千次阅读 2013-03-26 19:05:41
    --- 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区。 字符设备(Character device) ---...
  • 深入理解Linux字符设备驱动

    千次阅读 2016-03-20 11:09:13
    文章从上层应用访问字符设备驱动开始,步步地深入分析Linux字符设备的软件层次、组成框架和交互、如何编写驱动、设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解。
  • Linux字符设备驱动剖析

    千次阅读 2015-05-23 23:09:13
    忠于源码,讲述linux字符设备驱动的那些事儿,重点讲述字符设备的创建和访问过程。
  • Linux DRM()基本概念和特性

    万次阅读 多人点赞 2017-10-30 16:29:42
    在《Linux DRM () Display Server》我们了解了 DRM 诞生的历史缘由。 本篇我们朝着 DRM 本尊再走几步,先介绍几个 DRM 的基本概念和特性,最后简单介绍 RK DRM 依赖的 Component 框架。
  • 程序员必知的 89 个操作系统核心概念

    万次阅读 多人点赞 2020-03-31 19:13:39
    操作系统需要处理管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供个让用户与系统交互的操作界面。 shell:它是个程序,可从键盘获取...
  • Linux设备驱动子系统第弹 - SD卡

    万次阅读 2010-10-01 19:59:00
    4. 块设备 1. 总论  1.1 概念 MMC - MultiMedia CardSD - Secure Digital Card 1.2 分类 按存储大小,普通SD卡(2GB,按体积大小,普通SD卡,mini-SD卡,micro-SD卡(TF卡) 1.3 速度 默认模式: ...
  • 如何在个月内完成个USB设备

    千次阅读 2007-01-18 19:45:00
    如果想学习USB的开发,做个简单的HID设备个很好的选择,你不用去编写驱动程序,因为操作系统都自带了。唯一要做的就是做固件(firmware)。个多月前,我开始了USB开发的学习,之前对硬件这东西是知之甚少了...
  • 转载请在文首保留原文... 介绍   Linux FC/iSCSI存储设备管理系列,主要介绍Linux系统管理FC/iSCSI磁盘设备的相关概念与技术细节,内容包括: 1. Linux磁盘设备驱动介绍 2. 磁盘设备管理():FC磁盘管理
  • Device Tree():基本概念

    万次阅读 2014-06-28 15:42:22
    、前言 一些背景知识(例如:为何要引入Device Tree,这个机制是用来解决什么问题的)请参考引入Device Tree的原因,本文主要是介绍Device Tree的基础概念。 简单的说,如果要使用Device Tree,首先用户要了解...
  • 电力行业基本概念

    千次阅读 2011-11-22 13:21:12
    发电厂和变电所的电气设备分为一次设备二次设备。 一次设备(也称主设备)是构成电力系统的主体,它是直接生产、输送和分配电能的设备,包括发电机、电力变压器、断路器、隔离开关、电力母线、电力电缆和输电线路...
  • 20. 数据结构进阶十文件相关概念

    千次阅读 2017-09-24 21:25:18
    20. 数据结构进阶十文件相关概念 “生活是欺骗不了的,个人要生活得光明磊落。 -- 冯雪峰” 最后在数据结构进阶这块,我们来看些文件相关的概念。 1. 文件   文件是性质相同的记录的集合。文件的数据量...
  • 查看/proc/devices 文件可以获知系统中注册的设备,第 1 列为主设备号,第 2 列为设备名,主设备号是与驱动对应的概念,同一类设备一般使用相同的主设备号,不同类的设备一般使用不同的主设备号(但...
  • 设备信息函数 、一些概念及说明 1、主机端(Host端)、设备端(Device端、GPU端) 在CUDA中,有主机端和设备端这两个概念,主机端是指CPU+内存,设备端是指GPU+显存。主机端的代码在CPU上执行,访问主机内存;...
  • 卷积神经网络CNN基本概念)上采样 下采样 参考网址:https://blog.csdn.net/majinlei121/article/details/46742339 缩小图像:或称为下采样(subsampled)或降采样(downsampled) 主要目的有两个:1、使得...
  • 最好最实用的二次开发教程

    千次阅读 2016-07-28 19:56:01
    最好最实用的二次开发教程  ◆二次开发  什么是二次开发?  二次开发,简单的说就是在现有的软件上进行定制修改,功能的扩展,然后达到自己想要的功能和效果,一般来说都不会改变原有系统的内核。  为什么要...
  • 计算机网络()_基本概念扫盲

    千次阅读 2020-05-13 19:34:52
    总结一下计算机网络入门的一些基本概念 文章目录三言两语轻松计算机网络入门局域网、广域网、Internet、ISPOSI七层参考模型计算机数据通信过程数据封装过程通信协议TCP/IP协议栈计算机网络的性能指标 局域网、广域...
  • oracle 11g RAC 的一些基本概念

    万次阅读 2015-11-14 11:52:56
    集群的相关概念 配置Active/active集群  在这种模式下,所有的节点都能提供服务(不会有用户请求在standby上被闲置的情况)。大部分案例中,集群成员的硬件配置都是相同的,避免可能的性能问题,也更容易...
  • 浅谈Linux PCI设备驱动(

    万次阅读 多人点赞 2010-08-30 14:31:00
    要弄清楚Linux PCI设备驱动,首先要明白,所谓的Linux PCI设备驱动实际包括Linux PCI设备驱动和设备本身驱动两部分。不知道读者理不理解这句话,本人觉得这句话很重要,对于PCI、USB这样的驱动来说,必须要理解这个...
  • Linux内核大讲堂 () 传说中的字符设备(4)

    万次阅读 热门讨论 2011-06-13 00:52:00
    Linux内核大讲堂 () 传说中的字符设备(4)经过前面的学习,我们发现有个东西像恶梦一样挥之不去,无论是讲驱动模型中的sysfs还是讲字符驱动的file,这些文件系统内的概念和模块已经让我们达到了无法忍受的地步,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 210,284
精华内容 84,113
关键字:

一次设备二次设备的概念