《嵌入式软件的时间分析》读书活动:1 第一章读书笔记-基础知识
[复制链接]
本帖最后由 hehung 于 2024-6-25 08:49 编辑
第一章讲解的是基础知识,这部分知识是每个嵌入式软件工程师都应该了解,子章节如下:
1.1 实时系统
1.2 阶段性的软件开发模型——V-Model
1.3 编译过程:从模型到可执行文件
- 1.3.1 基于模型的软件开发和代码生成
- 1.3.2 C 预编译器
- 1.3.3 C 编译器
- 1.3.4 编译器执行的代码优化
- 1.3.5 汇编器
- 1.3.6 链接器
- 1.3.7 定位器
- 1.3.8 链接脚本
- 1.3.9 调试器
1.4 总结
1. 实时系统
很简短的一个章节,说明了实时系统的定义。简而言之就是能够保证时间需求的系统,任何情况下都符合时间需求。
2. V模型
V模型在汽车行业很常见,功能安全要求必须符合V模块开发。
V模型图示如下,项目一般都是现有抽象的需求,根据需求拆解出设计(架构设计,详细设计),然后才是代码的实现以及集成测试,然后是模块测试(单元测试),最后是系统级测试。
3. 编译过程
这一章节对于嵌入式软件开发人员尤其重要,能够学习到一些编译原理相关的知识。
下图展示了编译以及链接过程,我们平时写的C语言代码最终会生成机器码,由机器执行,从C语言代码编程机器码会经过如下几个过程:预编译 -> 编译 -> 汇编 -> 链接 -> 定位,每个流程都有一个单独的工具来实现,只不过我们平时使用的IDE帮我们做了这些事情,实现了一健操作。
- 预编译过程:预编译会处理所有的预编译指令,比如 #define, #include, #if, #else, #endif... ,此过程会将所有的宏进行替换,读取#include包含的全部文件,然后从条件变异种删除不满足的代码;
- 编译过程:预编译的输出会传输给编译器,由编译器生成特定处理器的机器码(汇编代码),此过程并不会定义函数、便来那个、跳转地址等存储地址,只会以符号的形式存储;
- 汇编过程:汇编器将将编译之后的程序代码转换为二进制代码,即目标文件。该过程也不会定义函数、变量、跳转地址;
- 链接过程:链接器将汇编出来的目标文件整合到一个将要完成的程序中,只是仍然没有具体地址。链接过程也会整合一些外部引用库文件,比如.a或者.lib的函数库文件。链接过程也会解析使用到的所有符号(比如函数),会在整合的所有对象中搜索符号,如果搜索到了,则会解析对该符号的引用,如果整合文件中没找到,则会在包含的库文件中查找。如果所有地方都没有搜索到,则会提示“unresolved external <symbolname>”;如果在多个目标文件中都搜索到了,则会提示“redefinieiton of symbol <symbolname>”;
- 定位过程:定位器就是为每一个符号的存储地址进行分配,定位器的输出文件是可执行文件(一般为hex、s19、elf等),一般开发工具中,都将定位器和链接器合并了,统称为链接器。一般工具还可以创建一个map文件,其中包含所有符号的存储位置列表,方便程序员查看。
4. 链接脚本
1.3.8章节讲解了链接脚本,但是比较基础,通过该章节并不能掌握链接相关知识,只能说做一个初学者的入门,不同的编译器的链接脚本的语法都不一定相同,但是基本原理都是类似的。
链接器一般都是和定位器做到一起的,用于将汇编后的代码分配具体的执行位置,使代码能够在单片机上运行。感兴趣的小伙伴可以自行找到GNU或者其他编译器的链接文档学习。
5. 调试器
调试器不属于编译系统的工具链,用来调试器有助于开发人员快速定位问题以及解决问题。
调试器一般可以读取可执行文件(GNU生成的是elf,其他编译器有不同的格式,但一般都提供工具转换成ELF格式),还可以加载源代码,可以逐步指令的让处理器执行代码,并显示每一步在程序中的位置。此外,开发人员也可以看到变量和寄存器的内容。
调试器的运行一般都是访问ELF中的调试信息,一般都是DWARF格式保存的,其中保存了每个存储地址的源文件和行号。
用好调试器也必须结合具体的编译器,需要到编译器的指南文档中进一步学习,本书该章节只是一个入门讲解。
6. 总结
该章节基本上算的上是一个入门讲解,嵌入式开发人员都应当了解,对于调试器,应该熟练掌握,因为没有任何一个程序员可以保证自己开发的代码没有bug,所以就需要借助调试器来解决定位这些bug,并解决这些bug。
|