驱动程序开发入门知识_驱动程序开发入门知识点

       感谢大家给予我这个机会,让我为大家解答驱动程序开发入门知识的问题。这个问题集合囊括了一系列与驱动程序开发入门知识相关的问题,我将全力以赴地回答并提供有用的信息。

1.学习嵌入式驱动前需要掌握哪些知识?

2.linux音频驱动架构linux音频驱动

3.电脑驱动程序的工作原理

4.驱动开发

5.驱动开发的步骤有哪些

6.嵌入式驱动开发需要学什么

驱动程序开发入门知识_驱动程序开发入门知识点

学习嵌入式驱动前需要掌握哪些知识?

       嵌入式门槛虽然较高,但也跟其他事物一样,并不是牢不可破。只要我们用心去对待,冬雪终将化去,春风定会吹来。

       具体步骤如下:

       1、《C语言》第二版 谭浩强 ; 《C程序设计语言》第二版 徐宝文译 机械工业出版社

        你能区分开指针数组和数组指针吗?你知道函数指针吗?

        你能区分开定义一个变量时系统给它分配的空间与用malloc()函数给一个变量分配的空间有什么不一样吗?

       2、《数据结构》C语言版 黄国愉、叶乃青编 清华大学出版社

        你能合上书本,用C语言实现书中的单链表、双链表数据结构吗?

       3、《实用C++程序设计》第二板 中国电力出版社 Steve_Oualline著

        此阶段主要是学习其面向对象的编程思想,加深对C语言和数据结构的理解。

       4、学习单片机,最好能找个前辈带一带。

        你能用51单片机做出一样实际的东西吗?即使它再简单!

        要注意加深对中断的理解。

       5、学习ARM单片机。

        (1)、细读《ARM微控制器基础与实战》周立工编写(注:即使你不用书中的开发板)

        (2)、细读相关芯片的原版英文文档。如:arm920TE.pdf S3C2410_1.2.pdf

       6、学习uCOS!!操作系统。

        (1)、细读《嵌入式实时操作系统uC/OS-!!》第二版 召贝贝译

        你能把uCOS!!移植到自己的平台上吗?

        (2)、能编写在uCOS!!操作系统环境下运行的针对具体硬件的驱动程序

       7、熟悉Linux环境,学习Linux环境编程,学习交叉编程

        (1)、细读《linux命令大全.pdf》

        (2)、细读《GNU Make 使用手册(中译版).pdf》

        (3)、学习创建交叉编程环境.

       8、学习Linux操作系统。

        (1)、《UNIX环境高级编程》

        (2)、细读“joyfire 笔记”,可在“www.qianrushi.com”网站的好书下载栏目获取

        (3)、细读《linux内核完全注释》

        (4)、细读《understanding the linux kernel 2》

        (5)、利用源代码阅读利器工具”Source Insight”进行真正的linux内核原码刨析

        (6)、最后进行内核移植,并能编写在linux操作系统环境下运行的针对具体硬件的驱动程序

       9、学习Linux设备驱动编写。可参考《Linux设备驱动程序》

