图书前言

前言

嵌入式技术本质上属于“全栈”技术,不仅需要懂得硬件原理,也需要对软件在硬件中的运行过程了如指掌,因为嵌入式工程师很多时候就是在解决软件世界和硬件世界的衔接问题,是人类和机器的协调者。对于两个世界的思维方式、世界观、边界条件的适用性都要非常熟悉,知道如何解决冲突或进行妥协,这也是嵌入式技术的难点和迷人之处,因此,它要求从业者具备较好的计算机软硬件基础。

本书以嵌入式软件开发中用到的C语言为主线,构建出一条学习路线。C语言本身属于较为底层的高级语言,可以认为它是专为底层和系统层设计的,是唯一能被机器世界和人类世界这一对在计算机发展历史上不断斗争的两方阵营都认可的编程语言。C语言牺牲了一些人类思维所认可的特性,换来了对硬件的完美支持,同样C语言也增加了一些对硬件而言属于“人体工程学”的设计,以提升编程体验,并且没有明显地丧失操作效率。

如果说先有计算机硬件,最原始的编程语言机器码就是“道生一”,汇编语言是“一生二”,而C语言是“二生三”,在C语言之后的编程语言是“三生万物”。笔者在本书的写作过程中也尝试体现出这样的一条演进道路,但愿能对读者有所启迪。

本书主要内容

本书分为扫盲篇、上手篇、提高篇、高级篇和实战篇共5篇。

扫盲篇主要介绍计算机硬件的构成和分类,以及计算机硬件原理。除了大众化的计算机基础知识普及,笔者尝试引入一些生活中可见的技术性话题,例如“为何内存不需要驱动程序?”“I/O设备在计算机硬件中的位置”等,尝试让读者理解计算机硬件世界的一些基本世界观和基本架构。在对这些问题的探讨过程中会描述在计算机系统中是如何通过软硬件的配合实现识别I/O设备、如何通过内存操作I/O设备,以及内存在计算机中的地位。只要这些问题有了答案,读者对硬件世界的恐惧感就会消失,兴趣也会增加。

对以上背景知识有所了解之后,此时虽然还未做具体的编程实践,但已经容易理解从机器码、汇编语言到C语言的演进过程,并明白这样的演进是基于哪些现实条件而得到发展的。计算机如何使用驱动程序操作外设、外设如何和内存产生联系、软件为何要分层及操作系统的作用是什么?这些问题的答案都或多或少地隐藏在计算机硬件的设计思想中。

上手篇属于常规C语言知识介绍,但本书相对于一般的知识性介绍有很大不同,主要在于对一些关键知识点进行了重点讲解,例如“优先级和结合性”“表达式的隐式规则”“位操作”等在嵌入式软件开发中常见,并且对应用开发中不常用的技术点做了详细介绍。除此之外,“二进制、十进制、十六进制之间的转换”“计算机中整数的表示”也是很多初学者应该掌握的知识点,这些知识不牢固会导致在软件开发中常犯数值类型的错误。

提高篇的主题——C代码在运行中,言简意赅地表示本部分和C程序的运行态有关。这部分主要阐述了数据在内存中的组织及存放形式,以及使用这些数据所要遵守的一些规则。

提高篇同样提出了很多人类思维与机器实现之间矛盾处理有关的问题,例如编译器是怎样调和空间效率和电子元器件效率之间的矛盾的?指针访问时数据类型意味着什么?数据的作用域和生命周期如何控制数据的访问权限?在C程序代码变成可执行的机器码的过程中,编译器使用了何种机制实现了代码信息中类似人类世界的角色和地位到冰冷机器世界的转换?为了实现C代码的空间概念,链接器是如何对程序信息进行定义的?为了实现代码的时间概念,栈内存和堆内存在程序的运行中又承担了什么样的角色?而整个C语言程序在内存中是如何被加载运行的?程序又是由哪些不同属性的段组成的?这些段在程序运行过程中承担了什么职责?以及这些职责是如何被确定的?以上一系列问题,在提高篇都进行了详细研究,并给出了解释。

高级篇对函数参数、函数的调用策略、指针高级用法及GCC的一些高级属性有较详细的论述,并再次讨论了程序在内存中运行时的一些深层细节问题。这些深层问题产生的原因、为突破这些限制可以打破的规则及这些被打破的规则在C语言世界中存在的边界条件,在此篇都进行了较为深入的讨论。

当这些边界条件不再适用时,硬件世界给出了何种补救方法?这些补救方法又是如何超越了C语言本身的能力限制,发挥出了硬件的性能?经过此篇的论述,相信读者对此会有更直观的理解。

实战篇不再讲述C语言和计算机硬件的知识,转而对职业方向、编译管理方法等职场背景知识做出了较详细的描述。经过此部分的学习,相信读者会对嵌入式工程师的职业风格有一定了解,从而更好地迈入嵌入式世界的大门。

阅读建议

零基础或者基础较差者建议从扫盲篇开始按顺序阅读,具有一定基础者可酌情跳过相关章节。

资源下载提示

素材(源码)等资源: 扫描目录上方的二维码下载。

视频等资源: 扫描封底的文泉云盘防盗码,再扫描书中相应章节的二维码,可以在线学习。

致谢

感谢我的助手、妻子,在本书成书期间承担了较多的辅助性工作。

由于时间仓促,书中难免存在疏漏之处,请读者见谅,并提出宝贵意见。

孟皓2025年4月