C ARM处理器最干净的重置

C ARM处理器最干净的重置,c,arm,reset,processor,C,Arm,Reset,Processor,最近,我一直在清理一些运行在ARM7控制器上的C代码。在某些情况下(升级、致命错误等),程序将执行重置。目前,它只是跳到0,并假设启动代码将正确地重新初始化所有内容。这让我开始思考什么才是手臂复位的最佳程序“不留痕迹”。这是我的第一次尝试: void Reset(void) { /* Disable interrupts */ __disable_interrupts(); /* Reset peripherals, externals and processor */ AT91C

最近,我一直在清理一些运行在ARM7控制器上的C代码。在某些情况下(升级、致命错误等),程序将执行重置。目前,它只是跳到0,并假设启动代码将正确地重新初始化所有内容。这让我开始思考什么才是手臂复位的最佳程序“不留痕迹”。这是我的第一次尝试:

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。有什么我没有考虑过的吗?

应该可以。我对Atmel SAM3U使用了类似的函数。我从来没有费心去调查状态登记册,但这是一个好主意,我现在就去添加它

但是,由于处理器将已经重置,因此永远不应到达重置向量行。IAR有一个
\uuuu noreturn
属性,可用于这些情况,以允许进一步优化编译器。我还将重置功能加载到ram中(请参见
\uu 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);
}

与简单地跳过重置向量不同,实现“硬重置”的最佳解决方案是强制看门狗定时器重置--——如果您有看门狗定时器重置,也就是说


因为你的标题是“最干净的重置”,这是我的建议。如果您只需执行“跳转到重置向量”,系统可能处于任意数量的状态(外围设备仍处于活动状态,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);

#定义SYSRESETREQ(1在上面的示例代码中,重置外围设备(内部和外部)完成。AFAIK看门狗重置是最常见的方法。但是,与设置短超时和等待不同,您通常可以向看门狗提供错误的代码-在大多数实现中,它会导致立即重置。手动重置可能会忘记重置某些内容,使用看门狗您无需麻烦。