Можно ли построить Libffi для Cortex-M3?
Вопрос
Я пытаюсь создать библиотеку интерфейса иностранных функций для процессора Cortex-M3 с помощью GCC. Согласно с http://gcc.gnu.org/onlinedocs/gcc/arm-options.html:
-mthumb
Создайте код для набора инструкций большого пальца. По умолчанию является использование 32-разрядного набора инструкций ARM. Эта опция автоматически включает в себя либо 16-разрядные инструкции Thumb-1, либо смешанные 16/32-битные инструкции Thumb-2 на основе параметров -mcpu = name и -march = имени. Этот вариант не передается в ассемблер. Если вы хотите, чтобы файлы ассемблера интерпретировались как код большого пальца, либо добавьте директиву «.Thumb» в источник, либо передайте опцию -mthumb непосредственно в ассемблер, префиксируя ее с -Ва.
Я попытался передавать различные аргументы в ассемблер и не могу понять это. Типичный выход следующим образом:
Файл здания: ../source/ffi/sysv.s
Вызов: GCC Assembler
arm-bare_newlib_cortex_m3_nommu-eabi-gcc -wa, -mthumb-interwork -i "/home/neil/m3projects/robovero/inclode/include" -o "source/ffi/sysv.o" .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, я получаю разные ошибки.
Решение
Ненавижу это говорить, но это усилие для порта. Выполнимый, не обязательно должен быть экспертом по ассемблеру, но ему нужно будет изучить некоторых. Переход от большого пальца к руке легко, Thumb2, мне придется посмотреть на это, большая часть Thumb2 - это всего лишь инструкции. И у большого пальца есть сопоставление с одним к одному с инструкциями, но не наоборот. Большой палец в основном ограничивает вас до нижних 8 регистров во всех инструкциях по рабочей лошади, с особыми версиями или специальными инструкциями для использования верхних регистров. Так много инструкций по вашей руке превратится в более чем одну инструкцию большого пальца.
Первоначально посмотрите, есть ли вариант сборки для создания этого пакета без использования ассемблера или перейти в этот каталог, и посмотрите, есть ли что -то, что вы можете сделать в Makefile, чтобы использовать программу C вместо ассемблера. Я предполагаю, что есть серьезная проблема с использованием C, поэтому есть ассемблер для начала. Thumb2 в теории более эффективен, чем ARM, но это не обязательно означает прямой порт от Arm до thumb2. Таким образом, с некоторым опытом вы сможете передать порт на Thumb2 и сохранить некоторую производительность.
РЕДАКТИРОВАТЬ:
Загрузил файл, о котором идет речь. Определительный материал впереди подразумевает, что он осведомлен о большом пальце и ARMV7M. Это то, как вы попадаете туда, где вы меняли STM, чтобы толкнуть?
Другие советы
Я изменяю sysv.s как follolwing, ошибка вызвана директивой «.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
Ассемблер говорит вам правду-код сборки ARM не может быть собран, чтобы успешно работать на процессоре только для большого пальца 2, такого как M3. У сборщика нет способа сопоставить инструкцию ARM Mnemonics в Opcodes, которые будут иметь смысл для коры-M3. Вам нужно будет перенести файлы сборки в код сборки пальца-2, чтобы заставить вещи работать. В зависимости от того, что делает оригинальный код сборки, вам может повезти, и вместо этого вы сможете портить в C, но это может стоить вам значительного удара.
Добавить "-wa, -mimplicite-It = thumb" в CFLAG GCC, чтобы избежать «Условная инструкция большого пальца в блоке 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]