Можно ли построить Libffi для Cortex-M3? - PullRequest
3 голосов
/ 16 января 2011

Я пытаюсь создать библиотеку интерфейса сторонних функций для процессора Cortex-M3, используя GCC. Согласно http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html:

-mthumb
Создать код для набора команд Thumb. По умолчанию используется 32-битный набор инструкций ARM. Эта опция автоматически включает 16-битные Thumb-1 или смешанные 16/32-битные инструкции Thumb-2 на основе параметров -mcpu = name и -march = name. Эта опция не передается ассемблеру. Если вы хотите, чтобы файлы ассемблера интерпретировались как код Thumb, либо добавьте директиву .thumb к источнику, либо передайте опцию -mthumb непосредственно ассемблеру, добавив префикс -Wa.

Я пытался передать различные аргументы ассемблеру и не могу понять это. Типичный вывод следующим образом:

Файл сборки: ../source/ffi/sysv.S
Вызов: GCC Assembler
arm-bare_newlib_cortex_m3_nommu-eabi-gcc -Wa, -mthumb-interwork -I "/ home / neil / m3projects / robovero / firmware / включает в себя источник" -o "/ ffi / sysv.o" ../source/ffi/sysv .S "
../source/ffi/sysv.S: Сообщения ассемблера:
../source/ffi/sysv.S:145: Ошибка: выбранный процессор не поддерживает коды операций ARM
../source/ffi/sysv.S:147: Ошибка: попытка использовать инструкцию ARM на процессоре с большим пальцем - `stmfd sp!, {r0-r3, fp, lr} '
...

Могу ли я использовать libffi на Cortex-M3, не становясь экспертом по сборке?

Возможно, стоит отметить, что когда я вызываю arm-bare_newlib_cortex_m3_nommu-eabi-as напрямую, я получаю разные ошибки.

Ответы [ 4 ]

2 голосов
/ 01 ноября 2012

Я изменяю sysV.S следующим образом: ошибка вызвана директивой ".arm", при использовании cortex-m3 ее следует закомментировать.

#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
#undef __THUMB_INTERWORK__
#endif

#if __ARM_ARCH__ >= 5
# define call_reg(x)    blx x
#elif defined (__ARM_ARCH_4T__)
# define call_reg(x)    mov lr, pc ; bx x
# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
#  define __INTERWORKING__
# endif
#else
# define call_reg(x)    mov lr, pc ; mov    pc, x
#endif

/* Conditionally compile unwinder directives.  */
#ifdef __ARM_EABI__
#define UNWIND
#else
#define UNWIND @
#endif  


#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
.macro  ARM_FUNC_START name
    .text
    .align 0
    .thumb
    .thumb_func
#ifdef __APPLE__
    ENTRY($0)
#else
    ENTRY(\name)
#endif
#ifndef __ARM_ARCH_7M__ /* not cortex-m3 */
    bx  pc
    nop
    .arm
#endif
    UNWIND .fnstart
/* A hook to tell gdb that we've switched to ARM mode.  Also used to call
   directly from other local arm routines.  */
#ifdef __APPLE__
_L__$0:
#else
_L__\name:
#endif
.endm
1 голос
/ 07 февраля 2011

Ненавижу это говорить, но это усилия по переносу.Выполнимо, не обязательно быть экспертом по ассемблеру, но нужно будет выучить кое-что.Легко переходить от большого пальца к руке, thumb2, мне пришлось бы искать это, большая часть thumb2 - это просто инструкции большого пальца.и у большого пальца есть однозначное соответствие инструкциям, но не наоборот.Thumb в основном ограничивает вас нижними 8 регистрами по всем инструкциям рабочей лошадки со специальными версиями или специальными инструкциями по использованию верхних регистров.Так что многие из ваших инструкций по руке превратятся в более чем одну инструкцию для большого пальца.

Сначала посмотрите, есть ли опция сборки для сборки этого пакета без использования ассемблера, или перейдите в этот каталог и посмотрите, есть ли что-то, что вы можете сделать в make-файле, чтобы использовать программу на C вместо ассемблера.Я предполагаю, что существует серьезная проблема с производительностью при использовании C, поэтому для начала существует ассемблер.Thumb2 в теории более эффективен, чем рука, но это не обязательно означает прямой порт от руки к большому пальцу2.Поэтому, имея некоторый опыт, вы сможете передать порт на thumb2 и сохранить некоторую производительность.

РЕДАКТИРОВАТЬ:

Загрузил рассматриваемый файл.Определенный материал впереди подразумевает, что он знает как большой палец, так и armv7m.это то, как вы попадаете туда, где вы меняете stm для push?

1 голос
/ 16 января 2011

Ассемблер говорит вам правду - код сборки ARM не может быть собран для успешной работы на процессоре, поддерживающем только Thumb-2, например M3.Для ассемблера нет способа отобразить мнемонику команд ARM в коды операций, которые будут иметь смысл для Cortex-M3.Вам нужно будет перенести файлы сборки на код сборки Thumb-2, чтобы все заработало.В зависимости от того, что делает исходный код сборки, вам может повезти, и вы сможете вместо этого портировать на C, но это может стоить вам значительного снижения производительности.

0 голосов
/ 01 ноября 2012

Добавьте «-Wa, -mimplicit-it = thumb» в gcc CFLAGS, чтобы избежать «условная инструкция большого пальца должна быть в блоке IT» ошибка

--- libffi.orig/src/arm/sysv.S
+++ libffi/src/arm/sysv.S
@@ -91,6 +91,10 @@
 # define __ARM_ARCH__ 7
 #endif

+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+#undef __THUMB_INTERWORK__
+#endif
+
 #if __ARM_ARCH__ >= 5
 # define call_reg(x)   blx x
 #elif defined (__ARM_ARCH_4T__)
@@ -121,9 +125,11 @@
 #else
    ENTRY(\name)
 #endif
+#ifndef __ARM_ARCH_7M__ /* not cortex-m3 */
    bx  pc
    nop
    .arm
+#endif
    UNWIND .fnstart
 /* A hook to tell gdb that we've switched to ARM mode.  Also used to call
    directly from other local arm routines.  */
@@ -164,6 +170,10 @@ _L__\name:
 #endif
 .endm

+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+   .syntax unified
+#endif
+
    @ r0:   ffi_prep_args
    @ r1:   &ecif
    @ r2:   cif->bytes
@@ -180,7 +190,11 @@ ARM_FUNC_START ffi_call_SYSV
    UNWIND .setfp   fp, sp

    @ Make room for all of the new args.
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+   sub sp, sp, r2
+#else
    sub sp, fp, r2
+#endif

    @ Place all of the ffi_prep_args in position
    mov r0, sp
@@ -193,7 +207,12 @@ ARM_FUNC_START ffi_call_SYSV
    ldmia   sp, {r0-r3}

    @ and adjust stack
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+   mov lr, sp
+   sub lr, fp, lr  @ cif->bytes == fp - sp
+#else
    sub lr, fp, sp  @ cif->bytes == fp - sp
+#endif
    ldr ip, [fp]    @ load fn() in advance
    cmp lr, #16
    movhs   lr, #16
@@ -305,7 +324,13 @@ ARM_FUNC_START ffi_closure_SYSV
    beq .Lretlonglong
 .Lclosure_epilogue:
    add sp, sp, #16
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+   ldr     ip, [sp, #4]
+   ldr     sp, [sp]
+   mov     pc, ip
+#else
    ldmfd   sp, {sp, pc}
+#endif
 .Lretint:
    ldr r0, [sp]
    b   .Lclosure_epilogue
@@ -381,7 +406,12 @@ LSYM(Lbase_args):
    ldmia   sp, {r0-r3}

    @ and adjust stack
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+   mov lr, sp
+   sub lr, ip, lr  @ cif->bytes == (fp - 64) - sp
+#else
    sub lr, ip, sp  @ cif->bytes == (fp - 64) - sp
+#endif
    ldr ip, [fp]    @ load fn() in advance
         cmp    lr, #16
    movhs   lr, #16
@@ -469,7 +499,13 @@ ARM_FUNC_START ffi_closure_VFP

 .Lclosure_epilogue_vfp:
    add sp, sp, #72
+#ifdef __ARM_ARCH_7M__ /* cortex-m3 */
+   ldr     ip, [sp, #4]
+   ldr     sp, [sp]
+   mov     pc, ip
+#else
    ldmfd   sp, {sp, pc}
+#endif

 .Lretfloat_vfp:
    flds    s0, [sp]
...