本帖最后由 pattywu 于 2013-12-8 20:44 编辑
【原创】
本帖教你如何用Cortex-M的MemManage_Fault,在确定某一款MCU的SRAM的大小。
在Cortex-M处理器中,有一个系统中断(Fault),叫存储器管理Fault。看过《ARM Cortex-M3 权威指南》的开发者,应该能查到这个Fault。
1、在初始化内存时,读取SRAM中的数据,边界为了1K字节或2K字节。绝大部分的MCU中,SRAM的设计,是以2K字节为单位的。比如:2K、4K、6K、8K、10K、12K、16K、20K、24K、32K、48K、64K、96K、128K等等。
2、当读取的数据地址不存在于SRAM中时,会发生MemManage_Fault。如果没有使能MemManage_Fault时,就会引发Hard_Fault。
3、MemManage_Fault或Hard_Fault的处理过程:
MemManage_Handler PROC
EXPORT MemManage_Handler
MRS R0, MSP ; 读MSP
LDR R1, [R0,#24] ; 读PC值
ADD R1,#2 ; PC+2,路过内存访问的指令
STR R1, [R0,#24] ; PC的值写回到堆栈中
BX LR ; 中断返回到线程模式,使用PSP
ENDP
4、获取SRAM大小的处理过程:
#define SRAM_BASE 0x20000000 // 定义内存的基址,(存在MCU的SRAM的基地址不为0x20000000的)
int GetMemSize() // 初始化全局内存池
{
int i, j=0;
u32* p;
u32 val=0x12345679;
p=(u32*)SRAM_BASE; // 取SRAM基地址,宏定义:0x20000000(有些)
for(i=1; i<=1024; i++) // 1024*2K
{
p += 512; // 512字(2K字节)为单位
if(val != *p) // 读出来数据
{
val = *p; // MemFault时,相当于没读数据
}
else // 如果数据相同
{
j = *(u32*)0xe000ed34; // Fault后,保存的数据地址
if(j == (u32)p) // 数据地址相同与本次访问的地址相同
{
break; // 跳出
}
}
}
return (j-SRAM_BASE); // 首次MemManage_Fault的地址,就是SRAM内存的最大地址
}
5、需要解释一下的是:当发生MemManage_Fault时,地址0xe000ed34处保存有引发MemManage_Fault时的内存地址。
6、说个小秘密:经检测,STM32F103VC的SRAM,不是手册上的48K,而是64K,FLASH也不是手册上的256K,而是512K.
|