CheckMultipleBlocks函数引发的异常与解决

//=====================================================================
//TITLE:
//    CheckMultipleBlocks函数引发的异常与解决
//AUTHOR:
//    norains
//DATE:
//    Wednesday  12-January-2011
//Environment:
//    .Net Micro Framework Porting 4.1
//    MDK V4.0.0
//    VS2010
//=====================================================================

 

     最近在调试TinyCLR的时候,发现程序一定会跑到AppDomain_Mark函数,并且执行到函数内的CheckMultipleBlocks调用必定会发生Hard Fault异常。查了很多文档,也做了很多猜测性调试,一直都没有解决该问题。

 

     在百般苦恼的时候,抱着死马当活马医的态度,将叶帆的《TinyCLR编译与测试》(http://blog.csdn.net/yefanqiu/archive/2010/02/18/5310634.aspx)一文中的配置放到我的工程中,没想到,奇迹出现了,程序再也没有跑到AppDomain_Mark里,但却正常输出了.Net Micro Framework的相关信息!

 

     这究竟是怎么一回事呢?经过多次的对比测试,发现原因出在Heap的设置上。因为我想使用单芯片解决方案,不采用外部RAM,想将Heap,Custom_Heap和Stack全部放到STM32F103ZE的内部RAM中,所以书写了如下的内存分配:
 <Set Name="Heap_Begin"         Value="0x20005200"/>
    <Set Name="Heap_End"           Value="0x20008CFC"/>
    <Set Name="Custom_Heap_Begin"  Value="0x20008D00"/>
    <Set Name="Custom_Heap_End"    Value="0x20008DFC"/>
    <Set Name="Stack_Bottom"      Value="0x20008E00"/>
 <Set Name="Stack_Top"          Value="0x20008FFC"/>

 

    Heap的大小为0x20008CFC - 0x20005200 = 0x3AFC = 15 100,也就是大概15KB左右,而这个对于TinyCLR来说太小了,完全就不能满足最小的需求。看到这里,也许有人说,为什么不把Heap_Begin的数值往前移一点,变为0x20003000之类?这也是不可能的。因为在编译TinyCLR的时候,0x20005200之前的内存已经被使用殆尽,再也没有可用的余地了。打开tinyclr.symdefs文件,我们就能够清晰看到这点,如图:


 

    那往前不行,往后可以么?查看了一下我的配置文件,发现有这么一节也是占用RAM的:
    <IfDefined Name="PROFILE_BUILD">
        <Set Name="ProfileBuffer_Begin" Value="0x20009000"/>
        <Set Name="ProfileBuffer_End"   Value="0x2000EFFC"/>
    </IfDefined>

 

    但在实际测试中,发现将ProfileBuffer屏蔽掉后其实也是可以正常编译的。换句话来说,ProfileBuffer在目前的编译方式中,是可有可无的,那么为什么我们不物尽其用,将其所占据的这部份内存拿来挥霍呢?于是,我们的离散文件可以更改配置如下:
    <Set Name="Heap_Begin"        Value="0x20008000"/>
    <Set Name="Heap_End"          Value="0x2000DFFC"/>
    <Set Name="Custom_Heap_Begin" Value="+0"/>
    <Set Name="Custom_Heap_End"   Value="0x2000EFFC"/>
    <Set Name="Stack_Bottom"      Value="+0"/>
    <Set Name="Stack_Top"         Value="0x2000FFFC"/>

 

    编译,测试,一切顺利!TinyCLR正常跑起来了!

 

    但这还是留下了小小的隐患,因为目前TinyCLR还比较小,并没有挂载相应的.NMF程序。如果以后放置了更多的.NMF应用程序,会不会因为RAM空间不够,再次引发类似的莫名其妙的问题呢?这个确实不好说。不过,对此我们也并不是没有办法,开发板不是还有外部的RAM么?如果担心内部的64K RAM不够用,我们完全可以用外部的RAM嘛!我们可以将,Heap和Custom_Heap放置到外部RAM,而Stack依旧放置到内部的RAM,也就是说这时候的离散文件配置如下:
    <Set Name="Heap_Begin"          Value="0x68000000"/>
    <Set Name="Heap_End"            Value="0x6801DFFC"/>
    <Set Name="Custom_Heap_Begin"   Value="0x6801E000"/>
    <Set Name="Custom_Heap_End"     Value="0x6801FFFC"/>
    <Set Name="Stack_Bottom"        Value="0x20008000"/>
    <Set Name="Stack_Top"           Value="0x2000FFFC"/>

 

    编译,将TinyCLR下载到开发板,运行,也是一切顺利!TinyCLR也能够在外部RAM跑起来了!

posted @ 2011-01-12 17:32  我的一天  阅读(153)  评论(0编辑  收藏  举报