嵌入式Linux设备驱动程序开发指南(原书第2版)

0
(0)

嵌入式Linux设备驱动程序开发指南(原书第2版)

作者:[西] 阿尔贝托·利贝拉尔·德·洛斯里奥斯(AlbertoLiberaldelosRíos)

出版社:机械工业出版社

原作名:LinuxDriverDevelopmentforEmbeddedProcessors,SecondEdition

译者:文洋/李唯杰/谢宝友/武彦/李宁/陈乾新/陆灿江

出版年:2021-7

定价:159.00

装帧:平装

丛书:电子与嵌入式系统设计译丛

ISBN:9787111684558

内容简介
······

本书将告诉你如何为设备树嵌入式Linux系统开发设备驱动程序。你将学会如何编写不同类型的Linux驱动程序,以及如何使用适当的API(应用程序接口)实现与内核和用户态的交互。本书内容以实用为主,但也提供重要的理论基础知识。

本书编写了近30个驱动程序,并将其移植到三种不同的处理器上。你可以选择NXP i.MX7D、Microchip SAMA5D2和Broadcom BCM2837三种处理器来开发和测试这些驱动程序,本书的实验部分详细介绍了这些驱动程序的实现。在你开始阅读之前,建议你使用一个开发板,这个开发板需要有一些GPIO,以及至少一个SPI和I2C控制器。本书详细介绍了用于开发驱动程序的不同评估板的硬件配置,其中用于实现驱动程序的单板包括著名的Raspberry Pi 3 Model B。我鼓励你在开始阅读之前,先找到一块这样的单板,因为本书的内容注重实践,用单板做实验将有助于你应用贯穿全书的理论知识。

你将学习如何开发驱动程序,从最简单的不与任何外部硬件交互的驱动程序,到管理不同类型设备(如加速度计、DAC、ADC、RGB LED、多显LED控制器、I/O扩展器和按钮)的驱动程序。你还将开发DMA驱动程序、管理中断的驱动程序,以及通过写入/读取处理器内部寄存器来控制外部设备的驱动程序。为了简化这些驱动程序的开发,你将使用不同类型的框架:杂项框架、LED框架、UIO框架、输入框架和IIO工业框架。

本书是一个学习工具,可以帮助读者在没有任何领域知识的情况下开始开发驱动程序。本书的写作目的是介绍如何开发没有高度复杂性的驱动程序,这既有助于强化主要的驱动程序开发概念,也有助于读者开始开发自己的驱动程序。记住,开发驱动程序的最好方法不是从头开始写。你可以重用与Linux内核主线驱动程序类似的免费代码。本书中所写的所有驱动程序都遵循GPL许可,因此你可以在相同许可证下修改和重新发布它们。

作者简介
······

阿尔贝托·利贝拉尔·德·洛斯里奥斯(Alberto Liberal de los Ríos)是Arrow Electronics的现场应用工程师,在嵌入式系统方面有超过15年的经验。在过去的几年里,他一直在Arrow公司支持高端处理器和FPGA。Alberto也是一个Linux爱好者,在过去的几年里,他举办了多场关于嵌入式Linux与Linux设备驱动程序的技术研讨会和实践讲习班。Alberto涉足的其他专业领域包括多媒体SoC和实时操作系统(RTOS)。他目前居住在西班牙马德里,他最大的爱好是和女儿一起在马德里市中心散步。他还喜欢阅读电影杂志和观看科幻电影。

目录
······

译者序

前言

作者简介

第1章 构建系统1

1.1 引导加载程序1

1.2 Linux内核3

1.3 系统调用接口和C运行时库6

1.4 系统共享库7

1.5 根文件系统8

1.6 Linux启动过程9

1.7 构建嵌入式Linux系统10

1.8 设置以太网通信11

1.9 为NXP i.MX7D处理器构建嵌入式Linux系统11

1.9.1 简介12

1.9.2 主机软件包12

1.9.3 设置repo工具13

1.9.4 Yocto工程的安装和映像构建13

1.9.5 Yocto 之外的工作15

1.9.6 构建Linux内核18

1.9.7 安装TFTP服务器20

1.9.8 安装NFS服务器20

1.9.9 设置U-Boot环境变量21

