修正STM32F103ZE的散列文件

//=====================================================================
//TITLE:
//    修正STM32F103ZE的散列文件
//AUTHOR:
//    norains
//DATE:
//    Tuesday  20-October-2010
//Environment:
//    KEIL MDK 4.0
//    .NET Micro Framework Porting 4.1
//    RedCow Board
//=====================================================================

 

     如果你需要编译NativeSample工程,那么不可避免地就需要接触到散列文件。对于MDK来说,所用到的则是scatterfile_tools_mdk.xml文件。只不过,如果你是采用默认生成的数值,那么结果会让你很郁闷。那么,为了能有一个快乐的移植之旅,我们现在就来看看这些数值应该如何更改。

 

     在开始之前,我们先来了解一下向量表。对于CORTEX-M3来说,向量表应该位于0x00000000位置。为什么是这个位置呢?因为复位之后,PC指针指向0x00000000。所以,我们先有这么个概念,在开始调试之后,PC应该指向向量表的地址。

 

     对于原来的散列文件内容,有一点不太喜欢的是,居然将向量表和代码分开了,如:
 

 

     两者分开之后,如果数值设置不好的话,会有很严重的后果,比如向量表会被一些印射的代码所覆盖,或是向量表没有圆整到2的次幂,等等。所以,这里我是将这两者合而为一,如:


 

     当我们以FLASH方式编译时,内存印射如下:


 

     如果以RAM方式编译,内存印射如下:


 

     完整的散列文件scatterfile_tools_mdk.xml内容如下:

