课程简介
嵌入式系统在现实生活中随处可见,大到航天、汽车、通讯系统,小到手机、机顶盒,等等。嵌入式软件开发作为软件行业的一个分枝,也面临着其它软件领域所面临的各种挑战 —— 如何快速上市?如何保证交付软件的最终质量?如何帮助工程师在工作与生活间取得平衡?等等。由于嵌入式软件开发是一个软硬件结合非常紧密的领域,这也使得其面临更大的挑战 —— 软件的可开发性问题可能很突出、对开发人员的综合能力要求更高。
从事嵌入式软件开发,最困难的莫过于学习操作系统原理和处理器方面的知识。讲解操作系统原理如果以Linux、Windows CE、VxWorks等成熟的操作系统为素材并不好,因为它们太大,很容易让人“只见森林不见树木”,也容易让人望而生畏而失去学习的兴趣和信心。从软件开发的角度来看,操作系统的概念和实现原理一旦掌握,不论基于哪一个操作系统做开发都只是调用不同的函数而已。为了让学员获得最好的学习体验,本课程以讲师自己设计的一个实现简洁、完整的“实时”操作系统 —— ClearRTOS,为基础,通过渐进式的方式细致地讲解操作系统的概念和实现原理。至于处理器方面的知识,本课程没有针对某一具体处理器,而是就编程方面所需的通用知识进行了讲解。对这些通用知识的掌握,将使得处理器对于学员不再那么神秘。
与非嵌入式软件开发采用集成开发环境不同,嵌入式软件开发大多是基于命令行的。软件开发工程师除了进行编码工作,还得能驾驭自己的编译环境并运用其他的开发工具辅助开发工作。本课程以来自GNU的工具为例帮助学员战胜这一挑战。
要实现高质高效地从事软件开发工作,工程师还必须理解软件设计的重要性,并借助一定的质量保证方法论来提高工作质量和效率。软件设计和质量保证方法论是业内比较抽象和高级的话题,为此本课程通过带领实践的方式逐步展开讲解,以帮助学员获得一些实用的设计原则、最佳实践和一套有效的质量保证方法论。
目标收益
掌握嵌入式软件开发所需的与处理器相关的通用知识。
明白信号完整性对嵌入式软件开发的影响。
掌握嵌入式软件开发所需掌握的GNU工具。包括gcc、binutils和ld。
实现更加深入地理解C编程语言。
了解引导加载器的大致工作原理和功能。
掌握实时操作系统的设计和实现原理。主要聚集于讲解多任务原理。
理解设计是软件质量之本,并掌握一种有效的模块管理、错误管理和目录结构管理方法。
理解什么是可开发性问题和了解一种解决方法。
理解平台与框架开发是打造高质量软件之路。
理解软件开发的困难和质量保证需要系统性的方法论。
理解软件工程的工作习惯对软件质量的影响。掌握一些终身受用的编程好习惯。
理解单元测试的重要性,并掌握一种简单有效的部署方法。
理解代码覆盖、静态分析和动态分析对构建高质软件的重要性。
培训对象
以C为编程语言的嵌入式和非嵌入式软件开发工程师。
部分内容适合软件质量相关管理人员。
课程大纲
关于行业和职业发展的思考 |
1. 工程师要掌握的终极技术是什么 2. 自己在行业中处于什么层次,又应向哪发展 3. 我应走技术线,还是技术管理线 4. 出色技术团队的关键要素是什么 |
掌握处理器的基本概念 |
1. 如何区分微处理器与微控制器 2. 寄存器的分类和常用寄存器 3. 处理器是如何启动的 4. 什么是外设的输入与输出 5. 指令与数据分别是什么 6. 为什么要有中断 7. 字节序的原理 8. 数据边界对齐为何能提高程序的性能 9. 断点的实现原理和作用是什么 10. 内存管理单元有什么用处 11. 为什么要有缓存 |
警惕硬件不稳定而导致软件问题 |
1. 两个软件异常案例背后的原因是什么 2. 信号完整性为何会导致软件问题 3. 有哪些应对信号完整性问题的方法 |
Gcc 编译器的工作流程和常用选项 |
1. 什么是交叉编译和交叉编译环境 2. Gcc 在幕后是如何工作的 3. 掌握 gcc 选项以便改善工作效率 |
通过 bintuils 工具集改善工作效率 |
1. addr2line,指令地址翻译器 2. ar,静态库生成器 3. nm,符号显示器 4. objdump,信息查看器 5. objcopy,段剪辑器 6. size,段大小观察器 7. strings,字符串窥视器 8. strip,程序文件瘦身器 |
链接器的关键概念 |
1. 什么是重定位 2. 如何读懂链接脚本 |
掌握必要的汇编知识 |
1. AT&T 和 Intel 汇编语法的区别 2. As 汇编器的语法 3. 如何在 C 程序中嵌入汇编 |
理解程序的结构 |
1. 什么是段 2. 栈的概念和用处是什么 3. 堆的作用 |
ABI 和 EABI 规范解析 |
1. C 语言中的数据类型与 CPU 是如何映射的 2. 字节对齐的规范从哪来 3. 寄存器的功能如何定义 4. 栈帧的作用和生命周期是什么 5. 理解栈溢出攻击 |
混淆指针与数组所导致问题的分析与预防 |
1. 问题示例 2. 问题分析 3. 问题成因 4. 如何完全杜绝这一问题 |
深刻理解 volatile 的使用场景 | 从例子理解volatile |
软件设计的内涵与设计原则 |
1. 软件设计是什么 2. 软件质量的概念 3. 阻碍改善软件设计的常见观念 4. 如何提高软件设计能力 5. 设计模式、设计原则和设计思想三者是什么关系 6. 放之四海皆适用的设计原则 7. 对软件技术发展驱动力的思考 |
重视模块管理保障系统有序运行 |
1. 为什么要模块管理参照系 2. 模块管理设计的一种思路 3. 一些思考 |
错误管理是不可或缺的用户需求 |
1. 错误管理的现状与出路 2. 表达错误的一种通用方法 3. 优化错误日志提高查错效率的一种思路 |
重视代码目录结构管理 |
1. 规划代码目录结构的意义 2. 出色代码目录结构的特点 3. 一个示例 |
平台与框架开发是高质量软件打造之路 |
1. 系统库、平台和框架的区别 2. 平台与框架开发的本质和优点 3. 平台与框架的架构模型 4. 平台与框架开发的困境与生命周期理论 |
落实可开发性设计提升开发效率 |
1. 什么是可开发性问题 2. 可开发性设计的内涵 3. 引入设备抽象层解决可开发性问题 4. 更复杂的设备抽象层 5. 图形界面的可开发性设计 6. 其他可开发性设计 |
引导加载器 boot loader 的作用与原理 |
1. 引导加载器的功能是什么 2. 引导加载器的文件存储布局 3. 程序加载原理 4. 引入引导加载器的优点 |
任务调度原理 |
1. 什么是任务情景 2. 任务情景切换原理 3. 任务调度原理 4. 任务的生命周期 5. 任务竞争问题与中断控制 6. 任务与中断状态 |
质量保证的困境和应对方法 |
1. 软件开发的特点是什么 2. 保证质量的关键要素有哪些 3. 质量保证需要系统性的方法论 4. 走出质量困境的指导性思想 |
编程好习惯是质量保证的基本条件 | 编程习惯实例讲解 |
单元测试是一种非常有效的质量保证方法 |
1. 警惕单元测试无用论 2. 一个简单但不完善的单元测试例子 3. 构建单元测试框架 4. 无缝整合单元测试提升工程效率 5. 几个实施问题 6. 桩函数和打桩 7. 通过错误注入提升软件的可测试性 8. 平台开发与单元测试如何结合 9. 什么是被测行为的确定性 10. 被测用例的有效性 |
通过代码覆盖衡量单元测试效果 |
1. 代码覆盖工具介绍 2. 无缝整合代码覆盖提升工程效率 3. 代码覆盖有哪些度量指标 |
关于行业和职业发展的思考 1. 工程师要掌握的终极技术是什么 2. 自己在行业中处于什么层次,又应向哪发展 3. 我应走技术线,还是技术管理线 4. 出色技术团队的关键要素是什么 |
掌握处理器的基本概念 1. 如何区分微处理器与微控制器 2. 寄存器的分类和常用寄存器 3. 处理器是如何启动的 4. 什么是外设的输入与输出 5. 指令与数据分别是什么 6. 为什么要有中断 7. 字节序的原理 8. 数据边界对齐为何能提高程序的性能 9. 断点的实现原理和作用是什么 10. 内存管理单元有什么用处 11. 为什么要有缓存 |
警惕硬件不稳定而导致软件问题 1. 两个软件异常案例背后的原因是什么 2. 信号完整性为何会导致软件问题 3. 有哪些应对信号完整性问题的方法 |
Gcc 编译器的工作流程和常用选项 1. 什么是交叉编译和交叉编译环境 2. Gcc 在幕后是如何工作的 3. 掌握 gcc 选项以便改善工作效率 |
通过 bintuils 工具集改善工作效率 1. addr2line,指令地址翻译器 2. ar,静态库生成器 3. nm,符号显示器 4. objdump,信息查看器 5. objcopy,段剪辑器 6. size,段大小观察器 7. strings,字符串窥视器 8. strip,程序文件瘦身器 |
链接器的关键概念 1. 什么是重定位 2. 如何读懂链接脚本 |
掌握必要的汇编知识 1. AT&T 和 Intel 汇编语法的区别 2. As 汇编器的语法 3. 如何在 C 程序中嵌入汇编 |
理解程序的结构 1. 什么是段 2. 栈的概念和用处是什么 3. 堆的作用 |
ABI 和 EABI 规范解析 1. C 语言中的数据类型与 CPU 是如何映射的 2. 字节对齐的规范从哪来 3. 寄存器的功能如何定义 4. 栈帧的作用和生命周期是什么 5. 理解栈溢出攻击 |
混淆指针与数组所导致问题的分析与预防 1. 问题示例 2. 问题分析 3. 问题成因 4. 如何完全杜绝这一问题 |
深刻理解 volatile 的使用场景 从例子理解volatile |
软件设计的内涵与设计原则 1. 软件设计是什么 2. 软件质量的概念 3. 阻碍改善软件设计的常见观念 4. 如何提高软件设计能力 5. 设计模式、设计原则和设计思想三者是什么关系 6. 放之四海皆适用的设计原则 7. 对软件技术发展驱动力的思考 |
重视模块管理保障系统有序运行 1. 为什么要模块管理参照系 2. 模块管理设计的一种思路 3. 一些思考 |
错误管理是不可或缺的用户需求 1. 错误管理的现状与出路 2. 表达错误的一种通用方法 3. 优化错误日志提高查错效率的一种思路 |
重视代码目录结构管理 1. 规划代码目录结构的意义 2. 出色代码目录结构的特点 3. 一个示例 |
平台与框架开发是高质量软件打造之路 1. 系统库、平台和框架的区别 2. 平台与框架开发的本质和优点 3. 平台与框架的架构模型 4. 平台与框架开发的困境与生命周期理论 |
落实可开发性设计提升开发效率 1. 什么是可开发性问题 2. 可开发性设计的内涵 3. 引入设备抽象层解决可开发性问题 4. 更复杂的设备抽象层 5. 图形界面的可开发性设计 6. 其他可开发性设计 |
引导加载器 boot loader 的作用与原理 1. 引导加载器的功能是什么 2. 引导加载器的文件存储布局 3. 程序加载原理 4. 引入引导加载器的优点 |
任务调度原理 1. 什么是任务情景 2. 任务情景切换原理 3. 任务调度原理 4. 任务的生命周期 5. 任务竞争问题与中断控制 6. 任务与中断状态 |
质量保证的困境和应对方法 1. 软件开发的特点是什么 2. 保证质量的关键要素有哪些 3. 质量保证需要系统性的方法论 4. 走出质量困境的指导性思想 |
编程好习惯是质量保证的基本条件 编程习惯实例讲解 |
单元测试是一种非常有效的质量保证方法 1. 警惕单元测试无用论 2. 一个简单但不完善的单元测试例子 3. 构建单元测试框架 4. 无缝整合单元测试提升工程效率 5. 几个实施问题 6. 桩函数和打桩 7. 通过错误注入提升软件的可测试性 8. 平台开发与单元测试如何结合 9. 什么是被测行为的确定性 10. 被测用例的有效性 |
通过代码覆盖衡量单元测试效果 1. 代码覆盖工具介绍 2. 无缝整合代码覆盖提升工程效率 3. 代码覆盖有哪些度量指标 |