1.10 为Microchip SAMA5D2处理器构建嵌入式Linux系统21

1.10.1 简介22

1.10.2 主机软件包22

1.10.3 Yocto工程的安装和映像构建22

1.10.4 Yocto 之外的工作25

1.10.5 构建Linux内核25

1.10.6 安装TFTP服务器27

1.10.7 安装NFS服务器27

1.10.8 设置U-Boot环境变量28

1.11 为Broadcom BCM2837处理器构建Linux嵌入式系统28

1.11.1 Raspbian28

1.11.2 构建Linux内核29

1.11.3 将文件复制到Raspberry Pi31

1.12 使用Eclipse33

1.12.1 用于内核源码的Eclipse配置33

1.12.2 用于开发Linux驱动程序的Eclipse配置38

第2章 Linux设备与驱动模型42

2.1 总线核心驱动42

2.2 总线控制器驱动45

2.3 设备驱动45

2.4 设备树简介46

第3章 最简驱动程序50

3.1 许可证51

3.2 实验3-1:“helloworld”模块51

3.3 代码清单3-1:helloworld_imx.c52

3.4 代码清单3-2:Makefile52

3.5 helloworld_imx.ko演示53

3.6 实验3-2:“带参数的helloworld”模块53

3.7 代码清单3-3:helloworld_imx_with_parameters.c54

3.8 helloworld_imx_with_parameters.ko演示54

3.9 实验3-3:“helloworld计时”模块55

3.10 代码清单3-4:helloworld_imx_with_timing.c55

3.11 helloworld_imx_with_timing.ko演示56

第4章 字符设备驱动57

4.1 实验4-1:“helloworld字符设备”模块59

4.2 代码清单4-1:helloworld_imx_char_driver.c63

4.3 代码清单4-2:Makefile65

4.4 代码清单 4-3:ioctl_test.c65

4.5 helloworld_imx_char_driver.ko演示66

4.6 将模块添加到内核构建66

4.7 使用设备文件系统创建设备文件67

4.8 实验4-2:“class字符设备”模块68

4.9 代码清单4-4:helloworld_imx_class_driver.c70

4.10 helloworld_imx_class_driver.ko演示72

4.11 杂项字符设备驱动72

4.12 实验4-3:“杂项字符设备”模块73

4.13 代码清单4-5:misc_imx_driver.c74

4.14 misc_imx_driver.ko演示75

第5章 平台设备驱动76

5.1 实验5-1:“平台设备”模块78

5.2 代码清单5-1:hellokeys_imx.c81

5.3 hellokeys_imx.ko演示82

5.4 操作硬件的文档82

5.5 硬件命名约定83

5.6 引脚控制器84

5.7 引脚控制子系统86

5.8 设备树引脚控制器绑定92

5.9 GPIO 控制器驱动96

5.10 GPIO描述符使用者接口98

5.10.1 获取和释放GPIO98

5.10.2 使用GPIO99

5.10.3 GPIO映射到中断99

5.10.4 GPIO设备树100

5.11 在内核和用户态之间交换数据100

5.12 MMIO(内存映射I/O)设备访问101

5.13 实验5-2:“RGB LED平台设备”模块103

5.13.1 i.MX7D处理器的硬件描述103

5.13.2 SAMA5D2处理器的硬件描述105

5.13.3 BCM2837处理器的硬件描述107

5.13.4 i.MX7D处理器的设备树107

5.13.5 SAMA5D2处理器的设备树111

5.13.6 BCM2837处理器的设备树114

5.13.7 “RGB LED平台设备”模块的代码描述115

5.14 代码清单5-2:ledRGB_sam_platform.c119

5.15 ledRGB_sam_platform.ko演示124

5.16 平台驱动资源124

5.17 Linux LED类126

5.18 实验5-3:“RGB LED类”模块128

5.18.1 i.MX7D、SAMA5D2和BCM2837处理器的设备树128

5.18.2 “RGB LED类”模块的代码描述130

5.19 代码清单5.3:ledRGB_sam_class_platform.c134

5.20 ledRGB_sam_class_platform.ko演示137

5.21 用户态中的平台设备驱动137

5.22 用户定义的I/O:UIO139

