STM32的缓存Cache

你这个问题涉及到 ARM Cortex-M架构和具体芯片实现的区别

先说结论:

Cortex-M3/M4内核本身通常没有Cache设计,但Cortex-M4可以带Cache(取决于芯片厂商实现)。STM32F407有"预取缓存/指令缓存",严格来说不是完整意义上的CPU Cache。

我们详细拆开。


1. Cortex-M3/M4内核默认有没有Cache?

Cortex-M3

例如:

  • STM32F103
  • NXP LPC176x

Cortex-M3:

复制代码
CPU
 |
 |
总线
 |
Flash

没有:

  • I-Cache
  • D-Cache

原因:

M3定位:

  • 低成本
  • 实时控制
  • 简单确定性

典型:

几十MHz~100MHz。


Cortex-M4

情况复杂。

Cortex-M4架构:

可以没有Cache,也可以带Cache。

例如:

STM32F103:

Cortex-M3:

无Cache。

STM32F407:

Cortex-M4:

有:

  • ART Accelerator
  • Flash Prefetch
  • Instruction Cache

但是没有传统意义上的:

复制代码
L1 I-Cache
L1 D-Cache

2. STM32F407为什么需要Cache?

因为:

F407:

CPU:

复制代码
168MHz

但是Flash:

访问速度:

远低于CPU。

比如:

CPU:

复制代码
168MHz

一个周期:

约:

复制代码
5.9ns

Flash:

读取可能:

几十ns。

如果CPU每次取指:

复制代码
CPU
 |
Flash

CPU大量等待。


所以STM32加了:

ART Accelerator

Adaptive Real-Time Accelerator。

结构:

复制代码
        Cortex-M4

            |
            |
          ART
            |
            |
          Flash

作用类似:

指令Cache。


3. 它和真正Cache有什么区别?

比如Cortex-A:

手机CPU:

复制代码
CPU
 |
L1 Cache
 |
L2 Cache
 |
RAM

Cache里面存:

  • 指令
  • 数据

F407:

主要优化:

复制代码
Flash指令读取

也就是:

I-Cache。

它会:

提前读取Flash中的指令。


例如:

你的代码:

c 复制代码
for(i=0;i<1000;i++)
{
    a++;
}

CPU第一次:

读Flash:

复制代码

ART保存:

复制代码
缓存

下一次:

直接取。


4. 为什么M3/M4很多不用Cache?

因为实时控制很看重:

确定性。

例如FOC:

20kHz ISR:

要求:

复制代码
50us

如果:

Cache miss:

突然:

慢几十个周期。

可能:

PWM更新抖动。

所以很多MCU采用:

  • TCM
  • SRAM执行
  • 指令预取

而不是大Cache。


5. 那为什么STM32H7更复杂?

比如:

STM32H743:

Cortex-M7:

有:

复制代码
I-Cache
D-Cache

真正Cache。

结构:

复制代码
        M7

     I-cache
        |
     D-cache
        |
      AXI
        |
      SRAM

所以需要:

DMA缓存一致性处理。

例如:

DMA写ADC:

CPU Cache里还是旧数据:

必须:

c 复制代码
SCB_InvalidateDCache();

6. 对你做FOC有什么影响?

你之前:

ESP32 20kHz FOC

以后如果换:

STM32G431:

Cortex-M4:

复制代码
170MHz

没有D-cache。

优势:

实时性简单。

STM32F407:

复制代码
168MHz M4

ART加速:

跑普通代码快。

但是:

FOC:

主要吃:

  • ADC采样
  • PWM同步
  • DSP计算

Cache不是关键。


7. 简单总结

内核 Cache情况
Cortex-M3 通常无Cache
Cortex-M4 可无,也可有厂商加速
STM32F103 无Cache
STM32F407 ART指令缓存/预取,不是完整DCache
Cortex-M7 真正I/D Cache

所以:

不是Cortex-M4突然支持Cache,而是ARM只定义了内核接口,芯片厂商可以增加自己的存储加速结构。

对于FOC来说,像 STM32G4、TI C2000 这种实时控制MCU,反而更倾向于"高速Flash加速 + SRAM确定性执行",而不是像手机CPU那样依赖大Cache。你之前研究F2800137和G431做FOC,这也是为什么这些芯片强调实时PWM、ADC触发、CLA/DSP,而不是Cache大小。




