LINKER 脚本 GCC 如何避免单板调用

Posted

技术标签:

【中文标题】LINKER 脚本 GCC 如何避免单板调用【英文标题】:LINKER script GCC how to avoid veneer call 【发布时间】:2019-09-24 22:25:50 【问题描述】:

我从事的项目是我将一些函数从 FLASH 复制到 RAM 并调用它们。一切都很好,除了我遇到的一个小问题 - 如果我直接调用函数,编译器会添加单板调用(它会正确调用 RAM 中的函数)。

如果我通过指针调用它,一切正常。调试器显示函数的解析地址是正确的。

#define RAMFCALL(func, ...)   unsigned (* volatile fptr)() =  (unsigned (* volatile)())func; fptr(__VA_ARGS__);

RAMFCALL(FLASH_EraseSector, 0, 0);
FLASH_EraseSector(0,0);

以及相应的调用:

 311        RAMFCALL(FLASH_EraseSector, 0, 0);
0801738e:   ldr     r3, [pc, #88]   ; (0x80173e8 <flashSTMInit+140>)
08017390:   str     r3, [sp, #12]
08017392:   ldr     r3, [sp, #12]
08017394:   movs    r1, #0
08017396:   mov     r0, r1
08017398:   blx     r3
 312        FLASH_EraseSector(0,0);
0801739a:   movs    r1, #0
0801739c:   mov     r0, r1
0801739e:   bl      0x801e9f0 <__FLASH_EraseSector_veneer>

调试器显示正确的地址。

和链接描述文件的相应部分

  OVERLAY : NOCROs-s-rEFS
  
      .RAM_functions 
      
        . = ALIGN(512);
        RAM_functions_load = LOADADDR(.RAM_functions);
        PROVIDE(RAM_VectorTable_start = .);
        KEEP(*(.RAM_VectorTable))
        KEEP(*(.RAM_VectorTable*))
        PROVIDE(RAM_VectorTable_end = .);

        . = ALIGN(4);
        RAM_functions_start = .;
        KEEP(*(.RAM_functions))
        KEEP(*(.RAM_functions*))
        RAM_functions_end = .;

        . = ALIGN(4);
        RAM_functionsDATA_start = .;
        KEEP(*(.RAM_functionsDATA))
        KEEP(*(.RAM_functionsDATA*))
        RAM_functionsDATA_end = .;   
        . = ALIGN(4);
        RAM_functionsBUFFER_start = .;
       

      /* used by the startup to initialize data */

      /* Initialized data sections goes into RAM, load LMA copy after code */
      .data   
      
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start */
        *(.data)           /* .data sections */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end */
       
  >RAM AT> FLASH

又是一个问题:如何删除单板调用

【问题讨论】:

【参考方案1】:

找到原因我会回答自己的:)

bl 指令相对于 PC 为 += 32MB。我从 FLASH 调用 RAM 中的函数,实际距离远大于 32MB。所以链接器必须放置胶合函数调用。

【讨论】:

以上是关于LINKER 脚本 GCC 如何避免单板调用的主要内容,如果未能解决你的问题,请参考以下文章

如何避免从 Bash 脚本中多次调用 Python 解释器?

如何避免从 Bash 脚本中多次调用 Python 解释器?

gcc - 如何使用地址清理器

如何启用递归函数以避免堆栈溢出?

如何避免由于内存不足导致的gcc崩溃

[GCC] Linker