自从完成Redboot的启动工作以来,一直有一个问题困扰着我,只是由于影响不大,所以都没有进行研究。这个问题就是在使用reset命令重启的时候,总是会在“... Resetting.”之后打印出乱码,和前面在cs8900驱动中遇到的乱码类似的。
今天有点闲工夫,于是决定解决这个问题,首先看了一下代码,发现经过了好几次的宏替换,实际上在do_reset函数里面最终调用的是\common\current\src\hal_if.c中的reset函数。reset函数采用了两种方式来重启系统,一种是调用平台提供的HAL_PLATFORM_RESET()函数;另一种就是简单的goto到入口地址HAL_PLATFORM_RESET_ENTRY处执行。
本来想通过加入while(1)死循环定位函数,然后用AxD进行单步调试来找到问题所在。先将死循环放到reset函数的起始位置,发现还没有出现乱码,但是单步执行却没有发生重启;然后将死循环的位置往后挪,却突然发现将死循环放到HAL_PLATFORM_RESET()之后,系统运行reset命令时竟然没有出现乱码并成功重启了。
屏蔽掉HAL_PLATFORM_RESET()和死循环后,再下载试运行reset命令,重启成功时乱码又出现了。这说明乱码是由于简单的采用goto语句跳转到入口地址时出现的,具体是怎么引起的还不清楚。实际上reset函数里面的注释也表明这种方法Not quite as good as a reset, but it is often enough.再看看HAL_PLATFORM_RESET(),实际上就是通过采用一个很短时间的看门狗复位来实现的。由于reset函数在两种复位的实现之间没有等待看门狗复位的时间,所以实际上起作用的是后面这个方法,在之间插入了死循环之后就使得看门狗复位成功了。于是修改了一下reset函数,在HAL_PLATFORM_RESET()之后加入了一段延时程序,以便保证看门狗复位能够起作用。即使在看门狗复位无法工作的情况下,还可以使用goto语句直接重启!
阅读(7354) | 评论(16) | 转发(0) |