你的问题问到CPU架构的核心了。

先回答第一个:

Cache 是CPU内核的东西吗?

答案:

大多数情况下,是的。Cache通常属于CPU内核的一部分(更准确说属于处理器微架构),但也可以由芯片厂商在CPU和存储器之间增加类似缓存的加速模块。

比如:

Cortex-M7:

ARM给出的内核:

复制代码
        Cortex-M7 Core

       ┌──────────┐
       │ I-Cache  │  ← 指令缓存
       │ D-Cache  │  ← 数据缓存
       └──────────┘

            |
            |
          总线
            |
          SRAM/Flash

这里的Cache就是CPU内核的一部分。


而 STM32F407:

不是这种:

复制代码
Cortex-M4
   |
 I-Cache
 D-Cache

它是:

复制代码
Cortex-M4

   |
   |
 ART Accelerator
   |
 Flash

这是ST自己设计的Flash加速器。


1. 为什么需要Cache?

CPU速度和内存速度差距巨大。

比如:

CPU:

复制代码
4GHz

内存:

复制代码
几十~几百MHz

如果CPU每次:

复制代码
取指令
   |
   ↓
内存
   |
   ↓
执行

CPU会等内存。

所以加一个高速小容量存储:

复制代码
CPU
 |
Cache
 |
RAM

Cache存什么?

两类:

  1. 程序代码
  2. 数据

所以分:

  • I-Cache
  • D-Cache

2. L1 I-Cache是什么?

L1:

Level 1 Cache

一级缓存。

I:

Instruction

指令。

也就是:

缓存CPU要执行的代码。

例如:

你的程序:

c 复制代码
void motor_control()
{
    pwm_update();
    current_pid();
    svpwm();
}

编译后:

变成机器指令:

复制代码
MOV
ADD
MUL
STR
BNE
...

这些存在Flash/RAM。

CPU执行:

第一步:

取指令:

复制代码
PC地址
 |
 ↓
找代码

如果没有I-Cache:

复制代码
CPU
 |
Flash

慢。

有I-Cache:

第一次:

复制代码
Flash → I-Cache

以后:

复制代码
I-Cache → CPU

快。


3. L1 D-Cache是什么?

D:

Data

数据。

缓存变量。

例如:

你的FOC:

c 复制代码
float iq;
float id;
float angle;
float rpm;

这些变量在RAM:

复制代码
RAM:
0x20000000

iq=1.2
id=0.1

CPU读取:

没有D-Cache:

复制代码
CPU
 |
RAM

有D-Cache:

复制代码
CPU
 |
D-Cache
 |
RAM

4. 为什么要分开?

因为:

代码和数据访问规律不同。

CPU执行程序:

主要:

复制代码
读代码

很少修改。

所以:

I-Cache:

特点:

复制代码
只读

数据:

比如:

c 复制代码
iq++;

数据:

复制代码
读
改
写

所以D-Cache复杂很多。


5. D-Cache为什么麻烦?

举个STM32H7 DMA例子。

CPU:

读取:

c 复制代码
adc_value

第一次:

RAM:

复制代码
100

进入D-Cache:

复制代码
Cache=100

然后:

DMA采样:

直接写RAM:

复制代码
RAM=200

但是:

CPU再次读:

发现Cache里面:

复制代码
100

于是:

CPU看到:

旧数据。

这叫:

Cache一致性问题。

解决:

清Cache:

c 复制代码
SCB_InvalidateDCache();

6. L1是什么意思?

现代CPU:

很多级:

复制代码
CPU

 ↓

L1 Cache
(最快,最小)

 ↓

L2 Cache
(慢一点,大一点)

 ↓

L3 Cache
(更大)

 ↓

RAM

例如电脑CPU:

Intel:

复制代码
L1
几十KB

L2
几百KB

L3
几十MB

嵌入式:

Cortex-M:

一般:

复制代码
L1

就结束。


7. 为什么Cortex-M3/M4没有?

因为定位不同。

Cortex-A:

手机:

复制代码
性能优先

需要Cache。

Cortex-M:

单片机:

