解决&Load$$ER_RAM$$Base赋值语句的崩溃
//=====================================================================
//TITLE:
// 解决&Load$$ER_RAM$$Base赋值语句的崩溃
//AUTHOR:
// norains
//DATE:
// Monday 27-September-2010
//Environment:
// KEIL MDK 4.0
// .NET Micro Framework 4.1
//=====================================================================
也许大家将一切参数都规规矩矩设置完毕,满怀希望开始调试NativeSample时,突然发现在调试TinyHal.CPP的BootEntry函数时卡壳了。具体点来说,就是在调试到LOAD_IMAGE_Start = (UINT32)&Load$$ER_RAM$$Base;这个语句的时候,会出现总线错误,如图:
这时候可能大家的第一反应是Heap或Stack的设置有误。但实际上,无论你怎么设置Heap或Stack,这个错误还是依然存在的。所以基本可以确定,问题不出在Heap和Stack的设置。如果大家还有心的话,修改TinyHal.cpp的代码,比如在BootEntry增添如下语句:
会发现一切都是正常的。那么为什么偏偏给LOAD_IMAGE_Start赋值的时候就出错了呢?是不是LOAD_IMAGE_Start有什么蹊跷?我们可以再次执行debug,设置断点,然后在symbols窗口查看LOAD_IMAGE_Start的地址,如图:
看到什么了么?没错!LOAD_IMAGE_Start的地址是0x0000 0040,而这个根本就不是内存的地址!那么0x0000 0040此时会是什么地址呢?如果是以Flash模式启动,Flash的地址就印射到0x0000 0000,那么这时候的0x0000 0040指向的就是Flash!现在直接往Flash写数值,肯定会引发BUS ERROR!
找到问题的根源,一切就好办了。打开scatterfile_tools_mdk.xml文件,发现ER_RAM_RO字段的设置如下:
<ExecRegion Name="ER_RAM_RO" Base="0x00000000" Options="ABSOLUTE" Size="">
起始地址为0x0000 0000,这是不正确的,因为内存地址是以0x2000 0000为起始的。如果大家不明白这地址的来源,可以查看我这篇文章:《详解STM32F10x在.Net Micro Framework的Processor Properties的取值》(http://blog.csdn.net/norains/archive/2010/09/20/5896807.aspx)。现在只要将Base的数值更改为0x2000 0000即可,如:
<ExecRegion Name="ER_RAM_RO" Base="0x20000000" Options="ABSOLUTE" Size="">
这时候再开始调试,发现已经能够顺利执行LOAD_IMAGE_Start变量的赋值,如图: