各位看官,在看EFM32的MSC里面的函数时,例如在看MSC_ErasePage()这个函数的时候,有否注意这个函数上面的一大段解释呢。详细的英文如下: This function MUST be executed from RAM. Failure to execute this portion of the code in RAM will result in a hardfault. For IAR, Rowley and Codesourcery this will be achieved automatically. For Keil uVision 4 you must define a section called "ram_code" and place this manually in your project's scatter file. 大致上的意思是,这个函数必须在RAM中执行。如果在不在RAM中执行的话,会产生硬件错误中断即Hardfault。 如果使用IAR, Rowley, Codesourcery,这个函数会自动在RAM中执行,而在Keil uVersion4中,则必须定义个叫做"ram_code"的段,并在项目的scatter 文件中申明。 首先为什么IAR等可以自动在RAM中执行呢? 1.IAR提供了__ramfunc,这个关键字,他会把函数自动拷贝到RAM中执行。在efm32_msc.h中对MSC_ErasePage()函数的定义如下: __ramfunc msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress); 2.类似,在Rowley中,定义如下: msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress) __attribute__ ((section(".fast"))); 3.类似,在Codesourcery,定义如下: msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress) __attribute__ ((section(".ram"))); 三种定义各有不同,但是都实现了函数在RAM中执行的效果。而且也无需用户设置。 在Keil的目前版本中,就比较麻烦,举个例子来说,例如想在G STK上对操作的话,需要对Keil的工程配置中的Linker做一定的修改。具体示例如下: 1.取消Use Menory layout from Target Dialog 选项 2.在Scatter file中选择自定义的.sct文件。 接下来,我们可以看一下,这个文件里面定义了什么。 ; ************************************************************* LR_IROM1 0x00000000 0x00020000 { ; load region size_region 里面定义了ROM的地址,RAM的地址,但是多定义了一个叫做ram_code的东东。这个ram_code就是将那几个MSC里面的操作函数放到RAM里面的定义了。 各位看官可以拷贝这段信息,再根据自己的型号进行修改,然后保存为.sct 文件即可。然后通过Keil加载进来。 但是为什么非的要拷贝到RAM中执行呢?原因是因为在擦写Flash的时候,是不能对Flash进行操作的。而且擦写Flash需要一定的时间去操作。在我们的函数中,会使用代码去读取MSC相关的寄存器,然后判断操作是否完成。因此这里会有一个悖论就是,你既需要运行代码去判断是否完成,又不能在Flash中运行代码,所以,一个解决办法就是在RAM中运行喽。 |
|
来自: BeautymengRoom > 《嵌入式系统》