复制代码
实时确定性

很多情况下:

不要复杂Cache。

比如FOC:

20kHz:

周期:

50us。

你希望:

每次:

复制代码
ADC
 ↓
PI
 ↓
SVPWM

时间稳定。

Cache miss:

可能突然:

慢几十周期。


8. 和你做FOC相关

比如:

STM32G431:

Cortex-M4:

没有DCache。

你的FOC:

复制代码
ADC DMA
 ↓
电流环
 ↓
SVPWM

非常确定。

STM32H743:

M7:

有DCache。

性能更强:

但是:

DMA、ADC、PWM数据需要处理Cache。


总结一句:

Cache就是CPU和内存之间的高速"小仓库"。L1 I-Cache存程序指令,让取代码快;L1 D-Cache存变量数据,让读写数据快。I-Cache主要加速"执行什么",D-Cache主要加速"处理的数据"。

你前面研究 STM32G4、F407、TI C2000 做FOC,其实也是在选一种取舍:实时控制更喜欢确定性,通用CPU更喜欢Cache带来的平均性能提升。




你的理解方向接近了,但是有几个关键点需要纠正。


1. Cache速度和CPU频率一样吗?

不一定等于,但通常非常接近CPU核心速度。

以现代CPU为例:

text 复制代码
CPU核心
  |
  |  几个CPU周期
  ↓
L1 Cache
  |
  |  几十个CPU周期
  ↓
L2 Cache
  |
  |  更慢
  ↓
RAM
  |
  ↓
Flash/硬盘

L1 Cache通常就在CPU核心旁边,甚至集成在CPU核心内部。

例如:

CPU:

复制代码
3GHz

一个周期:

T=\\frac1{3GHz}=0.33ns

L1 Cache访问:

可能:

复制代码
1~4个CPU周期

也就是:

复制代码
0.3ns~1ns级别

所以速度非常接近CPU。


而RAM:

比如DDR:

几十纳秒。

Flash:

几十到几百纳秒。

差距巨大。


2. CPU可以像读Flash一样读写Cache吗?

这里是一个非常关键的区别:

CPU不是直接"操作Cache地址"的。

正常情况下:

CPU认为自己访问的是内存地址。

例如:

c 复制代码
int a;

a = 10;

编译后:

CPU执行:

复制代码
读取地址0x20000000

CPU内部先判断:

复制代码
这个地址的数据在Cache里面吗?

情况1:Cache命中

例如:

复制代码
CPU请求:
0x20000000

Cache:
有这个数据

直接返回

路径:

复制代码
CPU
 |
Cache

情况2:Cache没有

叫:

Cache Miss

路径:

复制代码
CPU
 |
Cache
 |
RAM

RAM数据取回来:

放入Cache:

再给CPU。


所以:

CPU感觉:

一直是在读:

复制代码
0x20000000

实际上:

有时候读Cache,有时候读RAM。

这个过程硬件自动完成。


3. 那CPU能不能直接访问Cache?

一般:

应用程序不能。

比如你写:

c 复制代码
cache[0]=123;

是不可能的。

Cache不是普通RAM。

它没有固定地址。


但是:

CPU提供一些特殊指令:

例如ARM:

c 复制代码
SCB_CleanDCache();
SCB_InvalidateDCache();

这些是:

管理Cache。

不是读写Cache内容。


4. 那Cache里面的数据怎么修改?

比如:

c 复制代码
int speed=100;

假设:

speed地址:

复制代码
0x20000000

CPU执行:

复制代码
speed=200;

如果有D-Cache:

过程:

第一步:

读取:

复制代码
RAM:
speed=100

进入:

复制代码
D-Cache:
speed=100

第二步:

修改:

复制代码
D-Cache:
speed=200

注意:

此时RAM可能还是:

复制代码
speed=100

过一段时间:

Cache写回:

复制代码
D-Cache
 ↓
RAM

这叫:

Write Back Cache(回写缓存)


还有一种:

Write Through(直写)

修改:

同时写:

复制代码
Cache
+
RAM

简单,但是慢。


5. 为什么STM32H7 DMA要管Cache?

比如:

ADC DMA:

直接写RAM:

复制代码
DMA
 |
RAM

但是CPU:

