wxfje 发表于 2014-9-3 22:15:57

分享Freescale ARM Cortex-M系列软复位的使用方法

   “复位”这个词对我们搞嵌入式的同志们来说是再熟悉不过了,不过相比于上电复位和硬件管脚复位等我们常见的复位类型来说,软件复位可能对一些初入门道的菜鸟们来说还是比较陌生的东西(记得当初第一次接触软复位的时候,觉着这个东西真的很奇妙,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”字符来触发软件复位,效果还是刚刚的,如果大家手头有相应工具不妨试上一试。

湛泸骏驰 发表于 2014-9-3 22:20:22

今天还在他的博客看了一会哈。。{:lol:}

mypear 发表于 2014-9-3 22:25:40

学习      

wangpengcheng 发表于 2014-9-3 22:31:08

嗯,我在Boot中就用了这招,好用,呵呵!

zwei99999999 发表于 2014-9-3 22:34:50

学习了{:handshake:}            

fengyunyu 发表于 2014-9-3 22:35:52

收藏,学习

laotui 发表于 2014-9-3 22:52:41

我对51用过这招。收藏。

lzl000 发表于 2014-9-3 22:56:26

对stm32用过这个,都是arm的架构嘛

sunnyqd 发表于 2014-9-3 23:02:55

嗯呢,很好用

wanstrive 发表于 2014-9-3 23:18:37

不错不错。。。。。。。

步之道 发表于 2014-9-3 23:30:51

学习了,现在的芯片自带的内部看门狗不是可以实现软件复位嘛

rockyyangyang 发表于 2014-9-3 23:34:12

学习了!!!

bli19 发表于 2014-9-4 03:38:23

长见识了,看上去很短也很有效阿

chwnin 发表于 2014-9-4 07:24:24

学习了,以后用stm32试试。

wxfje 发表于 2014-9-4 22:41:51

湛泸骏驰 发表于 2014-9-3 22:20
今天还在他的博客看了一会哈。。

因为最近就遇到一个难解决的问题,又不想出现情况死机,所以就只能加软复位了

wxfje 发表于 2014-9-4 22:42:53

wangpengcheng 发表于 2014-9-3 22:31
嗯,我在Boot中就用了这招,好用,呵呵!

请教下,在boot中怎么使用呢,我没在boot中使用过,觉得boot应该不需要这个吧

wxfje 发表于 2014-9-4 22:44:25

步之道 发表于 2014-9-3 23:30
学习了,现在的芯片自带的内部看门狗不是可以实现软件复位嘛

这个不一样,看门狗的复位时被动的,而软件复位时主动的,是在我需要复位的时候进行的

wxfje 发表于 2014-9-4 22:46:02

chwnin 发表于 2014-9-4 07:24
学习了,以后用stm32试试。

不一定stm32,各种单片机都可以,只是执行的方式不同但目的都一样

wxfje 发表于 2014-9-4 22:48:02

bli19 发表于 2014-9-4 03:38
长见识了,看上去很短也很有效阿

软件复位的指令本来就很少,以前用一款单片机时,没有软复位的指令,就用两种方式,一就是给个死循环,让看门狗复位,二就是直接让单片机从flash的零地址开始运行

dragon19809200 发表于 2014-9-4 22:51:28

收藏 学习了

wangpengcheng 发表于 2014-9-5 10:45:10

wxfje 发表于 2014-9-4 22:42
请教下,在boot中怎么使用呢,我没在boot中使用过,觉得boot应该不需要这个吧 ...

在Boot中做完Flash编程的事情后我用的它,然后启动后直接判断是否软启,如果是软启动就直接跳到应用程序中,这样有个好处,就是Boot占用的一些资源能释放出来给应用程序!

mcucow 发表于 2014-9-5 10:51:08

若片子可靠 不需要软复位, 一旦不可靠了,软复位也不放心, 所以成本允许养条狗吧

wxfje 发表于 2014-9-5 19:23:53

wangpengcheng 发表于 2014-9-5 10:45
在Boot中做完Flash编程的事情后我用的它,然后启动后直接判断是否软启,如果是软启动就直接跳到应用程序 ...

这个做法不错,看来自己还是欠考虑了

wxfje 发表于 2014-9-5 19:25:08

mcucow 发表于 2014-9-5 10:51
若片子可靠 不需要软复位, 一旦不可靠了,软复位也不放心, 所以成本允许养条狗吧 ...

养狗是必须的,但在前期我是不用狗的,怕用狗发现不了问题,狗只是以防万一的

月光疾風 发表于 2014-9-6 16:52:49

学习了~~

arm_m0 发表于 2014-9-10 16:10:31

挑一句重点出来

“ARM Cortex-M系列MCU则为此专门划出了一个寄存器用来做这种软件复位功能,即SCB_AIRCR寄存器。我们只需置位该寄存器的SYSRESETREQ位即可把内核送往系统复位发生器的请求线置为有效,从而引起整个芯片系统的复位,当然值得一提的是,这种复位时一种系统复位,会把大多数的外设模块复位(有些个别的外设寄存器只能在上电复位的情况下才能复位),但是却不会复位芯片内部的调试模块,所以我们在IAR或者Keil的调试环境下也可以正常监控和使用软件复位,非常方便。”

以前都是用看门狗饿死复位的,还真不知道有这功能,下回试试

浪里白条 发表于 2014-9-10 16:14:49

这个就是软复位嘛,还是硬件看门狗可靠一些。

ZY71 发表于 2014-9-10 16:38:50

在STM32的Hard_Fault中断里用过,以前用STC的时候也有个寄存器操作某个位可以复位的

qqliyunpeng 发表于 2014-9-10 16:43:53

像必须上电复位的51,带有软件复位引脚的,是不是可以设计成按软件复位引脚来下载程序呢,不知LZ知道不知道。看着软件复位挺爽的样子。

829xuming 发表于 2014-9-10 18:44:27

之前搞用s08 的Bootloader时用过,绝对跳转指令实现

青龙 发表于 2014-9-10 18:46:23

嘿嘿,顶一下顶一下

wxfje 发表于 2014-9-10 21:45:01

arm_m0 发表于 2014-9-10 16:10
挑一句重点出来

“ARM Cortex-M系列MCU则为此专门划出了一个寄存器用来做这种软件复位功能,即SCB_AIRCR寄 ...

以前不知道的时候也是饿死狗,知道了这个后,就再也不去饿他了{:lol:}

wxfje 发表于 2014-9-10 21:46:48

浪里白条 发表于 2014-9-10 16:14
这个就是软复位嘛,还是硬件看门狗可靠一些。

我觉得软件复位就是在自己需要复位的时候去进行了,但硬件看门狗的复位是自己无法预料到的情况

wxfje 发表于 2014-9-10 21:48:39

ZY71 发表于 2014-9-10 16:38
在STM32的Hard_Fault中断里用过,以前用STC的时候也有个寄存器操作某个位可以复位的 ...

我也会在Hard Fault加软件复位,以防万一。但在调试阶段,一般都会去找造成Hard Fault的原因

wxfje 发表于 2014-9-10 21:51:58

qqliyunpeng 发表于 2014-9-10 16:43
像必须上电复位的51,带有软件复位引脚的,是不是可以设计成按软件复位引脚来下载程序呢,不知LZ知道不知道 ...

软件复位引脚?那还叫软件复位吗,那个是外部复位引脚吧
你说的下载程序就不是很明白了

qqliyunpeng 发表于 2014-9-10 22:06:10

wxfje 发表于 2014-9-10 21:51
软件复位引脚?那还叫软件复位吗,那个是外部复位引脚吧
你说的下载程序就不是很明白了 ...


这里的rst2低电压复位,我理解错了,只是最近看到有款产品用到按键按下,就能整个系统复位,并且能下载程序,感觉很神奇。省去了拔掉电源在上电的烦恼。一直想不通。

zhaotyue 发表于 2014-9-19 16:19:10

思路很好,学习了!         

divineliu 发表于 2014-9-19 16:24:34

这个比MSP430方便一点,MSP430都是故意写错狗的密码来实现软复位的。

32MCU 发表于 2014-9-23 08:58:42


收藏,学习。
页: [1]
查看完整版本: 分享Freescale ARM Cortex-M系列软复位的使用方法