链接脚本(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驱动测试程序。

posted @ 2019-09-05 11:19  凉风SK  阅读(2375)  评论(1编辑  收藏  举报