5.22.1 UIO如何运转140

5.22.2 内核中的UIO API141

5.23 实验5-4:“LED UIO平台”模块142

5.23.1 i.MX7D、SAMA5D2和BCM2837处理器的设备树143

5.23.2 “LED UIO平台”模块的代码描述144

5.24 代码清单5-4:led_sam_UIO_platform.c146

5.25 代码清单5-5:UIO_app.c148

5.26 led_sam_UIO_platform.ko及UIO_app演示150

第6章 I2C从端驱动151

6.1 Linux I2C 子系统152

6.2 编写I2C 从端驱动155

6.2.1 注册I2C从端驱动155

6.2.2 在设备树中声明I2C设备157

6.3 实验6-1:“I2C I/O 扩展设备”模块159

6.3.1 i.MX7D处理器的硬件描述159

6.3.2 SAMA5D2 处理器的硬件描述159

6.3.3 BCM2837处理器的硬件描述160

6.3.4 i.MX7D处理器的设备树161

6.3.5 SAMA5D2处理器的设备树162

6.3.6 BCM2837处理器的设备树163

6.3.7 “I2C I/O扩展设备”模块的代码描述164

6.4 代码清单6-1:io_imx_expander.c167

6.5 io_imx_expander.ko演示170

6.6 sysfs文件系统171

6.7 实验6-2:“I2C多显LED”模块174

6.7.1 i.MX7D处理器的硬件描述175

6.7.2 SAMA5D2处理器的硬件描述176

6.7.3 BCM2837处理器的硬件描述176

6.7.4 i.MX7D处理器的设备树177

6.7.5 SAMA5D2处理器的设备树178

6.7.6 BCM2837处理器的设备树180

6.7.7 ACPI和设备树的统一设备属性接口181

6.7.8 “I2C多显LED”模块的代码描述182

6.8 代码清单6-2:ltc3206_imx_led_class.c186

6.9 ltc3206_imx_led_class.ko演示192

第7章 处理设备驱动中的中断194

7.1 GPIO控制器在Linux内核的中断域196

7.2 设备树中断处理203

7.3 在Linux设备驱动中申请中断206

7.4 实验7-1:“按钮中断设备”模块207

7.4.1 i.MX7D处理器的硬件描述208

7.4.2 SAMA5D2处理器的硬件描述208

7.4.3 BCM2837处理器的硬件描述208

7.4.4 i.MX7D 处理器的设备树208

7.4.5 SAMA5D2 处理器的设备树209

7.4.6 BCM2837 处理器的设备树210

7.4.7 “按钮中断设备”模块的代码描述211

7.5 代码清单7-1:int_imx_key.c213

7.6 int_imx_key.ko演示215

7.7 延迟工作215

7.7.1 软中断216

7.7.2 tasklet217

7.7.3 定时器218

7.7.4 线程化的中断221

7.7.5 工作队列223

7.8 内核中的锁226

7.8.1 锁和单处理器内核227

7.8.2 在中断和进程上下文之间共享自旋锁227

7.8.3 在用户上下文使用锁227

7.9 内核中的睡眠228

7.10 实验7-2:“睡眠设备”模块229

7.10.1 i.MX7D处理器的设备树230

7.10.2 SAMA5D2处理器的设备树231

7.10.3 BCM2837处理器的设备树232

7.10.4 “睡眠设备”模块的代码描述233

7.11 代码清单7-2:int_imx_key_wait.c236

7.12 int_imx_key_wait.ko演示239

7.13 内核线程239

7.14 实验7-3:“keyled类”模块240

7.14.1 i.MX7D处理器的硬件描述240

7.14.2 SAMA5D2处理器的硬件描述241

7.14.3 BCM2837处理器的硬件描述241

7.14.4 i.MX7D 处理器的设备树242

7.14.5 SAMA5D2处理器的设备树245

7.14.6 BCM2837处理器的设备树247

7.14.7 “keyled类”模块的代码描述249

7.15 代码清单7-3:keyled_imx_class.c255

7.16 keyled_imx_class.ko演示264

第8章 在Linux驱动中分配内存266

8.1 查询ARM的MMU转换表267

8.2 Linux地址的类型271