linux音频驱动架构linux音频驱动

       向内核世界说一声:hello,我来了。如果你是一个初学者,并对这个世界充满好奇心,请从这一章开始,我们一起打招呼~

       第1章 Hello World驱动 1

       1.1 从Hello World开始 2

       1.1.1 HelloDRIVER 4

       1.1.2 代码解释 8

       1.1.3 驱动程序的编译和安装 11

       1.1.4 查看我们的驱动 14

       1.2 虚拟环境 15

       1.2.1 使用虚拟环境进行驱动开发 15

       1.2.2 使用VMware虚拟机 15

       1.2.3 目标机设置 16

       1.2.4 Virtual PC虚拟机 18

       1.3 小结 19

       如何在规范的商业环境中,开发成功而有效的驱动软件?驱网站长马勇(ZnSoft)将向你娓娓道来。你会学到这些内容:建立一个简单而有效的开发、调试环境;64位环境下的内核编程技巧;如何发布你的驱动软件。

       第2章 商业驱动开发技术 20

       2.1 建立开发调试环境 21

       2.1.1 SVN环境 21

       2.1.2 创建工程,导入SVN 23

       2.1.3 建立符号服务器 25

       2.1.4 用符号调试 27

       2.2 64位驱动开发技术 34

       2.2.1 64位驱动编写技术 35

       2.2.2 32位应用程序与64位驱动混合模式 36

       2.3 驱动程序的发布与测试 42

       2.3.1 驱动程序签名 42

       2.3.2 驱动程序测试 46

       2.3.3 WHQL 49

       2.4 小结 50

       WDF是目前最新的驱动编程框架。当很多内核程序员还紧抱WDM的巨大佛脚时,千万要记住,WDF已是大势所趋。本章介绍了WDF最重要的几个概念,并进行了一定程度的深度挖掘。对于WDF框架的三大核心模型:对象模型、事件模型、PNP/Power模型,本章作了重点讲述。

       第3章 WDF概述 51

       3.1 主要特点 52

       3.2 框架视图 53

       3.3 兼容性 55

       3.4 对象模型 56

       3.4.1 对象和句柄 59

       3.4.2 引用计数 60

       3.4.3 上下文空间 61

       3.4.4 PME接口 67

       3.4.5 DDI接口 69

       3.4.6 父子关系 76

       3.4.7 对象同步 77

       3.5 驱动对象和设备对象 78

       3.5.1 驱动对象 78

       3.5.2 驱动入口DriverEntry 81

       3.5.3 设备对象 84

       3.5.4 创建设备对象 85

       3.5.5 设备栈 86

       3.6 IO模型 88

       3.6.1 IO目标对象 88

       3.6.2 IO目标对象的细节 90

       3.6.3 安全的缓冲区 93

       3.6.4 内存对象(一) 96

       3.6.5 内存对象(二) 98

       3.6.6 框架和IO请求 102

       3.6.7 更详细的处理流程 103

       3.6.8 IO请求参数 105

       3.6.9 队列 107

       3.6.10 创建IO请求 110

       3.7 PNP和电源模型 112

       3.8 小结 115

       使用WDF框架开发USB驱动,方便且简单。本章首先总体上从硬件和软件两个方面介绍USB相关知识点,包括设备的电气特性、总线结构、USB驱动类型以及类驱动。编程方面,从USB设备初始化、数据操作以及设备控制等几个方面来讲解,透彻并且翔实。

       第4章 WDF USB设备驱动开发 116

       4.1 USB设备硬件结构 117

       4.1.1 主从结构 117

       4.1.2 硬件拓扑 118

       4.1.3 USB中断 119

       4.2 USB软件结构 120

       4.2.1 总线驱动 120

       4.2.2 系统类驱动 121

       4.2.3 功能驱动 122

       4.2.4 父驱动与混合设备 122

       4.2.5 过滤驱动 125

       4.2.6 USB驱动栈、设备栈 125

       4.3 内核开发 127

       4.3.1 设备驱动 127

       4.3.2 入口函数 128

       4.3.3 USB描述符 129

       4.3.4 描述符介绍 130

       4.3.5 汇总举例 133

       4.3.6 读取描述符 135

       4.3.7 初始化 137

       4.3.8 设备初始化函数 138

       4.3.9 创建设备对象 141

       4.3.10 设备命名、符号链接 143

       4.3.11 启动设备 147

       4.3.12 创建队列 156

       4.3.13 停止设备/反初始化 158

       4.4 数据I/O操作 160

       4.4.1 USB控制命令 160

       4.4.2 构造并发送控制命令 162

       4.4.3 读USB中断端口 163

       4.4.4 连续读操作 165

       4.4.5 数据处理函数 166

       4.4.6 中断端口的效率 167

       4.4.7 读/写批量端口 168

       4.5 设备控制 171

       4.5.1 关于I/O Target对象 171

       4.5.2 获取USB版本 172

       4.5.3 管道重置 174

       4.5.4 设备重置 176

       4.5.5 管道中止与终止 177

       4.6 用户程序 179

       4.6.1 内核读/写 179

       4.6.2 控制命令 179

       4.7 小结 180

       1394俗称火线。大伙平时最多接触它的地方大概是内核调试时,借助1394卡进行双机互联。本章首先从硬件方面介绍了1394的知识,它的总线结构很特别,极具可扩性,能非常方便地在各种类型的1394设备之间建立数据链路。内核编程方面,本章重点讲解了数据通信相关知识,分为异步通信和同步通信两种方式,颇为复杂,相对难于掌握,但套路是现成的,变化的东西不多,可以熟能生巧。本章最后介绍了1394双机互联的原理,有兴趣的读者可参考之。

       第5章 WDF 1394驱动开发 181

       5.1 1394一席谈 182

       5.1.1 版本情况 183

       5.1.2 电源特性 183

       5.1.3 1394卡 183

       5.1.4 总线拓扑 184

       5.2 发送请求 186

       5.2.1 同步方式 187

       5.2.2 异步方式 189

       5.2.3 对WDM的回忆 191

       5.3 总线重置与计数 193

       5.3.1 总线重置 193

       5.3.2 设置重置回调 193

       5.3.3 计数更新 194

       5.4 PNP操作 195

       5.5 异步通信 196

       5.5.1 地址范围 197

       5.5.2 异步读 200

       5.5.3 异步写 201

       5.5.4 异步锁请求 202

       5.5.5 数据流 203

       5.6 等时通信 204

       5.6.1 申请带宽 205

       5.6.2 释放带宽 206

       5.6.3 等时通道 206

       5.6.4 资源句柄 207

       5.6.5 缓冲区挂载 210

       5.6.6 缓冲区解挂 211

       5.6.7 开始传输 211

       5.6.8 停止传输 212

       5.6.9 其他等时操作 213

       5.7 其他操作 213

       5.7.1 设备配置 213

       5.7.2 获取控制器信息 214

       5.7.3 速度信息 215

       5.7.4 厂商自定义命令 216

       5.8 安装与测试 216

       5.8.1 1394虚拟设备 216

       5.8.2 创建虚拟设备 218

       5.8.3 示例代码 219

       5.8.4 安装与测试 221

       5.9 小结 222

       内核天生适合于C语言编程,但越来越多的内核项目,规模达到10数万的规模。在这种情况下,人们不由地会将目光投向优雅的C++语言。总体上说,C和C++是至亲好友,内核中使用C++本不应有什么大问题,但有几个暗礁潜伏已久,不小心的程序员,你可千万不要触礁。

       第6章 内核驱动C++编程 223

       6.1 驱动中的类 224

       6.1.1 一个简单的例子 224

       6.1.2 new/delete 225

       6.1.3 extern C 227

       6.1.4 全局/静态变量 228

       6.1.5 栈的忧虑 230

       6.2 类封装的驱动程序 233

       6.2.1 寻找合适的存储所 233

       6.2.2 类方法与事件函数 235

       6.2.3 KMDF驱动实现 236

       6.2.4 WDM驱动实现 237

       6.3 多态 238

       6.3.1 基类、子类 238

       6.3.2 实现多态 239

       6.3.3 测试 241

       6.4 小结 241

       使用WDF框架编写的驱动程序,在测试和调试的时候,有特殊的工具。本章介绍了目前所知的三个,它们分别是:Windbg扩展调试命令、WDFTester测试工具、WDFVerifier测试工具。本章将以示例方式,介绍这些工具的使用。

       第7章 WDF驱动测试 242

       7.1 WDF错误 243

       7.1.1 实例分析 245

       7.1.2 USB错误 246

       7.2 WDF扩展调试命令 247

       7.3 WDFTester 254

       7.3.1 WDFFiTester 254

       7.3.2 使用 256

       7.3.3 WDFCallTracer 260

       7.4 WDFVerifier 263

       7.4.1 识别KMDF驱动 263

       7.4.2 使用与介绍 265

       7.5 小结 266

       SoftIce渐行渐远之后,Windbg成为内核调试的第一利器。使用Windbg的最大难点是命令繁多,参数复杂。本章以总结归纳的形式,介绍了作者在工作中经常用到的几大类调试命令,并以实例形式一一介绍。作者根据个人经验所作的分类,未能全备,但能够保证的是,所有实例翔实而可靠,可以作为可信的参考。

       第8章 调试命令详解 267

       8.1 概述 268

       8.1.1 寻求帮助 269

       8.1.2 DML语言 270

       8.1.3 基本信息 271

       8.1.4 基本设置 272

       8.1.5 格式化显示 273

       8.1.6 开始调试 273

       8.2 符号与源码 276

       8.2.1 模块列表 277

       8.2.2 模块信息 279

       8.2.3 符号路径 280

       8.2.4 符号加载 283

       8.2.5 符号搜索 285

       8.2.6 源码命令 287

       8.3 进程与线程 289

       8.3.1 进程命令 289

       8.3.2 线程命令 292

       8.3.3 异常与事件 296

       8.3.4 局部变量 300

       8.3.5 显示类型 301

       8.4 断点 301

       8.4.1 软件断点 301

       8.4.2 硬件断点 303

       8.4.3 其他操作 303

       8.5 内存命令 304

       8.5.1 查看内存 304

       8.5.2 内存信息 307

       8.5.3 其他命令 311

       8.6 小结 312

       相信大多数人在学习内核开发的时候,都问过这样一个问题:内核驱动怎么向用户程序发送消息,或者如何调用Win32函数。用户程序和内核同步,是一个基本而重要的知识,本章介绍了三种主要的实现方式。至于内核是否可以调用Win32函数,读一读本章开篇的话,你就有答案了。

       第9章 内核同步 313

       9.1 关于内核同步 314

       9.2 内核事件同步 316

       9.2.1 原理 316

       9.2.2 用户程序 318

       9.2.3 内核实现 319

       9.3 IRP同步 320

       9.3.1 用户程序 321

       9.3.2 内核实现 323

       9.4 WMI同步 325

       9.5 数据缓冲区同步 326

       9.6 反向调用 328

       9.7 小结 330

       微软最新的音视频编程框架即AVStream框架,不管从什么方面来说,音视频编程都是一个很小众的领域。AVStream框架极其复杂,个人看法是掌握的难度超过了WDF。本章介绍了AVStream框架的各种基本知识点,并以实例讲解一个内核音频过滤器在系统中是如何工作的。

       第10章 音频驱动开发 331

       10.1 简介 332

       10.1.1 音频模块架构 332

       10.1.2 系统中的音频设备 334

       10.2 AVStream对象 338

       10.2.1 设备对象 339

       10.2.2 Filter工厂和Filter对象 340

       10.2.3 Pin工厂和Pin对象 342

       10.2.4 Node对象与Connection结构体 343

       10.3 AVStream描述符 346

       10.3.1 描述符简介 346

       10.3.2 描述符示例 347

       10.3.3 分发函数表 349

       10.3.4 自控表 349

       10.3.5 自控表示例 351

       10.4 代码讲解 355

       10.4.1 入口函数 355

       10.4.2 设备分发函数 357

       10.4.3 Filter与Pin分发函数 358

       10.4.4 创建和删除 359

       10.4.5 数据处理 360

       10.4.6 数据格式 362

       10.5 自控表函数 364

       10.5.1 事件函数 364

       10.5.2 属性函数 366

       10.5.3 方法函数 367

       10.5.4 用户接口 367

       10.6 硬件操作 370

       10.6.1 数据DMA 370

       10.6.2 AVStream中的DMA实现 371

       10.6.3 谈谈ISR 374

       10.7 安装与测试 376

       10.7.1 安装 376

       10.7.2 测试工具 376

       10.8 小结 379

       ASIO音频驱动具有两个非常亮眼的优点:低延迟、多通道。低延迟能够达到几毫秒,使得最灵敏的耳朵也难也察觉;多通道则让通常的双声道、6.1声道等一齐歇菜,而可以很轻松地让多达十几、几十个声道同时工作,在进行高级音频编辑时,这非常重要。

       第11章 ASIO虚拟声卡 380

       11.1 引言 381

       11.2 关于ASIO 383

       11.3 ASIO用户驱动 384

       11.3.1 COM接口 384

       11.3.2 安装与卸载 386

       11.3.3 IASIO接口 387

       11.3.4 技术核心 390

       11.3.5 计算延迟 392

       11.4 内核驱动实现 393

       11.4.1 同步 393

       11.4.2 原理 393

       11.4.3 实现 396

       11.5 ASIO音频软件 396

       11.6 小结 397

       从本章开始的三章内容,讲的都是“驱动安装”这个话题。在本章中,介绍了系统中和驱动安装有关的各种系统模块。读者通过阅读本章后,至少能够掌握这两个基本知识:系统如何识别一个旧设备,并为它加载合适的驱动文件;系统如何发现一个新设备,并完成驱动安装。

       第12章 设备驱动安装入门 399

       12.1 基础知识预介 400

       12.1.1 设备类型 400

       12.1.2 设备实例ID 401

       12.1.3 驱动加载和安装 403

       12.2 安装模块 404

       12.2.1 内核PNP管理器 405

       12.2.2 用户PNP管理器 406

       12.2.3 安装接口函数(Setup API) 408

       12.2.4 配置管理器接口(CfgMgr API) 410

       12.2.5 类安装器(Class Installers) 410

       12.2.6 类协安装器(Class Co-Installers) 410

       12.2.7 设备协安装器(Device Co-Installers) 411

       12.2.8 驱动包(Driver Package) 412

       12.2.9 驱动仓库(Driver Store) 413

       12.2.10 设备管理器(Device Manager) 414

       12.2.11 安装程序 415

       12.2.12 新设备向导 416

       12.2.13 添加硬件向导 416

       12.2.14 驱动安装器(Driver Installer) 416

       12.3 重要问题 417

       12.3.1 寻找和选择 417

       12.3.2 32位与64位系统兼容 418

       12.3.3 系统重启 419

       12.4 安装模式 420

       12.4.1 示例1:客户端模式 421

       12.4.2 示例2:服务器模式 423

       12.5 安装器编程 424

       12.5.1 DIF码 424

       12.5.2 处理流程 427

       12.5.3 工程示例 429

       12.5.4 注册 430

       12.6 小结 431

       INF文件即驱动程序的“安装文件”,它包含了各种与驱动安装有关的指令信息。通过INF文件,系统知道如何处理驱动包中的各个文件,并在系统注册表中做出准确记录。本章主要从指令和域,这两个方面进行讲解。

       第13章 深入解析INF文件 432

       13.1 概述 433

       13.1.1 域 433

       13.1.2 指令 434

       13.1.3 多系统 435

       13.2 注册表指令 436

       13.2.1 缩写根键 436

       13.2.2 软件键 437

       13.2.3 硬件键 437

       13.2.4 AddReg 438

       13.2.5 DelReg 440

       13.2.6 BitReg 441

       13.3 文件操作指令 441

       13.3.1 CopyFiles 441

       13.3.2 DelFiles 443

       13.3.3 RenFiles 443

       13.4 服务指令 444

       13.4.1 AddService 444

       13.4.2 DelService 445

       13.5 基本域 446

       13.5.1 版本域 446

       13.5.2 文件域 447

       13.5.3 默认安装域 451

       13.5.4 控制域 454

       13.5.5 字符串域 457

       13.6 设备类安装域 458

       13.6.1 主域 459

       13.6.2 服务子域 461

       13.7 接口类安装域 461

       13.8 厂商/产品域 462

       13.8.1 厂商域 463

       13.8.2 产品域 464

       13.9 设备安装域 464

       13.9.1 硬件子域 466

       13.9.2 协安装器子域 467

       13.9.3 接口子域 468

       13.9.4 厂商默认配置子域 469

       13.9.5 逻辑优先配置子域 470

       13.10 ChkInf介绍 471

       13.11 小结 472

       驱动安装程序让你的驱动软件显得更加专业,所以,放弃手动安装驱动的做法吧,你的驱动将显得更靓。本章的示例软件MyDrvInst,可以作为读者设计更漂亮的安装软件的开始。

       第14章 设计驱动安装程序 473

       14.1 驱动包 474

       14.1.1 安装方式 474

       14.1.2 安装驱动包 475

       14.1.3 卸载驱动包 476

       14.2 驱动更新 477

       14.2.1 设备已连接 477

       14.2.2 设备未连接 478

       14.2.3 枚举系统设备 481

       14.3 分析INF文件 484

       14.3.1 函数介绍 484

       14.3.2 打印设备ID 486

       14.4 MyDrvInst介绍 487

       14.5 制作软件安装包 490

       14.5.1 视图介绍 490

       14.5.2 我们的工程 492

       14.5.3 编译执行 493

       14.6 小结 494

       附录A CY001 USB开发板 495

       附录B VisualKD + VMWare实现单机内核调试 501

