zoukankan      html  css  js  c++  java
  • 链接脚本(Linker Script)应用实例(一)使用copy table将函数载入到RAM中运行

    将函数载入到RAM中运行需要以下三个步骤:

    (1)用编译器命令#pragma section "<section name>" <user functions> #pragma section 将想要载入RAM运行的函数存储为自定义段名的程序段,其中ax是#pragma section命令中的可选设置——<flags>,a表示allocatable,x表示executable,具体

    #pragma section ".flash_driver" ax
    
    void PFlashProgram( uint32 flash, uint32 addr, uint32 word_l, uint32 word_u )
    {
        uint32 load_cnt;
        uint16 endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPasswordInline();
    
        IfxFlash_enterPageMode(addr);
    
        /* wait until unbusy */
        IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_P0);
    
        /* write 32 bytes (8 doublewords) into assembly buffer */
        for (load_cnt = 0; load_cnt < 4; load_cnt++)
        {
            IfxFlash_loadPage2X32(addr, word_l, word_u);
        }
    
        /* write page */
        IfxScuWdt_clearSafetyEndinitInline(endinitSfty_pw);
        IfxFlash_writePage(addr);
        IfxScuWdt_setSafetyEndinitInline(endinitSfty_pw);
    
        /* wait until unbusy */
        IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_P0);
    }
    #pragma section

    (2)在链接脚本中,以自定义的程序段为输入,定义输出段output section:

       /* user defined output section, used to allocate ram space(VMA) for code running in ram, */
        /* and also allocate rom space(LMA) to store it */
        .code2ram : 
        {
            *(.flash_driver)
            *(.flash_driver.*)
            . = ALIGN(8);
        } > psram_local AT> pfls0 =0

    (3)将该输出段.code2ram的LMA、VMA和SIZE等信息加入到copy table中,以使CPU启动时将该段(函数)从ROM拷贝到RAM中(从而正常运行)。这里贴出相关的上下文以便于读者的整体理解

      (注:这里有一个VMA和LMA概念的问题,会在之前的博文——链接脚本(linker script)用法解析(一)中讲解)

    /* user defined output section, used to allocate ram space(VMA) for code running in ram, */
        /* and also allocate rom space(LMA) to store it */
        .code2ram : 
        {
            *(.flash_driver)
            *(.flash_driver.*)
            . = ALIGN(8);
        } > psram_local AT> pfls0 =0
              
           .rodata : FLAGS(arl)
        {
            *(.rodata)
            *(.rodata.*)
            *(.gnu.linkonce.r.*)    
            /*
              * Create the clear and copy tables that tell the startup code
              * which memory areas to clear and to copy, respectively.
              */
            . = ALIGN(16) ;
            PROVIDE(__clear_table = .) ;
            LONG(0 + ADDR(.CPU2.zbss));     LONG(SIZEOF(.CPU2.zbss));
            LONG(0 + ADDR(.CPU2.bss));    LONG(SIZEOF(.CPU2.bss));
            LONG(0 + ADDR(.CPU1.zbss));     LONG(SIZEOF(.CPU1.zbss));
            LONG(0 + ADDR(.CPU1.bss));    LONG(SIZEOF(.CPU1.bss));
            LONG(0 + ADDR(.CPU0.zbss));     LONG(SIZEOF(.CPU0.zbss));
            LONG(0 + ADDR(.CPU0.bss));    LONG(SIZEOF(.CPU0.bss));
            LONG(0 + ADDR(.zbss));     LONG(SIZEOF(.zbss));
            LONG(0 + ADDR(.sbss));     LONG(SIZEOF(.sbss));
            LONG(0 + ADDR(.bss));    LONG(SIZEOF(.bss));
            LONG(0 + ADDR(.sbss4));    LONG(SIZEOF(.sbss4));
            LONG(-1);                 LONG(-1);
            PROVIDE(__copy_table = .) ;
            LONG(LOADADDR(.CPU2.zdata));    LONG(0 + ADDR(.CPU2.zdata));    LONG(SIZEOF(.CPU2.zdata));
            LONG(LOADADDR(.CPU2.data));    LONG(0 + ADDR(.CPU2.data));    LONG(SIZEOF(.CPU2.data));
            LONG(LOADADDR(.CPU1.zdata));    LONG(0 + ADDR(.CPU1.zdata));    LONG(SIZEOF(.CPU1.zdata));
            LONG(LOADADDR(.CPU1.data));    LONG(0 + ADDR(.CPU1.data));    LONG(SIZEOF(.CPU1.data));
            LONG(LOADADDR(.CPU0.zdata));    LONG(0 + ADDR(.CPU0.zdata));    LONG(SIZEOF(.CPU0.zdata));
            LONG(LOADADDR(.CPU0.data));    LONG(0 + ADDR(.CPU0.data));    LONG(SIZEOF(.CPU0.data));
            LONG(LOADADDR(.zdata));    LONG(0 + ADDR(.zdata));    LONG(SIZEOF(.zdata));
            LONG(LOADADDR(.sdata));    LONG(0 + ADDR(.sdata));    LONG(SIZEOF(.sdata));
            LONG(LOADADDR(.data));    LONG(0 + ADDR(.data));    LONG(SIZEOF(.data));
            LONG(LOADADDR(.sdata4));    LONG(0 + ADDR(.sdata4));    LONG(SIZEOF(.sdata4));
            LONG(LOADADDR(.code2ram));        LONG(0 + ADDR(.code2ram));        LONG(SIZEOF(.code2ram));
            LONG(-1);                 LONG(-1);                 LONG(-1);
            . = ALIGN(16);
          } > pfls0
          
          .text  : FLAGS(axl)
        {
            *(.text)
            *(.text.*)
            *(.gnu.linkonce.t.*)
            *(.gnu.warning)        /* .gnu.warning sections are handled specially by elf32.em. */
            . = ALIGN(16);
        } > pfls0

    以上的示例来源于TC297的Flash驱动测试程序。

  • 相关阅读:
    Umbraco中更换IndexSet中的NodeType后,搜索页面没有做出对应更改的效果
    Umbraco部署到IIS中权限问题(back office没有权限新建template)
    C控制台密码输入:输入一个字符显示一个星号
    C项目实践--家庭财务管理系统
    C 编程中fseek、ftell的用法总结
    C ++模板的声明和实现为何要放在头文件中?
    头文件与cpp文件为什么要分开写
    printf、sprintf与fprintf 的用法区分
    C编程中fread 、fwrite 用法总结
    C从控制台(stdin)输入带空格的字符串到字符数组中
  • 原文地址:https://www.cnblogs.com/uestcliming666/p/11464709.html
Copyright © 2011-2022 走看看