Вызов функции C из функции ARM, определенной с помощью __asm - PullRequest
0 голосов
/ 26 июня 2018

У меня проблемы с пониманием моего компилятора. Мы используем утилиту Scons для компиляции кода ARM для процессора M0 + (в Windows, если это имеет значение. Это компиляция ARMCC). Я пытаюсь захватить адрес указателя стека во время прерывания, используя ответ на этот вопрос .

Для моего компилятора я получаю следующее: Error: #20: identifier "asm" is undefined Единственный способ, которым я смог получить его (в основном) для компиляции, был следующим:

  void IRQHandler_real( uint32_t *sp )
  {
     // Do some work
  }

  __asm void IRQHandler( void )
  {
     MOV R0,SP
     ADDS R0, #1
     LDR R1, =IRQHandler_real //<<-- This line fails
     BX R1
  }

Код ошибки

  Error: A1516E: Bad symbol 'IRQHandler_real', not defined or external

Замена двух последних сборочных линий на BL IRQHandler_real приводит к той же ошибке.

Этот ответ объясняет, что встроенная сборка чрезвычайно зависит от компилятора, поэтому я не смог найти пример, соответствующий моему коду.

Я прочитал здесь , что мне нужен вызов "extern C", но я пока не нашел подробностей о том, как это выглядит.

Я дважды проверил мой синтаксис скомпилированного кода процессора, и он выглядит идентично командам, которые я использую. Я думаю, что символ не определен во время оценки сборки. Я просто не понял, как определить и связать символы.

TL: DR, мне нужно вызвать функцию C из сборки ARM, но я не прошел мимо компилятора.

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Похоже, что компилятор оценивает код ARM отдельно от и после того, как весь код C будет оценен. Я исправил это, импортировав функцию с помощью команды IMPORT. Мой окончательный код выглядит так:

IMPORT IRQHandler_real
PUSH { R4, lr }
MOV R4, SP; The compiler does this from the C code, I'm assuming to avoid a hardware limitation.
MOV R0, R4
BL IRQHandler_real
POP { R4, PC }
ENDP

Это работает для ARMCC 5.6. Я думаю, что большая часть документации для GCC ARM (asm("statement");). Я все еще получаю Warning: #667-D: "asm" function is nonstandard, поэтому я с радостью приму "более правильный" ответ, если таковой существует.

0 голосов
/ 26 июня 2018

Если ваш компилятор является компилятором C ++, вам нужно использовать extern "C", как этот;

extern "C" {
  void IRQHandler_real( uint32_t *sp )
  {
     // Do some work
  }
}
...