0

ハードフォールトハンドラーに少し組み立てがあります。アセンブリは基本的に、現在のスタック ポインターをパラメーターとして (R0 で) 渡すことを目的としています。みたいですね...

__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);

提案?

4

2 に答える 2

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");

.
.
.
}
于 2012-10-11T19:53:28.140 に答える
1

あなたのコードは、正しい呼び出しでも機能しません。

bl _SavePC
bx lr

命令のLRレジスタの値はどうなると思いますか? bx lr命令自体のアドレス!bl命令はそれをそこに置きました。これは事実上while (1);、bx 命令を使用したものです。

ネストされた関数呼び出しは、次のようになります。

push lr
bl _SavePC
pop pc

スタック レジスタを取得するには、対応する CMSIS 関数を使用します。

  • __get_MSP()メイン スタック ポインター (MSP) 用
  • __get_PSP()プロセス スタック ポインター (PSP) 用
于 2012-10-07T14:26:55.130 に答える