当前位置:首页 > 工业技术
Android深度探索  卷1  HAL与驱动开发
Android深度探索  卷1  HAL与驱动开发

Android深度探索 卷1 HAL与驱动开发PDF电子书下载

工业技术

  • 电子书积分:18 积分如何计算积分?
  • 作 者:李宁编著
  • 出 版 社:北京:人民邮电出版社
  • 出版年份:2013
  • ISBN:9787115298027
  • 页数:637 页
图书介绍:本书作为学习Android驱动的第一本书,将对Android以及Linux驱动做一个总体的介绍,以便使读者了解开发Android驱动和开发Linux驱动的联系和区别,并更好地掌握学习Android驱动和移植的方法和技巧。
《Android深度探索 卷1 HAL与驱动开发》目录

第一篇 Android驱动开发前的准备 1

第1章 Android系统移植与驱动开发概述 3

1.1 Android系统架构 3

1.2 Android系统移植的主要工作 4

1.3 查看Linux内核版本 5

1.4 Linux内核版本号的定义规则 6

1.5 如何学习Linux驱动开发 7

1.6 Linux设备驱动 8

1.6.1 设备驱动的发展和作用 8

1.6.2 设备的分类及特点 9

1.7 见识一下什么叫Linux驱动:LED 9

1.8 小结 11

第2章 搭建Android开发环境 12

2.1 Android底层开发需要哪些工具 12

2.2 安装JDK 13

2.3 搭建Android应用程序开发环境 13

2.3.1 安装Android SDK 13

2.3.2 安装Eclipse 15

2.3.3 安装ADT 16

2.3.4 配置ADT 18

2.3.5 建立AVD 19

2.4 安装Android NDK开发环境 20

2.4.1 下载Android NDK 20

2.4.2 安装CDT 21

2.4.3 命令行方式编译Android NDK程序 21

2.4.4 导入Android NDK的例子 22

2.4.5 配置Android NDK的集成开发环境 22

2.5 安装交叉编译环境 25

2.6 小结 28

第3章 Git使用入门 29

3.1 安装Git 29

3.2 查看Git文档 30

3.3 源代码的提交与获取 31

3.3.1 创建版本库:git init 31

3.3.2 将文件提交到本地版本库:git commit 32

3.3.3 创建本地分支:git branch 33

3.3.4 切换本地分支:git checkout 34

3.3.5 在GitHub上创建开源项目 34

3.3.6 上传源代码到GitHub:git push 36

3.3.7 从GitHub下载源代码:git clone 39

3.4 小结 39

第4章 源代码的下载和编译 41

4.1 下载、编译和测试Android源代码 41

4.1.1 配置Android源代码下载环境 41

4.1.2 Android源代码目录结构解析 43

4.1.3 下载Android源代码中的一部分 44

4.1.4 编译Android源代码 46

4.1.5 out目录结构分析 48

4.1.6 将自己的APK作为Android内置程序发布 49

4.1.7 用模拟器测试system.img文件 50

4.2 下载和编译Linux内核源代码 51

4.2.1 下载Linux内核源代码 51

4.2.2 Linux内核源代码的目录结构 51

4.2.3 安装Android内核的编译环境 52

4.2.4 配置和编译Linux内核 53

4.3 小结 57

第5章 搭建S3C6410开发板的测试环境 58

5.1 S3C6410开发板简介 58

5.2 安装串口调试工具:minicom 60

5.3 烧写Android系统 62

5.4 配置有线网络 65

5.5 小结 66

第二篇 Android底层开发入门 67

第6章 第一个Linux驱动程序:统计单词个数 69

6.1 Linux驱动到底是个什么东西 69

6.2 编写Linux驱动程序的步骤 70

6.3 第一个Linux驱动:统计单词个数 71

6.3.1 编写Linux驱动程序前的准备工作 72

6.3.2 编写Linux驱动程序的骨架(初始化和退出驱动) 72

6.3.3 指定与驱动相关的信息 75

6.3.4 注册和注销设备文件 78

6.3.5 指定回调函数 80

6.3.6 实现统计单词数的算法 84

6.3.7 编译、安装、卸载Linux驱动程序 87

