2012-10-05 6 views
0

하드 오류 처리기에 약간의 어셈블리가 있습니다. 어셈블리는 기본적으로 현재 스택 포인터를 매개 변수 (R0)로 전달합니다. 그것은 그렇게 보입니다 ...IAR EWARM의 인라인 어셈블러에서 다른 모듈의 C 함수를 호출하려면 어떻게해야합니까?

__asm(" mov  r0, sp\n" 
    " bl  SavePC\n" 
    " bx  lr"); 

SavePC가 동일한 c 파일에있을 때 제대로 작동합니다. 그러나 SavePC를 다른 C 파일에 넣을 때 나는 운이 없다. 같은 기능을 가져 오려고 노력했습니다 ...

__asm("IMPORT SavePC\n" 
" mov r0, sp\n" 
" bl SavePC\n" 
" bx lr"); 

...하지만 잘못된 것을해야합니다. 컴파일러는 ...

Error[Og005]: Unknown symbol in inline assembly: "IMPORT" 
Error[Og005]: Unknown symbol in inline assembly: "SavePC" 
Error[Og006]: Syntax error in inline assembly: "Error[54]: Expression can not be forward" 
Error[Og005]: Unknown symbol in inline assembly: "SavePC" 
Error while running C/C++ Compiler 

어셈블리와 함께 C 파일이 SavePC 프로토 타입과 헤더 파일을 포함 ...

extern void SavePC(unsigned long); 

제안은 다음을보고?

+0

당신은 기능이 있나요 ** 파일에서 extern으로 정의 된 SavePC ** 이 asm 코드가 상주합니까? –

+0

@ maths-help-seeker 나는 extern - extern void SavePC (unsigned long);로 정의 된 프로토 타입을 가진 SavePC 헤더 파일을 포함한다. 좋은? – Jason

+0

그래. 나는 어셈블러의 매뉴얼을 보러 가고 있었다. EXTERN 을 사용합니다. 가져 오기 대신 이것을 확인해 주시겠습니까? –

답변

1

올바른 전화를 건 경우에도 코드가 작동하지 않습니다.

bl _SavePC 
bx lr 

당신은 bx lr 명령에 LR 레지스터의 값이됩니다 어떻게 생각하십니까? 명령어 자체의 주소! bl 지시문에 설명이 있습니다. 사실 이것은 bx 명령을 사용하는 while (1);입니다.

push lr 
bl _SavePC 
pop pc 

스택 하나를 등록 얻으려면 해당 CMSIS 기능 사용 :

는 중첩 된 함수 호출은 더 다음과 같습니다 메인 스택 포인터 (MSP)에 대한

  • __get_MSP()
  • 을 프로세스 스택 포인터 (PSP)에 대한 __get_PSP()
1

extern을 사용하면 오류가 발생하기 쉽지 않으므로 나쁜 습관입니다. C-99 표준은 extern에 대한 안전한 대안을 제공합니다. extern 키워드없이 헤더 파일에 함수 프로토 타입을 작성해야합니다. 그런 다음 두 C 파일에 헤더 파일을 포함시킵니다. 링커는 다른 파일에 함수를 연결합니다.

예 :

파일 : custom_header.h

void SavePC(unsigned long); 

파일 : source_c_file.c

#include "custom_header.h" 

void SavePC(unsigned long) 
{ 
     .... 
     .... 

     .... 

} 

파일 : user_c_file.c

#include "custom_header.h" 

void someFunction(void) 
{ 
. 
. 
. 

__asm(" mov  r0, sp\n" 
    " bl  SavePC\n" 
    " bx  lr"); 

. 
. 
. 
}