Kinetis KL系列watchdog 注意事项
0赞某客户和我反映他在使用KL17时发现从Bootloader跳到Application后,开门狗没法正常复位,但是不用Bootloader时开门狗却是正常工作的。于是我就在KSDK2.0上去复现这个问题,刚开始也是遇到了同样的现象,
我把这个问题的整个过程给记录下来,
1)在原来的GPIO例子中,最后加入
// Jump to user application GoToUserApp(0x4000); return 0;
typedef void (*pFunction)(void);
void GoToUserApp(uint32_t app_start_addr)
{
pFunction jump_to_application;
uint32_t jump_addr;
jump_addr = *(uint32_t*)(app_start_addr + 4); //
if(*((uint32_t*)app_start_addr) != 0xFFFFFFFFUL )
{
jump_to_application = (pFunction)jump_addr;
__set_MSP(*(uint32_t*)app_start_addr); //
SCB->VTOR = app_start_addr;
jump_to_application();//
}
}2)在cop例子中
修改scf文件,注意KSDK2.0中使用的不是Keil里默认的分散加载文件,而是自己写的

点击Edit,将其中的
#define m_interrupts_start 0x00000000 #define m_interrupts_size 0x00000200 #define m_flash_config_start 0x00000400 #define m_flash_config_size 0x00000010 #define m_text_start 0x00000410 #define m_text_size 0x0003FBF0
改为:
#define m_interrupts_start 0x00000000+0x4000 #define m_interrupts_size 0x00000200 #define m_flash_config_start 0x00000400+0x4000 #define m_flash_config_size 0x00000010 #define m_text_start 0x00000410+0x4000 #define m_text_size 0x0003FBF0
然后分别将两个程序下载进去,你会发现程序虽然运行到cop工程,但是watchdog并没有其作用。那么原因是什么呢?
原因是:在gpio工程中
void SystemInit (void) {
#if (ACK_ISOLATION)
if(PMC->REGSC & PMC_REGSC_ACKISO_MASK) {
PMC->REGSC |= PMC_REGSC_ACKISO_MASK; /* VLLSx recovery */
}
#endif
#if (DISABLE_WDOG)
/* SIM->COPC: ?=0,COPCLKSEL=0,COPDBGEN=0,COPSTPEN=0,COPT=0,COPCLKS=0,COPW=0 */
SIM->COPC = (uint32_t)0x00u;
#endif /* (DISABLE_WDOG) */#ifndef DISABLE_WDOG #define DISABLE_WDOG 1 #endif
在这里有对watchdog的操作,实际上是把watchdog给关了,就算开关了,cop工程也会打开啊。。为什么不起作用呢??? 原因是COPC寄存器是written only once,所以后面的操作就没作用了

cop工程,DISABLE_WDOG宏是在这里定义的

这个逻辑是这样的,正常如果没有定义DISABLE_WDOG=0的话,程序里会把DISABLE_WDOG设置1,那么就会把看门狗关掉。也就是说定义DISABLE_WDOG=0的话,看门狗就不会关了。
那么这个问题该如何解决呢?
你第一反应应该是在Bootloader里把DISABLE_WDOG 宏设置为0,不关闭watchdog,但是这样就会出现一个问题,假设Bootloader里停留时间太久,芯片就会复位了,这种情况下需要自己控制好时间去不断喂狗。
还有一种方式是:在Bootloader里,刚开始判断是否需要升级,不升级的话就直接跳到APP里
如果需要升级的话,先关闭watchdog,等升级完成重新软复位一下,之后再跳到APP。
