juq2oyobhrl64031919635.gif
- V8 h! ~8 d( l# T8 u j- ], N& Q
点击上方蓝色字体,关注我们& x# ]( K/ |7 P3 w. I
# l; V- g" [& I2 [# N2 x13 O- m3 A% K/ c/ C
微控制器 (MCU)
$ W( L* s" {( n% ~# a$ @大多数微控制器 (MCU) 使用物理地址进行内存访问。MCU 通常是设计为简单、资源有限的嵌入式设备,目标是低功耗、低成本以及实时操作。* A- `+ V+ k1 a- W! D
$ p( d% S# ?+ d这些设备一般没有复杂的内存管理单元 (MMU) 来处理虚拟地址到物理地址的映射。因此,程序代码和数据是直接通过物理地址访问的。
7 d; @5 T+ t: u; b& X* ]- T+ U6 @* h2 x- b! l1 d
以常见的 STM32 系列微控制器为例: ]$ ]% N5 \" n) G8 c
Flash 存储器:通常从地址 0x08000000 开始。这个地址是物理地址,程序代码通常存储在这里。SRAM:通常从地址 0x20000000 开始。这个地址也是物理地址,用于数据存储和堆栈操作。
, p% f( C: B& @6 n0 {6 l3 U" z
" S2 i0 ? o- J0 K! Y在编程时,当开发者使用指针或访问某个变量时,实际操作的是物理地址。例如:: H7 ]3 B3 G* C9 {3 N- X( A
$ J6 w0 ? I* k3 h/ Q
#define LED_PIN (*(volatile uint32_t*)0x48000814) // 指定 GPIO 端口的物理地址 int main(void) { LED_PIN = 0x01; // 设置引脚电平为高 while (1);}
# q$ E7 r) i3 U2 T y在这个例子中,0x48000814 是直接引用的物理地址,用于控制 MCU 上的 GPIO 引脚。6 D* O4 ^: D/ |
2
' P- i# l3 S& u4 w$ A6 ?' ]8 |( |系统级芯片 (SoC)) B7 ?, [; N) E% U, N
与 MCU 不同,系统级芯片 (SoC) 通常集成了更复杂的处理器内核(例如 ARM Cortex-A 系列),并且可能运行如 Linux 这样的操作系统。! i: p: b9 r, x! O) ^
/ }. `# R2 S M7 S: O
这些 SoC 通常具有内存管理单元 (MMU),能够将虚拟地址映射到物理地址。因此,虚拟地址是应用程序通常使用的地址空间。
. A( t, |8 j# P Z. O8 k. s. g% n2 |+ b; o9 z% e& S8 _3 j
以 Raspberry Pi 这类基于 ARM Cortex-A 系列处理器的 SoC 为例:
) e* d9 Z8 k' L$ v) G# m0 n内核态地址空间:在操作系统内核中,内核会管理物理内存,内核代码通常可以直接访问物理地址,但通常仍使用虚拟地址进行管理。用户态地址空间:应用程序在用户态下运行,所有内存访问都是通过虚拟地址进行的。操作系统通过 MMU 将这些虚拟地址映射到实际的物理内存。 b+ z$ N' b7 D2 p5 W
; y# `) Q* Y$ X4 q U( J t
C 语言示例如下:9 Z( @* j/ b% L2 u- O
1 c# N) D- s/ @
#include #include int main() { int *ptr = (int *)malloc(sizeof(int)); if (ptr == NULL) { fprintf(stderr, "内存分配失败!
( ?1 A( Z" ^9 ~5 m- w"); return 1; } *ptr = 123; printf("虚拟地址: %p, 值: %d
/ Y0 A: ]2 M" m+ e", (void*)ptr, *ptr); free(ptr); return 0;}
# ~2 _% Z! h& U9 K: c' d# q) F8 I5 W在这个例子中,malloc 函数返回的指针 ptr 是一个虚拟地址。操作系统会通过 MMU 将其映射到物理内存。应用程序无需了解这个过程,操作系统自动管理虚拟地址和物理地址之间的映射关系。5 q! V7 A* W. j! e" t
! Z- Q1 I) ^; x, X
MCU 通常使用物理地址进行内存访问,因其设计简单且资源受限,不具备复杂的内存管理单元 (MMU)。SoC,特别是那些运行复杂操作系统的 SoC,如 ARM Cortex-A 系列,通常使用虚拟地址进行内存管理,依赖 MMU 将虚拟地址映射到物理地址。" n* Q q: Y, `% U; ~
; K+ `) A F# `
理解这两者的差异对于开发嵌入式系统的程序时至关重要,因为内存管理的复杂性和方式直接影响到程序的设计和调试方式。1 c1 {2 d k" `7 ?
" F" L) n3 q- ` w* I, ^ @
x1o5tsoha1y64031919735.jpg
+ d+ p& W' B. {+ U1 G8 E* ?
eif0p15bvpy64031919835.gif
. N+ _ Y9 P7 _2 e! v点击阅读原文,更精彩~ |