2011-01-16 5 views
2

GCC를 사용하는 Cortex-M3 프로세서 용 외부 함수 인터페이스 라이브러리를 작성하려고합니다. http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html에 따르면Cortex-M3 용 Libffi를 만들 수 있습니까?

-mthumb
Generate code for the Thumb instruction set. The default is to use the 32-bit ARM instruction set. This option automatically enables either 16-bit Thumb-1 or mixed 16/32-bit Thumb-2 instructions based on the -mcpu=name and -march=name options. This option is not passed to the assembler. If you want to force assembler files to be interpreted as Thumb code, either add a `.thumb' directive to the source or pass the -mthumb option directly to the assembler by prefixing it with -Wa.

내가 어셈블러에 여러 가지 다양한 인수를 전달 시도하고 그것을 알아낼 수 없습니다. 일반적인 출력은 다음과 같습니다 :

Building file: ../source/ffi/sysv.S
Invoking: GCC Assembler
arm-bare_newlib_cortex_m3_nommu-eabi-gcc -Wa,-mthumb-interwork -I"/home/neil/m3projects/robovero/firmware/include" -o"source/ffi/sysv.o" "../source/ffi/sysv.S"
../source/ffi/sysv.S: Assembler messages:
../source/ffi/sysv.S:145: Error: selected processor does not support ARM opcodes
../source/ffi/sysv.S:147: Error: attempt to use an ARM instruction on a Thumb-only processor -- `stmfd sp!,{r0-r3,fp,lr}'
...

내가 조립 전문가가되기없이 코어 텍스 M3에 libffi를 사용할 수 있습니까?

arm-bare_newlib_cortex_m3_nommu-eabi를 호출 할 때 직접 다른 오류가 발생합니다.

답변

1

나는 그것을 말하는 것이 싫지만 포팅 작업입니다. Doable은 반드시 어셈블러 전문가 일 필요는 없지만 일부는 배워야합니다. 엄지에서 팔로가는 것은 쉽습니다. 엄지 2, 나는 그것을보아야 만합니다. 엄지 손가락 2의 대부분은 단지 엄지 손가락 지시입니다. 엄지 손가락은 일대일 지침에 따라 일대일로 매핑되지만 다른 방법으로는 매핑되지 않습니다. Thumb은 주로 상위 레지스터를 사용하기위한 특별 버전 또는 특별 지침과 함께 모든 주력 지침의 하위 8 개 레지스터로 제한합니다. 팔 지침의 많은 부분이 하나 이상의 엄지 지시로 바뀔 것입니다.

처음에는 어셈블러를 사용하지 않고이 패키지를 빌드하는 빌드 옵션이 있는지 확인하거나 해당 디렉토리로 이동하여 어셈블러 대신 C 프로그램을 사용하기 위해 makefile에서 수행 할 수있는 작업이 있는지 확인하십시오. 거기에 왜 C와 함께 시작하는 어셈블러가 사용하는 심각한 성능 문제가 있다고 가정합니다. 이론적으로 Thumb2는 팔보다 효율적이지만 팔에서 엄지 2 로의 직접 포트를 의미하지는 않습니다. 따라서 약간의 경험을 통해 포트를 thumb2에 전달하고 성능을 유지할 수 있습니다.

편집 :

해당 파일을 다운로드했습니다. 정면을 정의하면 엄지 손가락과 armv7m을 모두 인식하고 있음을 의미합니다. 그게 당신이 당신이 밀어 넣기 위해 stm을 바꾸고있는 곳으로가는 방법입니까?

+0

libffi-discuss의 누군가는 _armways_ 암시 모드를 암 모드로 설정하려고 시도한 .arm 명령어가 있음을 지적 했으므로 확실히 사용할 수 없습니다. 감사! – Neil

1

어셈블러가 사실을 말하고 있습니다. ARM 어셈블리 코드는 M3와 같은 Thumb-2 전용 프로세서에서 성공적으로 작동하도록 어셈블 할 수 없습니다. 어셈블러가 ARM 명령어 니모닉을 Cortex-M3에 적합한 opcode로 매핑 할 수있는 방법은 없습니다. 일을 처리하려면 어셈블리 파일을 Thumb-2 어셈블리 코드로 이식해야합니다. 원래 어셈블리 코드가 무엇을 하느냐에 따라 운이 좋으면 대신 C로 포팅 할 수 있지만 성능이 크게 저하 될 수 있습니다.

+0

을 "IT 차단에 엄지 손가락 조건부 명령해야한다"방지하기 위해 GCC CFLAGS에 "-Wa는 -mimplicit-는 엄지 손가락 ="!, { r0-r3, fp, lr}을 push {r0-r3, fp, lr}와 함께 사용하면 오류가 발생합니다. ARMv7-M 아키텍처 참조 설명서에 모든 버전의 Thumb 명령어 세트에 유효 함이 나와 있습니다. – Neil

+0

아니요, Cortex M3에는 알고있는 모든 설계에 FP 레지스터가 없습니다. 코 프로세서 지침은 소프트웨어에 있어야하며, 코드에서 많이 사용하는 경우 실제 성능이 저하됩니다. –

+0

FP는 R11의 별칭입니다. –

2

다음과 같이 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 
0

추가 오류를 그냥 STMFD SP는 대체

--- 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] 
관련 문제