8.3 用户进程的虚拟地址到物理地址的映射273

8.4 内核的虚拟地址到物理地址的映射273

8.5 内核内存分配器275

8.5.1 页面分配器275

8.5.2 页面分配器接口275

8.5.3 SLAB分配器276

8.5.4 SLAB分配器接口278

8.5.5 kmalloc内存分配器279

8.6 实验8-1:“链表内存分配”模块280

8.7 代码清单8-1:linkedlist_imx_platform.c283

8.8 linkedlist_imx_platform.ko演示287

第9章 在Linux设备驱动中使用DMA288

9.1 缓存一致性288

9.2 Linux DMA引擎API289

9.3 实验9-1:“流式DMA”模块295

9.4 代码清单9-1:sdma_imx_m2m.c302

9.5 sdma_imx_m2m.ko演示 306

9.6 DMA分散/聚集映射306

9.7 实验9-2:“分散/聚集DMA设备”模块 307

9.8 代码清单9-2:sdma_imx_sg_m2m.c310

9.9 sdma_imx_sg_m2m.ko演示 315

9.10 用户态DMA315

9.11 实验9-3:“用户态DMA”模块317

9.12 代码清单9-3:sdma_imx_mmap.c319

9.13 代码清单9-4:sdma.c323

9.14 sdma_imx_mmap.ko演示324

第10章 输入子系统设备驱动框架325

10.1 输入子系统驱动程序326

10.2 实验10-1:“输入子系统加速度计”模块327

10.2.1 设备树329

10.2.2 使用I2C交互的输入框架330

10.2.3 使用输入设备的输入框架331

10.3 代码清单10-1:i2c_imx_accel.c334

10.4 i2c_imx_accel.ko演示336

10.5 在Linux中使用SPI337

10.6 Linux的SPI子系统339

10.7 编写SPI从设备驱动程序 342

10.7.1 注册SPI从设备驱动程序 342

10.7.2 在设备树中声明SPI设备343

10.8 实验10-2:“SPI加速度计输入设备”模块346

10.8.1 i.MX7D 处理器的硬件描述347

10.8.2 SAMA5D2处理器的硬件描述 347

10.8.3 BCM2837处理器的硬件描述 348

10.8.4 i.MX7D处理器的设备树348

10.8.5 SAMA5D2处理器的设备树 349

10.8.6 BCM2837处理器的设备树350

10.8.7 “SPI加速度计输入设备”模块的代码描述351

10.9 代码清单10-2:adxl345_imx.c360

10.10 adxl345_imx.ko演示371

第11章 设备驱动中的工业IO 子系统373

11.1 IIO设备的sysfs接口375

11.2 IIO设备通道375

11.3 iio_info数据结构377

11.4 缓冲区378

11.4.1 IIO缓冲区的sysfs接口378

11.4.2 设置IIO缓冲区379

11.4.3 触发器380

11.4.4 触发式缓冲区380

11.5 工业I/O事件382

11.6 IIO工具386

11.7 实验11-1:“IIO子系统DAC”模块386

11.7.1 设备树387

11.7.2 用作I2C交互的工业框架389

11.7.3 用作IIO设备的工业框架389

11.8 代码清单11-1:ltc2607_imx_dual_device.c394

11.9 实验11-2:“SPIDEV双通道ADC用户”应用程序的“IIO子系统DAC”模块397

11.9.1 i.MX7D处理器的硬件描述399

11.9.2 SAMA5D2处理器的硬件描述399

11.9.3 BCM2837处理器的硬件描述399

11.9.4 i.MX7D处理器的设备树400

11.9.5 SAMA5D2处理器的设备树400

11.9.6 BCM2837处理器的设备树401

11.10 代码清单 11-2:LTC2422_spidev.c401

11.11 ltc2607_imx_dual_device.ko配合LTC2422_spidev使用演示404

11.12 实验11-3:“IIO子系统ADC”模块406

11.12.1 设备树406

11.12.2 用作SPI交互的工业框架407

11.12.3 用作IIO设备的工业框架408

11.13 代码清单11-3:ltc2422_imx_dual.c411

11.14 代码清单11-4:ltc2422_app.c413