复制代码
CPU
 |
D-Cache

里面可能还是旧数据。

所以:

DMA和CPU看到的数据可能不一致。


6. STM32F407的ART算Cache吗?

严格说:

它更像:

复制代码
Flash指令预取缓存

结构:

复制代码
CPU
 |
ART
 |
Flash

主要优化:

取指令。

不是:

复制代码
CPU
 |
L1 I-cache
 |
L1 D-cache

这种完整CPU Cache。


7. 对比一下速度

大概:

存储 速度
CPU寄存器 1周期
L1 Cache 几周期
L2 Cache 十几个周期
SRAM 几个~几十周期
Flash 更多周期
外部存储 更慢

8. 和你做FOC联系一下

比如:

20kHz电流环:

c 复制代码
iq = adc_current;
error = iq_ref - iq;
uq = PI(error);
svpwm(uq);

如果:

代码在Flash:

CPU不停取指令。

有I-Cache:

复制代码
第一次 Flash
后面 Cache

速度稳定。

如果:

数据在D-Cache:

例如:

ADC DMA更新电流:

就需要注意一致性。

所以:

像 STM32G431 这种 M4 无DCache,做FOC反而简单;

STM32H743 M7性能强,但做高速控制时必须懂Cache管理。


一句话总结:

Cache不是CPU可以像Flash一样读写的一块存储,它是CPU内部自动管理的高速缓存层。CPU访问内存地址时,硬件自动决定从Cache还是RAM取数据。L1 Cache速度接近CPU,而Flash/RAM远慢于CPU。




这个问题问到了CPU内部真正的工作方式。

先说结论:

CPU和Cache之间通过CPU内部的数据通路(总线/接口)交换数据,通常是一个硬件自动完成的过程,软件看不到。CPU并不是通过像读Flash那样发地址命令去"读Cache"。

我们拆开。


1. CPU内部大概结构

以带 L1 Cache 的处理器为例:

复制代码
              CPU核心

        ┌─────────────┐
        │  运算单元 ALU │
        │  寄存器       │
        └──────┬──────┘
               |
          Load/Store单元
               |
        ┌──────┴──────┐
        │             │
     I-Cache       D-Cache
   (指令缓存)    (数据缓存)
        │             │
        └──────┬──────┘
               |
             总线
               |
             RAM

CPU核心里面有:

  • 取指单元(Instruction Fetch)
  • Load/Store单元(读写数据)
  • ALU运算单元
  • 寄存器

Cache就在CPU和内存之间。


2. CPU取指令时怎么和I-Cache通信?

比如程序:

c 复制代码
a = b + c;

编译后:

CPU需要执行机器指令:

复制代码
ADD
MOV
LOAD
STORE

CPU有一个:

PC寄存器(Program Counter)

里面保存下一条指令地址。

例如:

复制代码
PC = 0x08001000

CPU说:

我要地址0x08001000的指令


情况1:I-Cache命中

硬件检查:

复制代码
I-Cache里面有没有0x08001000?

有:

复制代码
I-Cache
地址       数据

0x08001000 MOV R0,R1

直接返回:

复制代码
I-Cache
    |
    ↓
CPU取指单元

速度:

几个CPU周期。


情况2:I-Cache没有

叫:

Cache Miss

流程:

复制代码
CPU
 |
I-Cache
 |
总线
 |
Flash/RAM

取回来:

通常不是只取一条指令。

比如:

取一个Cache Line:

复制代码
32字节
64字节

放入:

复制代码
I-Cache

然后CPU继续执行。


3. D-Cache怎么交换数据?

例如:

c 复制代码
x = y + 1;

CPU执行:

读取y:

复制代码
LOAD y

CPU发送:

复制代码
地址:
0x20001000

给D-Cache。


命中:

D-Cache:

复制代码
地址        数据

0x20001000  100

返回:

复制代码
D-Cache
 ↓
CPU寄存器

然后:

ALU:

复制代码
100+1

结果:

101。


写数据:

例如:

c 复制代码
x=200;

CPU:

复制代码
STORE 200

到D-Cache。

如果Write Back:

复制代码
CPU
 |
D-Cache=200
 |
(以后)
 |
RAM=200

4. CPU和Cache之间速度为什么快?

