NXP MCU 技术论坛
直播中

jjll652

9年用户 1462经验值
私信 关注
[问答]

MPC5777C如何在禁用其余数据缓存的同时继续保持堆栈工作?

我按照 AN5191指南启动MPC5777C自定义板,它的一些内置测试要求我禁用缓存以执行某些作,然后重新启用它们以进行正常作。考虑到我把一半的数据缓存作为我的堆栈(使用基于 dcbz 和 dcbtls 指令的 AN5191代码),我应该如何在禁用其余数据缓存的同时继续保持堆栈工作?

回帖(1)

李玉兰

2025-3-31 18:07:56

在MPC5777C中实现禁用大部分数据缓存的同时保持堆栈使用缓存,需通过以下步骤实现:


1. 理解缓存锁定机制



  • MPC5777C的数据缓存(DCache)支持锁定机制,允许将特定缓存行固定(Locked),防止被替换。

  • 在初始化阶段,使用dcbz(Data Cache Block Zero)指令分配缓存行并清零,配合dcbtls(Data Cache Block Touch for Load Store)预取数据到锁定的缓存行,确保堆栈区域常驻缓存。


2. 配置堆栈使用锁定的缓存区域



  • 划分缓存区域:将数据缓存分为两部分,一半用于堆栈(锁定),另一半用于常规缓存。


  • 锁定缓存行:在初始化代码中,通过循环dcbz初始化堆栈区域,并使用dcbtls预取,确保这些行被锁定。


    // 示例代码:初始化锁定堆栈区域
    uint32_t *stack_base = (uint32_t*)STACK_START_ADDR;
    for (int i = 0; i < CACHE_LINES_FOR_STACK; i++) {
       asm volatile("dcbz 0, %0" :: "r"(stack_base + i * CACHE_LINE_SIZE));
       asm volatile("dcbtls 0, %0, 0" :: "r"(stack_base + i * CACHE_LINE_SIZE));
    }



3. 禁用全局缓存但保留锁定区域



  • 修改L1CSR寄存器:清除Cache Enable(CE)位以禁用全局缓存,但锁定行仍保持有效


  • 验证缓存状态:确保禁用缓存时,锁定的堆栈行不会被刷新或失效。


    // 禁用数据缓存(保留锁定行)
    uint32_t l1csr0;
    asm volatile("mfspr %0, 1011" : "=r"(l1csr0)); // 读取L1CSR0
    l1csr0 &= ~0x80000000; // 清除CE位
    asm volatile("mtspr 1011, %0" :: "r"(l1csr0));  // 写入L1CSR0



4. 确保内存访问策略一致性



  • 内存属性配置:通过MMU/MPU(如果可用)将堆栈区域标记为Cacheable,其他区域为Non-Cacheable

  • 写策略调整:对堆栈使用Write-Through策略,确保数据一致性。


5. 测试与验证



  • 功能测试:在禁用缓存后,通过堆栈操作(如函数调用、局部变量访问)验证是否命中缓存。

  • 性能分析:使用性能计数器确认堆栈访问延迟是否降低。


6. 重新启用缓存




  • 恢复CE位:测试完成后,重新设置L1CSR0的CE位,并刷新非锁定区域。


    // 重新启用数据缓存
    l1csr0 |= 0x80000000; // 设置CE位
    asm volatile("mtspr 1011, %0" :: "r"(l1csr0));



关键注意事项



  • 硬件限制:确认MPC5777C的锁定行在CE位清除后仍有效(查阅Reference Manual)。

  • 内存对齐:确保堆栈地址按缓存行大小(通常32字节)对齐。

  • 中断处理:在缓存禁用期间,若发生中断,需确保中断栈也在锁定区域。


通过上述步骤,可在禁用其余数据缓存的同时,维持堆栈在锁定缓存区域的正常运行,满足AN5191的测试要求。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分