11.15 ltc2422_imx_dual.ko配合ltc2422_app使用演示414

11.16 实验11-4:“具备硬件触发功能的IIO子系统ADC”模块415

11.16.1 i.MX7D、SAMA5D2和BCM2837处理器的设备树415

11.16.2 驱动里的睡眠和唤醒418

11.16.3 中断管理420

11.17 代码清单11-5:ltc2422_imx_trigger.c420

11.18 ltc2422_imx_trigger.ko配合LTC2422_app使用演示423

第12章 在Linux设备驱动程序中使用regmap API424

12.1 regmap的实现425

12.2 实验12-1:“SPI regmap IIO 设备”模块428

12.3 代码清单12-1:adxl345_imx_iio.c437

12.4 adxl345_imx_iio.ko演示446

第13章 Linux USB设备驱动450

13.1 USB 2.0总线拓扑450

13.2 USB总线枚举和设备布局451

13.3 USB数据传输453

13.4 USB设备类别454

13.5 USB描述符454

13.5.1 USB设备描述符455

13.5.2 USB配置描述符456

13.5.3 USB接口描述符457

13.5.4 USB端点描述符458

13.5.5 USB字符串描述符459

13.5.6 USB HID描述符459

13.6 Linux USB子系统461

13.7 编写Linux USB设备驱动程序462

13.7.1 注册USB设备驱动程序462

13.7.2 Linux主机端数据类型463

13.7.3 USB请求块465

13.8 实验13-1:USB HID设备应用程序468

13.8.1 步骤1:创建一个新工程468

13.8.2 步骤2:配置Harmony469

13.8.3 步骤3:修改生成的代码471

13.8.4 步骤4:声明USB状态机的状态471

13.8.5 步骤5:添加新成员到APP_DATA类型472

13.8.6 步骤6:声明接收缓冲区和发送缓冲区473

13.8.7 步骤7:初始化新成员473

13.8.8 步骤8:处理弹出474

13.8.9 步骤9:处理HID事件474

13.8.10 步骤10:创建USB状态机475

13.8.11 步骤11:调度新的报告接收请求477

13.8.12 步骤12:接收、准备和发送报告478

13.8.13 步骤13:烧写应用程序479

13.9 实验13-2:“USB LED”模块479

13.10 代码清单13-1:usb_led.c483

13.11 usb_led.ko演示485

13.12 实验13-3:“USB LED和开关”模块486

13.13 代码清单13-2:usb_urb_int_led.c490

13.14 usb_urb_int_led.ko演示495

13.15 实验13-4:“连接到USB多显LED的I2C”模块496

13.16 代码清单13-3:usb_ltc3206.c505

13.17 usb_ltc3206.ko演示510

附录 将内核模块移植到MicrochipSAMA5D27-SOM1上513

参考文献526

术语表528

评论 ······

看过不少内核驱动方面的书,鲜有一本能做到深入浅出,并结合实例代码完全透析驱动开发精要,但是本书做到了(感谢原著作者)。 4星完全是给原著,和中文版本没有半毛钱关系。 中文版翻译粗制滥造,很多直译的语句完全不能体现作者愿意,甚至晦涩难懂,大大增加了理解的难度。所幸,在网上找到英文原版,一下子顺畅太多了。

看到陈莉君老师有作序推荐,真不知道陈老师到底读过本书没有?她对翻译又是如何看待~

原书是好书,但翻译太烂了!!!

拿到这本书后,感觉还是非常有“华章”外观特点的。书中介绍了嵌入式Linux开发方面的各种内容,特别适合入门,当然也可以作为工程师的参考书籍。同时也能让读者形成完整的知识体系。为后续深入学习Linux打下坚实的基础。书中每个章节都使用三种不同的开发板,让读者能根据自己的开发板来实践,也可以看出作者的良苦用心!点赞!同时还提供了很多驱动实例,有很强的参考价值!任何事情都不可能一蹴而就,特别是做技术开发…

关于本书讨论,请加译者微信linux-kernel

点击星号评分!

平均分 0 / 5. 投票数: 0

还没有投票!请为他投一票。

推荐阅读

评论 抢沙发

评论前必须登录!

 

登录

找回密码

注册