因为它们通常:

  • 同一个芯片
  • 同一个时钟域
  • 很宽的数据通路

例如:

CPU一次取:

64bit

128bit

256bit

不是像外设:

SPI:

一位一位传。


5. Cache里面是什么结构?

Cache不是简单数组。

里面有:

Tag(标签)

记录:

这个数据来自哪个地址。

Data

真正的数据。

例如:

Cache Line:

复制代码
Tag:
0x1234

Data:
AA BB CC DD EE FF

CPU访问:

复制代码
地址0x12345678

Cache控制器拆地址:

复制代码
Tag
Index
Offset

判断:

有没有。


6. 那Cache满了怎么办?

比如:

L1 Cache:

32KB

已经满。

新的数据来了:

需要替换。

例如:

淘汰:

复制代码
旧Cache Line

如果数据修改过:

写回RAM。

这个叫:

Cache Replacement。


7. Cortex-M里面是什么情况?

比如:

Cortex-M7:

复制代码
M7 Core

  |
 AXI接口

  |
 L1 I-Cache
 L1 D-Cache

  |
 SRAM/Flash

CPU内部:

高速接口连接。


而你的STM32G431:

Cortex-M4:

没有DCache:

大概:

复制代码
CPU
 |
总线
 |
Flash/SRAM

F407:

复制代码
CPU
 |
ART Accelerator
 |
Flash

8. 一个简单比喻

CPU像工厂工人:

RAM像仓库:

Cache像工位旁边的小柜子。

没有Cache:

复制代码
工人
 ↓
跑仓库拿工具
 ↓
回来干活

很慢。

有Cache:

复制代码
工具放身边

伸手拿

快很多。


所以总结:

CPU和Cache通过内部高速硬件接口交换数据。CPU只负责发出"我要访问某个地址",Cache控制器自动判断数据是否存在,如果存在直接返回,不存在就去RAM取,并把数据复制到Cache。软件通常不知道这个过程。

这也是为什么现代CPU性能很大程度依赖Cache设计,而不是单纯看CPU频率。对于你做FOC的MCU来说,理解Cache最重要的是后面那个问题:DMA、ADC、PWM数据为什么会和Cache冲突。




这个问题非常关键,因为这里容易把 Flash、Cache、CPU读写方向搞混。

先说结论:

STM32通过Cache(或者Flash加速器)访问Flash时,通常是"从Flash把指令/数据读到Cache",不是把数据写入Cache再写Flash。

Cache主要解决"读取慢"的问题,不是用来保存Flash写入数据的。

我们分情况看。


1. CPU执行Flash里的代码

例如 STM32:

c 复制代码
void motor_control(void)
{
    pwm_update();
    pid_calc();
}

代码存放:

复制代码
Flash
0x08000000

CPU执行:

复制代码
CPU
 |
 | 请求指令地址
 ↓
Cache / ART
 |
 ↓
Flash

第一次:

复制代码
Flash
  |
  | 读取一段代码
  ↓
I-Cache
  |
  ↓
CPU执行

之后:

复制代码
I-Cache
  |
  ↓
CPU

速度快。

这里是:

Flash → Cache → CPU


2. 那CPU修改Flash里的数据呢?

例如:

c 复制代码
uint32_t value;

存Flash:

c 复制代码
const uint32_t value = 123;

Flash不是普通RAM。

CPU不能:

c 复制代码
value = 456;

直接改。

Flash写入需要:

  1. 解锁Flash控制器
  2. 擦除
  3. 编程写入

例如STM32:

c 复制代码
HAL_FLASH_Program(...)

流程:

复制代码
CPU
 |
Flash控制器
 |
Flash存储阵列

不是:

复制代码
CPU
 |
Cache
 |
Flash

3. 那Cache里面的数据会不会写回Flash?

不会。

这个非常重要。

普通CPU:

复制代码
CPU
 |
D-Cache
 |
RAM

D-Cache可以:

复制代码
Cache → RAM

因为RAM可以随便写。

但是:

Flash:

复制代码
Flash

不是这种缓存关系。

Flash写入:

  • 需要擦除
  • 有寿命限制

所以不会设计成:

复制代码
Cache → Flash自动回写