6.4 使用多种方式测试Linux驱动 88

6.4.1 使用Ubuntu Linux测试Linux驱动 88

6.4.2 在Android模拟器上通过原生(Native)C程序测试Linux驱动 90

6.4.3 使用Android NDK测试Linux驱动 93

6.4.4 使用Java代码直接操作设备文件来测试Linux驱动 98

6.4.5 使用S3C6410开发板测试Linux驱动 100

6.4.6 将驱动编译进Linux内核进行测试 101

6.5 使用Eclipse开发和测试Linux驱动程序 105

6.5.1 在Eclipse中开发Linux驱动程序 105

6.5.2 在Eclipse中测试Linux驱动 109

6.6 小结 110

第7章 LED将为我闪烁:控制发光二级管 111

7.1 LED驱动的实现原理 111

7.2 编写LED驱动 112

7.2.1 体验LED驱动的奇妙 112

7.2.2 创建LED驱动的设备文件 113

7.2.3 卸载LED驱动的设备文件 118

7.2.4 设置寄存器与初始化LED驱动 118

7.2.5 控制LED 121

7.2.6 LED驱动的模块参数 123

7.2.7 LED驱动的完整代码 125

7.3 测试LED驱动 129

7.3.1 编写测试I/O控制命令的通用程序 130

7.3.2 使用NDK测试LED驱动 132

7.3.3 使用Java测试LED驱动 135

7.4 LED驱动的移植 136

7.5 小结 138

第8章 让开发板发出声音:蜂鸣器驱动 139

8.1 Linux驱动的代码重用 139

8.1.1 编译是由多个文件组成的Linux驱动 139

8.1.2 Linux驱动模块的依赖(导出符号) 142

8.2 强行卸载Linux驱动 146

8.3 蜂鸣器(PWM)驱动 151

8.3.1 蜂鸣器驱动的原理 151

8.3.2 实现蜂鸣器驱动 152

8.3.3 测试蜂鸣器驱动 155

8.4 小结 155

第9章 硬件抽象层:HAL 156

9.1 为什么要在Android中加入HAL 156

9.2 Android HAL架构 157

9.3.1 编写一款支持HAL的Linux驱动程序的步骤 159

9.3.2 颠覆Linux驱动的设计理念:精简LED驱动 159

9.3.3 测试读写寄存器操作 166

9.3.4 编写调用LED驱动的HAL模块 169

9.3.5 编写调用HAL模块的Service 178

9.3.6 HAL模块的存放路径和命名规则 182

9.3.7 编写调用Service的Java库 186

9.3.8 测试LED驱动 187

9.4 小结 188

第10章 嵌入式Linux的调试技术 189

10.1 打印内核调试信息:printk 189

10.2 防止printk函数降低Linux驱动性能 192

10.3 通过虚拟文件系统(/proc)进行数据交互 195

10.4 调试工具 200

10.4.1 用gdb调试用户空间程序 200

10.4.2 用gdbserver远程调试用户空间程序 201

10.4.3 用kgdb远程调试内核程序 203

10.5 小结 204

第三篇 Linux驱动开发高级技术 205

第11章 Linux驱动程序中的并发控制 207

11.1 并发和竞态 207

11.2 原子操作 208

11.2.1 整型原子操作 208

11.2.2 64位整型原子操作 210

11.2.3 位原子操作 211

11.2.4 用原子操作阻止设备文件被多个进程打开 212

11.3 自旋锁(Spin Lock) 214

11.3.1 自旋锁的使用方法 215

11.3.2 使用自旋锁保护临界区 217

11.3.3 读写自旋锁 220

11.3.4 使用读写自旋锁保护临界区 223

11.3.5 顺序锁(seqlock) 228

11.3.6 使用顺序锁写入正在读取的共享资源 230

11.4 读—复制—更新(RCU)机制 232

11.4.1 RCU的原理 232

11.4.2 RCU API 234

11.4.3 RCU的应用 237

11.5 信号量(Semaphore) 238

11.5.1 信号量的使用 239

11.5.2 信号量用于同步 240

11.5.3 读写信号量 242

