这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32F769】记一次由于开启D-Cache之后DMA数据传输出错的问题查

共4条 1/1 1 跳转至

【STM32F769】记一次由于开启D-Cache之后DMA数据传输出错的问题查找与解决

工程师
2025-03-10 21:13:25   被打赏 35 分(兑奖)     打赏

缘由

我原来在STM32F769I-DISC1开发板上使用ST7789成功的实现了LVGL,使用spi_dma实现16bit传数据,原来跑得一切正常的。我今天移植FreeRTOS之后,考虑到性能优化,在main中,添加了指令缓存与数据缓存之后,就出现了花屏现象:

SCB_EnableICache();
  /* Enable D-Cache */
  SCB_EnableDCache();

现象如下:

image.png

禁用后,一切又正常了,因此我怀疑是开启I-Cache与D-Cache的原因。

原因分析

经查找资料,分析可能是我在发送DMA数据之前有缓存数据存在,因此发生送的数据有可能没有请理。网上的如下原因分析:

在 STM32F769 中启用指令缓存(I-Cache)和数据缓存(D-Cache)后,DMA 发送数据出错,可能是由缓存一致性问题导致的。下面详细分析可能的原因及对应的解决办法。 可能的原因 1. 缓存一致性问题 启用 D-Cache 后,数据可能会被缓存到高速缓存中,而 DMA 直接访问的是内存地址。如果缓存中的数据与内存中的数据不一致,DMA 就可能发送错误的数据。 2. 未进行缓存操作 在进行 DMA 操作前后,没有对相关的缓存区域进行适当的操作(如使无效、清理等),导致缓存中的数据没有及时更新到内存中,或者内存中的数据没有及时更新到缓存中。 3. 地址对齐问题 DMA 操作通常要求数据地址和长度满足一定的对齐要求。如果数据地址或长度没有正确对齐,可能会导致 DMA 传输出错。

解决方法

根据以及资料的提示,我找到了DMA发送的地方,在传输之前清理D-Cache,确保数据从缓存写回到内存。DMA发送结束之后使D-Cache无效,确保后续访问的数据是最新的。

修改代码如下:

while (total_size > 0)
        {
            uint16_t chunk_size = (total_size > 32000) ? 32000 : total_size;
            // 清理D-Cache,确保数据从缓存写回到内存
            SCB_CleanDCache_by_Addr((uint32_t *)(color_p + offset), chunk_size * 2);
            // 使用 DMA 发送数据
            if (HAL_SPI_Transmit_DMA(&hspi2, (uint8_t *)(color_p + offset), chunk_size*2) != HAL_OK)
            {
                printf("DMA transmission failed\r\n");
                break;
            }
            // 等待DMA传输完成
            while (spi2_dma_tx_flag == 0)
                ;
            // 使D-Cache无效,确保后续访问的数据是最新的
            SCB_InvalidateDCache_by_Addr((uint32_t *)(color_p + offset), chunk_size * 2);
            spi2_dma_tx_flag = 0; // 重置标志
            total_size -= chunk_size;
            offset += chunk_size;
        }

重新烧录程序后,花屏现象成功解决。

image.png

经验总结

这次的现象,是显示屏,很容易就出现问题。如果在其他的场合,比如发送串口数据,那问题暴露就不是这么的明显。因此在开启数据缓存功能之后,切记要注意这点,在DMA传输之前把数据清理。




关键词: STM32F769     D-Cache     数据     缓存    

专家
2025-03-12 18:42:25     打赏
2楼

过程很痛苦,经验很宝贵


院士
2025-03-12 19:02:31     打赏
3楼

Cache的开启会加速MCU,提高性能,但也会带来一些小的“烦恼”!


工程师
2025-03-12 20:31:07     打赏
4楼

也可以把使用DMA 搬运的显寸数据通过mpu 配置为no_cache属性,这样就不会因开关cache 将一些已经在cache里的非显存数据flush掉


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]