3

最近、ARM7コントローラーで実行されるいくつかのCコードをクリーンアップしています。状況によっては(アップグレード、致命的なエラーなど)、プログラムはリセットを実行します。現在、0にジャンプし、起動コードがすべてを正しく再初期化すると想定しています。ARMをリセットするための「LeaveNoTrace」の最良の手順は何かを考えるようになりました。これが私の最初の亀裂です:

void Reset(void)
{
   /* Disable interrupts */
   __disable_interrupts();

/* Reset peripherals, externals and processor */
AT91C_BASE_RSTC->RSTC_RCR = AT91C_RSTC_KEY | AT91C_RSTC_PERRST | AT91C_RSTC_EXTRST| AT91C_RSTC_PROCRST;

while(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_SRCMP);

/* Jump to the reset vector */
(*(void(*)())0)();
}

このコードは、IARARMコンパイラとAt91Libを想定しています。私が考慮していないことはありますか?

4

3 に答える 3

9

単にリセットベクトルをジャンプするのではなく、「ハードリセット」を実行するための最良の解決策は、ウォッチドッグタイマーを強制的にリセットすることです。

あなたのタイトルは「最もクリーンなリセット」なので、それが私のアドバイスです。単に「ベクトルをリセットするためのジャンプ」を実行すると、システムは任意の数の状態になる可能性があります(周辺機器がまだアクティブである、ADC変換が進行中など)。

于 2010-05-14T16:17:02.837 に答える
4

私は@Danに同意します。システムにウォッチドッグタイマーが利用できる場合、それは最もクリーンなボード全体のリセットを提供するはずです。ただし、プロセッサがARMv7-Mアーキテクチャ(Cortex-M3など)の場合、特定の実装によっては、使用可能なウォッチドッグタイマーがなくても、次のことができる場合があります。

#define SYSRESETREQ    (1<<2)
#define VECTKEY        (0x05fa0000UL)
#define VECTKEY_MASK   (0x0000ffffUL)
#define AIRCR          (*(uint32_t*)0xe000ed0cUL) // fixed arch-defined address
#define REQUEST_EXTERNAL_RESET (AIRCR=(AIRCR&VECTKEY_MASK)|VECTKEY|SYSRESETREQ)

printf("\nRequesting an external reset...\n");
fflush(stdout);
REQUEST_EXTERNAL_RESET;
printf("\nIt doesn't seem to have worked.\n");
fflush(stdout);

ARMv7-Mアーキテクチャリファレンスマニュアルを参照して、AIRCRおよびSYSRESETREQを検索してください。

これは「Maygarden判事」が投稿したものと実質的に同じ解決策かもしれませんが、彼の投稿で使用されている識別子はAtmel固有であるように見えますが、AIRCRレジスタとSYSRESETREQビットはAtmelではなく基盤となるARMv7-Mアーキテクチャによって定義されています。

于 2014-03-25T23:04:53.420 に答える
1

それでうまくいくはずです。AtmelSAM3Uでも同様の機能を使用しています。ステータスレジスタをポーリングすることはありませんでしたが、それは良い考えであり、今すぐ追加します。

ただし、プロセッサはすでにリセットされているため、リセットベクトルラインに到達しないでください。IARには、__noreturnこれらの場合に使用する属性があり、コンパイラーをさらに最適化できます。__ramfuncまた、ファームウェアの更新の最後にマイクロコントローラーをフラッシュから実行できない場合に使用するため、リセット機能をRAMにロードします(を参照)。

また、その回線で外部デバイスのリセットを制御している場合を除いて、AT91C_RSTC_EXTRSTフラグは必要ありません。

__noreturn void Reset(void)
{
    __disable_interrupts();

    AT91C_BASE_RSTC->RSTC_RCR = AT91C_RSTC_KEY |
                                AT91C_RSTC_PERRST |
                                AT91C_RSTC_EXTRST |
                                AT91C_RSTC_PROCRST;

    while (AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_SRCMP);
}
于 2010-05-14T13:43:55.260 に答える