11.5.4 使用读写信号量保护临界区 243

11.6 互斥体(Mutex) 245

11.7 完成量(Completion) 248

11.8 小结 252

第12章 Linux驱动程序中的阻塞和非阻塞I/O 253

12.1 等待队列 253

12.1.1 等待队列原理 253

12.1.2 等待队列的API 254

12.1.3 等待队列的使用方法 258

12.1.4 支持休眠和唤醒的Linux驱动 258

12.2 轮询操作 261

12.2.1 用户空间的select函数 261

12.2.2 内核空间的poll函数 261

12.2.3 以非阻塞的方式访问Linux驱动 262

12.3 小结 266

第13章 Linux驱动程序中的异步编程 267

13.1 信号与异步通知 267

13.1.1 Linux信号 267

13.1.2 接收Linux信号 268

13.1.3 发送信号 271

13.2 异步I/O(AIO) 276

13.2.1 异步操作的API 277

13.2.2 异步读写本地文件 280

13.2.3 Linux驱动中的异步函数(aio read和aio write) 282

13.2.4 接收信号时异步读取数据 283

13.2.5 AIO中的回调函数 285

13.3 小结 286

第14章 Linux中断和底半部 287

14.1 什么是中断 287

14.2 中断处理程序 288

14.3 Linux中断处理的核心:顶半部和底半部 288

14.4 获取Linux系统的中断统计信息 289

14.5 Linux中断编程 290

14.5.1 注册中断处理程序 290

14.5.2 注销中断处理程序 293

14.5.3 编写中断处理函数 293

14.5.4 共享中断处理程序 294

14.5.5 禁止和激活中断 294

14.5.6 禁止和激活中断线 295

14.5.7 获取中断系统的状态 296

14.5.8 与中断编程相关的函数和宏 296

14.6 实例:S3C6410实时钟中断 297

14.7 中断中下文 299

14.8 中断的实现原理 300

14.9 底半部 303

14.9.1 为什么要使用底半部 304

14.9.2 实现底半部的机制 304

14.9.3 软中断 305

14.9.4 Tasklet 309

14.9.5 实例:Tasklet演示 313

14.9.6 软中断处理线程(ksoftirqd) 314

14.9.7 工作队列(workqueue) 315

14.9.8 与工作队列相关的API 321

14.9.9 实例:工作队列演示 322

14.10 小结 324

第15章 时间管理 325

15.1 Linux内核中的时间概念 325

15.1.1 时钟频率 326

15.1.2 提高时钟频率的优点和缺点 326

15.2 节拍总数(jiffies) 327

15.2.1 访问jiffies 328

15.2.2 jiffies、时间和时钟频率之间的转换 328

15.2.3 jiffies的回绕 331

15.2.4 用户空间和时钟频率 332

15.3 实时时钟和定时器 333

15.4 时钟中断处理程序的实现 334

15.5 读写本地时间 337

15.6 内核定时器 340

15.6.1 如何使用内核定时器 341

15.6.2 实例:秒表定时器 343

15.7 内核延迟 347

15.7.1 忙等待 347

15.7.2 短延迟 348

15.7.3 休眠延迟(schedule_timeout) 349

15.8 小结 351

第16章 内存管理与I/O访问 352

16.1 内存管理模式 352

16.1.1 内存的基本单位:页(Page) 352

16.1.2 页的逻辑划分:区(zone) 354

16.1.3 获取页 361

16.1.4 释放页 363

16.2 分配连续的内存空间(Kmalloc) 364

16.2.1 gfp_mask标志 365

16.2.2 释放内存(kfree) 368

16.3 分配不连续的内存空间(vmalloc) 369

16.4 全局缓存(slab) 370

16.4.1 Slab层的实现原理 371

16.4.2 S1ab分配器 373

16.4.3 示例:从Slab高速缓存中分配和释放对象 375

16.5 Linux内存池 376

16.5.1 内存池的实现原理 377

16.5.2 示例:从内存池获取对象 381

16.6 虚拟地址与物理地址之间的转换 384

16.7 设备I/O端口与I/O内存 385

16.7.1 读写I/O端口 385