电脑驱动程序的工作原理

       linux网卡驱动开发流程?

       网卡驱动不涉及网络编程,所谓驱动就是硬件和OS通信的桥梁。想学linux驱动,自己网上买块开发板,买本linux设备驱动程序的书,然后从最简单的key驱动开始,然后触屏驱动,由浅入深。

       驱动信号的类型?

       内存NAND时钟电源DMAIO端口UARTUSB中断LCDIICIISSPI摄像头触屏按键声卡网卡SATAPCI-Express

       BSPGPIO

       设备种类:字符驱动块设备网络设备杂项设备

       五个子系统:进程调度内存管理虚拟文件网络接口IPC

       字符设备characterdevice:采用字符流方式访问的设备,如字符终端,串口,一般顺序访问,但也可以前后移动访问指针,如帧捕捉卡。

       常见要开发的有:触摸屏,自定义键盘,视频捕捉设备,音频设备等

       块设备Blockdevice:采用数据块方式访问的设备,如磁盘等,可以随意移动访问。和字符设备的差异在于内核内部管理数据的方式,如采用缓存机制等。并必须支持mount文件系统

       基本上不用自己开发,象硬盘,光盘,USB存储设备等Linux都提供了

       网络接口networkinterface:数据包传输方式访问的设备,和上两者不同。通过ifconfig来创建和配置设备。网络驱动同块驱动最大的不同在于网络驱动异步接受外界数据,而块驱动只对内核的请求作出响应

       需要自己开发

       其他other:总线类,如USB,PCI,SCSI等,一般同其他驱动联合使用

       常见要开发的如采用IIC,SPI,USB通信的一些设备驱动。

       按照硬件设备的具体工作方式,读写设备的寄存器,完成设备的轮询、中断处理、DMA通信,进行物理内存向虚拟内存的映射等,最终让通信设备能收发数据,让显示设备能显示文字和画面,让存储设备能记录文件和数据。

       字符设备指那些必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标等。块设备可以用任意顺序进行访问,以块为单位进行操作,如硬盘、软驱等。字符设备不经过系统的快速缓冲,而块设备经过系统的快速缓冲。但是,字符设备和块设备并没有明显的界限,如对于Flash设备,符合块设备的特点,但是我们仍然可以把它作为一个字符设备来访问。

       l编写Linux设备驱动要求工程师有非常好的硬件基础,懂得SRAM、Flash、SDRAM、磁盘的读写方式,UART、I2C、USB等设备的接口以及轮询、中断、DMA的原理,PCI总线的工作方式以及CPU的内存管理单元(MMU)等。

       l编写Linux设备驱动要求工程师有非常好的C语言基础,能灵活地运用C语言的结构体、指针、函数指针及内存动态申请和释放等。

       l编写Linux设备驱动要求工程师有一定的Linux内核基础,虽然并不要求工程师对内核各个部分有深入的研究,但至少要明白驱动与内核的接口。尤其是对于块设备、网络设备、Flash设备、串口设备等复杂设备,内核定义的驱动体系架构本身就非常复杂。

       l编写Linux设备驱动要求工程师有非常好的多任务并发控制和同步的基础,因为在驱动中会大量使用自旋锁、互斥、信号量、等待队列等并发与同步机制。

       什么叫驱动程序,那是干什么的?

       1)驱动程序一般指的是设备驱动程序(DeviceDriver),是一种可以使计算机和设备通信的特殊程序。相当于硬件的接口,操作系统只有通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。

       2)因此,驱动程序被比作“硬件的灵魂”、“硬件的主宰”、和“硬件和系统之间的桥梁”等。

       3)随着电子技术的飞速发展,电脑硬件的性能越来越强大。驱动程序是直接工作在各种硬件设备上的软件,其“驱动”这个名称也十分形象的指明了它的功能。正是通过驱动程序,各种硬件设备才能正常运行,达到既定的工作效果。

       4)硬件如果缺少了驱动程序的“驱动”,那么本来性能非常强大的硬件就无法根据软件发出的指令进行工作,硬件就是空有一身本领都无从发挥,毫无用武之地。这时候,电脑就正如古人所说的“万事俱备,只欠东风”,这“东风”的角色就落在了驱动程序身上。如此看来,驱动程序在电脑使用上还真起着举足轻重的作用。

       5)从理论上讲,所有的硬件设备都需要安装相应的驱动程序才能正常工作。但像CPU、内存、主板、软驱、键盘、显示器等设备却并不需要安装驱动程序也可以正常工作,而显卡、声卡、网卡等却一定要安装驱动程序,否则便无法正常工作。这主要是由于这些硬件对于一台个人电脑来说是必需的,所以早期的设计人员将这些硬件列为BIOS能直接支持的硬件。换句话说,上述硬件安装后就可以被BIOS和操作系统直接支持,不再需要安装驱动程序。从这个角度来说,BIOS也是一种驱动程序。但是对于其他的硬件,例如:网卡,声卡,显卡等等却必须要安装驱动程序,不然这些硬件就无法正常工作。

       6)当然,也并非所有驱动程序都是对实际的硬件进行操作的,有的驱动程序只是辅助系统的运行,如android中的有些驱动程序提供辅助操作系统的功能,这些驱动不是linux系统的标准驱动,如ashmen,binder等。

       Linux内核和驱动开发工程师的发展前景怎么样?

       我亲身体验,我之前是做数控系统开发的,做了有七八年,有x86的产品也有arm的产品,x86的linux相对开发驱动的地方不多,arm上比较多,存储,显示的,usb的,各种总线的,音频的,网络的,很多地方只要有订制需求都要改。驱动开门槛比较高,主要会软件还得了解些硬件知识,硬件的原理图,设备的数据手册,工作特性都要会,入门难但是一旦入门了就跟其他的一样做多了就熟悉了。之前公司是linux+qt,今年离职了进了一家安卓开发的公司,现在还在做安卓的驱动开发,感觉大同小异,只是硬件平台变了,开发的内容仍是没变。驱动这一块,人比较少,相对待遇也会好一些,现在我也不知道未来会不会随着年龄越大,会被淘汰掉,但是linux本身的应用范围是挺广的,而且作为一个成功的开源项目,只要社会有需求,后面应该还是会被广泛应用,至于个人就看自己的能力和精力了!

