用户操作
[即时聊天] [发私信] [加为好友]
温陵布衣ID:sikinzen
5499次访问,排名16915(-8)好友0人,关注者3
毕业于华侨大学电工理论与新技术
方向:嵌入式Linux的开发
sikinzen的文章
原创 18 篇
翻译 0 篇
转载 12 篇
评论 4 篇
温陵布衣的公告
刚开博客,希望能与有志于Linux学习与开发的朋友多多交流
最近评论
SS:你们的资源在哪里啊?怎么找不到?
sikinzen:大家有其它看法的,也欢迎写下来。
张思林:
sikinzen:摘录网上一个完整的回答。
已知:
M属于{3,6,9,12}
N属于{1,2,4,5,7,8}
月或日有重复为不知道
月或日无重复为知道

第1句

小明说:如果我不知道的话,小强肯定也不知道

假设M=3,那么小明不知道,小强也肯定不知道;
假设M=6,那……
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 ADS下的分散加载文件讲解收藏

    新一篇: 请不要做浮躁的嵌入式系统工程师(谨以此文与大家共勉) | 旧一篇: 如何治疗打嗝

    1.        .分散加载文件(.scf)格式

    load_region_name  start_address | "+"offset  [attributes] [max_size]
    {
        execution_region_name  start_address | "+"offset  [attributes][max_size]
        {
            module_select_pattern  ["("
                                        ("+" input_section_attr | input_section_pattern)
                                        ([","] "+" input_section_attr | "," input_section_pattern)) *
                                   ")"]
        }
    }

        其中:

    load_region            加载区,程序执行前和永久性数据的存放区域;

    execution_region     执行区,程序执行时,从加载区域将数据复制到相应执行区后才能被正确执行;

    load_region_name  加载区域名,便于连接器区别不同的加载区域,最多31个字符;

    start_address          起始地址,指示区域的首地址;

    +offset           前一个区域尾地址+offset 做为当前的起始地址,且“offset”应为“0”“4”的倍数;

    attributes                加载区域属性,可设置如下属性:

    PI                  与地址无关方式存放;

    RELOC        重新部署,保留定位信息,以便重新定位该段到新的执行区;

    OVERLAY   覆盖,允许多个可执行区域在同一个地址,ADS不支持;

    ABSOLUTE        绝对地址(默认);

    max_size                该区域的大小;

    execution_region_name  执行区域名;

    attributes       加载区域属性,可设置如下属性:

    PI           与地址无关,该区域的代码可任意移动后执行;

    OVERLAY     覆盖;

    ABSOLUTE    绝对地址(默认);

    FIXED       固定地址;

    UNINIT      不用初始化该区域的ZI段;

    module_select_pattern 目标文件滤波器,支持通配符“*”“?”*.o匹配所有目标,* (或“.ANY”)匹配所有目标文件和库。
        input_section_attr
              输入段属性。表示符合本输入段属性滤波的所有输入段都包含在本运行域中。每个输入段属性必须跟随在后;且大小写不敏感;支持的输入段属性列表如下:

    RO-CODE CODE

    RO-DATA CONST

    ROTEXT, selects both RO-CODE and RO-DATA

    RW-DATA

    RW-CODE

    RW DATA, selects both RW-CODE and RW-DATA

    ZI BSS

    ENTRY 表明本输入段包含一个入口点

    FIRST,用于指定存放在一个执行区域的第一个或最后一个区域;
          LAST
    ,同上;
    input_section_pattern
    输入段名;



    汇编中指定段:
         AREA    vectors, CODE, READONLY
    C中指定段:
       #pragma arm section [sort_type[[=]"name"]] [,sort_type="name"]*
    其中,sort_type为:    coderwdatarodata
    zidata
    如果“sort_type”指定了但没有指定“name”,那么之前的修改的段名将被恢复成默认值。

    如:#pragma arm section     // 恢复所有段名为默认设置。

    2.         分散加载文件(.scf)应用举例
    1)       
    #pragma arm section rwdata = "SRAM",zidata = "SRAM"
    static OS_STK  SecondTaskStk[256];              // “rwdata”“zidata”将定位在“sram”段中。
    #pragma arm section                                 // 恢复默认设置
    分散加载文件中定义如下:
        Exec_Sram  0x80000000  0x40000
        {
            * (sram)
        }

    2)        “PI” 属性使用示例:
    LR_1 0x010000 PI                ; The first load region is at 0x010000.
    {
        ER_RO +0                    ; The PI attribute is inherited from parent.
                                    ; The default execution address is 0x010000, but the code can be moved.
        {
            *(+RO)                  ; All the RO sections go here.
        }
        ER_RW +0 ABSOLUTE           ; PI attribute is overridden by ABSOLUTE.
        {
            *(+RW)                  ; The RW sections are placed next. They cannot be moved.
        }
        ER_ZI +0                    ; ER_ZI region placed after ER_RW region.
        {
            *(+ZI)                  ; All the ZI sections are placed consecutively here.
        }
    }
    LR_1 0x010000                   ; The first load region is at 0x010000.
    {
        ER_RO +0                    ; Default ABSOLUTE attribute is inherited from parent. The execution
                                    ; address  is 0x010000. The code and ro data cannot be moved.
        {
            *(+RO)                  ; All the RO sections go here.
        }
        ER_RW 0x018000 PI           ; PI attribute overrides ABSOLUTE
        {
            *(+RW)                  ; The RW sections are placed at 0x018000 and they can be moved.
        }
        ER_ZI +0                    ; ER_ZI region placed after ER_RW region.
        {
            *(+ZI)                  ; All the ZI sections are placed consecutively here.
        }
    }
    3.         程序中对某区域地址等的引用方法
    Load$$region_name$$Base             Load address of the region.
    Image$$region_name$$Base            Execution address of the region.
    Image$$region_name$$Length          Execution region length in bytes (multiple of 4).
    Image$$region_name$$Limit           Address of the byte beyond the end of the execution region.

    Image$$region_name$$ZI$$Base        Execution address of the ZI output section in this region.
    Image$$region_name$$ZI$$Length      Length of the ZI output section in bytes (multiple of 4).
    Image$$region_name$$ZI$$Limit       Address of the byte beyond the end of the ZI output sectionin the execution region.

    SectionName$$Base                   Input Address of the start of the consolidated section called SectionName.
    SectionName$$Limit                  Input Address of the byte beyond the end of the consolidated section called SectionName.

    Load:          加载区,即存放地址;
    Image:         执行区,即运行地址;
    Base:          区首地址;
    Limit:         区尾地址;
    Length:        区长度;
    region_name:   RO、RW、ZI、load_region_name、execution_region_name;

    例如:
        “RAM1”区域的首地址:      Image$$RAM1$$Base
        上例中“sram”段首地址:    sram$$Base

    1)        汇编引用示例:

      IMPORT |Load$$Exec_RAM1$$Base|              // Exec_RAM1 为“RW”段
      IMPORT |Image$$Exec_RAM1$$Base|
      IMPORT |Image$$Exec_RAM1$$Length|
      IMPORT |Image$$Exec_RAM1$$Limit|

      LDR  R0, =|Load$$Exec_RAM1$$Base|
      LDR  R1, =|Image$$Exec_RAM1$$Base|
      LDR  R2, =|Image$$Exec_RAM1$$Limit|
      CMP  R1,   R2
      LDRCC  R3,   [R0], #4
      STRCC R3,   [R1], #4
      BCC  %b0

    2)        C 引用:
    extern unsigned char Load$$Exec_RAM1$$Base;
    extern unsigned char Image$$Exec_RAM1$$Base;
    extern unsigned char Image$$Exec_RAM1$$Length;

    void MoveRO(void)
    {
     unsigned char * psrc, *pdst;
     unsigned int  count;

     count = (unsigned int)   &Image$$Exec_RAM1$$Length;
     psrc  = (unsigned char *)&Load$$Exec_RAM1$$Base;
     pdst  = (unsigned char *)&Image$$Exec_RAM1$$Base;

     while (count--) {
      *pdst++ = *psrc++;
     }
    }

    加载文件示例一:

    起始地址       大小

    ROM:      0x00000000    256K       ;0x1fc 保留为加密字,程序在ROM中运行;
    RAM       0x40000000    16K        ;用于全局变量及任务堆栈;
    SRAM     0x80000000    512K       ;SRAM速度慢,主要用于存放大的数据表;

    LOAD_ROM1 0x00000000  0x1f8                 ; 指定该加载区域首地址、大小
    {
        EXEC_ROM1  +0  0x1f8                    ; 没有前一加载区域,所以该执行区域首地址为加载区域首地址
                                                ; 并指定该区域长度
        {
            Startup.o (vectors, +FIRST)       ; 目标文件的“vectors”段放在该执行区域的第一段
            irq.o (+RO)                        ; 目标文件的所有“RO”段放在该执行区域
        }
    }

    LOAD_ROM2 0x00000200                        ; 第二个加载区域
    {
        EXEC_ROM2  +0  0x3e600
        {
            * (+RO)                             ; 所有目标文件和库文件中的“RO”段存放在该区域
        }

    RAM1   0x40000000   0x4000
        {
            * (+RW, +ZI)                        ; 所有目标文件和库文件的“RW”和“ZI”段存放在该区域
        }

    SRAM2  0x80000000  0x80000
        {
            * (sram)                            ; 所有目标文件中的“sram”段存放在该区域
        }
    }

    示例二:
        “iap.o”定义在“Exec_RAM1”中运行,所以设置“PI”属性;
        在调用“iap.c”中函数之前应该将其从“Load$$Exec_IAP$$Base”复制到指定的“Exec_RAM1”区域;

    Load_region1  0x00000000  0x1fc
    {
        EXEC_ROM1  +0
        {
            Startup.o (vectors, +FIRST)
            irq.o (+RO)
        }
    }

    Load_region2  0x00000200  0x3e600
    {
        EXEC_ROM2  +0
        {
            * (+RO)
        }

        Exec_IAP   +0  PI               // 可能引起链接器未使用该属性警告,忽略
        {
            iap.o (+RO)
        }

        Exec_RAM1  0x40000000  0x4000
        {
            * (+RW, +ZI)
        }

        Exec_Sram  0x80000000  0x40000
        {
            * (SRAM)
        }
    }

    // 移动“IAP.o”中的所有函数到“ImageExecIAPBase”加载区,并调用其中的函数
    extern unsigned char Load$$Exec_IAP$$Base;
    extern unsigned char Image$$Exec_IAP$$Length;

    #define  ImageExecIAPBase  (0x40000000+0x1000)   // 加载区首址

    void MoveIAPRO(void)
    {
     unsigned char * psrc, *pdst;
     unsigned int  count;

     count = (unsigned int)   &Image$$Exec_IAP$$Length;
     psrc  = (unsigned char *)&Load$$Exec_IAP$$Base;
     pdst  = (unsigned char *)ImageExecIAPBase;

     while (count--) {
      *pdst++ = *psrc++;
     }
    }

    // 调用“IAP.O”中的某函数
     {
      void (* pfnIAPWrite)(unsigned long, int);

      pfnIAPWrite = (void (*)(unsigned long, int))
       (ImageExecIAPBase +
       (unsigned int)IAPWrite -                        // 被调用函数名
       (unsigned int)&Load$$Exec_IAP$$Base);

      pfnIAPWrite((int)((CUPDATA *)CODESTARTADDR)->data,
         ((CUPDATA *)CODESTARTADDR)->length);
        }

    发表于 @ 2007年09月10日 14:06:00|评论(loading...)|编辑

    新一篇: 请不要做浮躁的嵌入式系统工程师(谨以此文与大家共勉) | 旧一篇: 如何治疗打嗝

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 温陵布衣