• 正文
  • 相关推荐
申请入驻 产业图谱

TouchGFX花屏解决方案:Cortex-M7 DCache 刷新必加,WBWA 模式性能不打折

1小时前
182
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

TouchGFX 图形渲染出现花屏,核心原因是帧缓冲配置为 WBWA 模式(Normal write-back + 读写分配)时,未刷新 DCache(数据缓存) ——CPU 仅更新 Cache 未同步物理内存,LTDC(LCD 控制器)读取旧数据导致数据不一致。解决方案:在flushFrameBuffer函数中添加SCB_CleanInvalidateDCache(),一键同步 Cache 与物理内存,兼顾性能与显示稳定性。

资料获取:LAT1443 TouchGFX 图形渲染没有刷新DCache导致的花屏问题分析

1. 问题背景:性能与显示的矛盾场景

1.1 核心配置

  • 硬件:Cortex-M7 内核 MCU(如 STM32F7/H7);
  • 帧缓冲属性:为追求高性能,配置为 WBWA 模式(TEX=1、C=1、B=1);
  • 图形框架:TouchGFX,执行部分渲染后出现局部花屏;
  • 对比现象:切换为 Write-through(透写)模式后花屏消失,但系统性能下降(单次写入开销增大)。

1.2 关键矛盾

  • WBWA 模式优势:写数据仅更新 DCache,不立即同步物理内存,速度快、总线开销小;
  • 隐藏风险:TouchGFX 渲染完成后,Cache 中更新的数据未同步到物理内存,LTDC 读取物理内存时拿到旧数据,导致显示花屏。

2. 根源拆解:DCache 数据一致性问题

2.1 WBWA 模式的缓存机制

  • 写操作:CPU 修改帧缓冲数据时,仅写入 DCache,标记为 “脏数据(Dirty)”,暂不写入物理内存;
  • 读取逻辑:LTDC 作为独立主机,直接访问物理内存,而非 DCache;
  • 冲突点:渲染完成后未执行 Cache 维护,DCache 中的新数据与物理内存的旧数据不一致,LTDC 显示异常。

2.2 TouchGFX 的渲染回调机制

TouchGFX 框架在每次局部渲染完成后,会自动调用flushFrameBuffer函数(定义在TouchGFXHAL.cpp),目的是通知框架 “渲染完成”,但默认实现未包含 DCache 刷新操作,无法解决 WBWA 模式下的数据一致性问题。

3. 解决方案:1 行代码修复,零性能损耗

flushFrameBuffer函数中添加 DCache 清洁 + 无效化操作,确保 Cache 数据同步到物理内存,步骤如下:

3.1 代码修改(核心步骤)

打开工程中的TouchGFXHAL.cpp,找到flushFrameBuffer函数,添加SCB_CleanInvalidateDCache()

void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
    // 调用父类实现,通知TouchGFX框架渲染完成(必须保留)
    TouchGFXGeneratedHAL::flushFrameBuffer(rect);
    
    // 核心修复:清洁并无效化DCache,同步数据到物理内存
    SCB_CleanInvalidateDCache();
}

3.2 函数作用说明

  • SCB_CleanInvalidateDCache():CMSIS 标准函数,执行两步操作:
    1. Clean(清洁):将 DCache 中标记为 “Dirty” 的脏数据写入物理内存;
    2. Invalidate(无效化):标记 DCache 对应区域为无效,后续读取直接从物理内存获取新数据;
  • 优势:仅在渲染完成后执行一次,对系统性能影响极小,完全保留 WBWA 模式的性能优势。

3.3 补充:MPU 帧缓冲配置(确保 WBWA 模式正确)

若未正确配置 MPU,DCache 模式可能失效,需按以下参数配置帧缓冲区域:

MPU 参数 配置值 说明
TEX 1 Normal 内存类型标记
C 1 启用 Cache
B 1 启用缓冲
S 0 非共享内存
内存类型 Normal 对应 WBWA 模式

4. 关键注意事项

  1. 模式适配:仅 WBWA 模式需要添加该代码,Write-through 模式无需(透写模式自动同步 Cache 与物理内存);
  2. 多主设备场景:除 LTDC 外,若 DMA、其他内核也访问帧缓冲,需同样执行 Cache 维护操作;
  3. 函数兼容性:SCB_CleanInvalidateDCache()适用于所有 Cortex-M7 内核 MCU,无需修改适配;
  4. 局部刷新优化:若仅局部渲染(如 rect 参数指定区域),可使用SCB_CleanInvalidateDCache_by_Addr()精准刷新指定地址范围,进一步提升效率:
    // 局部刷新示例:仅刷新渲染区域对应的Cache
    uint32_t fb_addr = (uint32_t)frame_buffer + rect.x + rect.y * LCD_WIDTH;
    uint32_t fb_size = rect.width * rect.height * sizeof(uint16_t); // 假设16位色深
    SCB_CleanInvalidateDCache_by_Addr((void*)fb_addr, fb_size);
    

TouchGFX 花屏的核心是 “WBWA 模式下 DCache 数据未同步”,而非硬件或渲染逻辑问题。通过在flushFrameBuffer中添加 1 行 Cache 刷新代码,即可兼顾 WBWA 模式的高性能与显示稳定性,无需牺牲性能切换到 Write-through 模式。该方案适用于所有 Cortex-M7 内核 + TouchGFX 的嵌入式图形应用。

相关推荐