Arm 在微控制器上读取内存映射IO比读取常规内存需要更长的时间吗?

Arm 在微控制器上读取内存映射IO比读取常规内存需要更长的时间吗?,arm,stm32,memory-mapping,Arm,Stm32,Memory Mapping,我的特定上下文是STM32 ARM M0,但问题更一般 读取或写入内存映射外围设备(例如,GPIO端口或串行端口缓冲区)的内容是否需要与物理RAM中位置相同的时钟数?这在不同的体系结构中有所不同吗?几乎总是肯定的。AHB或AXI总线比APB总线快得多。不仅时钟慢了,总线宽度也慢了。使事情快速进行需要消耗电力和模具面积。最大波特率为115200的串行端口不需要像DDR或串行SPI闪存控制器那样快。为了缓解这一问题,一些软件将加快驱动程序的速度。通常,供应商不会记录APB总线速度,因为他们使用ARM

我的特定上下文是STM32 ARM M0,但问题更一般


读取或写入内存映射外围设备(例如,GPIO端口或串行端口缓冲区)的内容是否需要与物理RAM中位置相同的时钟数?这在不同的体系结构中有所不同吗?

几乎总是肯定的。AHB或AXI总线比APB总线快得多。不仅时钟慢了,总线宽度也慢了。使事情快速进行需要消耗电力和模具面积。最大波特率为115200的串行端口不需要像DDR或串行SPI闪存控制器那样快。为了缓解这一问题,一些软件将加快驱动程序的速度。通常,供应商不会记录APB总线速度,因为他们使用ARM提供的IP。某个地方的ARM文档会告诉你。几乎总是,你的核心内存会非常快;尤其是在皮质M上的中医药

ARM是一种加载/存储体系结构。这意味着存在从寄存器加载/存储到内存的特定指令。不可能直接对内存进行操作。例如,某些CPU允许您向内存值添加常量。因此,“加载”和“存储”通常有一个管道阶段。在该阶段,任何内存都可能具有等待状态。您的编译器和CPU将知道这一点,通常会尝试获得尽可能多的性能。如果您对设备采用内存顺序,则这可能是一场灾难

如果您有驱动程序
读取
写入
例程,那么实现寄存器缓存通常会更快。最好将寄存器读写封装在内联线或定义中,因为总线将来可能会更改。包装读/写可能是必要的<代码>易失性本身可能不足以进行内存映射I/O。明天硬件可能会更改为SPI或其他方式以保留pin计数。如果对访问进行包装,则很容易添加阴影


从中的图中,您可以看到AHB总线上的闪存/RAM和APB上的外围设备。这意味着外围设备速度较慢


可能有帮助:

做一些测试,并报告结果!抓起示波器,进行“示波器分析”。这意味着使用示波器测量操作所需的时间。通过使用直接寄存器引脚写入(为了速度和一致性),在进行一系列寄存器测试写入之前,将引脚写入高位,在进行一系列寄存器测试写入之后,将引脚写入低位

如何对嵌入式源代码进行示波器评测 例如:写入引脚高/低

// set pin HIGH (set to 1)
GPIOA_ODR |= 1UL << (uint32_t)pin_index;
// set pin LOW (clear to 0)
GPIOA_ODR &= ~(1UL << (uint32_t)pin_i);
观察示波器上的方波。高脉冲时间减去一个过渡时间=操作所用的时间

ie:你的方程式如下:

total_time = time_transition_to_LOW - time_transition_to_HIGH - pin_write_time.
要获得
pin\u write\u time
,即写入pin HIGH或LOW所需的时间(但不是两者的组合,只有1),请快速应用程序写入HIGH,然后写入LOW,两者之间没有延迟。注意使用写技术,使写低和写高占用相同数量的时钟周期(即:使用
GPIOA\u ODR
寄存器,如我上面所示,而不是
GPIOA\u BSRR
GPIOA\u BRR
,这两个寄存器根据您写入的管脚是高还是低,采用不同的时钟周期数)。现在,在示波器上测量其总时间,对于该测试:

pin_write_time = time_transition_to_LOW - time_transition_to_HIGH
要写入RAM中的特定地址,因为您需要将其与寄存器写入进行比较,请执行下面类似的奇特指针操作。假设您要写入的地址是
0x20000000
。下面是一个写入
val
的示例

uint32_t val = 1234567;
*((volatile uint32_t *)0x20000000UL) = val;
注意不要覆盖RAM中使用的实际变量。我将不详细介绍,但您可以通过修改链接器脚本以保留某些地址空间来保证这一点,或者您可以检查并打印代码中使用的变量的一些地址,并确保选择远离这些地址的测试地址,这样您就可以拥有一个pret这是一个好主意,在使用中不要覆盖实际变量

请注意,您当然可以只使用普通代码写入变量,但执行上述操作非常重要,这样您就可以测试不同的地址,因为内存是基于地址分段的,不同的内存段具有不同类型的总线。请参阅芯片数据表中的内存映射。例如:from,p102,图22。内存映射(见下文),您可以看到有各种RAM组要测试:

  • ITCM内存
  • DTCM存储器
  • SRAM1
  • SRAM2
请注意,读取/写入电池备份SRAM(BKPRAM)和闪存需要特殊的访问程序和/或功能,因此上述指针操作本身无法工作。您必须遵循芯片参考手册中规定的正确程序

不管怎样,做一些测试,然后再联系我们。我对你的结果很感兴趣

参考资料:

    • 没有必要。答案的细节将取决于实现(如其他答案中所述)。在ARM体系结构中,内存读取并不关心互连另一端的外围设备-无论是外围设备还是内存控制器

      在一个低性能的部分,两种类型的访问都可以是单周期的。一旦时钟速度开始增加,就需要考虑实现细节,并且更可能的是,至少一些内存访问将被优化(因为取指令是执行性能的主要限制)。


      通过高性能实时优化实现,您可能会发现一些内存访问比延迟优化的外围设备访问慢得多,但仍然会有一些“紧密耦合内存”,它们的性能与这些外围设备一样快或更快。

      因设计而异,因此同一公司不同系列或di不同的筹码。你可以看到我
      uint32_t val = 1234567;
      *((volatile uint32_t *)0x20000000UL) = val;