| 本帖最后由 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.
 
 |