|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Day 124: EMU - 多架构 CPU 模拟器" |
| 4 | +date: 2026-06-25 23:58:00 +0800 |
| 5 | +categories: Build_Your_Own_X |
| 6 | +--- |
| 7 | + |
| 8 | +# EMU - 多架构 CPU 模拟器 |
| 9 | + |
| 10 | +一个模块化、可扩展的 CPU 模拟器框架,支持多种 CPU 架构和外设设备。 |
| 11 | + |
| 12 | +## 项目特性 |
| 13 | + |
| 14 | +### 已实现的 CPU 架构 |
| 15 | + |
| 16 | +#### 1. RISC-V (RV32I) |
| 17 | +- **完整的 RV32I 基础指令集** (47 条指令) |
| 18 | +- 支持所有算术、逻辑、内存访问、控制流指令 |
| 19 | +- CSR (控制状态寄存器) 支持 |
| 20 | +- 系统调用 (ECALL, EBREAK) |
| 21 | +- 内存屏障 (FENCE) |
| 22 | + |
| 23 | +#### 2. MCS-51/8051 |
| 24 | +- **经典 8051 微控制器架构** |
| 25 | +- 8 位累加器和 B 寄存器 |
| 26 | +- 程序状态字 (PSW) - 进位、辅助进位、溢出、奇偶校验 |
| 27 | +- 128 字节内部 RAM |
| 28 | +- 128 字节特殊功能寄存器 (SFR) |
| 29 | +- 16 位数据指针 (DPTR) |
| 30 | +- 栈操作 (PUSH/POP) |
| 31 | +- 寄存器组选择 (4 组 × 8 寄存器) |
| 32 | + |
| 33 | +### 核心系统 |
| 34 | + |
| 35 | +- **内存总线系统**: 支持 RAM 和 MMIO 设备的统一地址空间 |
| 36 | +- **CPU 抽象接口**: 易于添加新的 CPU 架构 |
| 37 | +- **设备框架**: 标准化的设备接口 (read/write/tick) |
| 38 | +- **中断控制器**: 可配置优先级的中断管理 |
| 39 | + |
| 40 | +### 外设设备 |
| 41 | + |
| 42 | +#### UART (通用异步收发器) |
| 43 | +- 16 字节 TX/RX FIFO |
| 44 | +- 状态寄存器 (TX ready/empty, RX ready/full) |
| 45 | +- 控制寄存器 (TX/RX enable, 中断使能) |
| 46 | +- 波特率除数寄存器 |
| 47 | +- 中断生成 (TX/RX 事件) |
| 48 | +- 输出回调机制 |
| 49 | + |
| 50 | +**寄存器映射:** |
| 51 | +- 0x00: 数据寄存器 (RX/TX) |
| 52 | +- 0x04: 状态寄存器 |
| 53 | +- 0x08: 控制寄存器 |
| 54 | +- 0x0C: 波特率除数 |
| 55 | + |
| 56 | +#### 定时器 |
| 57 | +- 32 位计数器,可配置预分频器 |
| 58 | +- 比较寄存器 (周期中断) |
| 59 | +- 自动重置模式 (周期定时器) |
| 60 | +- 单次触发模式 (超时事件) |
| 61 | +- 比较匹配中断 |
| 62 | +- 手动计数器设置/读取 |
| 63 | + |
| 64 | +**寄存器映射:** |
| 65 | +- 0x00: 控制寄存器 (enable, IRQ, auto-reset, one-shot) |
| 66 | +- 0x04: 状态寄存器 (running, match, overflow) |
| 67 | +- 0x08: 计数器值 |
| 68 | +- 0x0C: 比较值 |
| 69 | +- 0x10: 预分频器除数 |
| 70 | + |
| 71 | +## 测试覆盖 |
| 72 | + |
| 73 | +- **9 个测试套件**, 100% 通过 |
| 74 | +- 完整的单元测试覆盖所有组件 |
| 75 | +- 每个 CPU 架构都有专门的测试套件 |
| 76 | +- 设备功能的全面测试 |
| 77 | + |
| 78 | +## 示例应用 |
| 79 | + |
| 80 | +### RISC-V 演示程序 |
| 81 | +位于 `targets/freertos-riscv/demo.c` |
| 82 | + |
| 83 | +功能演示: |
| 84 | +- CPU 初始化和复位 |
| 85 | +- 内存映射 I/O 访问 |
| 86 | +- UART 设备配置和数据传输 |
| 87 | +- 程序执行和设备交互 |
| 88 | + |
| 89 | +**运行演示:** |
| 90 | +```bash |
| 91 | +cd build |
| 92 | +./targets/freertos-riscv/riscv_demo |
| 93 | +``` |
| 94 | + |
| 95 | +**输出:** |
| 96 | +``` |
| 97 | +=== RISC-V Emulator Demo === |
| 98 | +Simple program: Print 'Hi' via UART |
| 99 | +
|
| 100 | +Starting execution at 0x80000000 |
| 101 | +Output from UART: |
| 102 | +---------------------------------------- |
| 103 | +Hi |
| 104 | +
|
| 105 | +---------------------------------------- |
| 106 | +Execution completed |
| 107 | +``` |
| 108 | + |
| 109 | +## 构建说明 |
| 110 | + |
| 111 | +### 依赖 |
| 112 | +- CMake 3.12+ |
| 113 | +- C11 编译器 (GCC/Clang) |
| 114 | + |
| 115 | +### 编译 |
| 116 | +```bash |
| 117 | +mkdir build |
| 118 | +cd build |
| 119 | +cmake .. |
| 120 | +make -j4 |
| 121 | +``` |
| 122 | + |
| 123 | +### 运行测试 |
| 124 | +```bash |
| 125 | +make test |
| 126 | +``` |
| 127 | + |
| 128 | +## 项目结构 |
| 129 | + |
| 130 | +``` |
| 131 | +EMU/ |
| 132 | +├── include/ |
| 133 | +│ ├── emu/ # 核心框架头文件 |
| 134 | +│ │ ├── cpu.h # CPU 抽象接口 |
| 135 | +│ │ ├── memory.h # 内存总线 |
| 136 | +│ │ ├── device.h # 设备接口 |
| 137 | +│ │ ├── interrupt.h |
| 138 | +│ │ └── machine.h |
| 139 | +│ ├── cpu/ # CPU 架构头文件 |
| 140 | +│ │ ├── riscv.h |
| 141 | +│ │ └── mcs51.h |
| 142 | +│ └── devices/ # 设备头文件 |
| 143 | +│ ├── uart.h |
| 144 | +│ └── timer.h |
| 145 | +├── src/ |
| 146 | +│ ├── core/ # 核心实现 |
| 147 | +│ ├── cpu/ # CPU 实现 |
| 148 | +│ │ ├── riscv/ |
| 149 | +│ │ └── mcs51/ |
| 150 | +│ └── devices/ # 设备实现 |
| 151 | +├── tests/ |
| 152 | +│ └── unit/ # 单元测试 |
| 153 | +├── targets/ # 示例应用 |
| 154 | +│ └── freertos-riscv/ |
| 155 | +└── CMakeLists.txt |
| 156 | +``` |
| 157 | + |
| 158 | +## 扩展性 |
| 159 | + |
| 160 | +### 添加新的 CPU 架构 |
| 161 | + |
| 162 | +1. 在 `include/cpu/` 创建头文件 |
| 163 | +2. 实现 `emu_cpu_ops_t` 接口 |
| 164 | +3. 在 `src/cpu/` 实现 CPU 逻辑 |
| 165 | +4. 调用 `emu_cpu_register()` 注册 |
| 166 | + |
| 167 | +### 添加新设备 |
| 168 | + |
| 169 | +1. 在 `include/devices/` 创建头文件 |
| 170 | +2. 实现 `emu_device_t` 接口 (read/write/tick) |
| 171 | +3. 在 `src/devices/` 实现设备逻辑 |
| 172 | +4. 通过 `emu_memory_bus_add_region()` 映射到地址空间 |
| 173 | + |
| 174 | +## 内存映射示例 (RISC-V 演示) |
| 175 | + |
| 176 | +| 基地址 | 大小 | 设备 | |
| 177 | +|-----------|------|-------| |
| 178 | +| 0x80000000 | 64KB | RAM | |
| 179 | +| 0x10000000 | 4KB | UART | |
| 180 | +| 0x10001000 | 4KB | Timer | |
| 181 | + |
| 182 | +## 已完成的任务 |
| 183 | + |
| 184 | +✅ **RISC-V RV32I 完整指令集** - 所有基础指令,47 条 |
| 185 | +✅ **UART 设备** - 串口通信,带 FIFO 和中断 |
| 186 | +✅ **定时器设备** - RTOS 时钟源,多种模式 |
| 187 | +✅ **RISC-V 演示程序** - 可运行的示例应用 |
| 188 | +✅ **MCS-51/8051 架构** - 经典 8 位微控制器 |
| 189 | + |
| 190 | +## 待实现功能 |
| 191 | + |
| 192 | +- **GDB 远程调试支持** - GDB RSP 协议实现 |
| 193 | +- **更多 8051 指令** - 扩展指令集覆盖 |
| 194 | +- **更多外设** - GPIO, SPI, I2C, ADC |
| 195 | +- **NES/6502 架构** - 第三个 CPU 架构 |
| 196 | +- **完整的 FreeRTOS 移植** - 任务调度和 RTOS API |
| 197 | + |
| 198 | +## 技术亮点 |
| 199 | + |
| 200 | +1. **架构抽象清晰**: CPU、内存、设备完全解耦 |
| 201 | +2. **高度可扩展**: 通过注册机制轻松添加新组件 |
| 202 | +3. **内存映射 I/O**: 统一的地址空间,设备访问透明 |
| 203 | +4. **测试驱动**: 所有功能都有单元测试保证 |
| 204 | +5. **实用性**: 可以运行真实的二进制程序 |
| 205 | + |
| 206 | +## 性能特点 |
| 207 | + |
| 208 | +- 指令级模拟,准确度高 |
| 209 | +- 设备 tick 机制支持周期性操作 |
| 210 | +- 高效的内存访问(最近访问缓存) |
| 211 | +- 适合教学、原型开发、固件测试 |
| 212 | + |
| 213 | +## 使用场景 |
| 214 | + |
| 215 | +- **嵌入式系统开发**: 在 PC 上测试固件 |
| 216 | +- **教学**: 学习 CPU 架构和汇编语言 |
| 217 | +- **逆向工程**: 分析未知固件 |
| 218 | +- **原型验证**: 在硬件可用前验证算法 |
| 219 | +- **自动化测试**: CI/CD 中的固件测试 |
| 220 | + |
| 221 | +## 许可证 |
| 222 | + |
| 223 | +MIT License |
| 224 | + |
| 225 | +## 贡献者 |
| 226 | + |
| 227 | +- Initial implementation by Claude Sonnet 4.6 |
| 228 | +- Project architecture and design |
| 229 | + |
| 230 | +--- |
| 231 | + |
| 232 | +**最后更新**: 2026-06-20 |
| 233 | +**版本**: 0.1.0 |
| 234 | +**状态**: 活跃开发中 |
0 commit comments