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。