驱动开发

       资料来源: /view/1048.htm一、什么是驱动程序

       根据百度百科:驱动程序,英文名为“Device Driver”,全称为“设备驱动程序”, 是一种可以使计算机和设备通信的特殊程序,可以 说相当于硬件的接口,操作系统只有通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。 因此,驱动程序被誉为“ 硬件的灵魂”、“硬件的主宰”、和“硬件和系统之间的桥梁”等。

       刚安装好的系统操作系统,很可能驱动程序安装得不完整。硬件越新,这种可能性越大。菜菜熊之前看到的“图标很大且颜色难看”就是没有安装好驱动的原因。

       在软件测试中:在自底向上测试中,要编写称为测试驱动的模块调用正在测试的模块。测试驱动模块以和将来真正模块同样的方式挂接,向处于测试的模块发送测试用例数据,接受返回结果,验证结果是否正确。

       二、驱动程序的作用

       随着电子技术的飞速发展,电脑硬件的性能越来越强大。驱动程序是直接工作在各种硬件设备上的软件,其“驱动”这个名称也十分形象的指明了它的功能。正是通过驱动程序,各种硬件设备才能正常运行,达到既定的工作效果。

       硬件如果缺少了驱动程序的“驱动”,那么本来性能非常强大的硬件就无法根据软件发出的指令进行工作,硬件就是空有一身本领都无从发挥,毫无用武 之地。这时候,电脑就正如古人所说的“万事俱备,只欠东风”,这“东风”的角色就落在了驱动程序身上。如此看来,驱动程序在电脑使用上还真起着举足轻重的 作用。

       从理论上讲,所有的硬件设备都需要安装相应的驱动程序才能正常工作。但像CPU、内存、主板、软驱、键盘、显示器等设备却并不需要安装驱动程序也可以正常工作,而显卡、声卡、网卡等却一定要安装驱动程序,否则便无法正常工作。这是为什么呢?

       这主要是由于这些硬件对于一台个人电脑来说是必需的,所以早期的设计人员将这些硬件列为BIOS能直接支持的硬件。换句话说,上述硬件安装后就 可以被BIOS和操作系统直接支持,不再需要安装驱动程序。从这个角度来说,BIOS也是一种驱动程序。但是对于其他的硬件,例如:网卡,声卡,显卡等等 却必须要安装驱动程序,不然这些硬件就无法正常工作。

       三、驱动程序的界定

       驱动程序可以界定为官方正式版、微软WHQL认证版、第三方驱动、发烧友修改版、Beta测试版。

       1、官方正式版

       官方正式版驱动是指按照芯片厂商的设计研发出来的,经过反复测试、修正,最终通过官方渠道发布出来的正式版驱动程序,又名公版驱动。通常官方正 式版的发布方式包括官方网站发布及硬件产品附带光盘这两种方式。稳定性、兼容性好是官方正式版驱动最大的亮点,同时也是区别于发烧友修改版与测试版的显著 特征。因此推荐普通用户使用官方正式版,而喜欢尝鲜、体现个性的玩家则推荐使用发烧友修改版及Beta测试版。

       2、微软WHQL认证版

       WHQL是Windows Hardware Quality Labs的缩写,是微软对各硬件厂商驱动的一个认证,是为了测试驱动程序与操作系统的相容性及稳定性而制定的。也就是说通过了WHQL认证的驱动程序与Windows系统基本上不存在兼容性的问题。

       3、第三方驱动

       第三方驱动一般是指硬件产品OEM厂商发布的基于官方驱动优化而成的驱动程序。第三方驱动拥有稳定性、兼容性好,基于官方正式版驱动优化并比官 方正式版拥有更加完善的功能和更加强劲的整体性能的特性。因此,对于品牌机用户来说,笔者推荐用户的首选驱动是第三方驱动,第二选才是官方正式版驱动;对 于组装机用户来说,第三方驱动的选择可能相对复杂一点,因此官方正式版驱动仍是首选。

       4、发烧友修改版

       发烧友令笔者首先就联想到了显卡,这是为什么呢?因为一直以来,发烧友很常都被用来形容游戏爱好者。笔者的这个想法也正好和发烧友修改版的诞生 典故相符的,因为发烧友修改版的驱动最先就是出现在显卡驱动上的,由于众多发烧友对游戏的狂热,对于显卡性能的期望也就是比较高的,这时候厂商所发布的显 卡驱动就往往都不能满足游戏爱好者的需求了,因此经修改过的以满足游戏爱好者更多的功能性要求的显卡驱动也就应运而生了。如今,发烧友修改版驱动又名改版 驱动,是指经修改过的驱动程序,而又不专指经修改过的驱动程序。

       5、Beta测试版

       测试版驱动是指处于测试阶段,还没有正式发布的驱动程序。这样的驱动往往具有稳定性不够、与系统的兼容性不够等bug。尝鲜和风险总是同时存在的,所以对于使用Beta测试版驱动的用户要做好出现故障的心理准备。

       四、驱动程序介绍

       驱动程序(Device Driver)全称为“设备驱动程序”,是一种可以使计算机和设备通信的特殊程序,可以说相当于硬件的接口,操作系统只能通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。

       正因为这个原因,驱动程序在系统中的所占的地位十分重要,一般当操作系统安装完毕后,首要的便是安装硬件设备的驱动程序。不过,大多数情况下,我们并不需要安装所有硬件设备的驱动程序,例如硬盘、显示器、光驱、键盘、鼠标等就不需要安装驱动程序,而显卡、声卡、扫描仪、摄像头、Modem等就需要安装驱动程序。另外,不同版本的操作系统对硬件设备的支持也是不同的,一般情况下版本越高所支持的硬件设备也越多,例如笔者使用了Windows XP,装好系统后一个驱动程序也不用安装。

       设备驱动程序用来将硬件本身的功能告诉操作系统,完成硬件设备电子信号与操作系统及软件的高级编程语言之间的互相翻译。当操作系统需要使用某个硬件时,比如:让声卡播放音乐,它会先发送相应指令到声卡驱动程序,声卡驱动程序接收到后,马上将其翻译成声卡才能听懂的电子信号命令,从而让声卡播放音乐。

       所以简单的说,驱动程序提供了硬件到操作系统的一个接口以及协调二者之间的关系,而因为驱动程序有如此重要的作用,所以人们都称“驱动程序是硬件的灵魂”、“硬件的主宰”,同时驱动程序也被形象的称为“硬件和系统之间的桥梁”。

       驱动程序即添加到操作系统中的一小块代码,其中包含有关硬件设备的信息。有了此信息,计算机就可以与设备进行通信。驱动程序是硬件厂商根据操作系统编写的配置文件,可以说没有驱动程序,计算机中的硬件就无法工作。操作系统不同,硬件的驱动程序也不同,各个硬件厂商为了保证硬件的兼容性及增强硬件的功能会不断地升级驱动程序。如:Nvidia 显卡芯片公司平均每个月会升级显卡驱动程序2-3次。驱动程序是硬件的一部分,当你安装新硬件时,驱动程序是一项不可或缺的重要元件。凡是安装一个原本不属于你电脑中的硬件设备时,系统就会要求你安装驱动程序,将新的硬件与电脑系统连接起来。驱动程序扮演沟通的角色,把硬件的功能告诉电脑系统,并且也将系统的指令传达给硬件,让它开始工作。

       当你在安装新硬件时总会被要求放入“这种硬件的驱动程序”,很多人这时就开始头痛。不是找不到驱动程序的盘片,就是找不到文件的位置,或是根本不知道什么是驱动程序。比如安装打印机这类的硬件外设,并不是把连接线接上就算完成,如果你这时候开始使用,系统会告诉你,找不到驱动程序。怎么办呢?参照说明书也未必就能顺利安装。其实在安装方面还是有一定的惯例与通则可寻的,这些都可以帮你做到无障碍安装。

       在Windows系统中,需要安装主板、光驱、显卡、声卡等一套完整的驱动程序。如果你需要外接别的硬件设备,则还要安装相应的驱动程序,如:外接游戏硬件要安装手柄、方向盘、摇杆、跳舞毯等的驱动程序,外接打印机要安装打印机驱动程序,上网或接入局域网要安装网卡、Moden甚至ISDN、ADSL的驱动程序。说了这么多的驱动程序,你是否有一点头痛了。下面就介绍Windows系统中各种的不同硬件设备的驱动程序,希望能让你拨云见日。

       在Windows 9x下,驱动程序按照其提供的硬件支持可以分为:声卡驱动程序、显卡驱动程序、鼠标驱动程序、主板驱动程序、网络设备驱动程序、打印机驱动程序、扫描仪驱动程序等等。为什么没有CPU、内存驱动程序呢?因为CPU和内存无需驱动程序便可使用,不仅如此,绝大多数键盘、鼠标、硬盘、软驱、显示器和主板上的标准设备都可以用Windows自带的标准驱动程序来驱动,当然其它特定功能除外。如果你需要在Windows系统中的DOS模式下使用光驱,那么还需要在DOS模式下安装光驱驱动程序。多数显卡、声卡、网卡等内置扩展卡和打印机、扫描仪、外置Modem等外设都需要安装与设备型号相符的驱动程序,否则无法发挥其部分或全部功能。驱动程序一般可通过三种途径得到,一是购买的硬件附带有驱动程序;二是Windows系统自带有大量驱动程序;三是从Internet下载驱动程序。最后一种途径往往能够得到最新的驱动程序。

       供Windows 9x使用的驱动程序包通常由一些.vxd(或.386)、.drv、.sys、.dll或.exe等文件组成,在安装过程中,大部分文件都会被拷贝到“Windows\ System”目录下。

       五、驱动程序的开发

       驱动程序的开发工作是很具挑战性的,因为必须配合著硬件与软件上相当明确与高级的平台技术。由于大多数的驱动程序(device drivers)运行在内核模式(kernel mode),软件的错误经常造成系统严重的不稳定,例如蓝屏(blue screen),这跟过去的用户模式(user mode)下的程序设计(例如Delphi、VB、Java)有明显的差异性。

       Windows平台

       为了大量减轻驱动程序开发人员的负担,微软不断的改进驱动程序的开发软件与架构,从早期复杂深晦的VxD,到Windows XP上的Windows Driver Model(以下简称WDM)开发架构,如今Windows Driver Foundation(以下简称WDF)已成为新一代的Windows平台驱动程序发展架构,这个架构大量简化了驱动程序的开发流程,更符合面向对象的精神,此架构包含了UserMode Driver Framework 与 Kernel Mode DriverFramework两种开发模式。在开发Windows平台上的驱动程序之前,必须先安装DDK包,目前DDK最新版本为5600,同时支持WDM与WDF两种架构。

       Linux平台

       Linux作为UNIX的一个变种,继承了UNIX的设备管理方法,将所有的设备是具体的文件,通过文件系统层对设备进行访问。 这种设备管理方法可以很好地做到“设备无关性”,可以根据硬件外设的更新进行方便的扩展。

       Linux中的设备大致可以分为三类:字符设备,块设备,网络设备。

       字符设备没有缓冲区,以字节为单位顺序处理数据,不支持随机读写。常见的字符设备如普通打印机、系统的串口、终端显示器、嵌入式设备中的简单按键、手写板等。

       块设备是指在输入输出时数据处理以块为单位的设备,一般都采用缓冲技术,支持数据的随机读写。典型的块设备有硬盘、光驱等。

       字符设备和块设备面向的上一层是文件系统层。对用户来说,块设备和字符设备的访问接口都是一组基于文件的系统调用,如read, write等。

       网络设备与块设备和字符设备不同,网络设备面向的上一层是网络协议层。设备文件是一个唯一的名字(如eth0),在文件系统中不存在对应的节点项。内核和网络驱动程序之间的通信使用的是一套和数据包传输相关的函数,而不是read, write等。

       每一个设备都有一对主设备号、次设备号的参数作为唯一的标识。主设备号标识设备对应的驱动程序;次设备号用来区分具体驱动程序的实例。主设备号的获取可以通过动态分配或指定的方式。在嵌入式系统中外设较少,一般采用指定的方式。

       n [编辑本段]驱动程序的一般安装顺序  驱动程序安装的一般顺序:主板芯片组(Chipset)→显卡(VGA)→声卡(Audio)→网卡(LAN)→无线网卡(Wireless LAN)→红外线(IR)→触控板(Touchpad)→PCMCIA控制器(PCMCIA)→读卡器(Flash Media Reader)→调制解调器(Modem)→其它(如电视卡、CDMA上网适配器等等)。不按顺序安装很有可能导致某些软件安装失败。

       第一步,安装操作系统后,首先应该装上操作系统的Service Pack(SP)补丁。我们知道驱动程序直接面对的是操作系统与硬件,所以首先应该用SP补丁解决了操作系统的兼容性问题,这样才能尽量确保操作系统和驱动程序的无缝结合。

       第二步,安装主板驱动。主板驱动主要用来开启主板芯片组内置功能及特性,主板驱动里一般是主板识别和管理硬盘的IDE驱动程序或补丁,比如Intel芯片组的INF驱动和VIA的4in1补丁等。如果还包含有AGP补丁的话,一定要先安装完IDE驱动再安装AGP补丁,这一步很重要,也是很多造成系统不稳定的直接原因。

       第三步,安装DirectX驱动。这里一般推荐安装最新版本,目前DirectX的最新版本是DirectX 9.0C。可能有些用户会认为:“我的显卡并不支持DirectX 9,没有必要安装DirectX 9.0C”,其实这是个错误的认识,把DirectX等同为了Direct3D。DirectX是微软嵌在操作系统上的应用程序接口(API),DirectX由显示部分、声音部分、输入部分和网络部分四大部分组成,显示部分又分为Direct Draw(负责2D加速)和Direct 3D(负责3D加速),所以说Direct3D只是它其中的一小部分而已。而新版本的DirectX改善的不仅仅是显示部分,其声音部分(DirectSound)——带来更好的声效;输入部分(Direct Input)——支持更多的游戏输入设备,并对这些设备的识别与驱动上更加细致,充分发挥设备的最佳状态和全部功能;网络部分(DirectPlay)——增强计算机的网络连接,提供更多的连接方式。只不过是DirectX在显示部分的改进比较大,也更引人关注,才忽略了其他部分的功劳,所以安装新版本的DirectX的意义并不仅是在显示部分了。当然,有兼容性问题时另当别论。

       第四步,这时再安装显卡、声卡、网卡、调制解调器等插在主板上的板卡类驱动。

       第五步,最后就可以装打印机、扫描仪、读写机这些外设驱动。

       这样的安装顺序就能使系统文件合理搭配,协同工作,充分发挥系统的整体性能。

       另外,显示器、键盘和鼠标等设备也是有专门的驱动程序,特别是一些品牌比较好的产品。虽然不用安装它们也可以被系统正确识别并使用,但是安装上这些驱动程序后,能增加一些额外的功能并提高稳定性和性能 [编辑本段]Windows中的inf文件  Windows怎样知道安装的是什么设备,以及要拷贝哪些文件呢?答案在于.inf文件。.inf是从Windows 95时代开始引入的一种描述设备安装信息的文件,它用特定语法的文字来说明要安装的设备类型、生产厂商、型号、要拷贝的文件、拷贝到的目标路径,以及要添加到注册表中的信息。通过读取和解释这些文字,Windows便知道应该如何安装驱动程序。目前几乎所有硬件厂商提供的用于Windows 9x下的驱动程序都带有安装信息文件。事实上,.inf文件不仅可用于安装驱动程序,还能用来安装与硬件并没有什么关系的软件,例如Windows 98支持“Windows更新”功能,更新时下载的系统部件就是利用.inf文件来说明如何安装该部件的。

       在安装驱动程序时,Windows一般要把.inf文件拷贝一份到“Win-dows\Inf”或“Windows\Inf\Other”目录下,以备将来使用。Inf目录下除了有.inf文件外,还有两个特殊文件Drvdata.bin和Drvidx.bin,以及一些.pnf文件,它们都是Windows为了加快处理速度而自动生成的二进制文件。Drvdata.bin和Drvidx.bin记录了.inf文件描述的所有硬件设备,也许朋友们会有印象:当我们在安装某些设备时,经常会看到一个“创建驱动程序信息库”的窗口,此时Windows便正在生成这两个二进制文件。

       Windows 9x专门提供有“添加新硬件向导”(以下简称硬件向导)来帮助使用者安装硬件驱动程序,使用者的工作就是在必要时告诉硬件向导在哪儿可以找到与硬件型号相匹配的.inf文件,剩下的绝大部分安装工作都将由硬件安装向导自己完成。

       给硬件设备安装驱动程序对Windows 9x用户来说并不是一件陌生事,在安装或重装Windows时需要安装驱动程序,在购买了某些新硬件之后也需要安装驱动程序。如果驱动程序安装不正确,系统中某些硬件就可能无法正常使用。虽然Windows 9x支持即插即用,能够为用户减轻不少工作,但由于PC机的设备有非常多的品牌和型号,加上各种新产品不断问世,Windows不可能自动识别出所有设备,因此在安装很多设备时都需要人工干预。 资料来源: /view/1048.htm