<?xml version="1.0"?>
<ScatterFile xmlns="
http://schemas.microsoft.com/netmf/ScatterfileSchema.xsd">
 

    <Set Name="Valid" Value="false"/>

    <!-- ################################################################################ -->

  <If Name="TARGETLOCATION" Value="RAM">
   <Set Name="Heap_Begin"        Value="0x20002BFC"/>
     <Set Name="Heap_End"          Value="0x20002DFC"/>
     <Set Name="Stack_Bottom"      Value="+0"/>
   <Set Name="Stack_Top"         Value="0x20002FFC"/>
   <Set Name="ER_RAM_BaseAddress" Value="0x20003000"/>
  </If>
  
  <If Name="TARGETLOCATION" Value="RAM">
        <Set Name="Code_BaseAddress"   Value="0x20004000"/>
        <Set Name="Code_Size"          Value="0x0000C000"/>       
        <Set Name="Valid"              Value="true"/>
    </If>
  
  
  <If Name="TARGETLOCATION" Value="FLASH">
   <Set Name="Heap_Begin"        Value="0x2000EBFC"/>
     <Set Name="Heap_End"          Value="0x2000EDFC"/>
     <Set Name="Stack_Bottom"      Value="+0"/>
   <Set Name="Stack_Top"         Value="0x2000EFFC"/>
   <Set Name="ER_RAM_BaseAddress" Value="0x2000F000"/>
  </If>

    <If Name="TARGETLOCATION" Value="FLASH">       
        <Set Name="Config_BaseAddress"  Value="0x08070000"/>   
        <Set Name="Config_Size"         Value="0x00010000"/>
        <Set Name="Code_BaseAddress"    Value="0x08000000"/>
        <Set Name="Code_Size"           Value="0x00060000"/>
        <Set Name="Valid"               Value="true"/> 
       
        <IfDefined Name="ALTERNATEFLASHLOCATION">
            <!-- Set Name="Code_BaseAddress" Value="%Code_BaseAddress + Code_Size%"/ -->
        </IfDefined>

    </If>

   


    <!-- ################################################################################ -->

    <If Name="Valid" Value="false">
        <Error Message="Configuration not recognized"/>
    </If>

    <LoadRegion Name="LR_%TARGETLOCATION%" Base="%Code_BaseAddress%" Options="ABSOLUTE" Size="%Code_Size%">
     
        <ExecRegion Name="ER_%TARGETLOCATION%" Base="%Code_BaseAddress%" Options="FIXED" Size="">
      <FileMapping Name="VectorsTrampolines.obj" Options="(+RO, +FIRST)" /> <!-- for vector handlers to be far from the vectors -->
            <FileMapping Name="FirstEntry.obj"   Options="(+RO)" /> <!-- the entry pointer section goes into this region -->
            <FileMapping Name="ramtest.obj"      Options="(+RO)"         /> <!-- this must live somewhere other than RAM, for all but RAM builds -->
            <FileMapping Name="*" Options="(SectionForBootstrapOperations)" />
            <FileMapping Name="*" Options="(+RO-CODE)" />
            <FileMapping Name="*" Options="(+RO-DATA)" />

        </ExecRegion>

 
        <ExecRegion Name="ER_RAM_RO" Base="%ER_RAM_BaseAddress%" Options="ABSOLUTE" Size="">      
  
            <FileMapping Name="*"                      Options="(SectionForFlashOperations)" />
   
        </ExecRegion>

        <ExecRegion Name="ER_RAM_RW" Base="+0" Options="ABSOLUTE" Size="">

            <FileMapping Name="*"                Options="(+RW-DATA, +ZI)" />

        </ExecRegion>

        <ExecRegion Name="ER_HEAP_BEGIN" Base="%Heap_Begin%" Options="ABSOLUTE" Size="UNINIT">
            <FileMapping Name="*" Options="(SectionForHeapBegin)" />
        </ExecRegion>

        <!-- everything between heapbegin and heapend will be allocated for a heap -->

        <ExecRegion Name="ER_HEAP_END" Base="%Heap_End%" Options="ABSOLUTE" Size="UNINIT">
            <FileMapping Name="*" Options="(SectionForHeapEnd)" />
        </ExecRegion>


        <!-- this must go last here to provide a low water mark on the stack -->

        <ExecRegion Name="ER_STACK_BOTTOM" Base="%Stack_Bottom%" Options="ABSOLUTE" Size="UNINIT">
            <FileMapping Name="*" Options="(SectionForStackBottom)" />
        </ExecRegion>
       
        <ExecRegion Name="ER_STACK_TOP" Base="%Stack_Top%" Options="ABSOLUTE" Size="UNINIT">
            <FileMapping Name="*" Options="(SectionForStackTop)" />
        </ExecRegion>

    </LoadRegion>

    <IfDefined Name="Config_BaseAddress">

        <LoadRegion Name="LR_CONFIG" Base="%Config_BaseAddress%" Options="ABSOLUTE" Size="%Config_Size%">

            <ExecRegion Name="ER_CONFIG" Base="%Config_BaseAddress%" Options="FIXED" Size="%Config_Size%">

                <FileMapping Name="*" Options="(SectionForConfig)" />

            </ExecRegion>

        </LoadRegion>

    </IfDefined>

</ScatterFile>

 

     看得比较仔细的朋友,可能会发现这句已经被注释掉了:
<!-- Set Name="Code_BaseAddress" Value="%Code_BaseAddress + Code_Size%"/ -->
 
     如果不注释掉的话,那么代码是从高位向低位生长,而这却和STM32F103ZE的实际情况相反。所以这里就必须将其注释掉,以让代码从低位往高位生长。


     如果编译的是FLASH方式,可以直接通过MDK下载NativeSample.axf文件到开发板中,就能够正常运行。但如果是RAM方式,还需要配合脚本文件。因为编译的是RAM方式的话,如果PC指针默认指向ARM_Vectors,则执行会出现异常,但原因我还暂时还不清楚。不过,这个有个变通的方式,开始调试时,通过脚本文件将PC指针指向EntryPoint函数即可。和RAM配合的完整的脚本文件内容如下:

 

FUNC void InitNVIC(void)
{
 _WDWORD(0xE000ED08,0x20004000);
}
 
InitNVIC();
PC = EntryPoint;

 

     需要注意的是,这个脚本文件只能配合RAM方式,如果是FLASH,因为ARM_Vectors的位置和向量表寄存器的数值不符,则会导致程序异常。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值