Сценарий LINKER GCC, как избежать вызова шпона - PullRequest
1 голос
/ 07 мая 2019

Я работаю над проектом, где я копирую некоторые функции в ОЗУ из FLASH и вызываю их. Все в порядке, за исключением одной маленькой проблемы, которую я имею - если я вызываю функцию напрямую, компилятор добавляет вызов фанеры (который правильно вызывает функцию в ОЗУ).

ЕСЛИ я звоню через указатель, то все в порядке. Отладчик показывает, что разрешенный адрес функции правильный.

#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>

Отладчик показывает правильные адреса.

enter image description here

и соответствующая часть сценария компоновщика

  OVERLAY : NOCROSSREFS
  {
      .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 Ответ

0 голосов
/ 08 мая 2019

Я отвечу сам, как нашел reasun:)

Инструкция bl - + = 32 МБ относительно ПК.Я вызывал функцию в ОЗУ из FLASH, и фактическое расстояние было намного длиннее 32 МБ.Таким образом, компоновщик должен был выполнить вызов функции фанеры.

...