zoukankan      html  css  js  c++  java
  • (转)KEIL下分散加载文件 **.sct文件

    在keil中编译的程序通过了,但是debug的时候会出现一些错误:

    *** error 65: access violation at 0x4C000018 : no 'write' permission

    *** error 65: access violation at 0x00000000 : no 'execute/read' permission (ram.sct的时候)

    我发现当我工程设置中linker中选择了runinram.sct和runinflash.sct或者自动生成的sct文件的时候就出现上面的错误。应该就是地址的问题。但是具体怎么修改才能解决这个错误,还没弄明白。弄明白了再发。

     

    下面是找了一篇值得参考的文章:

    原文地址:

    http://hi.baidu.com/pengjj0807/blog/item/ef73e287a212453cc65cc3be.html

    KEIL下分散加载文件的使用

    ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; *************************************************************

    LR_IROM1 0x08000000 0x00004000 ; load region size_region 第一个加载域,起始地址0x08000000{ 大小0x00004000

    ER_IROM1 0x08000000 0x00004000 ; load address = execution address第一个运行时域,

    { 起始0x08000000,大小0x00004000

    *.o (RESET, +First) IAP第一阶段还是在FLASH中运行 *(InRoot$$Sections) startup_stm32f10x_md.o } ER_IROM2 0x20008000 0x00004000 ; load address = execution address第二个运行时域,

    { 起始0x20008000,大小0x00004000

    .ANY (+RO) IAP第二阶段加载到SDRAM中运行 } RW_IRAM1 0x20000000 0x00008000 ; RW data 把可读写的数据和初始化为0的数据放在内存SDRAM的开头

    {

    .ANY (+RW +ZI) } }

    让MDK自己分配--选linker-usexxx

     

     

     

    对于分散加载的概念,在《ARM体系结构与编程》书中第11章有明确介绍。

    分散加载文件(即scatter file 后缀为.scf)是一个文本文件,通过编写一个分散加载文件来指定
    ARM连接器在生成映像文件时如何分配RO,RW,ZI等数据的存放地址。如果不用SCATTER文件指定,那么
    ARM连接器会按照默认的方式来生成映像文件,一般情况下我们是不需要使用分散加载文件的。

    但在某些场合,我们希望把某些数据放在指定的地址处,那么这时候SCATTER文件就发挥了非常大的作用
    而且SCATTER文件用起来非常简单好用。

    举个例子:比如像LPC2378芯片具有多个不连续的SRAM,通用的RAM是32KB,可是32KB不够用,我想把
    某个.C中的RW数据放在USB的SRAM中,那么就可以通过SCATTER文件来完成这个功能。
    下面是就这个例子作的说明:


    这是一个标准的常用的分散加载文件,现在加注释于后,方便以后查阅:
    ;******************************************************************************
    ;
    ; SCATTER LOADING DEION
    ; ARM
    ; KEIL's uVision3
    ; (RealView Microprocessor Developer Kit)
    ;
    ; Filename : LPC2378_Flash.scat
    ;******************************************************************************

    LR_IROM1 0x00000000 0x00080000 ;; 第一个加载域,名字为LR_IROM1,起始
    {                  ;;地址为0x0,大小为0x80000
    ER_IROM1 0x00000000 0x00080000 ;;加载域中的运行时域,名字为ER_IROM1
    { ;; 起始地址为0x0,大小为0x80000
    vectors.o (VECT, +First) ;;将vectors.c编译后生成的文件vectors.o中的代码
    init.o (INIT) ;;以及init.o中的代码
    * (+RO) ;;以及所有编译生成的RO属性的代码全部存放在
    } ;;运行时域ER_IROM1指定的地址范围内,存放方式:顺序存放

    RW_IRAM1 0x40000000 0x0000e800  ;;这是第二个运行时域,功能同上
    { ;;其中 *是代表具有()里面指定的属性的全部数据
    *(+RW,+ZI) ;;与*功能相似的有.ANY,后面说明
    } ;; The following declarations select the "two region model" ;

    ;; A default __user_initial_stackheap() will be used ;
    ARM_LIB_HEAP 0x40007000 EMPTY 0x00000100 {} ;;指定堆栈地址
    ARM_LIB_STACK 0x40008000 EMPTY -0x00000E00 {}
    }


    下面是针对LPC2378的USB SRAM作数据RAM使用的配置:

    ;******************************************************************************
    ;
    ; SCATTER LOADING DEION
    ; ARM
    ; KEIL's uVision3
    ; (RealView Microprocessor Developer Kit)
    ;
    ; Filename : LPC2378_Flash.scat
    ;******************************************************************************

    LR_IROM1 0x00000000 0x00080000 ;; 第一个加载域,名字为LR_IROM1,起始
    {                  ;;地址为0x0,大小为0x80000
    ER_IROM1 0x00000000 0x00080000 ;;加载域中的运行时域,名字为ER_IROM1
    { ;; 起始地址为0x0,大小为0x80000
    vectors.o (VECT, +First)
    init.o (INIT)
    * (+RO)
    }

    RW_IRAM1 0x40000000 0x0000e800
    {
    .ANY(+RW,+ZI)     ;; 此处.ANY替换原来的*,是因为下面的一个执行域对指定的模块中的RW,ZI数据指定了存放地址
    ;;用.ANY就可以把已经被指定的具有RW,ZI属性的数据排除
    } ;; The following declarations select the "two region model" ;

    找了3个分散加载文件来分析:

    1、7x256的flash.sct分散加载文件:

    Load_region 0x100000 0x40000 {//ro起始地址为0x100000,大小为0x40000
    Fixed_region 0x100000 0x40000 { *(cstartup +First) .ANY (+RO) }
    Relocate_region 0x200000 {//rw和zi段的地址为0x200000

    *.o (VECTOR, +First) .ANY (+RW +ZI) }
    ARM_LIB_HEAP 0x20E000 EMPTY 0x1000 { }
    ARM_LIB_STACK 0x210000 EMPTY -0x1000 { } }

    2、sram.sct文件

    Load_region 0x200000 0x10000 {
    Fixed_region 0x200000 { *.o (VECTOR, +First) .ANY (+RO) }
    Relocate_region +0 { *(cstartup +First) .ANY (+RW +ZI) }
    ScatterAssert((ImageLength(Fixed_region) + ImageLength(Relocate_region)) < 0xE000)
    ARM_LIB_HEAP 0x20E000 EMPTY 0x1000 { }
    ARM_LIB_STACK 0x210000 EMPTY -0x1000 { } }

    3、自定义的sram.sct

    LR_IROM1 0x00200000 0x00008000 { ; load region size_region ER_IROM1 0x00200000 0x00008000 { ; load address = execution address//加载域等于运行域 *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x00208000 UNINIT 0x00008000 { ; RW data//rw和zi段 .ANY (+RW +ZI) } }

    什么是分散加载文件这里就不赘述了。

    前面两个分散加载文件是从别的地方拷过来的,用在自己的程序中可能会有问题,因为如果不修改它的话它就固定了加载地址和运行地址,如果程序简单又比较小的话可能不会有问题,但是如果程序代码比较大,超出了那两个加载文件的定义大小可能就会出问题,解决办法也很简单,直接修改.sct文件直到适合你的代码。

    更好的办法是自己定义一个分散加载文件,在keil中勾选Use Memory Layout from Target Dialog,那么加载文件就是从你定义irom和iram等地址得到的,如果不勾选的话就是通过你自己指定的加载文件来加载。

    如果分散加载文件不对的话,可能出现的问题就是明明是在sram中调试程序,但是却能神奇的通过flash downloader下载到flash中去,刚开始也是不解,后来才发现是分散加载文件有错误,我使用了一个指定的flash.sct分散加载文件,这样的话我设置的irom和iram都无效了,编译器直接根据我指定的flash.sct来分布代码和加载代码,又查看了一下flash.sct文件是加代码加载到flash地址空间的,这就是为什么在jlink-sram工程中也能通过flash downloader工具烧写代码到flash中去的原因

  • 相关阅读:
    HDU 5313 bitset优化背包
    bzoj 2595 斯坦纳树
    COJ 1287 求匹配串在模式串中出现的次数
    HDU 5381 The sum of gcd
    POJ 1739
    HDU 3377 插头dp
    HDU 1693 二进制表示的简单插头dp
    HDU 5353
    URAL 1519 基础插头DP
    UVA 10294 等价类计数
  • 原文地址:https://www.cnblogs.com/darren-715/p/3457214.html
Copyright © 2011-2022 走看看