最近在基于S32K116和YMODEM调试IAP升级,但总是通信不成功,经过一个周的艰苦努力,终于调试成功,现将过程记录如下:
首先经过测试,YMODEM协议是没有问题的,问题出现在读写flash的过程中,经过在读写flash函数的前后加断点,发现前面的断点可以运行到,而后面的断点无法运行到,说明程序卡死在读写flash的函数中。
使用在线仿真进入函数中,通过单步调试,发现可以正常运行,也可以正常将数据写入flash中,继续通过加断点的方式进一步确认出问题的语句,发现程序卡在这个函数中:
static status_t FLASH_DRV_CommandSequence(const flash_ssd_config_t *pSSDConfig)
这个函数是对flash操作具体实现的函数,通过在这个函数内加断点调试,是可以运行通过的,但是把断点取消后就又会出现卡死或者复位的情况。
经过各种尝试和查阅资料后,看到有资料说:
- 在线仿真时,加断点的函数是在加载到RAM中运行的。
- flash在擦除和写入时,是无法进行去读的。
也就是说,出现以上情况的原因是:加断点在线运行时,将函数加载到RAM中运行,在操作flash的同时,可以正确从RAM中加载下一句程序,从而顺利执行程序。而在不加断点时,并没有将FLASH_DRV_CommandSequence加载到RAM中,在操作flash时,就无法读取flash,无法加载下一句程序,从而造成卡死、复位等情况,且对flash操作失败。
因此解决方法为:将该函数加载到RAM中即可!
具体实现方法参考:KEIL中如何程序在 RAM 中运行_羽化的博客-优快云博客
经过使用第一种方法,即可成功将函数记载到RAM中,并可正确执行flash的操作,实现IAP升级等功能。
注:1、其实函数FLASH_DRV_CommandSequence的前面已经加入RAM的操作,不过不清楚为什么没有起作用,应该是配置不对导致的,有大佬知道如何解决还请不吝赐教!
START_FUNCTION_DECLARATION_RAMSECTION
static status_t FLASH_DRV_CommandSequence(const flash_ssd_config_t *pSSDConfig)
2、在KEIL中如何程序在 RAM 中运行_羽化的博客-优快云博客中 ,我们需要了解离散加载文件的使用,其实我们需要关注的只有一句
*.o(RAMCODE)
将这一句放到RAM的section中即可。