驱动开发的步骤有哪些

       驱动开发,顾名思义,就是软程序的编程开发应用。

       应用开发,就是根据你所研究的领域进行有选择的硬件开发、以计算机技术为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。它一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用 户的应用程序等四个部分组成,用于实现对其他设备的控制、监视或管理等功能。包括硬件和软件两部分。硬件包括处理器/微处理器、存储器及外设器件和I/O端口、图形控制器等。软件部分包括操作系统软件(OS)(要求实时和多任务操作)和应用程序编程。嵌入式系统中的软件一般都固化在存储器芯片或单片机本身中,而不是存贮于磁盘等载体中。

       嵌入式系统本身不具备自举开发能力,即使设计完成以后用户通常也是不能对其中的程序功能进行修改的,必须有一套开发工具和环境才能进行开发。推荐北京精仪达盛、亚龙、天煌等品牌的硬件产品,如系统开发板、DSP、ARM等。

       下面说你工作时要用稿的知识

       1.处理器技术 1)通用处理器 2)单用途处理器 3)专用处理器

       2.IC技术 1)全定制/VLSI 2)半定制ASIC 3)可编程ASIC

       3.设计/验证技术

       嵌入式系统的设计技术主要包括硬件设计技术和软件设计技术两大类。硬件设计领域的技术主要包括芯片级设计技术和电路板级设计技术芯片级设计技术的核心是编译/综合、库/IP、测试/验证。编译/综合技术使设计者用抽象的方式描述所需的功能,并自动分析和插入实现细节。库/IP技术将预先设计好的低抽象级实现用于高级。

       当然、一个出色的职业经理,除了商务,这些技术方面,也是必须要懂的。

       希望以上对你有所启示,不懂了可以留言、。

       驱动开发和应用开发的前景?你想问的是学好这些需要哪些基本功力是吧?真正的技术是积累出来的,多看专业书。等你学习到一定阶段你就会发现什么驱动,什么应用都是雕虫小技而已,现在慢慢学,不用急。多留心就好

       我问你你学习这一系列的东西是为了什么?开公司还是当老师 ?还是没事自己搞研发?现在时代的产品要求的是全方面的人才,艺多不压身,你着重往JAVA方面发展吧。但是C也是必须的,知道吧小弟,出来了就是工程师,想要比别人优秀,就要让自己的水平在你所在的领域游刃有余,要让你工作的地方 没你不行。至于怎样达到这个水平,哪是你自己的事了。

