阶段1 (CONFIG_COPY_ITCM_CODE=1): SRAM执行 → 准备ITCM → 复位
阶段2 (CONFIG_COPY_ITCM_CODE=0): ITCM执行 → 运行应用
#define CONFIG_ITCM_BASE_ADDR 0x30000000
csi_itcm_set_base_addr(CONFIG_ITCM_BASE_ADDR);
功能:设置ITCM在系统地址空间中的基地址地址选择:0x30000000是E907预留的ITCM地址空间作用:CPU访问该地址范围时直接映射到ITCM
csi_itcm_enable();
功能:激活ITCM控制器效果:使能后,ITCM才能被访问和使用
*(volatile int *)0x4004000C = 0x60;
寄存器地址:0x4004000C - 系统控制寄存器配置值:0x60 (0110_0000b)功能:配置ITCM slave端口的地址映射映射关系:将0x60000000地址范围映射到ITCM物理存储
memcpy((void *)0x60000000, yoc_bin, yoc_bin_len);
源:yoc_bin - 存储在SRAM/Flash中的固件镜像目标:0x60000000 - ITCM的slave访问地址说明:通过slave接口将代码写入ITCM
// 设置复位后从ITCM启动
*(volatile int *)0x40040010 = 0x1;
// 设置复位向量基地址
*(volatile int *)0x40040018 = CONFIG_ITCM_BASE_ADDR;
0x40040010:Boot模式控制寄存器,设置为1表示从ITCM启动0x40040018:RVBA(Reset Vector Base Address)寄存器,设置复位向量基地址
__asm volatile("csrsi mexstatus, 1");
指令:CSR Set Immediate - 设置mexstatus的bit 0效果:触发处理器核心软复位玄铁特性:mexstatus是玄铁处理器的扩展状态寄存器
printf("start to run in itcm.
");
此时代码已经从ITCM的0x30000000地址开始执行
void *p = malloc(100);
if (p == NULL) {
printf("malloc failed.
");
} else {
printf("malloc 100B success.
");
free(p);
}
目的:验证堆内存管理功能正常验证点:C运行时环境是否正确初始化
ITCM双端口访问机制:
┌─────────────────────────┐
│ CPU Core (E907) │
├─────────┬───────────────┤
│Master端 │ Slave端 │
│0x30000000│ 0x60000000 │
└─────────┴───────────────┘
↓ ↓
┌──────────────────┐
│ ITCM Memory │
└──────────────────┘
Power On/Reset
↓
Boot from SRAM/Flash
↓
CONFIG_COPY_ITCM_CODE=1?
↓ Yes
Configure ITCM
↓
Copy Code to ITCM
↓
Configure Boot Mode
↓
Software Reset
↓
Boot from ITCM (0x30000000)
↓
Run Application
从CPU侧来看,ITCM的Master和Slave端口设计是一种典型的双端口存储器架构,让我详细分析它们的作用和特性:
┌─────────────────────────────────────────┐
│ CPU Core (E907) │
├──────────────────┬──────────────────────┤
│ Instruction │ Data/Debug │
│ Fetch Path │ Access Path │
└────────┬─────────┴──────────┬───────────┘
↓ Master Port ↓ Slave Port
┌────────────────────────────────┐
│ ITCM Memory │
│ (Dual-Port SRAM) │
└────────────────────────────────┘
// Master端口特征
- 地址范围: 0x30000000 (CONFIG_ITCM_BASE_ADDR)
- 访问类型: 只读(指令获取)
- 访问宽度: 通常32/64/128位(取决于CPU取指宽度)
- 访问优先级: 最高优先级
1. 指令获取(Instruction Fetch)
// CPU取指阶段直接从Master端口读取
PC: 0x30000000 → Master Port → Instruction: 0xXXXXXXXX
PC: 0x30000004 → Master Port → Instruction: 0xYYYYYYYY
2. 零等待周期访问
特性分析:
- 无总线仲裁延迟
- 无Cache miss penalty
- 确定性的指令获取时间
- 适合硬实时系统需求
3. 并行访问能力
// Master端口可以与Slave端口同时工作
While (CPU_Fetch_Instruction_via_Master) {
// 同时可以通过Slave端口进行数据访问
Debug_Access_via_Slave();
}
// Slave端口特征
- 地址范围: 0x60000000 (通过寄存器0x4004000C配置)
- 访问类型: 读/写
- 访问来源: 系统总线、DMA、调试器
- 访问优先级: 低于Master端口
1. 代码加载和更新
// 通过Slave端口加载代码到ITCM
memcpy((void *)0x60000000, // Slave端口地址
yoc_bin, // 源代码
yoc_bin_len); // 代码长度
// 这样做的好处:
// - 不影响CPU当前执行
// - 可以在运行时更新ITCM内容
// - 支持动态代码加载
2. 调试访问
// 调试器通过Slave端口访问ITCM
typedef struct {
uint32_t breakpoint_addr;
uint32_t original_instruction;
} debug_access_t;
// 调试器可以:
- 读取ITCM中的指令进行反汇编
- 设置软件断点
- 验证代码完整性
3. DMA传输
// DMA可以通过Slave端口高效传输代码
dma_config_t dma_cfg = {
.src_addr = flash_code_addr,
.dst_addr = 0x60000000, // ITCM Slave端口
.size = code_size,
.mode = DMA_MEM_TO_MEM
};
| 特性 | Master端口 | Slave端口 |
| 访问源 | CPU指令获取单元 | 系统总线/DMA/调试器 |
| 访问类型 | 只读(取指) | 读/写 |
| 优先级 | 最高 | 较低 |
| 延迟 | 零等待 | 可能有总线延迟 |
| 带宽 | 全带宽 | 受总线带宽限制 |
| 用途 | 执行代码 | 加载/调试/维护 |
| 地址空间 | 0x30000000 | 0x60000000 |
// ITCM内部仲裁逻辑(伪代码)
if (master_port_request && slave_port_request) {
// Master端口优先
serve_master_port();
// Slave端口等待
delay_slave_port();
} else {
// 独立访问,无冲突
serve_available_port();
}
场景1:Boot过程
// 阶段1:通过Slave端口加载代码
Phase1_Load_Code() {
// CPU从Flash/SRAM执行
// 通过Slave端口写入代码到ITCM
memcpy((void *)SLAVE_ADDR, boot_code, size);
}
// 阶段2:切换到Master端口执行
Phase2_Execute() {
// 设置PC到Master端口地址
jump_to(MASTER_ADDR); // 0x30000000
// CPU现在从ITCM取指执行
}
场景2:在线更新
// 运行时代码更新(类似A/B分区)
Runtime_Update() {
// ITCM分两个区域
#define ITCM_ZONE_A 0x30000000
#define ITCM_ZONE_B 0x30008000
if (current_zone == ZONE_A) {
// 通过Slave更新Zone B
update_via_slave(0x60008000, new_code);
// 切换到Zone B执行
switch_to_zone_b();
}
}
TCM中的Master和Slave定义是相对于总线而言的,不是相对于CPU。
Master(主设备)
能够主动发起总线访问请求的设备控制总线传输的时序和地址典型的Master:CPU核心、DMA控制器、GPU、高性能外设等Slave(从设备)
被动响应Master请求的设备不能主动发起总线访问典型的Slave:存储器(包括TCM)、外设寄存器、中断控制器等TCM作为Slave:
TCM本质上是一个从设备(Slave)它是被CPU或其他Master访问的高速存储器响应来自Master的读写请求TCM作为Slave设备,可以被不同的Master通过不同的接口访问:
┌─────────────────────────────────────────┐
│ │
│ ┌──────┐ 直接接口 │
│ │ CPU ├──────────────────┐ │
│ └──────┘ │ │
│ ▼ │
│ ┌──────────┐ │
│ ┌──────┐ │ │ │
│ │ DMA ├───────────► TCM │ │
│ └──────┘ 专用端口 │ (Slave) │ │
│ │ │ │
│ ┌──────┐ └─────┬────┘ │
│ │Debug ├─────────────────┘ │
│ └──────┘ 调试接口 │
│ │
└─────────────────────────────────────────┘
CPU (Master) ──[专用接口]──> TCM (Slave)
- 特点:最低延迟,固定时钟周期
- 不经过系统总线,零等待状态
DMA (Master) ──[DMA端口]──> TCM (Slave)
- 特点:后台传输,不占用CPU
- 可能需要仲裁,但仍是高优先级
外部Master ──[系统总线]──> 总线接口 ──> TCM (Slave)
- 特点:其他总线Master也能访问TCM
- 延迟较高,可能需要总线仲裁
特点:
- 地址:0x60000000(总线视角)
- 用途:加载代码时使用
- 路径:CPU → 系统总线 → ITCM Slave端口
- 延迟:相对较高(经过总线仲裁)
特点:
- 地址:0x30000000(CPU视角)
- 用途:取指执行时使用
- 路径:CPU → 专用ITCM接口
- 延迟:极低(0等待,确定性访问)