16.7.2 读写I/O内存 385

16.7.3 将I/O端口映射为I/O内存 387

16.7.4 申请和释放设备I/O端口和I/O内存 387

16.7.5 使用设备I/O端口和I/O内存的一般步骤 388

16.8 内核空间与用户空间共享数据 389

16.8.1 内存映射与VMA 390

16.8.2 示例:用户程序读取内核空间数据 392

16.9 I/O内存静态映射 395

16.10 小结 397

第四篇 Linux设备驱动与Android底层开发 399

第17章 RTC驱动 401

17.1 实时时钟(RTC)结构与移植内容 401

17.1.1 RTC系统的结构 401

17.1.2 RTC驱动主要的移植工作 403

17.2 RTC系统中的Android部分 403

17.2.1 警报管理:AlarmManager 403

17.2.2 警报服务:AlarmManagerService 406

17.2.3 直接与Alarm驱动交互的JNI代码 409

17.3 Alarm驱动的分析与移植 411

17.3.1 Alarm驱动简介 411

17.3.2 Alarm驱动中的关键数据结构 412

17.3.3 Alarm驱动的应用层接口(alarm_dev.c)代码分析 414

17.3.4 Alarm驱动的通用文件(alarm.c)代码分析 419

17.4 RTC驱动的分析与移植 423

17.4.1 实时时钟(RTC)的特性 423

17.4.2 RTC的结构 423

17.4.3 RTC芯片的寄存器 425

17.4.4 RTC驱动的用户空间接口 427

17.4.5 RTC系统组件之间的调用关系 428

17.4.6 设备文件(/dev/rtc0)的I/O命令 435

17.4.7 sysfs虚拟文件处理函数 437

17.4.8 proc虚拟文件处理函数 438

17.5 小结 440

第18章 LCD驱动 441

18.1 LCD简介 441

18.1.1 液晶的工作原理 441

18.1.2 LCD的种类 442

18.1.3 LCD的技术参数 444

18.1.4 LCD时序图 444

18.2 LCD驱动结构分析和移植要点 446

18.3 帧缓冲(FrameBuffer)驱动设计与实现 447

18.3.1 FrameBuffer设备 447

18.3.2 示例:通过dd命令与FrameBuffer设备文件交互 448

18.3.3 示例:编写访问FrameBufier设备文件的程序 449

18.3.4 FrameBuffer驱动的架构 451

18.3.5 FrameBuffer驱动主要的数据结构 452

18.3.6 如何在Linux内核中查找指定的内容 455

18.3.7 FrameBuffer驱动设备事件的处理(fbmem.c) 458

18.3.8 FrameBuffer驱动源代码分析与移植 461

18.4 FrameBuffer驱动的HAL层分析 469

18.4.1 Gralloc库 469

18.4.2 初始化HAL Gralloc的核心结构体 470

18.4.3 获取Gralloc HAL模块 472

18.4.4 与FrameBuffer设备文件交互 475

18.5 调用Gralloc HAL库 478

18.6 小结 481

第19章 音频驱动 482

19.1 音频驱动基础 482

19.1.1 数字音频简介 482

19.1.2 ALSA架构简介 483

19.1.3 ALSA设备文件 483

19.1.4 数字采样与数字录音 484

19.1.5 混音器 485

19.1.6 音频驱动的目录结构 486

19.1.7 音频设备硬件接口 487

19.1.8 ALSA架构支持的声卡芯片 488

19.2 AC97芯片的寄存器 489

19.2.1 控制寄存器 489

19.2.2 状态寄存器 490

19.2.3 编解码器命令寄存器 490

19.2.4 编解码器状态寄存器 491

19.2.5 PCM输出/输入通道FIFO数据寄存器 491

19.2.6 MIC输入通道FIFO地址寄存器 491

19.2.7 PCM输出/输入通道FIFO数据寄存器 492

19.2.8 MIC输入通道FIFO数据寄存器 492

19.3 创建声卡 492

19.3.1 声卡的顶层数据结构 492

19.3.2 创建声卡的步骤 493

19.3.3 示例:基于ARM的AC97音频驱动 496

19.4 音频逻辑设备 501

