本站支持尊重有效期内的版权/著作权,所有的资源均来自于互联网网友分享或网盘资源,一旦发现资源涉及侵权,将立即删除。希望所有用户一同监督并反馈问题,如有侵权请联系站长或发送邮件到ebook666@outlook.com,本站将立马改正
1.本书基于三种主流开发板(包括Raspberry Pi 3 Model B)编写了近30个驱动程序的实验,帮助读者学习和掌握在嵌入式Linux系统中开发驱动程序的技巧和方法,这些驱动程序支持NXP i.MX7D、Microchip SAMA5D2和Broadcom BCM2837微处理器。 2.本书作者在嵌入式系统方面有超过15年的丰富工程实践经验,他通过技术研讨会、实践讲习班和本书的方式,将他在嵌入式Linux与Linux设备驱动程序开发的技巧和方法传播和分享。本书中文版译者也是相关领域的专家和爱好者,通过他们的专业翻译,也让读者原汁原味地理解和体会该书的精华。 3.本书配套的开发工具和实验代码都可以从网上获得,或者通过书中作者提供的访问链接下载,方便读者阅读实践。
嵌入式微处理器功能强大、节能和低成本与嵌入式Linux系统的灵活性结合,促使业界许多公司基于嵌入式微处理器开发出了很多新产品。本书教读者基于设备树嵌入式Linux系统如何开发设备驱动程序。读者将学习编写不同类型的Linux驱动程序,以及与内核和用户空间交互的应用程序程序接口(API)和方法。本书以实战为核心,阐述了Linux内核基础知识,将编写大约30个驱动程序并移植到三种不同的微处理器上。本书在实验部分中基于NXP i.MX7D、Microchip SAMA5D2和Broadcom BCM2837三种不同微处理器详细阐述了驱动程序的开发的实现,读者可参考实验部分选择开发和测试自己的驱动程序。在阅读本书之前,建议读者先购买一个基于这些微处理器之一的开发板,板上至少应有一个SPI和I2C控制器,例如Raspberry Pi3模型B板。
Alberto Liberty是Arrow Electronics的现场应用工程师,在嵌入式系统方面有超过15年的经验。在过去的几年里,他一直在Arrow公司支持 处理器和FPGA产品。Alberto也是Linux爱好者,在过去的几年里,他举办了多场关于嵌入式Linux与Linux设备驱动程序的技术研讨会和实践讲习班。Alberto的专业技能还包括多媒体芯片(SoC)和嵌入式实时操作系统(RTOS)。他目前居住在西班牙马德里,他 的爱好是和女儿一起在马德里市中心散步,他还喜欢阅读电影杂志和观看科幻电影。
译者序<br/>前言<br/>作者简介<br/>第1章 构建系统1<br/>1.1 引导加载程序1<br/>1.2 Linux内核3<br/>1.3 系统调用接口和C运行时库6<br/>1.4 系统共享库7<br/>1.5 根文件系统8<br/>1.6 Linux启动过程9<br/>1.7 构建嵌入式Linux系统10<br/>1.8 设置以太网通信11<br/>1.9 为NXP i.MX7D处理器构建嵌入式Linux系统11<br/>1.9.1 简介12<br/>1.9.2 主机软件包12<br/>1.9.3 设置repo工具13<br/>1.9.4 Yocto工程的安装和映像构建13<br/>1.9.5 Yocto 之外的工作15<br/>1.9.6 构建Linux内核18<br/>1.9.7 安装TFTP服务器20<br/>1.9.8 安装NFS服务器20<br/>1.9.9 设置U-Boot环境变量21<br/>1.10 为Microchip SAMA5D2处理器构建嵌入式Linux系统21<br/>1.10.1 简介22<br/>1.10.2 主机软件包22<br/>1.10.3 Yocto工程的安装和映像构建22<br/>1.10.4 Yocto 之外的工作25<br/>1.10.5 构建Linux内核25<br/>1.10.6 安装TFTP服务器27<br/>1.10.7 安装NFS服务器27<br/>1.10.8 设置U-Boot环境变量28<br/>1.11 为Broadcom BCM2837处理器构建Linux嵌入式系统28<br/>1.11.1 Raspbian28<br/>1.11.2 构建Linux内核29<br/>1.11.3 将文件复制到Raspberry Pi31<br/>1.12 使用Eclipse33<br/>1.12.1 用于内核源码的Eclipse配置33<br/>1.12.2 用于开发Linux驱动程序的Eclipse配置38<br/>第2章 Linux设备与驱动模型42<br/>2.1 总线核心驱动42<br/>2.2 总线控制器驱动45<br/>2.3 设备驱动45<br/>2.4 设备树简介46<br/>第3章 简驱动程序50<br/>3.1 许可证51<br/>3.2 实验3-1:“helloworld”模块51<br/>3.3 代码清单3-1:helloworld_imx.c52<br/>3.4 代码清单3-2:Makefile52<br/>3.5 helloworld_imx.ko演示53<br/>3.6 实验3-2:“带参数的helloworld”模块53<br/>3.7 代码清单3-3:helloworld_imx_with_parameters.c54<br/>3.8 helloworld_imx_with_parameters.ko演示54<br/>3.9 实验3-3:“helloworld计时”模块55<br/>3.10 代码清单3-4:helloworld_imx_with_timing.c55<br/>3.11 helloworld_imx_with_timing.ko演示56<br/>第4章 字符设备驱动57<br/>4.1 实验4-1:“helloworld字符设备”模块59<br/>4.2 代码清单4-1:helloworld_imx_char_driver.c63<br/>4.3 代码清单4-2:Makefile65<br/>4.4 代码清单 4-3:ioctl_test.c65<br/>4.5 helloworld_imx_char_driver.ko演示66<br/>4.6 将模块添加到内核构建66<br/>4.7 使用设备文件系统创建设备文件67<br/>4.8 实验4-2:“class字符设备”模块68<br/>4.9 代码清单4-4:helloworld_imx_class_driver.c70<br/>4.10 helloworld_imx_class_driver.ko演示72<br/>4.11 杂项字符设备驱动72<br/>4.12 实验4-3:“杂项字符设备”模块73<br/>4.13 代码清单4-5:misc_imx_driver.c74<br/>4.14 misc_imx_driver.ko演示75<br/>第5章 平台设备驱动76<br/>5.1 实验5-1:“平台设备”模块78<br/>5.2 代码清单5-1:hellokeys_imx.c81<br/>5.3 hellokeys_imx.ko演示82<br/>5.4 操作硬件的文档82<br/>5.5 硬件命名约定83<br/>5.6 引脚控制器84<br/>5.7 引脚控制子系统86<br/>5.8 设备树引脚控制器绑定92<br/>5.9 GPIO 控制器驱动96<br/>5.10 GPIO描述符使用者接口98<br/>5.10.1 获取和释放GPIO98<br/>5.10.2 使用GPIO99<br/>5.10.3 GPIO映射到中断99<br/>5.10.4 GPIO设备树100<br/>5.11 在内核和用户态之间交换数据100<br/>5.12 MMIO(内存映射I/O)设备访问101<br/>5.13 实验5-2:“RGB LED平台设备”模块103<br/>5.13.1 i.MX7D处理器的硬件描述103<br/>5.13.2 SAMA5D2处理器的硬件描述105<br/>5.13.3 BCM2837处理器的硬件描述107<br/>5.13.4 i.MX7D处理器的设备树107<br/>5.13.5 SAMA5D2处理器的设备树111<br/>5.13.6 BCM2837处理器的设备树114<br/>5.13.7 “RGB LED平台设备”模块的代码描述115<br/>5.14 代码清单5-2:ledRGB_sam_platform.c119<br/>5.15 ledRGB_sam_platform.ko演示124<br/>5.16 平台驱动资源124<br/>5.17 Linux LED类126<br/>5.18 实验5-3:“RGB LED类”模块128<br/>5.18.1 i.MX7D、SAMA5D2和BCM2837处理器的设备树128<br/>5.18.2 “RGB LED类”模块的代码描述130<br/>5.19 代码清单5.3:ledRGB_sam_class_platform.c134<br/>5.20 ledRGB_sam_class_platform.ko演示137<br/>5.21 用户态中的平台设备驱动137<br/>5.22 用户定义的I/O:UIO139<br/>5.22.1 UIO如何运转140<br/>5.22.2 内核中的UIO API141<br/>5.23 实验5-4:“LED UIO平台”模块142<br/>5.23.1 i.MX7D、SAMA5D2和BCM2837处理器的设备树143<br/>5.23.2 “LED UIO平台”模块的代码描述144<br/>5.24 代码清单5-4:led_sam_UIO_platform.c146<br/>5.25 代码清单5-5:UIO_app.c148<br/>5.26 led_sam_UIO_platform.ko及UIO_app演示150<br/>第6章 I2C从端驱动151<br/>6.1 Linux I2C 子系统152<br/>6.2 编写I2C 从端驱动155<br/>6.2.1 注册I2C从端驱动155<br/>6.2.2 在设备树中声明I2C设备157<br/>6.3 实验6-1:“I2C I/O 扩展设备”模块159<br/>6.3.1 i.MX7D处理器的硬件描述159<br/>6.3.2 SAMA5D2 处理器的硬件描述159<br/>6.3.3 BCM2837处理器的硬件描述160<br/>6.3.4 i.MX7D处理器的设备树161<br/>6.3.5 SAMA5D2处理器的设备树162<br/>6.3.6 BCM2837处理器的设备树163<br/>6.3.7 “I2C I/O扩展设备”模块的代码描述164<br/>6.4 代码清单6-1:io_imx_expander.c167<br/>6.5 io_imx_expander.ko演示170<br/>6.6 sysfs文件系统171<br/>6.7 实验6-2:“I2C多显LED”模块174<br/>6.7.1 i.MX7D处理器的硬件描述175<br/>6.7.2 SAMA5D2处理器的硬件描述176<br/>6.7.3 BCM2837处理器的硬件描述176<br/>6.7.4 i.MX7D处理器的设备树177<br/>6.7.5 SAMA5D2处理器的设备树178<br/>6.7.6 BCM2837处理器的设备树180<br/>6.7.7 ACPI和设备树的统一设备属性接口181<br/>6.7.8 “I2C多显LED”模块的代码描述182<br/>6.8 代码清单6-2:ltc3206_imx_led_class.c186<br/>6.9 ltc3206_imx_led_class.ko演示192<br/>第7章 处理设备驱动中的中断194<br/>7.1 GPIO控制器在Linux内核的中断域196<br/>7.2 设备树中断处理203<br/>7.3 在Linux设备驱动中申请中断206<br/>7.4 实验7-1:“按钮中断设备”模块207<br/>7.4.1 i.MX7D处理器的硬件描述208<br/>7.4.2 SAMA5D2处理器的硬件描述208<br/>7.4.3 BCM2837处理器的硬件描述208<br/>7.4.4 i.MX7D 处理器的设备树208<br/>7.4.5 SAMA5D2 处理器的设备树209<br/>7.4.6 BCM2837 处理器的设备树210<br/>7.4.7 “按钮中断设备”模块的代码描述211<br/>7.5 代码清单7-1:int_imx_key.c213<br/>7.6 int_imx_key.ko演示215<br/>7.7 延迟工作215<br/>7.7.1 软中断216<br/>7.7.2 tasklet217<br/>7.7.3 定时器218<br/>7.7.4 线程化的中断221<br/>7.7.5 工作队列223<br/>7.8 内核中的锁226<br/>7.8.1 锁和单处理器内核227<br/>7.8.2 在中断和进程上下文之间共享自旋锁227<br/>7.8.3 在用户上下文使用锁227<br/>7.9 内核中的睡眠228<br/>7.10 实验7-2:“睡眠设备”模块229<br/>7.10.1 i.MX7D处理器的设备树230<br/>7.10.2 SAMA5D2处理器的设备树231<br/>7.10.3 BCM2837处理器的设备树232<br/>7.10.4 “睡眠设备”模块的代码描述233<br/>7.11 代码清单7-2:int_imx_key_wait.c236<br/>7.12 int_imx_key_wait.ko演示239<br/>7.13 内核线程239<br/>7.14 实验7-3:“keyled类”模块240<br/>7.14.1 i.MX7D处理器的硬件描述240<br/>7.14.2 SAMA5D2处理器的硬件描述241<br/>7.14.3 BCM2837处理器的硬件描述241<br/>7.14.4 i.MX7D 处理器的设备树242<br/>7.14.5 SAMA5D2处理器的设备树245<br/>7.14.6 BCM2837处理器的设备树247<br/>7.14.7 “keyled类”模块的代码描述249<br/>7.15 代码清单7-3:keyled_imx_class.c255<br/>7.16 keyled_imx_class.ko演示264<br/>第8章 在Linux驱动中分配内存266<br/>8.1 查询ARM的MMU转换表267<br/>8.2 Linux地址的类型271<br/>8.3 用户进程的虚拟地址到物理地址的映射273<br/>8.4 内核的虚拟地址到物理地址的映射273<br/>8.5 内核内存分配器275<br/>8.5.1 页面分配器275<br/>8.5.2 页面分配器接口275<br/>8.5.3 SLAB分配器276<br/>8.5.4 SLAB分配器接口278<br/>8.5.5 kmalloc内存分配器279<br/>8.6 实验8-1:“链表内存分配”模块280<br/>8.7 代码清单8-1:linkedlist_imx_platform.c283<br/>8.8 linkedlist_imx_platform.ko演示287<br/>第9章 在Linux设备驱动中使用DMA288<br/>9.1 缓存一致性288<br/>9.2 Linux DMA引擎API289<br/>9.3 实验9-1:“流式DMA”模块295<br/>9.4 代码清单9-1:sdma_imx_m2m.c302<br/>9.5 sdma_imx_m2m.ko演示 306<br/>9.6 DMA分散/聚集映射306<br/>9.7 实验9-2:“分散/聚集DMA设备”模块 307<br/>9.8 代码清单9-2:sdma_imx_sg_m2m.c310<br/>9.9 sdma_imx_sg_m2m.ko演示 315<br/>9.10 用户态DMA315<br/>9.11 实验9-3:“用户态DMA”模块317<br/>9.12 代码清单9-3:sdma_imx_mmap.c319<br/>9.13 代码清单9-4:sdma.c323<br/>9.14 sdma_imx_mmap.ko演示324<br/> 0章 输入子系统设备驱动框架325<br/>10.1 输入子系统驱动程序326<br/>10.2 实验10-1:“输入子系统加速度计”模块327<br/>10.2.1 设备树329<br/>10.2.2 使用I2C交互的输入框架330<br/>10.2.3 使用输入设备的输入框架331<br/>10.3 代码清单10-1:i2c_imx_accel.c334<br/>10.4 i2c_imx_accel.ko演示336<br/>10.5 在Linux中使用SPI337<br/>10.6 Linux的SPI子系统339<br/>10.7 编写SPI从设备驱动程序 342<br/>10.7.1 注册SPI从设备驱动程序 342<br/>10.7.2 在设备树中声明SPI设备343<br/>10.8 实验10-2:“SPI加速度计输入设备”模块346<br/>10.8.1 i.MX7D 处理器的硬件描述347<br/>10.8.2 SAMA5D2处理器的硬件描述 347<br/>10.8.3 BCM2837处理器的硬件描述 348<br/>10.8.4 i.MX7D处理器的设备树348<br/>10.8.5 SAMA5D2处理器的设备树 349<br/>10.8.6 BCM2837处理器的设备树350<br/>10.8.7 “SPI加速度计输入设备”模块的代码描述351<br/>10.9 代码清单10-2:adxl345_imx.c360<br/>10.10 adxl345_imx.ko演示371<br/> 1章 设备驱动中的工业IO 子系统373<br/>11.1 IIO设备的sysfs接口375<br/>11.2 IIO设备通道375<br/>11.3 iio_info数据结构377<br/>11.4 缓冲区378<br/>11.4.1 IIO缓冲区的sysfs接口378<br/>11.4.2 设置IIO缓冲区379<br/>11.4.3 触发器380<br/>11.4.4 触发式缓冲区380<br/>11.5 工业I/O事件382<br/>11.6 IIO工具386<br/>11.7 实验11-1:“IIO子系统DAC”模块386<br/>11.7.1 设备树387<br/>11.7.2 用作I2C交互的工业框架389<br/>11.7.3 用作IIO设备的工业框架389<br/>11.8 代码清单11-1:ltc2607_imx_dual_device.c394<br/>11.9 实验11-2:“SPIDEV双通道ADC用户”应用程序的“IIO子系统DAC”模块397<br/>11.9.1 i.MX7D处理器的硬件描述399<br/>11.9.2 SAMA5D2处理器的硬件描述399<br/>11.9.3 BCM2837处理器的硬件描述399<br/>11.9.4 i.MX7D处理器的设备树400<br/>11.9.5 SAMA5D2处理器的设备树400<br/>11.9.6 BCM2837处理器的设备树401<br/>11.10 代码清单 11-2:LTC2422_spidev.c401<br/>11.11 ltc2607_imx_dual_device.ko配合LTC2422_spidev使用演示404<br/>11.12 实验11-3:“IIO子系统ADC”模块406<br/>11.12.1 设备树406<br/>11.12.2 用作SPI交互的工业框架407<br/>11.12.3 用作IIO设备的工业框架408<br/>11.13 代码清单11-3:ltc2422_imx_dual.c411<br/>11.14 代码清单11-4:ltc2422_app.c413<br/>11.15 ltc2422_imx_dual.ko配合ltc2422_app使用演示414<br/>11.16 实验11-4:“具备硬件触发功能的IIO子系统ADC”模块415<br/>11.16.1 i.MX7D、SAMA5D2和BCM2837处理器的设备树415<br/>11.16.2 驱动里的睡眠和唤醒418<br/>11.16.3 中断管理420<br/>11.17 代码清单11-5:ltc2422_imx_trigger.c420<br/>11.18 ltc2422_imx_trigger.ko配合LTC2422_app使用演示423<br/> 2章 在Linux设备驱动程序中使用regmap API424<br/>12.1 regmap的实现425<br/>12.2 实验12-1:“SPI regmap IIO 设备”模块428<br/>12.3 代码清单12-1:adxl345_imx_iio.c437<br/>12.4 adxl345_imx_iio.ko演示446<br/> 3章 Linux USB设备驱动450<br/>13.1 USB 2.0总线拓扑450<br/>13.2 USB总线枚举和设备布局451<br/>13.3 USB数据传输453<br/>13.4 USB设备类别454<br/>13.5 USB描述符454<br/>13.5.1 USB设备描述符455<br/>13.5.2 USB配置描述符456<br/>13.5.3 USB接口描述符457<br/>13.5.4 USB端点描述符458<br/>13.5.5 USB字符串描述符459<br/>13.5.6 USB HID描述符459<br/>13.6 Linux USB子系统461<br/>13.7 编写Linux USB设备驱动程序462<br/>13.7.1 注册USB设备驱动程序462<br/>13.7.2 Linux主机端数据类型463<br/>13.7.3 USB请求块465<br/>13.8 实验13-1:USB HID设备应用程序468<br/>13.8.1 步骤1:创建一个新工程468<br/>13.8.2 步骤2:配置Harmony469<br/>13.8.3 步骤3:修改生成的代码471<br/>13.8.4 步骤4:声明USB状态机的状态471<br/>13.8.5 步骤5:添加新成员到APP_DATA类型472<br/>13.8.6 步骤6:声明接收缓冲区和发送缓冲区473<br/>13.8.7 步骤7:初始化新成员473<br/>13.8.8 步骤8:处理弹出474<br/>13.8.9 步骤9:处理HID事件474<br/>13.8.10 步骤10:创建USB状态机475<br/>13.8.11 步骤11:调度新的报告接收请求477<br/>13.8.12 步骤12:接收、准备和发送报告478<br/>13.8.13 步骤13:烧写应用程序479<br/>13.9 实验13-2:“USB LED”模块479<br/>13.10 代码清单13-1:usb_led.c483<br/>13.11 usb_led.ko演示485<br/>13.12 实验13-3:“USB LED和开关”模块486<br/>13.13 码清单13-2:usb_urb_int_led.c490<br/>13.14 usb_urb_int_led.ko演示495<br/>13.15 实验13-4:“连接到USB多显LED的I2C”模块496<br/>13.16 代码清单13-3:usb_ltc3206.c505<br/>13.17 usb_ltc3206.ko演示510<br/>附录 将内核模块移植到MicrochipSAMA5D27-SOM1上513<br/>参考文献526<br/>术语表528