jicheng0622

【原创】Freescale ARM Cortex-M系列软复位的使用方法

0
阅读(12568)

    “复位”这个词对我们搞嵌入式的同志们来说是再熟悉不过了,不过相比于上电复位和硬件管脚复位等我们常见的复位类型来说,软件复位可能对一些初入门道的菜鸟们来说还是比较陌生的东西(记得当初第一次接触软复位的时候,觉着这个东西真的很奇妙,MCU自己对自己进行复位,想想就觉着很有意思,或许一直就是这种好奇的乐趣让我等屌丝对嵌入式的感情越陷越深吧,哈哈),即使对搞嵌入式的老鸟来说,软复位也是一种很有用的手段。

    可能说到这,还是有些人犯迷糊,软件复位到底是个什么东西,它到底有什么用。上面提到我们常见的上电复位和外部管脚Reset复位等严格来讲都是MCU被动的复位(看门狗复位我的定义是把它当做硬件复位来对待,因为实际上看门狗也只不过是MCU内部一个独立的外设模块罢了),即外部的触发条件让MCU完成对系统的复位操作,而软件复位则是通过软件触发让MCU自己对自己进行复位,也就是说通过执行某个指令来触发MCU的系统复位。软件复位的好处也是显而易见的,比如可以用在远程代码升级(一般我们做bootloader的时候通常需要让芯片复位等待通信接口的数据,然后代码升级之后一般也会再次触发复位让芯片重新执行新的用户代码,当然有些需要work on-line固件升级的领域除外),或者程序监控(如果监测到某些错误可以触发软件复位让芯片重新执行来消除一些异常,类似于我们手机死机拆电池,呵呵,当然它还达不到彻底断电的效果),当然软件复位也给广大做调试器仿真器的厂家提供了极大的便利,我们会发现调试接口的Reset管脚不接的情况下我们也能正常对芯片进行调试和下载,这就是软件复位的功劳了,哈哈。

    说到这里,可能会有些聪明的人提到,我们把PC指针直接指向代码的起始地址让它重头开始执行不就完了,咳咳,的确有点投机取巧,不过这种方法只能是让内核重新执行却无法让这个MCU系统复位,所以其作用还是有限的。而本篇的主角,ARM Cortex-M系列MCU则为此专门划出了一个寄存器用来做这种软件复位功能,即SCB_AIRCR寄存器。我们只需置位该寄存器的SYSRESETREQ位即可把内核送往系统复位发生器的请求线置为有效,从而引起整个芯片系统的复位,当然值得一提的是,这种复位时一种系统复位,会把大多数的外设模块复位(有些个别的外设寄存器只能在上电复位的情况下才能复位),但是却不会复位芯片内部的调试模块,所以我们在IAR或者Keil的调试环境下也可以正常监控和使用软件复位,非常方便。

    好了,说了这么多,该上硬菜了,呵呵。我下面直接把在Freescale Cortex-M0+的KL系列上的软件复位的代码贴上来了,其中对SCB_AIRCR寄存器配置中,前面的0x5FA << SCB_AIRCR_VECTKEY_SHIFT为该寄存器的“钥匙”,不得不说ARM将该寄存器保护的很好,还为其配了把钥匙,需要这个钥匙才能对其他的位进行操作,然后置位SYSRESETREQ即可实现软件复位。另外,在这个配置操作的前后,也分别添加了两个__DSB()指令,该指令用来保证在软件复位之前和之后保证内存数据操作都已完成,避免在有些数据还没有来的及更新到目标地址或者目标寄存器前就触发芯片复位从而造成数据丢失,这个还是很重要的,重点提一下。

void software_reset(void) 
{ 
                  __DSB();                                                     /* Ensure all outstanding memory accesses includedbuffered write are completed before reset */ 
                  SCB_AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_SHIFT)      | 
                                 SCB_AIRCR_SYSRESETREQ_MASK); 
                  __DSB();                                                     /* Ensure completion of memory access */ 
                  while(1);                                                    /* wait until reset */ 
}
/********************************************************************/ 
int main (void) 
{ 
    char ch; 
       
    printf("\nRunning the platinum project.\n");
    while(1) 
    { 
        ch = in_char(); 
                
        out_char(ch); 
                if(ch=='A') 
                  software_reset(); 
    } 
}

    下图为我做的一个测试,通过串口发送“A”字符来触发软件复位,效果还是刚刚的,如果大家手头有相应工具不妨试上一试,呵呵。

image

    好了,不多说了,加班加到有点晚了,得抓紧回去了,最近在看湖南台的变形记,真是感慨颇多呀,推荐有空的博友有时间看看,这可不是给湖南台做广告,呵呵。撤了,这点回去正好能看上,哈哈,未完待续~