4. STM32F407的ART到底做什么?

F407:

不是传统:

复制代码
CPU
 |
I-Cache
 |
Flash

而是:

复制代码
Cortex-M4
    |
    |
 ART Accelerator
    |
    |
 Flash

它缓存的是:

Flash读取的数据(主要是指令)

比如:

CPU需要:

复制代码
地址0x08001000

ART:

发现没有:

复制代码
去Flash读一块

保存:

复制代码
ART里面

以后CPU执行:

直接提供。


5. 那如果Flash里面的数据被修改怎么办?

例如:

你程序运行:

复制代码
Flash地址0x08080000

保存参数。

你执行:

复制代码
擦除Flash
写新数据

如果这个区域之前被Cache缓存了:

可能出现:

Cache里面还是旧数据。

所以一些CPU需要:

清Cache。

例如:

Cortex-M7:

复制代码
SCB_InvalidateICache();

告诉CPU:

之前缓存的东西失效。


6. 为什么D-Cache一般缓存RAM,不缓存Flash写?

因为典型结构:

数据:

复制代码
CPU
 |
D-Cache
 |
RAM

频繁读写。

程序:

复制代码
CPU
 |
I-Cache
 |
Flash

主要读取。

Flash写入:

是特殊操作:

复制代码
CPU
 |
Flash Controller
 |
Flash

7. 放到你熟悉的STM32 FOC

比如STM32G431:

你的FOC代码:

复制代码
Flash
 |
CPU执行

没有DCache。

STM32H743:

可能:

复制代码
Flash
 |
I-Cache
 |
CPU

代码执行。

ADC采样:

复制代码
ADC
 |
DMA
 |
RAM
 |
CPU

这里才涉及:

D-Cache一致性。


简单总结:

操作 数据流
CPU执行Flash代码 Flash → I-Cache → CPU
CPU读Flash常量 Flash → Cache → CPU
CPU写RAM变量 CPU → D-Cache → RAM
CPU写Flash参数 CPU → Flash控制器 → Flash
Cache自动写Flash ❌不存在

所以你的理解应该改成:

Cache是Flash/RAM的"读缓冲",不是Flash的"写缓冲"。STM32通过Cache访问Flash,本质是为了让CPU更快拿到指令和数据。




cache使用常见问题

使用 Cache 最大的问题不是"速度",而是:

CPU看到的数据,可能和内存里的真实数据不一致。

尤其是在嵌入式系统里,Cache、DMA、多核、外设一起用时容易踩坑。

下面按重要程度讲。


1. Cache一致性问题(最常见)

这是D-Cache最大的坑。

例如:

STM32H7:

text 复制代码
          CPU
           |
        D-Cache
           |
          RAM

同时:

text 复制代码
ADC
 |
DMA
 |
RAM

假设:

ADC采样结果:

c 复制代码
uint16_t adc_value;

地址:

复制代码
RAM = 100

第一次CPU读取

CPU:

c 复制代码
value = adc_value;

流程:

复制代码
RAM
 |
 ↓
D-Cache
 |
 ↓
CPU

Cache保存:

复制代码
D-Cache = 100

DMA更新数据

ADC来了新数据:

复制代码
DMA → RAM

RAM变成:

复制代码
RAM = 200

但是:

复制代码
D-Cache = 100

CPU再次读取

CPU:

c 复制代码
value = adc_value;

它优先看Cache:

发现:

复制代码
D-Cache有

直接返回:

复制代码
100

但是实际:

复制代码
RAM已经200

这就是:

Cache污染 / 数据不一致


解决:

DMA写入前:

c 复制代码
SCB_InvalidateDCache();

意思:

丢掉Cache里的旧数据,重新从RAM读取。


2. Cache写回问题(Write Back)

D-Cache通常采用:

Write Back

例如:

c 复制代码
speed = 100;

CPU修改:

可能:

复制代码
D-Cache = 100
RAM = 0

数据还没有写回RAM。

如果此时:

DMA读取RAM:

复制代码
DMA读到0

但是CPU认为:

复制代码
speed=100

解决:

写回Cache:

c 复制代码
SCB_CleanDCache();

意思:

把Cache里面修改的数据写回RAM。


3. 实时性抖动问题

