第 1 部分 RTOS、开发板与工具简介
第 1 章 实时系统简介 ..................... 2
1.1 究竟什么是“实时”............. 2
1.1.1 时序要求的范围......... 3
1.1.2 保证实时行为的方法 5
1.2 硬件与软件在实时系统中的作用........................ 5
1.2.1 纯硬件实现................. 5
1.2.2 底层固件实现............. 6
1.2.3 基于 RTOS 的固件..... 6
1.2.4 基于 RTOS 的软件..... 7
1.2.5 精心设计的操作系统软件 ....................... 7
1.3 RTOS 的定义 .......................... 8
1.3.1 硬实时系统................. 9
1.3.2 固实时系统................. 9
1.3.3 软实时系统............... 10
1.4 实际应用中的实时系统....... 10
1.4.1 RTOS 的类型范围.... 10
1.4.2 本书使用的 RTOS.... 11
1.5 选择 RTOS ............................ 12
1.6 总结 ........ 13
第 2 章 开发板简介 ........................ 15
2.1 开发板概述 ........................... 15
2.2 了解开发板的组件 ............... 17
2.2.1 MCU ......................... 17
2.2.2 CPU ........................... 18
2.2.3 MCU 区域的其他组件 ........................... 19
2.2.4 ST-LINK 调试探针 .. 19
2.3.1 MCU 产品系列 ........ 23
2.3.2 MCU 型号命名规则 24
2.3.3 开发板产品系列与型号命名规则 ......... 24
2.4 总结 ........ 25
第 3 章 开发工具介绍 ................... 26
3.1 本书说明与示例程序的使用方法...................... 27
3.2 IDE 与示例程序 ................... 28
3.2.1 STM32CubeIDE 简介 ............................. 28
3.2.2 STM32CubeIDE 的安装 ......................... 28
3.2.3 本书示例程序的安装 ............................. 29
3.2.4 Project Explorer 的使用 .......................... 32
3.2.5 编辑器的使用........... 32
3.2.6 项目的构建............... 33
3.3 J-Link、Ozone 与 SystemView 等调试工具 ..... 33
3.3.1 SEGGER J-Link 的使用 ......................... 34
3.3.2 工具的下载与安装... 34
3.3.3 将 ST-LINK 转换为 J-Link ..................... 34
3.3.4 SEGGER Ozone 的使用 ......................... 35
3.3.5 SEGGER SystemView 的使用................ 39
3.4 总结 ........ 42
第 4 章 理解超级循环 ................... 43
4.1 超级循环简介 ....................... 43
4.1.1 基本的超级循环....... 44
4.1.2 实时系统中的超级循环 ......................... 45
4.2 利用中断改进超级循环....... 46
4.2.1 中断简介................... 46
4.2.2 理解 ISR 与抖动 ...... 47
4.2.3 中断与超级循环....... 48
4.3 为超级循环添加定时器....... 49
4.3.1 让定时超级循环进入休眠状态 ............. 50
4.3.2 利用定时超级循环的特性 ..................... 52
4.3.3 时序相关的性能分析 ............................. 55
4.4 总结 ........ 56
第 5 章 实现超级循环 ................... 57
5.1 超级循环示例程序 ............... 57
5.1.2 示例程序的工作原理 ............................. 58
5.1.3 设计与测试注意事项 ............................. 65
5.1.4 运行示例程序........... 66
5.2 了解系统 API 与硬件特性 .. 67
5.2.1 HAL_DBGMCU_EnableDBGSleepMode ............................. 67
5.2.2 disable_irq ............. 68
5.3 超级循环程序的开发方法... 70
5.3.1 创建超级循环程序... 70
5.3.2 安装并配置调试器软件 ......................... 74
5.3.3 构建并运行固件....... 76
5.3.4 使用示波器测量时序 ............................. 76
5.4 总结 ........ 78
第 2 部分 FreeRTOS 调度器、任务与核心 API
第 6 章 理解 RTOS 任务............. 80
6.1 FreeRTOS 调度器与任务:概念概述................ 81
6.1.1 为何需要舍弃单纯的超级循环 ............. 81
6.1.2 RTOS 任务与超级循环函数的对比 ...... 82
6.1.3 将超级循环函数转换为 RTOS 任务 ..... 83
6.2 选择 FreeRTOS 作为 RTOS . 88
6.3 FreeRTOS 调度器与任务实战............................ 89
6.3.1 示例程序的理解与使用 ......................... 89
6.3.2 FreeRTOS 的安装与配置 ....................... 98
6.4 总结 ...... 100
第 7 章 运行 FreeRTOS 调度器 ........................... 101
7.1 创建任务与启动调度器..... 102
7.1.1 初始化硬件............. 102
7.1.2 定义任务函数......... 102
7.1.3 创建任务................. 105
7.1.4 检查返回值............. 106
7.1.5 启动调度器............. 107
7.2 删除任务 ............................. 108
7.2.1 任务自行删除......... 108
7.2.2 从其他任务删除任务 ........................... 108
7.3 代码实践 ............................. 109
7.3.1 构建并运行代码....................... 109
7.3.2 Ozone 的其他功能 . 110
7.3.3 使用 SystemView 分析任务执行 ......... 111
7.4 理解调度器 ......................... 113
7.4.1 理解 FreeRTOS 任务的状态 ................ 114
7.4.2 空闲任务................. 115
7.4.3 调度器的运行机制与运行时机 ........... 117
7.4.4 调度器架构............. 118
7.5 任务实现与问题排查......... 120
7.5.1 任务内存分配......... 120
7.5.2 内存保护任务的创建 ........................... 121
7.5.3 任务创建方式汇总. 121
7.5.4 优化任务状态......... 122
7.5.5 任务启动问题排查. 123
7.6 总结 ...... 125
第 8 章 数据保护与任务同步 .... 126
8.1 运行本章的示例程序......... 126
8.2 信号量—用于任务同步. 128
8.2.1 理解信号量............. 128
8.2.2 使用信号量............. 131
8.3 优先级翻转—信号量的错误使用方式........ 140
8.3.1 理解优先级翻转..... 140
8.3.2 优先级翻转示例程序 ........................... 141
8.4 互斥锁—增强型信号量. 145
8.4.1 理解互斥锁............. 145
8.4.2 解决优先级翻转的示例程序 ............... 146
8.4.3 避免互斥锁获取超时 ........................... 148
8.5 竞态条件—任务未正确同步时引发............ 149
8.5.1 使用互斥锁和信号量避免竞态条件 ... 149
8.5.2 竞态条件示例......... 150
8.6 软件定时器 ......................... 152
8.6.1 理解软件定时器..... 152
8.6.2 示例程序:一次性定时器与周期性定时器 ...................... 153
8.6.3 软件定时器使用准则 ........................... 156
8.7 总结 ...... 157
第 9 章 任务间通信...................... 158
9.1 理解 RTOS 队列 ................. 158
9.1.2 简单队列:接收数据项 ....................... 159
9.1.3 满队列:发送数据项 ........................... 159
9.1.4 空队列:接收数据项 ........................... 160
9.1.5 用于任务间通信的队列 ....................... 161
9.2 通过队列按值传递数据..... 162
9.2.1 按值传递 1 字节数据 ........................... 163
9.2.2 按值传递复合数据类型 ....................... 165
9.2.3 理解队列对执行流程的影响 ............... 168
9.2.4 示例的重要说明..... 169
9.3 通过队列按引用传递数据. 170
9.3.1 何时按引用传递..... 170
9.3.2 按值传递................. 171
9.3.3 按引用传递............. 171
9.3.4 重要说明................. 173
9.4 任务通知 ............................. 173
9.4.1 使用任务通知传递简单数据 ............... 174
9.4.2 任务通知的其他操作 ........................... 175
9.4.3 任务通知与队列的对比 ....................... 175
9.4.4 索引式任务通知..... 176
9.5 总结 ...... 177
第 3 部分 利用 FreeRTOS 构建系统
第 10 章 驱动程序与 ISR .......... 180
10.1 UART 简介 ....................... 180
10.2 创建轮询式 UART 驱动程序 ......................... 185
10.2.1 理解示例程序 ..... 185
10.2.2 运行示例程序 ..... 186
10.2.3 性能分析 ............. 187
10.2.4 轮询式驱动程序的优缺点 ................ 189
10.2.5 轮询式驱动程序的适用场景 ............ 189
10.3 FreeRTOS 任务与 ISR 的对比 ....................... 190
10.3.1 任务与 ISR 的区别............................ 190
10.3.2 在 ISR 中调用 FreeRTOS API .......... 192
10.3.3 配置用于 FreeRTOS 的中断 ............. 192
10.4 创建基于 ISR 的驱动程序 ............................. 195
10.4.1 基于队列的驱动程序 ........................ 195
10.4.3 基于缓冲区的驱动程序 .................... 201
10.4.4 性能分析 ............. 204
10.5 总结 .... 205
第 11 章 更高效的驱动程序与 ISR ....................... 206
11.1 构建基础的基于 DMA 的驱动程序 .............. 206
11.1.1 DMA 概念介绍... 207
11.1.2 配置 DMA 外设.. 208
11.1.3 启动 DMA 接收.. 212
11.1.4 基于 DMA 的缓冲区驱动程序......... 213
11.1.5 性能分析 ............. 214
11.2 构建增强型的基于 DMA 的驱动程序 .......... 217
11.2.1 流缓冲区介绍 ..... 217
11.2.2 双缓冲 DMA 介绍............................. 220
11.2.3 驱动程序的实现 . 221
11.2.4 流缓冲区的优化方案 ........................ 227
11.3 驱动模型的选择 ............... 228
11.3.1 驱动模型选型的核心问题 ................ 228
11.3.2 驱动模型选型的经验法则 ................ 231
11.4 选用第三方库和驱动程序 .............................. 232
11.5 总结 .... 233
第 12 章 在任务间共享硬件外设 ............................ 234
12.1 理解 USB 消息的发送机制 ............................ 235
12.2 使用简易的 USB API 发送消息..................... 237
12.2.1 理解代码 ............. 237
12.2.2 运行代码 ............. 239
12.2.3 代码分析 ............. 239
12.2.4 代码改进方案 ..... 240
12.3 基于流缓冲区实现 VCP 驱动 ........................ 241
12.3.1 理解应用程序 ..... 241
12.3.2 理解驱动程序 ..... 242
12.3.3 运行代码 ............. 245
12.3.4 分析驱动程序 ..... 246
12.4 增强 VCP 驱动以支持多任务调用 ................ 246
12.4.1 理解应用程序 ..... 246
12.4.2 理解驱动程序 ..... 248
12.4.3 性能数据的采集机制 ........................ 256
第 13 章 利用队列实现松耦合 . 261
13.1 创建命令队列 ................... 261
13.1.1 LED 的亮度函数 263
13.1.2 确定队列内容 ..... 264
13.1.3 定义架构 ............. 264
13.1.4 使用代码 ............. 271
13.2 为新目标重用队列定义... 272
13.2.1 队列接口 ............. 273
13.2.2 iPWM 接口 ......... 273
13.3 理解队列作为接口的作用.............................. 274
13.4 总结 .... 275
第 4 部分 系统设计与故障排除
第 14章 FreeRTOS 内存管理 .............................. 278
14.1 理解内存分配 ................... 278
14.1.1 静态内存 ............. 279
14.1.2 栈内存 ................. 279
14.1.3 堆内存 ................. 280
14.1.4 堆碎片 ................. 281
14.2 FreeRTOS 原语的静态分配与动态分配........ 282
14.2.1 动态分配示例 ..... 282
14.2.2 静态分配示例 ..... 284
14.2.3 完全禁用动态分配 ............................ 285
14.3 FreeRTOS 堆实现............. 286
14.3.1 5 种堆实现 .......... 287
14.3.2 FreeRTOS 堆实现的对比 .................. 287
14.3.3 选择 FreeRTOS 堆实现 ..................... 288
14.4 替换 malloc 和 free........... 289
14.5 监控栈和堆问题............... 290
14.5.1 监控栈空间 ......... 290
14.5.2 监控堆空间 ......... 292
14.6 使用内存保护单元(MPU) ......................... 292
14.7 总结 .... 293
第 15 章 多处理器与多核系统 . 294
15.1 多核与多处理器系统简介.............................. 294
15.2.1 异构多核系统 ..... 296
15.2.2 核心间通信 ......... 297
15.2.3 遗留应用扩展 ..... 298
15.2.4 高需求硬实时系统 ............................ 300
15.2.5 同构多核系统 ..... 301
15.3 多处理器系统详解........... 301
15.3.1 分布式系统 ......... 301
15.3.2 并行开发 ............. 302
15.3.3 设计复用 ............. 303
15.3.4 高可靠性系统 ..... 303
15.4 处理器间通信详解........... 303
15.4.1 选择通信介质的考量因素 ................ 304
15.4.2 通信标准 ............. 305
15.5 多核与多处理器系统的选择.......................... 306
15.5.1 何时使用多核 MCU .......................... 306
15.5.2 何时使用多处理器系统 .................... 307
15.6 总结 .... 307
第 16 章 故障排除技巧与后续步骤........................ 308
16.1 FreeRTOS 通用调试技术. 308
16.1.1 使用断言 ............. 309
16.1.2 用于分析任务和 ISR 的工具............ 315
16.1.3 内存使用的监控 . 315
16.1.4 栈溢出检测 ......... 315
16.2 调试工具故障排除........... 316
16.2.1 Ozone 故障排除 ........316
16.2.2 SystemView 故障排除....................... 320
16.3 后续步骤 ........................... 324
第 5 部分 参考资料与 FreeRTOS 安装说明
附录 A 工具快速参考 .................. 326
附录 C 创建 FreeRTOS 项目及安装 FreeRTOS ......................... 329