eCos初探之redboot重启命令:reset

环境参数:
eCos模版:redboot
硬件平台: STM32F103ZET6

1、reset实现的函数调用流程
reset命令对应的函数是:
packages/redboot/current/src/main.c
void do_reset(int argc, char *argv[])
{
    diag_printf("... Resetting.");
    CYGACC_CALL_IF_DELAY_US(2*100000);
    diag_printf("\n");
    CYGACC_CALL_IF_RESET();
    diag_printf("!! oops, RESET not working on this platform\n");
}
CYGACC_CALL_IF_RESET();宏定义在:
packages/hal/common/current/include/hal_if.h
#define CYGACC_CALL_IF_RESET()    CYGACC_CALL_VV0(__call_if_reset_t*, CYGNUM_CALL_IF_RESET)()
   __call_voidVV0(CYGNUM_CALL_IF_RESET, __call_if_reset_t, void)
并最终调用了static void reset(void)函数:
packages/hal/common/current/include/hal_if.c
static __call_if_reset_t reset;
static void reset(void)
{
    CYGARC_HAL_SAVE_GP();
    // With luck, the platform defines some magic that will cause a hardware
    // reset.
#ifdef HAL_PLATFORM_RESET
    HAL_PLATFORM_RESET();
#endif
#ifdef HAL_PLATFORM_RESET_ENTRY
    // If that's not the case (above is an empty statement) there may
    // be defined an address we can jump to - and effectively
    // reinitialize the system. Not quite as good as a reset, but it
    // is often enough.
    goto *HAL_PLATFORM_RESET_ENTRY;
#else
#error " no RESET_ENTRY"
#endif
    CYG_FAIL("Reset failed");
    CYGARC_HAL_RESTORE_GP();
}
由此函数可知,reset的实现有两种方式:
(1)调用平台提供的HAL_PLATFORM_RESET()函数
(2)直接goto到程序入口地址HAL_PLATFORM_RESET_ENTRY处:
#define HAL_PLATFORM_RESET_ENTRY &hal_reset_vsr
hal_reset_vsr指向程序的主入口函数void hal_reset_vsr( void ),关于该函数,注释说明如下:
//==========================================================================
// Main entry point
//
// Enter here from reset via slot 1 of VSR table. The stack pointer is
// already set to the value in VSR slot 0, usually the top of internal
// SRAM.
下面着重讲下第一种(1)复位方式,它涉及到芯片的具体操作。

2、reset实现涉及到的硬件操作
参考以下内容时对照该图:
AIRCR:应用程序中断及复位控制寄存器
技术分享
技术分享
AIRCR寄存器定义可知,在Cortex-M3中,有两种方式可以执行软件复位:
(1)通过置位AIRCR的VECTRESET(AIRCR[0]):
该方式下,复位的作用范围覆盖整个CM3,但不影响内核以外的所有其他电路,所以片上外设和其他电路不受影响。
(2)通过置位AIRCR的SYSRESETREQ(AIRCR[2]):
该方式下,复位操作波及整个芯片上的电路。

3、reset在redboot上的实现
HAL_PLATFORM_RESET()宏实现如下:
#define HAL_PLATFORM_RESET()                                            {                                                                           HAL_WRITE_UINT32(CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_AIRCR,                             CYGARC_REG_NVIC_AIRCR_KEY|                                              CYGARC_REG_NVIC_AIRCR_SYSRESETREQ );                   for(;;);                                                            }
HAL_WRITE_UINT32( _register_, _value_ )作用是往制定的寄存器@ _register_赋值@ _value_ 
在此:
_register_ = CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_AIRCR = 0xE000E000 + 0xD0C = 0xE000ED0C
_value_ = CYGARC_REG_NVIC_AIRCR_KEY | CYGARC_REG_NVIC_AIRCR_SYSRESETREQ = (0x5FA<<16) + (1<<2)
0x5FA是访问该寄存器的钥匙。
for(;;);死循环保证后面的指令不被执行到。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。