新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM的分散加載文件(scatter)介紹

        ARM的分散加載文件(scatter)介紹

        作者: 時間:2016-11-09 來源:網絡 收藏
        keil中編譯的程序通過了,但是debug的時候會出現一些錯誤:

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

        本文引用地址:http://www.104case.com/article/201611/317888.htm

        * 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
        ; KEILs 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
        ; KEILs 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中去的原因



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 鄂尔多斯市| 洞头县| 马公市| 麻栗坡县| 那曲县| 大英县| 邯郸市| 商城县| 铜川市| 丰城市| 郑州市| 伊通| 武强县| 新乐市| 和林格尔县| 莆田市| 砀山县| 宁蒗| 赤峰市| 郓城县| 夹江县| 高密市| 响水县| 乌恰县| 南充市| 兰溪市| 荔波县| 莆田市| 德阳市| 平度市| 海安县| 洪雅县| 福鼎市| 米脂县| 临猗县| 西安市| 周口市| 从江县| 育儿| 西华县| 喀什市|