`
java-mans
  • 浏览: 11342015 次
文章分类
社区版块
存档分类
最新评论

修正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的位置和向量表寄存器的数值不符,则会导致程序异常。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics