
本书基于典型的ARM处理器和Linux嵌入式系统讲解嵌入式系统基本原理、软件架构和应用设计等相关知识。基于长期的嵌入式系统开发和教学经验,作者从嵌入式系统研发初学者角度出发,以掌握嵌入式系统设计需要的基础知识、软件架构、设计方法等为目标,将嵌入式系统的基础与原理、软件架构、实践编程方法和嵌入式系统实际应用开发结合起来,形成一套完整的嵌入式系统原理、设计与开发的教学内容。本书结构合理、层次清晰,易于理解和学习,主要内容包括:嵌入式系统基础,Linux操作系统基础与内核,Linux驱动程序结构、开发与典型驱动程序开发实例,Linux系统移植与应用程序开发实例等。本书可供高等学校计算机、电子工程、自动化与控制类等专业的本科高年级学生作为教学参考书使用,也可供人工智能、机器人、智能网联汽车等相关专业方向的硕士研究生参考。
序 言 嵌入式系统技术在大多数行业都得到了广泛应用,行业对嵌入式系统开发人才的需求逐年增加。面向嵌入式系统开发的参考书籍与教材也是百花齐放、种类繁多。对于高校教师和学生,选择一本符合本专业培养目标的教材是一件比较困难的事。对于老师,既要考虑学生能够容易理解、掌握嵌入式系统原理和关键知识点,又要能够培养学生的实践和创新能力,这一点通过一本教材的内容是很难在有限的时间里办到的。对于初学者,需要一本好的参考书,这本书既能够系统地把嵌入式系统相关的知识说清楚,又能引导初学者学到有用的知识和技能,掌握嵌入式系统的学习方法,为后续学习打下良好的基础。嵌入式系统课程本身就是一门多学科交叉的课程,涵盖了电子技术、微机原理、高级编程语言、操作系统等课程内容,还涉及实践编程环节。要想在一本参考书中把所有这些知识都讲清楚是一件非常难的事。同时,不同读者的基础不同,学习需求也不一样。因此,针对电子信息专业类初学者,作者经过多年教学总结和科研成果,从应用开发和初学者的角度,结合嵌入式系统的关键技术原理编著本书,力求以最简洁的内容讲解嵌入式系统原理及开发相关的主要知识,把嵌入式系统相关知识结合具体操作系统和处理器进行分析讲解,让读者既能够学到嵌入式系统原理知识,又能够掌握具体的嵌入式系统软件开发方法,以便后续能够持续学习。 随着设备智能化、网联化的推广,基于ARM处理器和Linux的嵌入式系统开发越发广泛,对Linux的嵌入式开发人才需求量越来越大。鉴于此,本书以成熟的ARM处理器和Linux内核为基础,结合嵌入式系统基础知识和模块原理,对系统启动、驱动程序、嵌入式系统软件框架和实现难点进行分析,然后以具体实例进行讲解。 全书共10章。第1章讲解嵌入式系统基本概念、基础知识、嵌入式可执行代码生成流程与代码结构、交叉开发模式等内容;第2章结合嵌入式处理器基础知识,讲解ARM处理器的体系架构、编程模型、内存管理与异常处理等内容,为系统启动、内核移植与驱动程序开发等内容的理解打下基础;第3章主要讲解操作系统基础知识、Linux文件系统与模块机制等内容,为后续Linux内核的学习打下基础;第4章主要讲解Linux的内核结构、进程管理、内存管理、虚拟文件系统、进程间通信等几个方面,分析Linux内核各模块的作用与工作原理,为驱动程序与应用程序开发学习提供支撑;第5章主要讲解Linux设备驱动程序结构,重点分析内核设备模型、驱动程序结构、platform 总线与设备管理、设备树等内容,为后续字符设备与块设备驱动程序的学习打下理论基础;第6章首先分析字符设备的驱动程序结构、关键的数据结构和模块注册与卸载方法;然后以基于GPIO的LED驱动程序和基于platform总线的UART驱动程序为例,讲解典型字符设备驱动程序的主要开发流程、程序编写方法和关键数据操作;第7章针对块设备驱动程序的编写方法进行分析,从内核关键数据结构、操作传递过程分析讲解块设备驱动程序的主要软件结构层次、数据结构与重要函数接口、块设备管理与操作,然后以RAM驱动程序为例,分析说明块设备驱动程序的实现步骤与方法;第8章主要介绍网络设备驱动设计方法,首先分析网络设备驱动程序的数据结构、管理和控制操作方法等,然后以以太网设备驱动程序为例讲解网络设备的驱动程序结构与编写方法;第9章主要讲解Linux移植与系统启动,该部分内容是Linux应用的一个难点,主要涉及系统启动、内核裁剪、根文件系统移植等部分,搭建Linux程序正常运行的基本环境;第10章首先综合分析程序、进程与线程的关系,讲解线程管理方法;然后以OBU应用编程为例,讲解Linux应用层软件结构、开发的流程、进程与线程的创建方法、进程与线程的通信编程等,为读者提供应用程序开发样例。 在编排方面,整本书先分析讲解模块结构与原理,然后结合软件结构分析讲解实例,并将理论与应用实践充分结合起来,让初学者从粗到细、从原理到实例进行学习,这样更容易掌握和理解嵌入式系统关键知识和程序编写方法。 我们对参与资料整理的何浩、李振东、罗小龙、马万路、梁大彬、曾鑫、赵健宽、杨谊、王建军、林家瑞、连皓宁、王章琦、李蔚敏等同学表示感谢!同时感谢重庆邮电大学自动化学院的领导、自动控制与机器人工程系的同事,感谢他们在本书编著过程中给出的宝贵建议和无私帮助。编著过程中,我们参考了大量网上资料和文献,通过这些参考资料,我们能够以浅显的描述使本书内容在一些细节上更加完美,对这些文献作者的支持和贡献表示感谢! 虽然我们在编著过程中力求完美,但书中难免存在不足和错误,请读者给予指正和建议。在此,我们表示衷心的感谢!
目 录 第1章 嵌入式系统基础 (1) 1.1 嵌入式系统概述 (1) 1.1.1 嵌入式系统基本概念 (1) 1.1.2 嵌入式系统的分类 (4) 1.1.3 嵌入式系统的现状和趋势 (9) 1.2 嵌入式系统基础知识 (11) 1.2.1 嵌入式系统基本组成 (12) 1.2.2 嵌入式处理器概述 (13) 1.2.3 嵌入式操作系统概述 (15) 1.3 嵌入式可执行代码生成流程与代码结构 (20) 1.3.1 嵌入式可执行代码生成流程 (20) 1.3.2 嵌入式软件代码结构 (22) 1.4 嵌入式软件交叉开发模式 (26) 1.4.1 交叉开发模式概述 (26) 1.4.2 调试通信端口与协议 (27) 作业 (30) 第2章 ARM处理器体系架构 (31) 2.1 嵌入式处理器基础 (31) 2.1.1 处理器的结构 (31) 2.1.2 处理器指令执行过程 (32) 2.1.3 微处理器的体系结构 (34) 2.2 ARM体系架构与编程模型 (37) 2.2.1 ARM处理器体系架构概述 (37) 2.2.2 ARM编程模型 (40) 2.3 ARM处理器内存管理 (46) 2.3.1 内存映射 (46) 2.3.2 集成外设寄存器访问方法 (48) 2.4 ARM异常处理 (50) 2.4.1 ARM处理器异常类型 (50) 2.4.2 ARM处理器对异常的响应 (51) 2.4.3 ARM系统的中断编程机制 (53) 作业 (57) 第3章 Linux操作系统基础知识 (58) 3.1 操作系统基础知识 (58) 3.1.1 操作系统主要功能 (59) 3.1.2 嵌入式操作系统基本概念 (60) 3.2 嵌入式Linux简介 (69) 3.2.1 Linux内核版本与分类 (69) 3.2.2 Linux系统结构 (71) 3.2.3 嵌入式Linux特点 (72) 3.3 Linux文件系统 (73) 3.3.1 Linux文件系统基本作用 (73) 3.3.2 Linux常见文件系统简介 (73) 3.3.3 Linux文件系统框架 (76) 3.3.4 Linux文件操作函数 (78) 3.4 Linux模块机制 (82) 3.4.1 Linux模块概述 (82) 3.4.2 Linux模块代码结构 (83) 3.4.3 模块加载 (84) 3.4.4 模块卸载 (85) 作业 (86) 第4章 ARM体系结构的Linux内核 (87) 4.1 ARM-Linux内核简介 (87) 4.1.1 ARM-Linux内核和普通Linux内核的区别 (87) 4.1.2 ARM-Linux代码结构与内核组成 (88) 4.2 ARM-Linux进程管理与调度 (91) 4.2.1 进程的表示和生命周期 (91) 4.2.2 Linux进程创建、执行和销毁 (97) 4.2.3 Linux进程调度 (101) 4.3 ARM-Linux内存管理 (105) 4.3.1 内存管理基本概念 (105) 4.3.2 ARM-Linux存储机制 (107) 4.3.3 虚拟内存管理 (109) 4.4 ARM-Linux虚拟文件系统 (111) 4.4.1 虚拟文件系统介绍 (111) 4.4.2 虚拟文件系统数据结构 (112) 4.4.3 基于虚拟文件系统的文件I/O操作 (118) 4.5 ARM-Linux进程间通信 (121) 4.5.1 进程间通信的目的 (121) 4.5.2 进程间通信的方式 (121) 作业 (130) 第5章 Linux设备驱动程序结构 (131) 5.1 Linux设备驱动程序简介 (131) 5.1.1 Linux设备分类 (131) 5.1.2 设备文件与设备号 (133) 5.1.3 Linux设备驱动程序代码分布与特点 (134) 5.2 Linux内核设备模型 (135) 5.2.1 设备模型建立的目的 (135) 5.2.2 设备拓扑结构 (135) 5.2.3 设备模型 (136) 5.3 Linux设备驱动程序结构 (139) 5.3.1 Linux设备驱动程序分层思想 (139) 5.3.2 Linux总线设备驱动程序注册与注销 (140) 5.3.3 设备打开与关闭 (144) 5.3.4 设备操作函数 (145) 5.3.5 设备中断与轮询处理 (147) 5.4 platform总线与设备管理 (151) 5.4.1 platform总线的定义 (151) 5.4.2 platform总线设备重要数据结构与函数 (153) 5.4.3 platform总线设备驱动程序实例 (158) 5.5 设备树 (160) 5.5.1 设备树的基本概念及作用 (160) 5.5.2 DTS、DTB和DTC (161) 5.5.3 DTS语法 (162) 5.5.4 设备与驱动程序的匹配 (170) 作业 (173) 第6章 字符设备驱动程序与应用实例 (174) 6.1 字符设备驱动程序结构分析 (174) 6.1.1 字符设备驱动程序框架 (174) 6.1.2 字符设备驱动程序组成 (175) 6.2 GPIO设备驱动程序实例—LED驱动程序 (185) 6.2.1 寄存器地址映射 (186) 6.2.2 修改设备树文件 (187) 6.2.3 LED驱动程序实例分析 (188) 6.3 基于platform总线的UART驱动程序实例 (195) 6.3.1 UART工作原理 (195) 6.3.2 Linux UART驱动程序结构分析 (196) 6.3.3 I.MX6U UART驱动程序分析 (202) 作业 (211) 第7章 块设备驱动程序与应用实例 (212) 7.1 块设备驱动程序框架 (212) 7.1.1 块设备数据交换方式 (212) 7.1.2 块设备读写请求 (214) 7.2 块设备驱动程序数据结构与函数 (216) 7.2.1 gendisk数据结构与操作 (217) 7.2.2 request数据结构与操作 (220) 7.2.3 request_queue数据结构与操作 (223) 7.2.4 bio数据结构与操作 (226) 7.3 块设备管理与操作 (229) 7.3.1 块设备的注册与注销 (229) 7.3.2 块设备初始化与卸载 (230) 7.3.3 块设备操作 (232) 7.4 RAM驱动程序实例 (234) 7.4.1 SDRAM简介 (234) 7.4.2 基于请求队列的RAM驱动程序实例 (235) 作业 (241) 第8章 网络设备驱动程序与应用实例 (242) 8.1 Linux网络设备驱动程序框架 (242) 8.1.1 网络设备驱动程序框架 (242) 8.1.2 网络设备驱动程序重要数据结构 (243) 8.1.3 网络设备管理 (254) 8.1.4 网络设备数据收发 (264) 8.2 I.MX6ULL以太网驱动程序实例分析 (269) 8.2.1 I.MX6ULL网络外设设备树 (269) 8.2.2 I.MX6ULL网络驱动程序源码简析 (272) 8.2.3 fec_netdev_ops操作集 (280) 作业 (285) 第9章 Linux移植与系统启动 (286) 9.1 Linux系统启动与U-Boot (287) 9.1.1 Bootloader的选择 (287) 9.1.2 U-Boot编译流程分析 (289) 9.1.3 I.MX6 U-Boot启动流程 (294) 9.2 Linux内核裁剪 (298) 9.2.1 内核配置过程分析 (298) 9.2.2 内核编译过程分析 (302) 9.2.3 内核启动过程分析 (305) 9.2.4 内核移植过程 (319) 9.3 Linux根文件系统移植 (323) 9.3.1 根文件系统概述 (323) 9.3.2 编译Busybox构建根文件系统 (326) 9.3.3 根文件系统的启动过程分析 (335) 作业 (336) 第10章 Linux应用编程与实例 (337) 10.1 程序、进程与线程 (337) 10.1.1 程序和进程 (337) 10.1.2 进程和线程 (338) 10.2 线程管理 (339) 10.2.1 线程创建 (339) 10.2.2 线程管理 (342) 10.2.3 一个实例 (344) 10.3 C-V2X OBU应用编程实例 (345) 10.3.1 C-V2X OBU功能分析与软件架构 (345) 10.3.2 应用程序设计 (349) 10.3.3 V2X消息接收线程 (353) 10.3.4 防撞预警线程 (357) 10.3.5 V2N通信线程 (360) 作业 (367) 参考文献 (368)