[英]The Cleanest Reset for an ARM Processor
最近,我一直在清理一些在 ARM7 controller 上運行的 C 代碼。在某些情況下(升級、致命錯誤等),程序將執行重置。 目前它只是跳轉到 0 並假定啟動代碼將正確地重新初始化所有內容。 這讓我開始思考什么是 ARM 重置的最佳程序,如“不留痕跡”。 這是我的第一個嘗試:
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)();
}
此代碼假定 IAR ARM 編譯器和 At91Lib。 有什么我沒有考慮到的嗎?
實現“硬復位”的最佳解決方案,就是簡單地跳過復位向量,是強制看門狗定時器復位 - 如果你有一個,那就是。
由於你的頭銜是“最干凈的重置”,這是我的建議。 如果您只是“跳轉到復位向量”,系統可能處於任意數量的狀態(外設仍處於活動狀態,正在進行ADC轉換等...)
我同意@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。
這可能與“Judgar Maygarden”發布的解決方案實際上是相同的,但是他的帖子中使用的標識符似乎是Atmel特定的,而AIRCR寄存器和SYSRESETREQ位是由底層ARMv7-M架構定義的,而不是由Atmel定義的。
這應該夠了吧。 我使用與Atmel SAM3U類似的功能。 我從不打擾輪詢狀態寄存器,但這是一個好主意,我現在就去添加它!
但是,由於處理器已經重置,因此您永遠不應該進入復位向量線。 IAR具有__noreturn
屬性,可用於這些情況以進一步優化編譯器。 我還將我的重置功能加載到ram中(參見__ramfunc
),因為我在固件更新結束時使用,其中微控制器無法從閃存運行。
此外,除非您使用該線路控制外部設備的復位,否則不應使用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);
}
現在,使用 CMSIS __NVIC_SystemReset(void) 不是最干凈的嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.