tags: [source-summary] type: source source: "微机原理与操作系统硬件基础-原理与本质" author: "AI助手" date: 2026-09-19
锚点:CPU寄存器 = CPU内部的高速存储。上下文切换 = 把当前任务的寄存器值保存到栈 + 从栈恢复下一个任务的寄存器值。SP和PC是切换的关键。
| 寄存器 | 用途 | 为什么上下文切换要保存它 |
|---|---|---|
| R0-R3 | 函数参数/返回值 | 调用者保存(caller-saved),ISR自动保存 |
| R4-R11 | 通用变量 | 被调用者保存(callee-saved),上下文切换手动保存 |
| SP(R13) | 栈指针 | 切换的核心——保存到TCB,恢复时从TCB取出 |
| LR(R14) | 链接寄存器(返回地址) | 中断返回时自动恢复 |
| PC(R15) | 程序计数器 | 中断返回时从栈恢复 |
| xPSR | 程序状态(N/Z/C/V标志) | 保存运算状态,否则切换后标志位丢失 |
ARM Cortex-M有多种CPU模式(Handler mode、Thread mode),不同模式使用不同的SP:
PSP(Process Stack Pointer):任务使用,每个任务的栈通过PSP访问
graph TD
A[任务运行] --> B[中断发生]
B --> C[切换到MSP<br/>保存任务寄存器到任务栈]
C --> D[PendSV处理]
D --> E[切换PSP到新任务栈]
E --> F[恢复新任务寄存器]
F --> G[新任务运行]
来源:ARM架构01-从零认识ARM
锚点:三总线 = 地址总线(传地址)+ 数据总线(传数据)+ 控制总线(传控制信号)。分开是为了让多个设备能共享同一组线路而不冲突。
| 总线 | 传什么 | 类比 | 宽度决定什么 |
|---|---|---|---|
| 地址总线 | 内存/设备地址 | 信封上的地址 | 能寻址多大空间(32位→4GB) |
| 数据总线 | 实际数据 | 信封里的信 | 一次传多少数据(32位→一次4字节) |
| 控制总线 | 读/写/中断信号 | 邮递员的手势 | 读操作、写操作、中断请求等 |
CPU用同一套地址总线访问内存和外设,但地址空间分成了两块:
这就是为什么驱动能控制硬件:向某个"外设地址"写入数据,实际是向硬件寄存器写入控制命令。*(volatile uint32_t *)0x40020014 = 0x01; 就是在操作GPIO的ODR寄存器。
volatile告诉编译器:这个变量的值可能被硬件改变,每次访问都要从内存重新读取来源:组成原理/计算机系统概述
锚点:GIC(Generic Interrupt Controller)是ARM的中断管家——接收所有中断源的请求,按优先级排队,决定哪个中断能"插队"到哪个CPU。
| 类型 | 全称 | 数量 | 来源 | 特点 |
|---|---|---|---|---|
| SGI | Software Generated Interrupt | 16个 | 软件触发 | 核间通信用 |
| PPI | Private Peripheral Interrupt | 16个 | 每个CPU私有 | 如本地定时器 |
| SPI | Shared Peripheral Interrupt | 最多988个 | 外部设备共享 | 如UART、GPIO中断 |
处理完高优先级后,再回到低优先级ISR继续
sequenceDiagram
participant CPU as CPU
participant ISR_L as 低优先级ISR
participant ISR_H as 高优先级ISR
CPU->>ISR_L: 开始执行低优先级ISR
Note over ISR_L: 执行到一半...
ISR_H->>CPU: 高优先级中断到来
CPU->>ISR_H: 暂停低优先级,先处理高优先级
ISR_H-->>CPU: 高优先级处理完毕
CPU->>ISR_L: 恢复低优先级ISR继续执行
ISR_L-->>CPU: 低优先级处理完毕
FreeRTOS用两种方式保护临界区:
来源:ARM架构01-从零认识ARM
锚点:MMU(Memory Management Unit)是CPU的"翻译官"——把进程使用的虚拟地址翻译成物理内存的真实地址。有了它,每个进程都以为自己独占整块内存。
没有MMU的世界:程序直接访问物理地址 → 进程A访问0x20000000,进程B也访问0x20000000 → 数据互相覆盖。
有了MMU:进程A的0x20000000可能映射到物理0x30000000,进程B的0x20000000可能映射到物理0x50000000 → 互不干扰。
ARM Cortex-M使用两级页表(为了节省内存):
graph LR
VA["虚拟地址<br/>32位"] --> L1["一级页表<br/>[31:20] 12位<br/>索引4096个条目"]
VA --> L2["二级页表<br/>[19:12] 8位<br/>索引256个条目"]
VA --> Offset["页内偏移<br/>[11:0] 12位<br/>4KB页大小"]
L1 --> PT["页表基地址<br/>TTBR0/TTBR1"]
L2 --> PA["物理地址"]
Offset --> PA
页表翻译需要多次内存访问(L1→L2→物理页),太慢。TLB(Translation Lookaside Buffer)缓存最近使用的翻译结果:
FreeRTOS面向没有MMU的MCU(如STM32),所有任务运行在同一个地址空间。这简化了设计,但意味着:
来源:Linux内核04-进程调度与中断管理、ARM架构01
| 硬件 | 操作系统用它做什么 | 没有它会怎样 |
|---|---|---|
| 寄存器 | 上下文切换(保存/恢复执行现场) | 无法实现多任务 |
| 三总线 | CPU访问内存和外设 | 无法和外界通信 |
| 时钟 | 调度器的心跳、定时器 | 无法做时间片轮转 |
| 中断 | 事件驱动、任务唤醒 | 只能轮询,效率极低 |
| 中断控制器 | 优先级管理、中断嵌套 | 多设备中断冲突 |
| MMU | 进程隔离、虚拟内存、COW | 无进程保护,一个bug影响全局 |