前言
前段时间某客户反馈,在使用STM32H7的FMC时,如果使能了D-CACHE就运行不正常。数据没有写到FMC外部的存储器里,FMC接口也没有波形。而不使能D-CACHE是工作则是正常的。
其实对于这个问题,如果了解STM32H7的架构的话,就很容易理解了。下面我们就来看一看到底是什么原因让客户觉得使能DCACHE后FMC就工作不正常了。
STM32H7的架构
下面是STM32H7架构图中和FMC相关的部分。从图中可以看到,STM32H7是基于Cortex-M7内核,在内部的Cortex-M7内核里带有一个16KB的D-CACHE和一个16KB的I-CACHE。内核通过AXIM总线连接到64位的AXI总线矩阵,再经过这个总线矩阵连接到FMC接口实现对外部存储器的访问。这里,当D-CACHE使能的时候,对FMC接口上的存储器的操作会用到内核的缓存(CACHE)的。
使能了CACHE的好处就是可以提高内核访问存储器的速度。为什么使用缓存能提高速度呢?是因为在操作可以被缓存的存储器的时候,内核不是每次都去直接操作这些存储器,而是从缓存里读取数据,或者将数据先写到缓存里。看到这里,是不是觉得和前面客户说的现象有点联系了。
Cache的操作
简单的说缓存工作时有两种方式:回写和透写。
回写【write back】就是数据平时只写到缓存【cache】,必要时才同步到下一级存储器中。
透写【write through】就是数据每次都同时写到缓存和下一级存储器中。这种方式可以解决数据不一致的问题,但同时也会消耗更多的总线访问时间。
缓存的操作方式,在启用缓存后有一个默认的设置 。也就是下面这张表:
请参考AN4839了解更多的关于Cache的使用说明。
问题分析及解决
客户是通过FMC的NOR存储控制器外接一个FPGA。映射的地址范围是0x60000000~0x7FFFFFFF。从上图可以看到,它默认的缓存操作方式是WBWA(回写写分配)。也就是说,当打开DCACHE后,所有对该地址范围的操作都会先到缓存。这也解释了为什么客户发现数据没有真正写到外部存储器中。客户的数据需要实时写到FPGA中进行计算。所以对这个应用场景,回写的设置就不合适了。
对于客户的这个应用,可以通过MPU来进行配置,将0x60000000~0x7FFFFFFF范围地址的CACHE设置为透写的方式,这样数据就会实时的写到FPGA中去了。所以,针对这种情况,我们可以通过MPU合理配置来解决。
通过MPU,可以配置不同存储器空间的访问权限和Cache策略。HAL库里面提供了对应的函数和例程,参照例程用下面这段代码就可以解决客户的问题了。数据每次都是直接写到FPGA中,而不是缓存到内核的DCACHE中。
总结
D-CACHE的使用可以帮我们提高程序运行的性能,但也会带来缓存和二级存储器数据不一致和缓冲不击中带来的程序执行的时间不确定的情况,需要客户根据实际的应用来进行选择。对于实时性要求高的数据,可以像前面一样使用MPU配置成透写的方式,或者将数据放到DTCM RAM中。另外,在本文中只用MPU配置了FMC映射的部分存储区域。在实际使用中,应该对所有用到的存储空间(比如Flash, SRAM区)的属性根据实际情况进行合理配置,以免引起其它的问题。详情请参考AN4838.
关键字:stm32 D-CACHE FMC
引用地址:
stm32案例分享之使D-CACHE时FMC外设运行不正常原因
推荐阅读最新更新时间:2024-11-13 11:12
经典收藏!stm32最小系统完整版
采用stm32f103rc的 STM32 最小系统详细解析图,如下: 一、 STM32 主电路 二、USB转串口下载电路 注:此图中二极管D1不用接! 三、SWD模式调试仿真电路 四、指示电路 五、整体电路 注:此图中二极管D1不用接!
[单片机]
STM32CUBEIDE打印浮点数问题
IDE不像MDK5那样默认就可以使用串口输出浮点数。 解决办法: 右键你的工程,在最下面点击 properties 在弹出来的框中点击 C/C++ Build 下拉框 在下拉框中点击 Settings 在弹出来的框中最底部找到 Miscellaneous 并点击 在other flags 中点击 图标 输入 -u_printf_float ,然后点击ok 最后点击 Apply and close,就可以使用串口打印浮点数了。
[单片机]
关于STM32的定时器问题集锦
1、定时器外部计数功能 问:STM32处理器的定时器可以配置为对外部脉冲计数方式,其中一种方式是通过TIM的ETR引脚(外部触发引脚),另外一种方式是通过TIM的CH1或者CH2引脚来输入。现在我不明白这两种方式有什么区别,两种方式都能对外部脉冲计数,那么设置外部触发方式的目的指什么? 答:根据设计电路来使用不同的方法,他们最大的区别就是引脚不同,但是实现的功能是一样的。 2、TIM2用于捕获,如何调整TIM2的时钟? 问:TIM2用于捕获,如何调整TIM2的时钟?想调低TIM2的时钟频率,以减小计数器的值,避免溢出。 答:可在中断函数里修改配置。不过我想知道你的具体目的是什么 答:因被捕获脉冲频率很宽,有
[单片机]
STM32备忘——GPIO的几种模式
GPIO的模式学习 GPIO的综合描述 讲述的内容比较详细 输出模式通常使用推挽输出模式:GPIO_Mode_Out_PP 只有使用输出模式时才能设置频率:GPIO_Speed 使用串口通常使用复用模式: 选择IO接口工作方式: GPIO_Mode_AIN 模拟输入 GPIO_Mode_IN_FLOATING 浮空输入 //USART串口通信输入模式 GPIO_Mode_IPD 下拉输入 //按键的输入 GPIO_Mode_IPU 上拉输入 //按键的输入 GPIO_Mode_Out_PP 推挽输出 //GPIO引脚输出模式 GPIO_Mode_Out_OD 开漏输出 GPIO_Mode_AF_PP 复用推
[单片机]
嵌入式stm32学习:DMA-存储到存储
main.c #include stm32f4xx.h #include ./led/bsp_led.h /* 相关宏定义,使用存储器到存储器模式必须使用DMA2 */ #define DMA_STREAM DMA2_Stream0 #define DMA_CHANNEL DMA_Channel_0 #define DMA_STREAM_CLOCK RCC_AHB1Periph_DMA2 #define DMA_FLAG_TCIF DMA_FLAG_TCIF0 #define BUFFER_SIZE 32 #define TIMEOUT_MAX 1
[单片机]
新手入门使用STM32函数库之外部中断
啥也不说,先看看我的外星人开发板上的按键原理图。 板子偷懒,或者叫充分利用IO口得上拉功能,这边没有加常见的上拉电阻。到时候编程的时候使能IO的上拉就行了~看下面的接口知道了KEY0接到了STM32的PA13上! 曾经CZZ在梦里和我说过,STM32的任何一个IO都能作为外部中断输入,哇塞,超级强大! 参考一般的程序步骤如下: 1、系统初始化,如系统时钟初始化,使之进入72MHZ 主频; 2、GPIO 配置,务必注意打开GPIO 时钟时,一定打开AFIO 时钟。 3、EXTI 配置,在这里配置需要选择哪个引脚作为中断引脚。 4、NVIC 配置,这也是比单
[单片机]
STM32-自学笔记(2.ARMCortex-M3内核构架)
Cortex-M3 的CPU:32位CPU cpu的两种运行模式:线程模式(Thread)和处理模式(Handler)。 cpu不处理异常事件时,会运行在线程(Thread)模式下。而当cpu需要处理一个异常事件时,就会切换到处理(Handler)模式下。 此外 Cortex-M3的cpu还有两种处理代码的方式:私有模式和非私有模式。 私有模式下,cpu可以执行所有指令。 非私有模式下,部分指令是被禁止执行的(xPSR寄存器操作的MRS和MSR指令)。同时也不能对cpu的系统控制区中的寄存器进行进行操作。 另外,堆栈的使用也是可以设置的,主堆栈在线程模式和处理模式下都可以使用。通过设置,Handler模式也可以使用进程堆
[单片机]
无线传感器网络底层平台的深层研究
引言 目前,对WSN(Wireless Sensor Netwoek)的研究主要集中在协议栈、定位算法、能耗管理以及体系结构设计上,而针对无线传感网络操作系统的研究却相对较少,尤其是对其底层平台的研究更少,所以针对无线传感网络操作系统底层平台的研究有十分广阔的空间。本论文针对意法半导体STM32系列MCU和TI公司的CC2520无线模块进行介绍。主要描述了操作系统底层平台的构建,以及硬件驱动程序的实现。本论文的底层硬件抽象层是针对CC2520无线射频模块的,包括了平台构建、相关寄存器,以及外围接口等各个部分。而硬件驱动程序主要是为完成无线通信所需的硬件驱动设计,这主要包括:相应异步事件的中断机制;和PC通信的USART驱动;连
[单片机]