嵌入式驱动开发需要学什么

       步骤?没有什么现成的可作为规律来用的步骤。

       开发驱动主要有两方面的基础要求:

       a,明白你手头的硬件工作原理,包括处理器架构的知识,还有外设控制器的 datasheet 为必读之物;

       b,假如你们要开发的整个系统是裸机程序,那你要开发的驱动程序就是一套和硬件打交道的函数库;但是假如你们计划在产品中使用一个操作系统,那开发驱动之前就需要熟悉这个操作系统的相关内部操作原理,因为你写的是驱动程序需要很好的“镶嵌”到这个操作系统的环境中去。

       具体的,可以参考 JulianTec 的这篇文章:《应用程序,操作系统,驱动程序和硬件》

如何编写驱动程序?

       嵌入式驱动开发需要学以下:

       一:C语言

       嵌入式Linux工程师的学习需要具备一定的C语言基础,C语言是嵌入式领域最重要也是最主要的编程语言,通过大量编程实例重点理解C语言的基础编程以及高级编程知识。包括:基本数据类型、数组、指针、结构体、链表、文件操作、队列、栈等。

       二:Linux基础

       Linux操作系统的概念、安装方法,详细了解Linux下的目录结构、基本命令、编辑器VI ,编译器GCC,调试器GDB和 Make 项目管理工具, Shell Makefile脚本编写等知识,嵌入式开发环境的搭建。

       三:Linux系统编程

       重点学习标准I/O库,Linux多任务编程中的多进程和多线程,以及进程间通信(pipe、FIFO、消息队列、共享内存、signal、信号量等),同步与互斥对共享资源访问控制等重要知识,主要提升对Linux应用开发的理解和代码调试的能力。

       四:Linux网络编程

       计算机网络在嵌入式Linux系统应用开发过程中使用非常广泛,通过Linux网络发展、TCP/IP协议、socket编程、TCP网络编程、UDP网络编程、Web编程开发等方面入手,全面了解Linux网络应用程序开发。

       重点学习网络编程相关API,熟练掌握TCP协议服务器的编程方法和并发服务器的实现,了解HTTP协议及其实现方法,熟悉UDP广播、多播的原理及编程方法,掌握混合C/S架构网络通信系统的设计,熟悉HTML,Javascript等Web编程技术及实现方法。

       五:数据结构与算法

       数据结构及算法在嵌入式底层驱动、通信协议、及各种引擎开发中会得到大量应用,对其掌握的好坏直接影响程序的效率、简洁及健壮性。

       此阶段的学习要重点理解数据结构与算法的基础内容,包括顺序表、链表、队列、栈、树、图、哈希表、各种查找排序算法等应用及其C语言实现过程。

       六:C++ 、QT

       C++是Linux应用开发主要语言之一,本阶段重点掌握面向对象编程的基本思想以及C++的重要内容。图形界面编程是嵌入式开发中非常重要的一个环节。

       由于QT具有跨平台、面向对象、丰富API、支持2D/3D渲染、支持XML、多国语等强大功能,在嵌入式领域的GUI开发中得到了广范的应用,在本阶段通过基于QT图形库的学习使学员可以熟练编写GUI程序,并移植QT应用程序到Cortex-A8平台。

       包括IDE使用、QT部件及布局管理器、信息与槽机制的应用、鼠标、键盘及绘图事件处理及文件处理的应用。

       如何编写Linux设备驱动程序

        回想学习Linux操作系统已经有近一年的时间了,前前后后,零零碎碎的一路学习过来,也该试着写的东西了。也算是给自己能留下一点记忆和回忆吧!由于完全是自学的,以下内容若有不当之处,还请大家多指教。

       Linux是Unix操作系统的一种变种,在Linux下编写驱动程序的原理和思想完全类似于其他的Unix系统,但它dos或window环境下的驱动程序有很大的区别。在Linux环境下设计驱动程序,思想简洁,操作方便,功能也很强大,但是支持函数少,只能依赖kernel中的函数,有些常用的操作要自己来编写,而且调试也不方便。

       以下的一些文字主要来源于khg,johnsonm的Write linux device driver,Brennan's Guide to Inline Assembly,The Linux A-Z,还有清华BBS上的有关device driver的一些资料。

       一、Linux device driver 的概念

       系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:

       1、对设备初始化和释放。

       2、把数据从内核传送到硬件和从硬件读取数据。

       3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据。

       4、检测和处理设备出现的错误。

       在Linux操作系统下有三类主要的设备文件类型,一是字符设备,二是块设备,三是网络设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待。

       已经提到,用户进程是通过设备文件来与实际的硬件打交道。每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备?另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们。设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序。

       最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度。也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作。如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck。

       读/写时,它首先察看缓冲区的内容,如果缓冲区的数据未被处理,则先处理其中的内容。

       如何编写Linux操作系统下的设备驱动程序

       二、实例剖析

       我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理。把下面的C代码输入机器,你就会获得一个真正的设备驱动程序。

       #define __NO_VERSION__

       #include modules.h>

       #include version.h>

       char kernel_version [] = UTS_RELEASE;

       这一段定义了一些版本信息,虽然用处不是很大,但也必不可少。Johnsonm说所有的驱动程序的开头都要包含config.h>,一般来讲最好使用。

       由于用户进程是通过设备文件同硬件打交道,对设备文件的操作方式不外乎就是一些系统调用,如 open,read,write,close…, 注意,不是fopen, fread,但是如何把系统调用和驱动程序关联起来呢?这需要了解一个非常关键的数据结构:

       struct file_operations

       {

       int (*seek) (struct inode * ,struct file *, off_t ,int);

       int (*read) (struct inode * ,struct file *, char ,int);

       int (*write) (struct inode * ,struct file *, off_t ,int);

       int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);

       int (*select) (struct inode * ,struct file *, int ,select_table *);

       int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long);

       int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);

       int (*open) (struct inode * ,struct file *);

       int (*release) (struct inode * ,struct file *);

       int (*fsync) (struct inode * ,struct file *);

       int (*fasync) (struct inode * ,struct file *,int);

       int (*check_media_change) (struct inode * ,struct file *);

       int (*revalidate) (dev_t dev);

       }

       这个结构的每一个成员的名字都对应着一个系统调用。用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是linux的设备驱动程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。

       下面就开始写子程序。

       #include types.h>

       #include fs.h>

       #include mm.h>

       #includeconfig.h>

       #include errno.h>

       #include segment.h>

       unsigned int test_major = 0;

       static int read_test(struct inode *node,struct file *file,char *buf,int count)

       {

       int left;

       if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )

       return -EFAULT;

       for(left = count ; left > 0 ; left--)

       {

       __put_user(1,buf,1);

       buf++;

       }

       return count;

       }

       这个函数是为read调用准备的。当调用read时,read_test()被调用,它把用户的缓冲区全部写1。buf 是read调用的一个参数。它是用户进程空间的一个地址。但是在read_test被调用时,系统进入核心态。所以不能使用buf这个地址,必须用__put_user(),这是kernel提供的一个函数,用于向用户传送数据。另外还有很多类似功能的函数。请参考Robert著的《Linux内核设计与实现》(第二版)。然而,在向用户空间拷贝数据之前,必须验证buf是否可用。这就用到函数verify_area。

       static int write_tibet(struct inode *inode,struct file *file,const char *buf,int count)

       {

       return count;

       }

       static int open_tibet(struct inode *inode,struct file *file )

       {

       MOD_INC_USE_COUNT;

       return 0;

       }

       static void release_tibet(struct inode *inode,struct file *file )

       {

       MOD_DEC_USE_COUNT;

       }

       这几个函数都是空操作。实际调用发生时什么也不做,他们仅仅为下面的结构提供函数指针。

       struct file_operations test_fops = {

       NULL,

       read_test,

       write_test,

       NULL, /* test_readdir */

       NULL,

       NULL, /* test_ioctl */

       NULL, /* test_mmap */

       open_test,

       release_test,

       NULL, /* test_fsync */

       NULL, /* test_fasync */

       /* nothing more, fill with NULLs */

       };

       这样,设备驱动程序的主体可以说是写好了。现在要把驱动程序嵌入内核。驱动程序可以按照两种方式编译。一种是编译进kernel,另一种是编译成模块(modules),如果编译进内核的话,会增加内核的大小,还要改动内核的源文件,而且不能动态的卸载,不利于调试,所以推荐使用模块方式。

       int init_module(void)

       {

       int result;

       result = register_chrdev(0, "test", &test_fops);

       if (result < 0) {

       printk(KERN_INFO "test: can't get major number\n");

       return result;

       }

       if (test_major == 0) test_major = result; /* dynamic */

       return 0;

       }

       在用insmod命令将编译好的模块调入内存时,init_module 函数被调用。在这里,init_module只做了一件事,就是向系统的字符设备表登记了一个字符设备。register_chrdev需要三个参数,参数一是希望获得的设备号,如果是零的话,系统将选择一个没有被占用的设备号返回。参数二是设备文件名,参数三用来登记驱动程序实际执行操作的函数的指针。

       如果登记成功,返回设备的主设备号,不成功,返回一个负值。

       void cleanup_module(void)

       {

       unregister_chrdev(test_major,"test");

       }

       在用rmmod卸载模块时,cleanup_module函数被调用,它释放字符设备test在系统字符设备表中占有的表项。

       一个极其简单的字符设备可以说写好了,文件名就叫test.c吧。

       下面编译 :

       $ gcc -O2 -DMODULE -D__KERNEL__ -c test.c

       得到文件test.o就是一个设备驱动程序。

       如果设备驱动程序有多个文件,把每个文件按上面的命令行编译,然后

       ld -r file1.o file2.o -o modulename。

       驱动程序已经编译好了,现在把它安装到系统中去。

       $ insmod –f test.o

       如果安装成功,在/proc/devices文件中就可以看到设备test,并可以看到它的主设备号。要卸载的话,运行 :

       $ rmmod test

       下一步要创建设备文件。

       mknod /dev/test c major minor

       c 是指字符设备,major是主设备号,就是在/proc/devices里看到的。

       用shell命令

       $ cat /proc/devices

       就可以获得主设备号,可以把上面的命令行加入你的shell script中去。

       minor是从设备号,设置成0就可以了。

       我们现在可以通过设备文件来访问我们的驱动程序。写一个小小的测试程序。

       #include

       #include types.h>

       #include stat.h>

       #include

       main()

       {

       int testdev;

       int i;

       char buf[10];

       testdev = open("/dev/test",O_RDWR);

       if ( testdev == -1 )

       {

       printf("Cann't open file \n");

       exit(0);

       }

       read(testdev,buf,10);

       for (i = 0; i < 10;i++)

       printf("%d\n",buf[i]);

       close(testdev);

       }

       编译运行,看看是不是打印出全1 ?

       以上只是一个简单的演示。真正实用的驱动程序要复杂的多,要处理如中断,DMA,I/O port等问题。这些才是真正的难点。请看下节,实际情况的处理。

       如何编写Linux操作系统下的设备驱动程序

        三、设备驱动程序中的一些具体问题

       1。 I/O Port。

       和硬件打交道离不开I/O Port,老的ISA设备经常是占用实际的I/O端口,在linux下,操作系统没有对I/O口屏蔽,也就是说,任何驱动程序都可对任意的I/O口操作,这样就很容易引起混乱。每个驱动程序应该自己避免误用端口。

       有两个重要的kernel函数可以保证驱动程序做到这一点。

       1)check_region(int io_port, int off_set)

       这个函数察看系统的I/O表,看是否有别的驱动程序占用某一段I/O口。

       参数1:I/O端口的基地址,

       参数2:I/O端口占用的范围。

       返回值:0 没有占用, 非0,已经被占用。

       2)request_region(int io_port, int off_set,char *devname)

       如果这段I/O端口没有被占用,在我们的驱动程序中就可以使用它。在使用之前,必须向系统登记,以防止被其他程序占用。登记后,在/proc/ioports文件中可以看到你登记的I/O口。

       参数1:io端口的基地址。

       参数2:io端口占用的范围。

       参数3:使用这段io地址的设备名。

       在对I/O口登记后,就可以放心地用inb(), outb()之类的函来访问了。

       在一些pci设备中,I/O端口被映射到一段内存中去,要访问这些端口就相当于访问一段内存。经常性的,我们要获得一块内存的物理地址。

       2。内存操作

       在设备驱动程序中动态开辟内存,不是用malloc,而是kmalloc,或者用get_free_pages直接申请页。释放内存用的是kfree,或free_pages。 请注意,kmalloc等函数返回的是物理地址!

       注意,kmalloc最大只能开辟128k-16,16个字节是被页描述符结构占用了。

       内存映射的I/O口,寄存器或者是硬件设备的RAM(如显存)一般占用F0000000以上的地址空间。在驱动程序中不能直接访问,要通过kernel函数vremap获得重新映射以后的地址。

       另外,很多硬件需要一块比较大的连续内存用作DMA传送。这块程序需要一直驻留在内存,不能被交换到文件中去。但是kmalloc最多只能开辟128k的内存。

       这可以通过牺牲一些系统内存的方法来解决。

       3。中断处理

       同处理I/O端口一样,要使用一个中断,必须先向系统登记。

       int request_irq(unsigned int irq ,void(*handle)(int,void *,struct pt_regs *),

       unsigned int long flags, const char *device);

       irq: 是要申请的中断。

       handle:中断处理函数指针。

       flags:SA_INTERRUPT 请求一个快速中断,0 正常中断。

       device:设备名。

       如果登记成功,返回0,这时在/proc/interrupts文件中可以看你请求的中断。

       4。一些常见的问题。

       对硬件操作,有时时序很重要(关于时序的具体问题就要参考具体的设备芯片手册啦!比如网卡芯片RTL8139)。但是如果用C语言写一些低级的硬件操作的话,gcc往往会对你的程序进行优化,这样时序会发生错误。如果用汇编写呢,gcc同样会对汇编代码进行优化,除非用volatile关键字修饰。最保险的办法是禁止优化。这当然只能对一部分你自己编写的代码。如果对所有的代码都不优化,你会发现驱动程序根本无法装载。这是因为在编译驱动程序时要用到gcc的一些扩展特性,而这些扩展特性必须在加了优化选项之后才能体现出来。

       写在后面:学习Linux确实不是一件容易的事情,因为要付出很多精力,也必须具备很好的C语言基础;但是,学习Linux也是一件非常有趣的事情,它里面包含了许多高手的智慧和“幽默”,这些都需要自己亲自动手才能体会到,O(∩_∩)O~哈哈!

       今天关于“驱动程序开发入门知识”的讲解就到这里了。希望大家能够更深入地了解这个主题,并从我的回答中找到需要的信息。如果您有任何问题或需要进一步的信息,请随时告诉我。