链接脚本(Linker Script)应用实例(一)使用copy table将函数载入到RAM中运行

2022-12-15,,,,

函数载入到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 = ; load_cnt < ; 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();
} > psram_local AT> pfls0 =

(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();
} > psram_local AT> pfls0 = .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() ;
PROVIDE(__clear_table = .) ;
LONG( + ADDR(.CPU2.zbss)); LONG(SIZEOF(.CPU2.zbss));
LONG( + ADDR(.CPU2.bss)); LONG(SIZEOF(.CPU2.bss));
LONG( + ADDR(.CPU1.zbss)); LONG(SIZEOF(.CPU1.zbss));
LONG( + ADDR(.CPU1.bss)); LONG(SIZEOF(.CPU1.bss));
LONG( + ADDR(.CPU0.zbss)); LONG(SIZEOF(.CPU0.zbss));
LONG( + ADDR(.CPU0.bss)); LONG(SIZEOF(.CPU0.bss));
LONG( + ADDR(.zbss)); LONG(SIZEOF(.zbss));
LONG( + ADDR(.sbss)); LONG(SIZEOF(.sbss));
LONG( + ADDR(.bss)); LONG(SIZEOF(.bss));
LONG( + ADDR(.sbss4)); LONG(SIZEOF(.sbss4));
LONG(-); LONG(-);
PROVIDE(__copy_table = .) ;
LONG(LOADADDR(.CPU2.zdata)); LONG( + ADDR(.CPU2.zdata)); LONG(SIZEOF(.CPU2.zdata));
LONG(LOADADDR(.CPU2.data)); LONG( + ADDR(.CPU2.data)); LONG(SIZEOF(.CPU2.data));
LONG(LOADADDR(.CPU1.zdata)); LONG( + ADDR(.CPU1.zdata)); LONG(SIZEOF(.CPU1.zdata));
LONG(LOADADDR(.CPU1.data)); LONG( + ADDR(.CPU1.data)); LONG(SIZEOF(.CPU1.data));
LONG(LOADADDR(.CPU0.zdata)); LONG( + ADDR(.CPU0.zdata)); LONG(SIZEOF(.CPU0.zdata));
LONG(LOADADDR(.CPU0.data)); LONG( + ADDR(.CPU0.data)); LONG(SIZEOF(.CPU0.data));
LONG(LOADADDR(.zdata)); LONG( + ADDR(.zdata)); LONG(SIZEOF(.zdata));
LONG(LOADADDR(.sdata)); LONG( + ADDR(.sdata)); LONG(SIZEOF(.sdata));
LONG(LOADADDR(.data)); LONG( + ADDR(.data)); LONG(SIZEOF(.data));
LONG(LOADADDR(.sdata4)); LONG( + ADDR(.sdata4)); LONG(SIZEOF(.sdata4));
LONG(LOADADDR(.code2ram)); LONG( + ADDR(.code2ram)); LONG(SIZEOF(.code2ram));
LONG(-); LONG(-); LONG(-);
. = ALIGN();
} > pfls0 .text : FLAGS(axl)
{
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.gnu.warning) /* .gnu.warning sections are handled specially by elf32.em. */
. = ALIGN();
} > pfls0

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

链接脚本(Linker Script)应用实例(一)使用copy table将函数载入到RAM中运行的相关教程结束。

《链接脚本(Linker Script)应用实例(一)使用copy table将函数载入到RAM中运行.doc》

下载本文的Word格式文档,以方便收藏与打印。