19.4.1 创建PCM设备 501

19.4.2 创建录音和播放设备文件节点 504

19.4.3 创建Control设备数据结构 508

19.4.4 创建Control设备 514

19.4.5 注册与打开音频字符设备 515

19.5 嵌入式设备中的ALSA(ASoC) 516

19.5.1 什么是ASoC 517

19.5.2 ASoC的硬件架构 517

19.5.3 ASoC的软件架构 518

19.5.4 如何确定S3C开发板使用了哪个音频驱动 518

19.5.5 ASoC架构中的Machine 520

19.5.6 ASoC架构中的Codec 529

19.5.7 ASoC架构中的Platform 531

19.6 音频驱动的HAL分析 534

19.6.1 实现HAL Library 534

19.6.2 调用HAL Library 541

19.7 小结 545

第20章 Linux块设备驱动 546

20.1 块设备简介 546

20.2 块设备的体系架构 546

20.3 块设备的数据结构与相关操作 549

20.3.1 磁盘设备(gendisk结构体) 549

20.3.2 block_device_operations结构体 550

20.3.3 I/O请求(request结构体) 551

20.3.4 请求队列(request_queue结构体) 553

20.3.5 块I/O(bio结构体) 555

20.4 块设备的加载和卸载 557

20.5 块设备的打开和释放 559

20.6 块设备的ioctl函数 559

20.7 块设备驱动的I/O请求处理 560

20.7.1 依赖请求队列 560

20.7.2 不依赖请求队列 561

20.8 实例1:依赖请求队列的RamDisk 562

20.9 在嵌入式设备上测试块设备驱动 567

20.9.1 编译、配置和安装Busybox 567

20.9.2 测试块设备驱动 569

20.10 实例2:不依赖请求队列的RamDisk 570

20.11 扇区与磁盘碎片整理 576

20.12 小结 577

第21章 网络设备驱动 578

21.1 Linux网络设备驱动的结构 578

21.1.1 网络协议接口层 579

21.1.2 网络设备接口层 583

21.1.3 设备驱动功能层 585

21.1.4 网络设备与媒介层 585

21.2 网络设备驱动设计与实现 586

21.2.1 网络设备的注册与注销 586

21.2.2 网络设备的初始化 587

21.2.3 网络设备的打开与释放 588

21.2.4 发送数据 589

21.2.5 接收数据 590

21.2.6 网络连接状态 590

21.3 示例:DM9000网卡设备驱动 591

21.3.1 如何确定S3C6410开发板使用的网络设备 591

21.3.2 DM9000网卡硬件描述 591

21.3.3 网络设备驱动的定义与安装 592

21.3.4 初始化DM9000网卡设备驱动 593

21.3.5 移出网络设备 597

21.3.6 打开和停止DM9000网卡 598

21.3.7 发送数据 600

21.3.8 接收数据 602

21.3.9 设置广播地址 605

21.4 小结 606

第22章 USB驱动 607

22.1 USB设备简介 607

22.2 USB驱动与USB核心之间的交互 608

22.2.1 端点(Endpoint) 608

22.2.2 接口(Interfaces) 609

22.2.3 配置(Config) 609

22.3 USB设备的核心数据结构 610

22.3.1 USB设备:usb_device结构体 610

22.3.2 USB驱动:usb_driver结构体 611

22.3.3 识别USB设备:usb_device_id结构体 612

22.3.4 USB端点:usb_host_endpoint结构体 613

22.3.5 USB接口:usb_interface结构体 613

22.3.6 USB配置:usb_host_config结构体 614

22.4 描述符数据结构 615

22.4.1 设备描述符 615

22.4.2 配置描述符 615

22.4.3 接口描述符 615

22.4.4 端点描述符 616

22.4.5 字符串描述符 616

22.4.6 查看描述符信息 616

22.5 USB和sysfs 618

22.6 URB(USB请求块) 620

22.6.1 URB结构体 621

22.6.2 URB的处理流程 622

22.6.3 简单的批量与控制URB 625

22.7 USB驱动程序的结构 626

22.8 鼠标驱动分析 633

22.9 小结 637

返回顶部