这个对FOC比较重要。

没有Cache:

比如:

一次循环:

复制代码
1000周期

每次差不多。

有Cache:

可能:

第一次:

复制代码
Cache miss
2000周期

后面:

复制代码
1000周期

时间变化:

复制代码
1000
1000
2000
1000

对于:

普通任务:

没关系。

对于:

FOC:

20kHz:

周期:

复制代码
50us

希望:

复制代码
每次稳定

Cache miss可能造成:

PWM更新抖动。

所以实时控制喜欢:

  • SRAM运行关键代码
  • 关闭Cache
  • 使用TCM

4. 调试困难

比如:

你打印:

c 复制代码
printf("%d", value);

看到:

复制代码
100

但是示波器:

实际PWM对应:

200。

原因:

可能:

  • Cache旧数据
  • 编译器优化
  • DMA不同步

这种问题非常折磨人。


5. 多核系统问题

比如ESP32:

两个CPU:

复制代码
CPU0
 |
变量x

CPU1
 |
变量x

如果有Cache:

CPU0 Cache:

复制代码
x=10

CPU1 Cache:

复制代码
x=20

两个CPU看到不同值。

需要:

  • Cache一致性协议
  • 内存屏障

6. 修改代码后执行旧代码

比如:

Bootloader升级:

Flash:

旧程序:

复制代码
A函数

Cache里面:

复制代码
A函数旧指令

然后:

Flash更新:

复制代码
A函数新代码

CPU可能继续执行Cache旧代码。

需要:

清I-Cache。


7. 内存占用增加

Cache需要芯片面积:

例如:

Cortex-M7:

复制代码
I-Cache 16KB
D-Cache 16KB

总共:

32KB SRAM。

芯片成本增加。


8. 对FOC有什么影响?

你做FOC:

20kHz电流环。

如果:

STM32G431:

无DCache:

优点:

复制代码
ADC DMA
 |
RAM
 |
CPU

简单。

如果:

STM32H743:

有DCache:

需要:

ADC DMA buffer:

放:

c 复制代码
__attribute__((section(".dma_buffer")))

或者:

配置:

不可缓存区域。

否则:

可能:

电流采样错误。


总结一下:

问题 原因
数据不是最新 Cache里有旧副本
DMA数据错误 DMA绕过Cache直接访问RAM
CPU和外设数据不一致 没有维护Cache
实时抖动 Cache miss
多核变量异常 Cache不同步
升级程序异常 旧指令还在Cache

所以:

Cache提高平均性能,但牺牲了一部分"确定性"和"简单性"。

这也是为什么做FOC、电机控制、工业控制时,很多芯片(STM32G4、TI C2000)宁愿没有复杂Cache,而是靠高速SRAM、DMA、硬件PWM触发来保证实时性。你之前关注的 STM32G431 vs F2800137,其实就是典型的"通用CPU性能"和"实时控制确定性"的取舍。

相关推荐
zcmodeltech2 小时前
供热系统模型多工况控制系统设计:基于STM32与Modbus RTU的热源-管网-末端联动方案
大数据·stm32·单片机·嵌入式硬件·制造·数据库系统
智闲电子设计3 小时前
STM32 定时器 PWM 实战:从呼吸灯到舵机控制
c语言·stm32·单片机·嵌入式硬件·学习
azwsm11 小时前
驱动第一阶段——启动流程
单片机·嵌入式硬件
单片机杂货铺13 小时前
基于单片机的自动开窗器设计
stm32·嵌入式硬件·51单片机·硬件工程
天天爱吃肉821815 小时前
商用车多体动力学实战笔记|第6篇:动力传动系统(发动机、变速箱、分动器、TCS、LSD限滑差速)
大数据·人工智能·笔记·python·嵌入式硬件·汽车
别催小唐敲代码15 小时前
STM32 I2C协议详解:从原理到实战
stm32·网络协议·协议
lhbweilai15 小时前
STM32 I2C(hal库)
stm32·单片机·嵌入式硬件
ai_coder_ai15 小时前
分布式缓存架构设计与实践
分布式·缓存
单片机杂货铺19 小时前
基于STM32的智能市政清洁小车系统设计
stm32·单片机·嵌入式硬件·物联网·硬件工程